From db832d4255e77c9edcedd7c5fc92750dba4fe41c Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Fri, 7 Mar 2025 21:47:34 -0300 Subject: [PATCH] use sonic json parser and other minor performance improvements. --- blossom/authorization.go | 4 ++-- go.mod | 14 +++++++------- go.sum | 24 ++++++++++++------------ handlers.go | 16 ++++++++++------ nip86.go | 4 ++-- 5 files changed, 33 insertions(+), 29 deletions(-) diff --git a/blossom/authorization.go b/blossom/authorization.go index d45ff2a..43e4b69 100644 --- a/blossom/authorization.go +++ b/blossom/authorization.go @@ -2,7 +2,6 @@ package blossom import ( "bytes" - "encoding/base64" "encoding/json" "fmt" "io" @@ -10,6 +9,7 @@ import ( "strconv" "strings" + "github.com/cloudwego/base64x" "github.com/nbd-wtf/go-nostr" ) @@ -21,7 +21,7 @@ func readAuthorization(r *http.Request) (*nostr.Event, error) { var reader io.Reader reader = bytes.NewReader([]byte(token)[6:]) - reader = base64.NewDecoder(base64.StdEncoding, reader) + reader = base64x.NewDecoder(base64x.StdEncoding, reader) var evt nostr.Event err := json.NewDecoder(reader).Decode(&evt) diff --git a/go.mod b/go.mod index f45a6ad..6238906 100644 --- a/go.mod +++ b/go.mod @@ -4,10 +4,11 @@ go 1.23.1 require ( github.com/bep/debounce v1.2.1 + github.com/cloudwego/base64x v0.1.5 github.com/fasthttp/websocket v1.5.12 - github.com/fiatjaf/eventstore v0.15.0 + github.com/fiatjaf/eventstore v0.16.2 github.com/liamg/magic v0.0.1 - github.com/nbd-wtf/go-nostr v0.50.3 + github.com/nbd-wtf/go-nostr v0.50.4 github.com/puzpuzpuz/xsync/v3 v3.5.0 github.com/rs/cors v1.11.1 github.com/stretchr/testify v1.10.0 @@ -16,15 +17,14 @@ require ( require ( fiatjaf.com/lib v0.2.0 // indirect github.com/ImVexed/fasturl v0.0.0-20230304231329-4e41488060f3 // indirect - github.com/PowerDNS/lmdb-go v1.9.2 // indirect + github.com/PowerDNS/lmdb-go v1.9.3 // indirect github.com/andybalholm/brotli v1.1.1 // indirect github.com/aquasecurity/esquery v0.2.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect - github.com/bytedance/sonic v1.12.10 // indirect - github.com/bytedance/sonic/loader v0.2.3 // indirect + github.com/bytedance/sonic v1.13.1 // indirect + github.com/bytedance/sonic/loader v0.2.4 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/cloudwego/base64x v0.1.5 // indirect github.com/coder/websocket v1.8.12 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/crypto/blake256 v1.1.0 // indirect @@ -66,7 +66,7 @@ require ( go.opentelemetry.io/otel/trace v1.32.0 // indirect golang.org/x/arch v0.15.0 // indirect golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac // indirect - golang.org/x/net v0.34.0 // indirect + golang.org/x/net v0.35.0 // indirect golang.org/x/sys v0.31.0 // indirect google.golang.org/protobuf v1.36.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 0ee2cb4..d03cb13 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,8 @@ filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/ImVexed/fasturl v0.0.0-20230304231329-4e41488060f3 h1:ClzzXMDDuUbWfNNZqGeYq4PnYOlwlOVIvSyNaIy0ykg= github.com/ImVexed/fasturl v0.0.0-20230304231329-4e41488060f3/go.mod h1:we0YA5CsBbH5+/NUzC/AlMmxaDtWlXeNsqrwXjTzmzA= -github.com/PowerDNS/lmdb-go v1.9.2 h1:Cmgerh9y3ZKBZGz1irxSShhfmFyRUh+Zdk4cZk7ZJvU= -github.com/PowerDNS/lmdb-go v1.9.2/go.mod h1:TE0l+EZK8Z1B4dx070ZxkWTlp8RG1mjN0/+FkFRQMtU= +github.com/PowerDNS/lmdb-go v1.9.3 h1:AUMY2pZT8WRpkEv39I9Id3MuoHd+NZbTVpNhruVkPTg= +github.com/PowerDNS/lmdb-go v1.9.3/go.mod h1:TE0l+EZK8Z1B4dx070ZxkWTlp8RG1mjN0/+FkFRQMtU= github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA= github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA= github.com/aquasecurity/esquery v0.2.0 h1:9WWXve95TE8hbm3736WB7nS6Owl8UGDeu+0jiyE9ttA= @@ -18,11 +18,11 @@ github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurT github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ= github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= -github.com/bytedance/sonic v1.12.10 h1:uVCQr6oS5669E9ZVW0HyksTLfNS7Q/9hV6IVS4nEMsI= -github.com/bytedance/sonic v1.12.10/go.mod h1:uVvFidNmlt9+wa31S1urfwwthTWteBgG0hWuoKAXTx8= +github.com/bytedance/sonic v1.13.1 h1:Jyd5CIvdFnkOWuKXr+wm4Nyk2h0yAFsr8ucJgEasO3g= +github.com/bytedance/sonic v1.13.1/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= -github.com/bytedance/sonic/loader v0.2.3 h1:yctD0Q3v2NOGfSWPLPvG2ggA2kV6TS6s4wioyEqssH0= -github.com/bytedance/sonic/loader v0.2.3/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= +github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -64,8 +64,8 @@ github.com/fasthttp/websocket v1.5.12 h1:e4RGPpWW2HTbL3zV0Y/t7g0ub294LkiuXXUuTOU github.com/fasthttp/websocket v1.5.12/go.mod h1:I+liyL7/4moHojiOgUOIKEWm9EIxHqxZChS+aMFltyg= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/fiatjaf/eventstore v0.15.0 h1:5UXe0+vIb30/cYcOWipks8nR3g+X8W224TFy5yPzivk= -github.com/fiatjaf/eventstore v0.15.0/go.mod h1:KAsld5BhkmSck48aF11Txu8X+OGNmoabw4TlYVWqInc= +github.com/fiatjaf/eventstore v0.16.2 h1:h4rHwSwPcqAKqWUsAbYWUhDeSgm2Kp+PBkJc3FgBYu4= +github.com/fiatjaf/eventstore v0.16.2/go.mod h1:0gU8fzYO/bG+NQAVlHtJWOlt3JKKFefh5Xjj2d1dLIs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -131,8 +131,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/nbd-wtf/go-nostr v0.50.3 h1:mRUJLOkCqnNTAwvjtSRogJyN3SUv1lze1UgnmqUBN0Q= -github.com/nbd-wtf/go-nostr v0.50.3/go.mod h1:XJyV09CfSZCtuf1ApdQFc+3RuEYzt4E/pbXn+doA8tQ= +github.com/nbd-wtf/go-nostr v0.50.4 h1:KFMLxL07FPUzrCgllc2AKPP6INip+0MhAy6ZJxCwOyo= +github.com/nbd-wtf/go-nostr v0.50.4/go.mod h1:IoEUVJKvV2308WFhVu8f2OwGC32oEYpFYnV86EH8dqA= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -196,8 +196,8 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= +golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/handlers.go b/handlers.go index 3ffb8ea..81f6d91 100644 --- a/handlers.go +++ b/handlers.go @@ -115,6 +115,8 @@ func (rl *Relay) HandleWebsocket(w http.ResponseWriter, r *http.Request) { onconnect(ctx) } + smp := nostr.NewSonicMessageParser() + for { typ, message, err := ws.conn.ReadMessage() if err != nil { @@ -137,15 +139,17 @@ func (rl *Relay) HandleWebsocket(w http.ResponseWriter, r *http.Request) { continue } + // parse messages sequentially otherwise the world breaks + envelope, err := smp.ParseMessage(message) + + // then delegate to the goroutine go func(message []byte) { - envelope := nostr.ParseMessage(message) - if envelope == nil { - if !rl.Negentropy { - // stop silently - return + if err != nil { + if err == nostr.UnknownLabel && rl.Negentropy { + envelope = nip77.ParseNegMessage(message) } - envelope = nip77.ParseNegMessage(message) if envelope == nil { + ws.WriteJSON(nostr.NoticeEnvelope("failed to parse envelope: " + err.Error())) return } } diff --git a/nip86.go b/nip86.go index 3c1b5af..575bc57 100644 --- a/nip86.go +++ b/nip86.go @@ -3,7 +3,6 @@ package khatru import ( "context" "crypto/sha256" - "encoding/base64" "encoding/hex" "encoding/json" "fmt" @@ -13,6 +12,7 @@ import ( "reflect" "strings" + "github.com/cloudwego/base64x" "github.com/nbd-wtf/go-nostr" "github.com/nbd-wtf/go-nostr/nip86" ) @@ -72,7 +72,7 @@ func (rl *Relay) HandleNIP86(w http.ResponseWriter, r *http.Request) { goto respond } - evtj, err := base64.StdEncoding.DecodeString(spl[1]) + evtj, err := base64x.StdEncoding.DecodeString(spl[1]) if err != nil { resp.Error = "invalid base64 auth" goto respond