diff --git a/go.mod b/go.mod index 1431fe3..30ceb71 100644 --- a/go.mod +++ b/go.mod @@ -4,15 +4,15 @@ go 1.23.1 require ( git.devvul.com/asara/gologger v0.9.0 - github.com/fiatjaf/eventstore v0.9.1 + github.com/fiatjaf/eventstore v0.11.3 github.com/fiatjaf/khatru v0.8.3 github.com/jmoiron/sqlx v1.4.0 github.com/lib/pq v1.10.9 - github.com/nbd-wtf/go-nostr v0.37.3 + github.com/nbd-wtf/go-nostr v0.38.2 ) require ( - github.com/andybalholm/brotli v1.1.0 // indirect + github.com/andybalholm/brotli v1.1.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect github.com/decred/dcrd/crypto/blake256 v1.1.0 // indirect @@ -22,7 +22,7 @@ require ( github.com/gobwas/pool v0.2.1 // indirect github.com/gobwas/ws v1.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/klauspost/compress v1.17.10 // indirect + github.com/klauspost/compress v1.17.11 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -30,12 +30,12 @@ require ( github.com/rs/cors v1.11.1 // indirect github.com/rs/zerolog v1.33.0 // indirect github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 // indirect - github.com/tidwall/gjson v1.17.3 // indirect + github.com/tidwall/gjson v1.18.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.56.0 // indirect - golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect - golang.org/x/net v0.29.0 // indirect - golang.org/x/sys v0.25.0 // indirect + golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect + golang.org/x/net v0.30.0 // indirect + golang.org/x/sys v0.26.0 // indirect ) diff --git a/go.sum b/go.sum index 9272f11..68a648b 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,8 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= git.devvul.com/asara/gologger v0.9.0 h1:gijJpkPjvzI5S/dmAXgYoKJbp5uuaETAOBYWo7bJg6U= git.devvul.com/asara/gologger v0.9.0/go.mod h1:APr1DdVYByFfPUGHqHtRMhxphQbj92/vT/t0iM40H/0= -github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= -github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= +github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA= +github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA= github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= 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= @@ -17,8 +17,8 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnN github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/fasthttp/websocket v1.5.10 h1:bc7NIGyrg1L6sd5pRzCIbXpro54SZLEluZCu0rOpcN4= github.com/fasthttp/websocket v1.5.10/go.mod h1:BwHeuXGWzCW1/BIKUKD3+qfCl+cTdsHu/f243NcAI/Q= -github.com/fiatjaf/eventstore v0.9.1 h1:dLum4W6NOkDXMgckjj5lLfKrRVW8oN3zS7tfbXzGxJg= -github.com/fiatjaf/eventstore v0.9.1/go.mod h1:h5CdLSF7mEQ7/rWpEABTRIrNuFoSwdQDi/nZkW/vVFU= +github.com/fiatjaf/eventstore v0.11.3 h1:Lqm/8fx0R+Q9jVAxx4y+TNA9UliXVYIhOSRuJgW8T7o= +github.com/fiatjaf/eventstore v0.11.3/go.mod h1:oCHPB4TprrNjbhH2kjMKt1O48O1pk3VxAy5iZkB5Fb0= github.com/fiatjaf/khatru v0.8.3 h1:bCXyfoPYesmJ00jmi7IyoLpE/CB/tPUw4nP62/3jbBw= github.com/fiatjaf/khatru v0.8.3/go.mod h1:44X/Mcc+2ObOqz+/fDbhAW3BeUEPKxDgrX9St/cXEKc= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= @@ -34,8 +34,8 @@ github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0= -github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= @@ -48,8 +48,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/nbd-wtf/go-nostr v0.37.3 h1:p/rrOWhaAk78UCVwzWtTN1C8WbP2k5eQV4HlpEYAeeA= -github.com/nbd-wtf/go-nostr v0.37.3/go.mod h1:TGKGj00BmJRXvRe0LlpDN3KKbELhhPXgBwUEhzu3Oq0= +github.com/nbd-wtf/go-nostr v0.38.2 h1:8PP+U8dx81jVEL89k/xMAejAlDeSDJ9ywNiyOj82so8= +github.com/nbd-wtf/go-nostr v0.38.2/go.mod h1:TGKGj00BmJRXvRe0LlpDN3KKbELhhPXgBwUEhzu3Oq0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -64,8 +64,8 @@ github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 h1:D0vL7YNisV2yqE55 github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38/go.mod h1:sM7Mt7uEoCeFSCBM+qBrqvEo+/9vdmj19wzp3yzUhmg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tidwall/gjson v1.17.3 h1:bwWLZU7icoKRG+C+0PNwIKC6FCJO/Q3p2pZvuP0jN94= -github.com/tidwall/gjson v1.17.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= @@ -75,14 +75,16 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.56.0 h1:bEZdJev/6LCBlpdORfrLu/WOZXXxvrUQSiyniuaoW8U= github.com/valyala/fasthttp v1.56.0/go.mod h1:sReBt3XZVnudxuLOx4J/fMrJVorWRiWY2koQKgABiVI= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= +github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/vendor/github.com/fiatjaf/eventstore/postgresql/query.go b/vendor/github.com/fiatjaf/eventstore/postgresql/query.go index 9bcf145..89fe568 100644 --- a/vendor/github.com/fiatjaf/eventstore/postgresql/query.go +++ b/vendor/github.com/fiatjaf/eventstore/postgresql/query.go @@ -72,8 +72,8 @@ var ( ) func (b PostgresBackend) queryEventsSql(filter nostr.Filter, doCount bool) (string, []any, error) { - var conditions []string - var params []any + conditions := make([]string, 0, 7) + params := make([]any, 0, 20) if len(filter.IDs) > 0 { if len(filter.IDs) > b.QueryIDsLimit { @@ -111,28 +111,25 @@ func (b PostgresBackend) queryEventsSql(filter nostr.Filter, doCount bool) (stri conditions = append(conditions, `kind IN (`+makePlaceHolders(len(filter.Kinds))+`)`) } - tagQuery := make([]string, 0, 1) + totalTags := 0 for _, values := range filter.Tags { if len(values) == 0 { // any tag set to [] is wrong return "", nil, EmptyTagSet } - // add these tags to the query - tagQuery = append(tagQuery, values...) - - if len(tagQuery) > b.QueryTagsLimit { - // too many tags, fail everything - return "", nil, TooManyTagValues - } - } - - if len(tagQuery) > 0 { - for _, tagValue := range tagQuery { + for _, tagValue := range values { params = append(params, tagValue) } - conditions = append(conditions, `tagvalues && ARRAY[`+makePlaceHolders(len(tagQuery))+`]`) + // each separate tag key is an independent condition + conditions = append(conditions, `tagvalues && ARRAY[`+makePlaceHolders(len(values))+`]`) + + totalTags += len(values) + if totalTags > b.QueryTagsLimit { + // too many tags, fail everything + return "", nil, TooManyTagValues + } } if filter.Since != nil { diff --git a/vendor/github.com/fiatjaf/eventstore/utils.go b/vendor/github.com/fiatjaf/eventstore/utils.go deleted file mode 100644 index 3718cc4..0000000 --- a/vendor/github.com/fiatjaf/eventstore/utils.go +++ /dev/null @@ -1,19 +0,0 @@ -package eventstore - -import ( - "encoding/hex" - "strconv" - "strings" -) - -func GetAddrTagElements(tagValue string) (kind uint16, pkb []byte, d string) { - spl := strings.Split(tagValue, ":") - if len(spl) == 3 { - if pkb, _ := hex.DecodeString(spl[1]); len(pkb) == 32 { - if kind, err := strconv.ParseUint(spl[0], 10, 16); err == nil { - return uint16(kind), pkb, spl[2] - } - } - } - return 0, nil, "" -} diff --git a/vendor/github.com/nbd-wtf/go-nostr/Makefile b/vendor/github.com/nbd-wtf/go-nostr/Makefile deleted file mode 100644 index d4f860b..0000000 --- a/vendor/github.com/nbd-wtf/go-nostr/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -### Tools needed for development -devtools: - @echo "Installing devtools" - go install mvdan.cc/gofumpt@latest - -### Formatting, linting, and vetting -fmt: - gofumpt -l -w . diff --git a/vendor/github.com/nbd-wtf/go-nostr/README.md b/vendor/github.com/nbd-wtf/go-nostr/README.md index 8335220..474c2cf 100644 --- a/vendor/github.com/nbd-wtf/go-nostr/README.md +++ b/vendor/github.com/nbd-wtf/go-nostr/README.md @@ -126,6 +126,25 @@ nostr.InfoLogger = log.New(io.Discard, "", 0) go run example/example.go ``` +### Using [`libsecp256k1`](https://github.com/bitcoin-core/secp256k1) + +[`libsecp256k1`](https://github.com/bitcoin-core/secp256k1) is very fast: + +``` +goos: linux +goarch: amd64 +cpu: Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz +BenchmarkWithoutLibsecp256k1/sign-4 2794 434114 ns/op +BenchmarkWithoutLibsecp256k1/check-4 4352 297416 ns/op +BenchmarkWithLibsecp256k1/sign-4 12559 94607 ns/op +BenchmarkWithLibsecp256k1/check-4 13761 84595 ns/op +PASS +``` + +But to use it you need the host to have it installed as a shared library and CGO to be supported, so we don't compile against it by default. + +To use it, use `-tags=libsecp256k1` whenever you're compiling your program that uses this library. + ## Warning: risk of goroutine bloat (if used incorrectly) Remember to cancel subscriptions, either by calling `.Unsub()` on them or ensuring their `context.Context` will be canceled at some point. diff --git a/vendor/github.com/nbd-wtf/go-nostr/event.go b/vendor/github.com/nbd-wtf/go-nostr/event.go index de7f9cb..156ca0d 100644 --- a/vendor/github.com/nbd-wtf/go-nostr/event.go +++ b/vendor/github.com/nbd-wtf/go-nostr/event.go @@ -5,8 +5,6 @@ import ( "encoding/hex" "fmt" - "github.com/btcsuite/btcd/btcec/v2" - "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/mailru/easyjson" ) @@ -85,63 +83,6 @@ func (evt *Event) Serialize() []byte { return dst } -// CheckSignature checks if the signature is valid for the id -// (which is a hash of the serialized event content). -// returns an error if the signature itself is invalid. -func (evt Event) CheckSignature() (bool, error) { - // read and check pubkey - pk, err := hex.DecodeString(evt.PubKey) - if err != nil { - return false, fmt.Errorf("event pubkey '%s' is invalid hex: %w", evt.PubKey, err) - } - - pubkey, err := schnorr.ParsePubKey(pk) - if err != nil { - return false, fmt.Errorf("event has invalid pubkey '%s': %w", evt.PubKey, err) - } - - // read signature - s, err := hex.DecodeString(evt.Sig) - if err != nil { - return false, fmt.Errorf("signature '%s' is invalid hex: %w", evt.Sig, err) - } - sig, err := schnorr.ParseSignature(s) - if err != nil { - return false, fmt.Errorf("failed to parse signature: %w", err) - } - - // check signature - hash := sha256.Sum256(evt.Serialize()) - return sig.Verify(hash[:], pubkey), nil -} - -// Sign signs an event with a given privateKey. -func (evt *Event) Sign(privateKey string, signOpts ...schnorr.SignOption) error { - s, err := hex.DecodeString(privateKey) - if err != nil { - return fmt.Errorf("Sign called with invalid private key '%s': %w", privateKey, err) - } - - if evt.Tags == nil { - evt.Tags = make(Tags, 0) - } - - sk, pk := btcec.PrivKeyFromBytes(s) - pkBytes := pk.SerializeCompressed() - evt.PubKey = hex.EncodeToString(pkBytes[1:]) - - h := sha256.Sum256(evt.Serialize()) - sig, err := schnorr.Sign(sk, h[:], signOpts...) - if err != nil { - return err - } - - evt.ID = hex.EncodeToString(h[:]) - evt.Sig = hex.EncodeToString(sig.Serialize()) - - return nil -} - // IsRegular checks if the given kind is in Regular range. func (evt *Event) IsRegular() bool { return evt.Kind < 10000 && evt.Kind != 0 && evt.Kind != 3 diff --git a/vendor/github.com/nbd-wtf/go-nostr/helpers.go b/vendor/github.com/nbd-wtf/go-nostr/helpers.go index 5504673..de13bf1 100644 --- a/vendor/github.com/nbd-wtf/go-nostr/helpers.go +++ b/vendor/github.com/nbd-wtf/go-nostr/helpers.go @@ -1,6 +1,8 @@ package nostr import ( + "strconv" + "strings" "sync" "unsafe" @@ -92,3 +94,12 @@ func arePointerValuesEqual[V comparable](a *V, b *V) bool { } return false } + +func subIdToSerial(subId string) int64 { + n := strings.Index(subId, ":") + if n < 0 || n > len(subId) { + return -1 + } + serialId, _ := strconv.ParseInt(subId[0:n], 10, 64) + return serialId +} diff --git a/vendor/github.com/nbd-wtf/go-nostr/pool.go b/vendor/github.com/nbd-wtf/go-nostr/pool.go index d91954c..7a5605c 100644 --- a/vendor/github.com/nbd-wtf/go-nostr/pool.go +++ b/vendor/github.com/nbd-wtf/go-nostr/pool.go @@ -27,9 +27,9 @@ type SimplePool struct { eventMiddleware []func(RelayEvent) // custom things not often used - signatureChecker func(Event) bool - penaltyBoxMu sync.Mutex - penaltyBox map[string][2]float64 + penaltyBoxMu sync.Mutex + penaltyBox map[string][2]float64 + userAgent string } type DirectedFilters struct { @@ -120,10 +120,20 @@ func (h WithEventMiddleware) ApplyPoolOption(pool *SimplePool) { pool.eventMiddleware = append(pool.eventMiddleware, h) } +// WithUserAgent sets the user-agent header for all relay connections in the pool. +func WithUserAgent(userAgent string) withUserAgentOpt { return withUserAgentOpt(userAgent) } + +type withUserAgentOpt string + +func (h withUserAgentOpt) ApplyPoolOption(pool *SimplePool) { + pool.userAgent = string(h) +} + var ( _ PoolOption = (WithAuthHandler)(nil) _ PoolOption = (WithEventMiddleware)(nil) _ PoolOption = WithPenaltyBox() + _ PoolOption = WithUserAgent("") ) func (pool *SimplePool) EnsureRelay(url string) (*Relay, error) { @@ -146,17 +156,14 @@ func (pool *SimplePool) EnsureRelay(url string) (*Relay, error) { } // try to connect - var err error // we use this ctx here so when the pool dies everything dies ctx, cancel := context.WithTimeout(pool.Context, time.Second*15) defer cancel() - opts := make([]RelayOption, 0, 1+len(pool.eventMiddleware)) - if pool.signatureChecker != nil { - opts = append(opts, WithSignatureChecker(pool.signatureChecker)) - } + relay = NewRelay(context.Background(), url) + relay.RequestHeader.Set("User-Agent", pool.userAgent) - if relay, err = RelayConnect(ctx, nm, opts...); err != nil { + if err := relay.Connect(ctx); err != nil { if pool.penaltyBox != nil { // putting relay in penalty box pool.penaltyBoxMu.Lock() @@ -173,16 +180,32 @@ func (pool *SimplePool) EnsureRelay(url string) (*Relay, error) { // SubMany opens a subscription with the given filters to multiple relays // the subscriptions only end when the context is canceled -func (pool *SimplePool) SubMany(ctx context.Context, urls []string, filters Filters) chan RelayEvent { - return pool.subMany(ctx, urls, filters, true) +func (pool *SimplePool) SubMany( + ctx context.Context, + urls []string, + filters Filters, + opts ...SubscriptionOption, +) chan RelayEvent { + return pool.subMany(ctx, urls, filters, true, opts) } // SubManyNonUnique is like SubMany, but returns duplicate events if they come from different relays -func (pool *SimplePool) SubManyNonUnique(ctx context.Context, urls []string, filters Filters) chan RelayEvent { - return pool.subMany(ctx, urls, filters, false) +func (pool *SimplePool) SubManyNonUnique( + ctx context.Context, + urls []string, + filters Filters, + opts ...SubscriptionOption, +) chan RelayEvent { + return pool.subMany(ctx, urls, filters, false, opts) } -func (pool *SimplePool) subMany(ctx context.Context, urls []string, filters Filters, unique bool) chan RelayEvent { +func (pool *SimplePool) subMany( + ctx context.Context, + urls []string, + filters Filters, + unique bool, + opts []SubscriptionOption, +) chan RelayEvent { ctx, cancel := context.WithCancel(ctx) _ = cancel // do this so `go vet` will stop complaining events := make(chan RelayEvent) @@ -228,7 +251,7 @@ func (pool *SimplePool) subMany(ctx context.Context, urls []string, filters Filt hasAuthed = false subscribe: - sub, err = relay.Subscribe(ctx, filters) + sub, err = relay.Subscribe(ctx, filters, opts...) if err != nil { goto reconnect } @@ -313,16 +336,32 @@ func (pool *SimplePool) subMany(ctx context.Context, urls []string, filters Filt } // SubManyEose is like SubMany, but it stops subscriptions and closes the channel when gets a EOSE -func (pool *SimplePool) SubManyEose(ctx context.Context, urls []string, filters Filters) chan RelayEvent { - return pool.subManyEose(ctx, urls, filters, true) +func (pool *SimplePool) SubManyEose( + ctx context.Context, + urls []string, + filters Filters, + opts ...SubscriptionOption, +) chan RelayEvent { + return pool.subManyEose(ctx, urls, filters, true, opts) } // SubManyEoseNonUnique is like SubManyEose, but returns duplicate events if they come from different relays -func (pool *SimplePool) SubManyEoseNonUnique(ctx context.Context, urls []string, filters Filters) chan RelayEvent { - return pool.subManyEose(ctx, urls, filters, false) +func (pool *SimplePool) SubManyEoseNonUnique( + ctx context.Context, + urls []string, + filters Filters, + opts ...SubscriptionOption, +) chan RelayEvent { + return pool.subManyEose(ctx, urls, filters, false, opts) } -func (pool *SimplePool) subManyEose(ctx context.Context, urls []string, filters Filters, unique bool) chan RelayEvent { +func (pool *SimplePool) subManyEose( + ctx context.Context, + urls []string, + filters Filters, + unique bool, + opts []SubscriptionOption, +) chan RelayEvent { ctx, cancel := context.WithCancel(ctx) events := make(chan RelayEvent) @@ -349,7 +388,7 @@ func (pool *SimplePool) subManyEose(ctx context.Context, urls []string, filters hasAuthed := false subscribe: - sub, err := relay.Subscribe(ctx, filters) + sub, err := relay.Subscribe(ctx, filters, opts...) if sub == nil { debugLogf("error subscribing to %s with %v: %s", relay, filters, err) return @@ -416,13 +455,14 @@ func (pool *SimplePool) QuerySingle(ctx context.Context, urls []string, filter F func (pool *SimplePool) batchedSubMany( ctx context.Context, dfs []DirectedFilters, - subFn func(context.Context, []string, Filters, bool) chan RelayEvent, + subFn func(context.Context, []string, Filters, bool, []SubscriptionOption) chan RelayEvent, + opts []SubscriptionOption, ) chan RelayEvent { res := make(chan RelayEvent) for _, df := range dfs { go func(df DirectedFilters) { - for ie := range subFn(ctx, []string{df.Relay}, df.Filters, true) { + for ie := range subFn(ctx, []string{df.Relay}, df.Filters, true, opts) { res <- ie } }(df) @@ -432,11 +472,19 @@ func (pool *SimplePool) batchedSubMany( } // BatchedSubMany fires subscriptions only to specific relays, but batches them when they are the same. -func (pool *SimplePool) BatchedSubMany(ctx context.Context, dfs []DirectedFilters) chan RelayEvent { - return pool.batchedSubMany(ctx, dfs, pool.subMany) +func (pool *SimplePool) BatchedSubMany( + ctx context.Context, + dfs []DirectedFilters, + opts ...SubscriptionOption, +) chan RelayEvent { + return pool.batchedSubMany(ctx, dfs, pool.subMany, opts) } // BatchedSubManyEose is like BatchedSubMany, but ends upon receiving EOSE from all relays. -func (pool *SimplePool) BatchedSubManyEose(ctx context.Context, dfs []DirectedFilters) chan RelayEvent { - return pool.batchedSubMany(ctx, dfs, pool.subManyEose) +func (pool *SimplePool) BatchedSubManyEose( + ctx context.Context, + dfs []DirectedFilters, + opts ...SubscriptionOption, +) chan RelayEvent { + return pool.batchedSubMany(ctx, dfs, pool.subManyEose, opts) } diff --git a/vendor/github.com/nbd-wtf/go-nostr/relay.go b/vendor/github.com/nbd-wtf/go-nostr/relay.go index 1ffb1fe..4f6cb4b 100644 --- a/vendor/github.com/nbd-wtf/go-nostr/relay.go +++ b/vendor/github.com/nbd-wtf/go-nostr/relay.go @@ -7,6 +7,7 @@ import ( "fmt" "log" "net/http" + "strconv" "sync" "sync/atomic" "time" @@ -18,7 +19,7 @@ import ( type Status int -var subscriptionIDCounter atomic.Int32 +var subscriptionIDCounter atomic.Int64 type Relay struct { closeMutex sync.Mutex @@ -27,7 +28,7 @@ type Relay struct { RequestHeader http.Header // e.g. for origin header Connection *Connection - Subscriptions *xsync.MapOf[string, *Subscription] + Subscriptions *xsync.MapOf[int64, *Subscription] ConnectionError error connectionContext context.Context // will be canceled when the connection closes @@ -39,7 +40,6 @@ type Relay struct { okCallbacks *xsync.MapOf[string, func(bool, string)] writeQueue chan writeRequest subscriptionChannelCloseQueue chan *Subscription - signatureChecker func(Event) bool // custom things that aren't often used // @@ -58,14 +58,11 @@ func NewRelay(ctx context.Context, url string, opts ...RelayOption) *Relay { URL: NormalizeURL(url), connectionContext: ctx, connectionContextCancel: cancel, - Subscriptions: xsync.NewMapOf[string, *Subscription](), + Subscriptions: xsync.NewMapOf[int64, *Subscription](), okCallbacks: xsync.NewMapOf[string, func(bool, string)](), writeQueue: make(chan writeRequest), subscriptionChannelCloseQueue: make(chan *Subscription), - signatureChecker: func(e Event) bool { - ok, _ := e.CheckSignature() - return ok - }, + RequestHeader: make(http.Header, 1), } for _, opt := range opts { @@ -92,7 +89,6 @@ type RelayOption interface { var ( _ RelayOption = (WithNoticeHandler)(nil) - _ RelayOption = (WithSignatureChecker)(nil) _ RelayOption = (WithCustomHandler)(nil) ) @@ -104,14 +100,6 @@ func (nh WithNoticeHandler) ApplyRelayOption(r *Relay) { r.noticeHandler = nh } -// WithSignatureChecker must be a function that checks the signature of an -// event and returns true or false. -type WithSignatureChecker func(Event) bool - -func (sc WithSignatureChecker) ApplyRelayOption(r *Relay) { - r.signatureChecker = sc -} - // WithCustomHandler must be a function that handles any relay message that couldn't be // parsed as a standard envelope. type WithCustomHandler func(data []byte) @@ -160,9 +148,6 @@ func (r *Relay) ConnectWithTLS(ctx context.Context, tlsConfig *tls.Config) error defer cancel() } - if r.RequestHeader == nil { - r.RequestHeader = make(http.Header, 1) - } if r.RequestHeader.Get("User-Agent") == "" { r.RequestHeader.Set("User-Agent", "github.com/nbd-wtf/go-nostr") } @@ -187,10 +172,9 @@ func (r *Relay) ConnectWithTLS(ctx context.Context, tlsConfig *tls.Config) error r.Connection = nil // close all subscriptions - r.Subscriptions.Range(func(_ string, sub *Subscription) bool { - go sub.Unsub() - return true - }) + for _, sub := range r.Subscriptions.Range { + sub.Unsub() + } }() // queue all write operations here so we don't do mutex spaghetti @@ -257,7 +241,8 @@ func (r *Relay) ConnectWithTLS(ctx context.Context, tlsConfig *tls.Config) error if env.SubscriptionID == nil { continue } - if subscription, ok := r.Subscriptions.Load(*env.SubscriptionID); !ok { + + if subscription, ok := r.Subscriptions.Load(subIdToSerial(*env.SubscriptionID)); !ok { // InfoLogger.Printf("{%s} no subscription with id '%s'\n", r.URL, *env.SubscriptionID) continue } else { @@ -269,7 +254,7 @@ func (r *Relay) ConnectWithTLS(ctx context.Context, tlsConfig *tls.Config) error // check signature, ignore invalid, except from trusted (AssumeValid) relays if !r.AssumeValid { - if ok := r.signatureChecker(env.Event); !ok { + if ok, _ := env.Event.CheckSignature(); !ok { InfoLogger.Printf("{%s} bad signature on %s\n", r.URL, env.Event.ID) continue } @@ -279,15 +264,15 @@ func (r *Relay) ConnectWithTLS(ctx context.Context, tlsConfig *tls.Config) error subscription.dispatchEvent(&env.Event) } case *EOSEEnvelope: - if subscription, ok := r.Subscriptions.Load(string(*env)); ok { + if subscription, ok := r.Subscriptions.Load(subIdToSerial(string(*env))); ok { subscription.dispatchEose() } case *ClosedEnvelope: - if subscription, ok := r.Subscriptions.Load(string(env.SubscriptionID)); ok { + if subscription, ok := r.Subscriptions.Load(subIdToSerial(env.SubscriptionID)); ok { subscription.dispatchClosed(env.Reason) } case *CountEnvelope: - if subscription, ok := r.Subscriptions.Load(string(env.SubscriptionID)); ok && env.Count != nil && subscription.countResult != nil { + if subscription, ok := r.Subscriptions.Load(subIdToSerial(env.SubscriptionID)); ok && env.Count != nil && subscription.countResult != nil { subscription.countResult <- *env.Count } case *OKEnvelope: @@ -416,7 +401,7 @@ func (r *Relay) PrepareSubscription(ctx context.Context, filters Filters, opts . Relay: r, Context: ctx, cancel: cancel, - counter: int(current), + counter: current, Events: make(chan *Event), EndOfStoredEvents: make(chan struct{}, 1), ClosedReason: make(chan string, 1), @@ -424,15 +409,24 @@ func (r *Relay) PrepareSubscription(ctx context.Context, filters Filters, opts . match: filters.Match, } + label := "" for _, opt := range opts { switch o := opt.(type) { case WithLabel: - sub.label = string(o) + label = string(o) } } - id := sub.GetID() - r.Subscriptions.Store(id, sub) + // subscription id calculation + buf := subIdPool.Get().([]byte)[:0] + buf = strconv.AppendInt(buf, sub.counter, 10) + buf = append(buf, ':') + buf = append(buf, label...) + defer subIdPool.Put(buf) + sub.id = string(buf) + + // we track subscriptions only by their counter, no need for the full id + r.Subscriptions.Store(int64(sub.counter), sub) // start handling events, eose, unsub etc: go sub.start() @@ -530,3 +524,7 @@ func (r *Relay) Close() error { return nil } + +var subIdPool = sync.Pool{ + New: func() any { return make([]byte, 0, 15) }, +} diff --git a/vendor/github.com/nbd-wtf/go-nostr/signature.go b/vendor/github.com/nbd-wtf/go-nostr/signature.go new file mode 100644 index 0000000..39d9a5e --- /dev/null +++ b/vendor/github.com/nbd-wtf/go-nostr/signature.go @@ -0,0 +1,69 @@ +//go:build !libsecp256k1 + +package nostr + +import ( + "crypto/sha256" + "encoding/hex" + "fmt" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/btcec/v2/schnorr" +) + +// CheckSignature checks if the signature is valid for the id +// (which is a hash of the serialized event content). +// returns an error if the signature itself is invalid. +func (evt Event) CheckSignature() (bool, error) { + // read and check pubkey + pk, err := hex.DecodeString(evt.PubKey) + if err != nil { + return false, fmt.Errorf("event pubkey '%s' is invalid hex: %w", evt.PubKey, err) + } + + pubkey, err := schnorr.ParsePubKey(pk) + if err != nil { + return false, fmt.Errorf("event has invalid pubkey '%s': %w", evt.PubKey, err) + } + + // read signature + s, err := hex.DecodeString(evt.Sig) + if err != nil { + return false, fmt.Errorf("signature '%s' is invalid hex: %w", evt.Sig, err) + } + sig, err := schnorr.ParseSignature(s) + if err != nil { + return false, fmt.Errorf("failed to parse signature: %w", err) + } + + // check signature + hash := sha256.Sum256(evt.Serialize()) + return sig.Verify(hash[:], pubkey), nil +} + +// Sign signs an event with a given privateKey. +func (evt *Event) Sign(secretKey string, signOpts ...schnorr.SignOption) error { + s, err := hex.DecodeString(secretKey) + if err != nil { + return fmt.Errorf("Sign called with invalid secret key '%s': %w", secretKey, err) + } + + if evt.Tags == nil { + evt.Tags = make(Tags, 0) + } + + sk, pk := btcec.PrivKeyFromBytes(s) + pkBytes := pk.SerializeCompressed() + evt.PubKey = hex.EncodeToString(pkBytes[1:]) + + h := sha256.Sum256(evt.Serialize()) + sig, err := schnorr.Sign(sk, h[:], signOpts...) + if err != nil { + return err + } + + evt.ID = hex.EncodeToString(h[:]) + evt.Sig = hex.EncodeToString(sig.Serialize()) + + return nil +} diff --git a/vendor/github.com/nbd-wtf/go-nostr/signature_libsecp256k1.go b/vendor/github.com/nbd-wtf/go-nostr/signature_libsecp256k1.go new file mode 100644 index 0000000..bf5ed7c --- /dev/null +++ b/vendor/github.com/nbd-wtf/go-nostr/signature_libsecp256k1.go @@ -0,0 +1,95 @@ +//go:build libsecp256k1 + +package nostr + +/* +#cgo LDFLAGS: -lsecp256k1 +#include +#include +#include +*/ +import "C" + +import ( + "crypto/rand" + "crypto/sha256" + "encoding/hex" + "errors" + "fmt" + "unsafe" + + "github.com/btcsuite/btcd/btcec/v2/schnorr" +) + +// CheckSignature checks if the signature is valid for the id +// (which is a hash of the serialized event content). +// returns an error if the signature itself is invalid. +func (evt Event) CheckSignature() (bool, error) { + var pk [32]byte + _, err := hex.Decode(pk[:], []byte(evt.PubKey)) + if err != nil { + return false, fmt.Errorf("event pubkey '%s' is invalid hex: %w", evt.PubKey, err) + } + + var sig [64]byte + _, err = hex.Decode(sig[:], []byte(evt.Sig)) + if err != nil { + return false, fmt.Errorf("event signature '%s' is invalid hex: %w", evt.Sig, err) + } + + msg := sha256.Sum256(evt.Serialize()) + + var xonly C.secp256k1_xonly_pubkey + if C.secp256k1_xonly_pubkey_parse(globalSecp256k1Context, &xonly, (*C.uchar)(unsafe.Pointer(&pk[0]))) != 1 { + return false, fmt.Errorf("failed to parse xonly pubkey") + } + + res := C.secp256k1_schnorrsig_verify(globalSecp256k1Context, (*C.uchar)(unsafe.Pointer(&sig[0])), (*C.uchar)(unsafe.Pointer(&msg[0])), 32, &xonly) + return res == 1, nil +} + +// Sign signs an event with a given privateKey. +func (evt *Event) Sign(secretKey string, signOpts ...schnorr.SignOption) error { + sk, err := hex.DecodeString(secretKey) + if err != nil { + return fmt.Errorf("Sign called with invalid secret key '%s': %w", secretKey, err) + } + + if evt.Tags == nil { + evt.Tags = make(Tags, 0) + } + + var keypair C.secp256k1_keypair + if C.secp256k1_keypair_create(globalSecp256k1Context, &keypair, (*C.uchar)(unsafe.Pointer(&sk[0]))) != 1 { + return errors.New("failed to parse private key") + } + + var xonly C.secp256k1_xonly_pubkey + var pk [32]byte + C.secp256k1_keypair_xonly_pub(globalSecp256k1Context, &xonly, nil, &keypair) + C.secp256k1_xonly_pubkey_serialize(globalSecp256k1Context, (*C.uchar)(unsafe.Pointer(&pk[0])), &xonly) + evt.PubKey = hex.EncodeToString(pk[:]) + + h := sha256.Sum256(evt.Serialize()) + + var sig [64]byte + var random [32]byte + rand.Read(random[:]) + if C.secp256k1_schnorrsig_sign32(globalSecp256k1Context, (*C.uchar)(unsafe.Pointer(&sig[0])), (*C.uchar)(unsafe.Pointer(&h[0])), &keypair, (*C.uchar)(unsafe.Pointer(&random[0]))) != 1 { + return errors.New("failed to sign message") + } + + evt.ID = hex.EncodeToString(h[:]) + evt.Sig = hex.EncodeToString(sig[:]) + + return nil +} + +var globalSecp256k1Context *C.secp256k1_context + +func init() { + globalSecp256k1Context = C.secp256k1_context_create(C.SECP256K1_CONTEXT_SIGN | C.SECP256K1_CONTEXT_VERIFY) + if globalSecp256k1Context == nil { + panic("failed to create secp256k1 context") + } +} diff --git a/vendor/github.com/nbd-wtf/go-nostr/subscription.go b/vendor/github.com/nbd-wtf/go-nostr/subscription.go index e1acc42..3995137 100644 --- a/vendor/github.com/nbd-wtf/go-nostr/subscription.go +++ b/vendor/github.com/nbd-wtf/go-nostr/subscription.go @@ -3,14 +3,13 @@ package nostr import ( "context" "fmt" - "strconv" "sync" "sync/atomic" ) type Subscription struct { - label string - counter int + counter int64 + id string Relay *Relay Filters Filters @@ -62,12 +61,6 @@ func (_ WithLabel) IsSubscriptionOption() {} var _ SubscriptionOption = (WithLabel)("") -// GetID return the Nostr subscription ID as given to the Relay -// it is a concatenation of the label and a serial number. -func (sub *Subscription) GetID() string { - return sub.label + ":" + strconv.Itoa(sub.counter) -} - func (sub *Subscription) start() { <-sub.Context.Done() // the subscription ends once the context is canceled (if not already) @@ -79,6 +72,8 @@ func (sub *Subscription) start() { sub.mu.Unlock() } +func (sub *Subscription) GetID() string { return sub.id } + func (sub *Subscription) dispatchEvent(evt *Event) { added := false if !sub.eosed.Load() { @@ -133,16 +128,14 @@ func (sub *Subscription) Unsub() { } // remove subscription from our map - sub.Relay.Subscriptions.Delete(sub.GetID()) + sub.Relay.Subscriptions.Delete(sub.counter) } // Close just sends a CLOSE message. You probably want Unsub() instead. func (sub *Subscription) Close() { if sub.Relay.IsConnected() { - id := sub.GetID() - closeMsg := CloseEnvelope(id) + closeMsg := CloseEnvelope(sub.id) closeb, _ := (&closeMsg).MarshalJSON() - debugLogf("{%s} sending %v", sub.Relay.URL, closeb) <-sub.Relay.Write(closeb) } } @@ -156,15 +149,12 @@ func (sub *Subscription) Sub(_ context.Context, filters Filters) { // Fire sends the "REQ" command to the relay. func (sub *Subscription) Fire() error { - id := sub.GetID() - var reqb []byte if sub.countResult == nil { - reqb, _ = ReqEnvelope{id, sub.Filters}.MarshalJSON() + reqb, _ = ReqEnvelope{sub.id, sub.Filters}.MarshalJSON() } else { - reqb, _ = CountEnvelope{id, sub.Filters, nil}.MarshalJSON() + reqb, _ = CountEnvelope{sub.id, sub.Filters, nil}.MarshalJSON() } - debugLogf("{%s} sending %v", sub.Relay.URL, reqb) sub.live.Store(true) if err := <-sub.Relay.Write(reqb); err != nil { diff --git a/vendor/github.com/nbd-wtf/go-nostr/utils.go b/vendor/github.com/nbd-wtf/go-nostr/utils.go index 984204b..165f31a 100644 --- a/vendor/github.com/nbd-wtf/go-nostr/utils.go +++ b/vendor/github.com/nbd-wtf/go-nostr/utils.go @@ -35,3 +35,44 @@ func CompareEvent(a, b Event) int { } return cmp.Compare(a.CreatedAt, b.CreatedAt) } + +func CompareEventReverse(b, a Event) int { + if a.CreatedAt == b.CreatedAt { + return strings.Compare(a.ID, b.ID) + } + return cmp.Compare(a.CreatedAt, b.CreatedAt) +} + +func CompareEventPtr(a, b *Event) int { + if a == nil { + if b == nil { + return 0 + } else { + return -1 + } + } else if b == nil { + return 1 + } + + if a.CreatedAt == b.CreatedAt { + return strings.Compare(a.ID, b.ID) + } + return cmp.Compare(a.CreatedAt, b.CreatedAt) +} + +func CompareEventPtrReverse(b, a *Event) int { + if a == nil { + if b == nil { + return 0 + } else { + return -1 + } + } else if b == nil { + return 1 + } + + if a.CreatedAt == b.CreatedAt { + return strings.Compare(a.ID, b.ID) + } + return cmp.Compare(a.CreatedAt, b.CreatedAt) +} diff --git a/vendor/github.com/tidwall/gjson/README.md b/vendor/github.com/tidwall/gjson/README.md index 7701cae..387766d 100644 --- a/vendor/github.com/tidwall/gjson/README.md +++ b/vendor/github.com/tidwall/gjson/README.md @@ -438,15 +438,15 @@ Benchmarks of GJSON alongside [encoding/json](https://golang.org/pkg/encoding/js and [json-iterator](https://github.com/json-iterator/go) ``` -BenchmarkGJSONGet-16 11644512 311 ns/op 0 B/op 0 allocs/op -BenchmarkGJSONUnmarshalMap-16 1122678 3094 ns/op 1920 B/op 26 allocs/op -BenchmarkJSONUnmarshalMap-16 516681 6810 ns/op 2944 B/op 69 allocs/op -BenchmarkJSONUnmarshalStruct-16 697053 5400 ns/op 928 B/op 13 allocs/op -BenchmarkJSONDecoder-16 330450 10217 ns/op 3845 B/op 160 allocs/op -BenchmarkFFJSONLexer-16 1424979 2585 ns/op 880 B/op 8 allocs/op -BenchmarkEasyJSONLexer-16 3000000 729 ns/op 501 B/op 5 allocs/op -BenchmarkJSONParserGet-16 3000000 366 ns/op 21 B/op 0 allocs/op -BenchmarkJSONIterator-16 3000000 869 ns/op 693 B/op 14 allocs/op +BenchmarkGJSONGet-10 17893731 202.1 ns/op 0 B/op 0 allocs/op +BenchmarkGJSONUnmarshalMap-10 1663548 2157 ns/op 1920 B/op 26 allocs/op +BenchmarkJSONUnmarshalMap-10 832236 4279 ns/op 2920 B/op 68 allocs/op +BenchmarkJSONUnmarshalStruct-10 1076475 3219 ns/op 920 B/op 12 allocs/op +BenchmarkJSONDecoder-10 585729 6126 ns/op 3845 B/op 160 allocs/op +BenchmarkFFJSONLexer-10 2508573 1391 ns/op 880 B/op 8 allocs/op +BenchmarkEasyJSONLexer-10 3000000 537.9 ns/op 501 B/op 5 allocs/op +BenchmarkJSONParserGet-10 13707510 263.9 ns/op 21 B/op 0 allocs/op +BenchmarkJSONIterator-10 3000000 561.2 ns/op 693 B/op 14 allocs/op ``` JSON document used: @@ -487,4 +487,6 @@ widget.image.hOffset widget.text.onMouseUp ``` -*These benchmarks were run on a MacBook Pro 16" 2.4 GHz Intel Core i9 using Go 1.17 and can be found [here](https://github.com/tidwall/gjson-benchmarks).* +** + +*These benchmarks were run on a MacBook Pro M1 Max using Go 1.22 and can be found [here](https://github.com/tidwall/gjson-benchmarks).* diff --git a/vendor/github.com/tidwall/gjson/gjson.go b/vendor/github.com/tidwall/gjson/gjson.go index 779fe61..5aa2a4f 100644 --- a/vendor/github.com/tidwall/gjson/gjson.go +++ b/vendor/github.com/tidwall/gjson/gjson.go @@ -1040,6 +1040,10 @@ func parseObjectPath(path string) (r objectPathResult) { return } +var vchars = [256]byte{ + '"': 2, '{': 3, '(': 3, '[': 3, '}': 1, ')': 1, ']': 1, +} + func parseSquash(json string, i int) (int, string) { // expects that the lead character is a '[' or '{' or '(' // squash the value, ignoring all nested arrays and objects. @@ -1047,43 +1051,137 @@ func parseSquash(json string, i int) (int, string) { s := i i++ depth := 1 - for ; i < len(json); i++ { - if json[i] >= '"' && json[i] <= '}' { - switch json[i] { - case '"': + var c byte + for i < len(json) { + for i < len(json)-8 { + jslice := json[i : i+8] + c = vchars[jslice[0]] + if c != 0 { + i += 0 + goto token + } + c = vchars[jslice[1]] + if c != 0 { + i += 1 + goto token + } + c = vchars[jslice[2]] + if c != 0 { + i += 2 + goto token + } + c = vchars[jslice[3]] + if c != 0 { + i += 3 + goto token + } + c = vchars[jslice[4]] + if c != 0 { + i += 4 + goto token + } + c = vchars[jslice[5]] + if c != 0 { + i += 5 + goto token + } + c = vchars[jslice[6]] + if c != 0 { + i += 6 + goto token + } + c = vchars[jslice[7]] + if c != 0 { + i += 7 + goto token + } + i += 8 + } + c = vchars[json[i]] + if c == 0 { + i++ + continue + } + token: + if c == 2 { + // '"' string + i++ + s2 := i + nextquote: + for i < len(json)-8 { + jslice := json[i : i+8] + if jslice[0] == '"' { + i += 0 + goto strchkesc + } + if jslice[1] == '"' { + i += 1 + goto strchkesc + } + if jslice[2] == '"' { + i += 2 + goto strchkesc + } + if jslice[3] == '"' { + i += 3 + goto strchkesc + } + if jslice[4] == '"' { + i += 4 + goto strchkesc + } + if jslice[5] == '"' { + i += 5 + goto strchkesc + } + if jslice[6] == '"' { + i += 6 + goto strchkesc + } + if jslice[7] == '"' { + i += 7 + goto strchkesc + } + i += 8 + } + goto strchkstd + strchkesc: + if json[i-1] != '\\' { i++ - s2 := i - for ; i < len(json); i++ { - if json[i] > '\\' { - continue - } - if json[i] == '"' { - // look for an escaped slash - if json[i-1] == '\\' { - n := 0 - for j := i - 2; j > s2-1; j-- { - if json[j] != '\\' { - break - } - n++ - } - if n%2 == 0 { - continue - } - } - break - } - } - case '{', '[', '(': - depth++ - case '}', ']', ')': - depth-- - if depth == 0 { + continue + } + strchkstd: + for i < len(json) { + if json[i] > '\\' || json[i] != '"' { i++ - return i, json[s:i] + continue } + // look for an escaped slash + if json[i-1] == '\\' { + n := 0 + for j := i - 2; j > s2-1; j-- { + if json[j] != '\\' { + break + } + n++ + } + if n%2 == 0 { + i++ + goto nextquote + } + } + break + } + } else { + // '{', '[', '(', '}', ']', ')' + // open close tokens + depth += int(c) - 2 + if depth == 0 { + i++ + return i, json[s:i] } } + i++ } return i, json[s:] } diff --git a/vendor/golang.org/x/sys/unix/README.md b/vendor/golang.org/x/sys/unix/README.md index 7d3c060..6e08a76 100644 --- a/vendor/golang.org/x/sys/unix/README.md +++ b/vendor/golang.org/x/sys/unix/README.md @@ -156,7 +156,7 @@ from the generated architecture-specific files listed below, and merge these into a common file for each OS. The merge is performed in the following steps: -1. Construct the set of common code that is idential in all architecture-specific files. +1. Construct the set of common code that is identical in all architecture-specific files. 2. Write this common code to the merged file. 3. Remove the common code from all architecture-specific files. diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index e14b766..ac54eca 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -656,7 +656,7 @@ errors=$( signals=$( echo '#include ' | $CC -x c - -E -dM $ccflags | awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' | - grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT\|SIGMAX64' | + grep -E -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' | sort ) @@ -666,7 +666,7 @@ echo '#include ' | $CC -x c - -E -dM $ccflags | sort >_error.grep echo '#include ' | $CC -x c - -E -dM $ccflags | awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' | - grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT\|SIGMAX64' | + grep -E -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' | sort >_signal.grep echo '// mkerrors.sh' "$@" diff --git a/vendor/golang.org/x/sys/unix/syscall_aix.go b/vendor/golang.org/x/sys/unix/syscall_aix.go index 67ce6ce..6f15ba1 100644 --- a/vendor/golang.org/x/sys/unix/syscall_aix.go +++ b/vendor/golang.org/x/sys/unix/syscall_aix.go @@ -360,7 +360,7 @@ func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, var status _C_int var r Pid_t err = ERESTART - // AIX wait4 may return with ERESTART errno, while the processus is still + // AIX wait4 may return with ERESTART errno, while the process is still // active. for err == ERESTART { r, err = wait4(Pid_t(pid), &status, options, rusage) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 3f1d3d4..f08abd4 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -1295,6 +1295,48 @@ func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) { return &value, err } +// GetsockoptTCPCCVegasInfo returns algorithm specific congestion control information for a socket using the "vegas" +// algorithm. +// +// The socket's congestion control algorighm can be retrieved via [GetsockoptString] with the [TCP_CONGESTION] option: +// +// algo, err := unix.GetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_CONGESTION) +func GetsockoptTCPCCVegasInfo(fd, level, opt int) (*TCPVegasInfo, error) { + var value [SizeofTCPCCInfo / 4]uint32 // ensure proper alignment + vallen := _Socklen(SizeofTCPCCInfo) + err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen) + out := (*TCPVegasInfo)(unsafe.Pointer(&value[0])) + return out, err +} + +// GetsockoptTCPCCDCTCPInfo returns algorithm specific congestion control information for a socket using the "dctp" +// algorithm. +// +// The socket's congestion control algorighm can be retrieved via [GetsockoptString] with the [TCP_CONGESTION] option: +// +// algo, err := unix.GetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_CONGESTION) +func GetsockoptTCPCCDCTCPInfo(fd, level, opt int) (*TCPDCTCPInfo, error) { + var value [SizeofTCPCCInfo / 4]uint32 // ensure proper alignment + vallen := _Socklen(SizeofTCPCCInfo) + err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen) + out := (*TCPDCTCPInfo)(unsafe.Pointer(&value[0])) + return out, err +} + +// GetsockoptTCPCCBBRInfo returns algorithm specific congestion control information for a socket using the "bbr" +// algorithm. +// +// The socket's congestion control algorighm can be retrieved via [GetsockoptString] with the [TCP_CONGESTION] option: +// +// algo, err := unix.GetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_CONGESTION) +func GetsockoptTCPCCBBRInfo(fd, level, opt int) (*TCPBBRInfo, error) { + var value [SizeofTCPCCInfo / 4]uint32 // ensure proper alignment + vallen := _Socklen(SizeofTCPCCInfo) + err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen) + out := (*TCPBBRInfo)(unsafe.Pointer(&value[0])) + return out, err +} + // GetsockoptString returns the string value of the socket option opt for the // socket associated with fd at the given socket level. func GetsockoptString(fd, level, opt int) (string, error) { @@ -1959,7 +2001,26 @@ func Getpgrp() (pid int) { //sysnb Getpid() (pid int) //sysnb Getppid() (ppid int) //sys Getpriority(which int, who int) (prio int, err error) -//sys Getrandom(buf []byte, flags int) (n int, err error) + +func Getrandom(buf []byte, flags int) (n int, err error) { + vdsoRet, supported := vgetrandom(buf, uint32(flags)) + if supported { + if vdsoRet < 0 { + return 0, errnoErr(syscall.Errno(-vdsoRet)) + } + return vdsoRet, nil + } + var p *byte + if len(buf) > 0 { + p = &buf[0] + } + r, _, e := Syscall(SYS_GETRANDOM, uintptr(unsafe.Pointer(p)), uintptr(len(buf)), uintptr(flags)) + if e != 0 { + return 0, errnoErr(e) + } + return int(r), nil +} + //sysnb Getrusage(who int, rusage *Rusage) (err error) //sysnb Getsid(pid int) (sid int, err error) //sysnb Gettid() (tid int) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go index cf2ee6c..745e5c7 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go @@ -182,3 +182,5 @@ func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error } return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags) } + +const SYS_FSTATAT = SYS_NEWFSTATAT diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go b/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go index 3d0e984..dd2262a 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go @@ -214,3 +214,5 @@ func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error } return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags) } + +const SYS_FSTATAT = SYS_NEWFSTATAT diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go b/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go index 6f5a288..8cf3670 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go @@ -187,3 +187,5 @@ func RISCVHWProbe(pairs []RISCVHWProbePairs, set *CPUSet, flags uint) (err error } return riscvHWProbe(pairs, setSize, set, flags) } + +const SYS_FSTATAT = SYS_NEWFSTATAT diff --git a/vendor/golang.org/x/sys/unix/vgetrandom_linux.go b/vendor/golang.org/x/sys/unix/vgetrandom_linux.go new file mode 100644 index 0000000..07ac8e0 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/vgetrandom_linux.go @@ -0,0 +1,13 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build linux && go1.24 + +package unix + +import _ "unsafe" + +//go:linkname vgetrandom runtime.vgetrandom +//go:noescape +func vgetrandom(p []byte, flags uint32) (ret int, supported bool) diff --git a/vendor/golang.org/x/sys/unix/vgetrandom_unsupported.go b/vendor/golang.org/x/sys/unix/vgetrandom_unsupported.go new file mode 100644 index 0000000..297e97b --- /dev/null +++ b/vendor/golang.org/x/sys/unix/vgetrandom_unsupported.go @@ -0,0 +1,11 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !linux || !go1.24 + +package unix + +func vgetrandom(p []byte, flags uint32) (ret int, supported bool) { + return -1, false +} diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index 01a70b2..de3b462 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -495,6 +495,7 @@ const ( BPF_F_TEST_REG_INVARIANTS = 0x80 BPF_F_TEST_RND_HI32 = 0x4 BPF_F_TEST_RUN_ON_CPU = 0x1 + BPF_F_TEST_SKB_CHECKSUM_COMPLETE = 0x4 BPF_F_TEST_STATE_FREQ = 0x8 BPF_F_TEST_XDP_LIVE_FRAMES = 0x2 BPF_F_XDP_DEV_BOUND_ONLY = 0x40 @@ -1922,6 +1923,7 @@ const ( MNT_EXPIRE = 0x4 MNT_FORCE = 0x1 MNT_ID_REQ_SIZE_VER0 = 0x18 + MNT_ID_REQ_SIZE_VER1 = 0x20 MODULE_INIT_COMPRESSED_FILE = 0x4 MODULE_INIT_IGNORE_MODVERSIONS = 0x1 MODULE_INIT_IGNORE_VERMAGIC = 0x2 @@ -2187,7 +2189,7 @@ const ( NFT_REG_SIZE = 0x10 NFT_REJECT_ICMPX_MAX = 0x3 NFT_RT_MAX = 0x4 - NFT_SECMARK_CTX_MAXLEN = 0x100 + NFT_SECMARK_CTX_MAXLEN = 0x1000 NFT_SET_MAXNAMELEN = 0x100 NFT_SOCKET_MAX = 0x3 NFT_TABLE_F_MASK = 0x7 @@ -2356,9 +2358,11 @@ const ( PERF_MEM_LVLNUM_IO = 0xa PERF_MEM_LVLNUM_L1 = 0x1 PERF_MEM_LVLNUM_L2 = 0x2 + PERF_MEM_LVLNUM_L2_MHB = 0x5 PERF_MEM_LVLNUM_L3 = 0x3 PERF_MEM_LVLNUM_L4 = 0x4 PERF_MEM_LVLNUM_LFB = 0xc + PERF_MEM_LVLNUM_MSC = 0x6 PERF_MEM_LVLNUM_NA = 0xf PERF_MEM_LVLNUM_PMEM = 0xe PERF_MEM_LVLNUM_RAM = 0xd @@ -2431,6 +2435,7 @@ const ( PRIO_PGRP = 0x1 PRIO_PROCESS = 0x0 PRIO_USER = 0x2 + PROCFS_IOCTL_MAGIC = 'f' PROC_SUPER_MAGIC = 0x9fa0 PROT_EXEC = 0x4 PROT_GROWSDOWN = 0x1000000 @@ -2933,11 +2938,12 @@ const ( RUSAGE_SELF = 0x0 RUSAGE_THREAD = 0x1 RWF_APPEND = 0x10 + RWF_ATOMIC = 0x40 RWF_DSYNC = 0x2 RWF_HIPRI = 0x1 RWF_NOAPPEND = 0x20 RWF_NOWAIT = 0x8 - RWF_SUPPORTED = 0x3f + RWF_SUPPORTED = 0x7f RWF_SYNC = 0x4 RWF_WRITE_LIFE_NOT_SET = 0x0 SCHED_BATCH = 0x3 @@ -3210,6 +3216,7 @@ const ( STATX_ATTR_MOUNT_ROOT = 0x2000 STATX_ATTR_NODUMP = 0x40 STATX_ATTR_VERITY = 0x100000 + STATX_ATTR_WRITE_ATOMIC = 0x400000 STATX_BASIC_STATS = 0x7ff STATX_BLOCKS = 0x400 STATX_BTIME = 0x800 @@ -3226,6 +3233,7 @@ const ( STATX_SUBVOL = 0x8000 STATX_TYPE = 0x1 STATX_UID = 0x8 + STATX_WRITE_ATOMIC = 0x10000 STATX__RESERVED = 0x80000000 SYNC_FILE_RANGE_WAIT_AFTER = 0x4 SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 @@ -3624,6 +3632,7 @@ const ( XDP_UMEM_PGOFF_COMPLETION_RING = 0x180000000 XDP_UMEM_PGOFF_FILL_RING = 0x100000000 XDP_UMEM_REG = 0x4 + XDP_UMEM_TX_METADATA_LEN = 0x4 XDP_UMEM_TX_SW_CSUM = 0x2 XDP_UMEM_UNALIGNED_CHUNK_FLAG = 0x1 XDP_USE_NEED_WAKEUP = 0x8 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index 684a516..8aa6d77 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -153,9 +153,14 @@ const ( NFDBITS = 0x20 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x8008b705 NS_GET_NSTYPE = 0xb703 NS_GET_OWNER_UID = 0xb704 NS_GET_PARENT = 0xb702 + NS_GET_PID_FROM_PIDNS = 0x8004b706 + NS_GET_PID_IN_PIDNS = 0x8004b708 + NS_GET_TGID_FROM_PIDNS = 0x8004b707 + NS_GET_TGID_IN_PIDNS = 0x8004b709 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index 61d74b5..da428f4 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -153,9 +153,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x8008b705 NS_GET_NSTYPE = 0xb703 NS_GET_OWNER_UID = 0xb704 NS_GET_PARENT = 0xb702 + NS_GET_PID_FROM_PIDNS = 0x8004b706 + NS_GET_PID_IN_PIDNS = 0x8004b708 + NS_GET_TGID_FROM_PIDNS = 0x8004b707 + NS_GET_TGID_IN_PIDNS = 0x8004b709 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index a28c9e3..bf45bfe 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -150,9 +150,14 @@ const ( NFDBITS = 0x20 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x8008b705 NS_GET_NSTYPE = 0xb703 NS_GET_OWNER_UID = 0xb704 NS_GET_PARENT = 0xb702 + NS_GET_PID_FROM_PIDNS = 0x8004b706 + NS_GET_PID_IN_PIDNS = 0x8004b708 + NS_GET_TGID_FROM_PIDNS = 0x8004b707 + NS_GET_TGID_IN_PIDNS = 0x8004b709 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index ab5d1fe..71c6716 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -154,9 +154,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x8008b705 NS_GET_NSTYPE = 0xb703 NS_GET_OWNER_UID = 0xb704 NS_GET_PARENT = 0xb702 + NS_GET_PID_FROM_PIDNS = 0x8004b706 + NS_GET_PID_IN_PIDNS = 0x8004b708 + NS_GET_TGID_FROM_PIDNS = 0x8004b707 + NS_GET_TGID_IN_PIDNS = 0x8004b709 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go index c523090..9476628 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go @@ -154,9 +154,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x8008b705 NS_GET_NSTYPE = 0xb703 NS_GET_OWNER_UID = 0xb704 NS_GET_PARENT = 0xb702 + NS_GET_PID_FROM_PIDNS = 0x8004b706 + NS_GET_PID_IN_PIDNS = 0x8004b708 + NS_GET_TGID_FROM_PIDNS = 0x8004b707 + NS_GET_TGID_IN_PIDNS = 0x8004b709 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index 01e6ea7..b9e85f3 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -150,9 +150,14 @@ const ( NFDBITS = 0x20 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x2 ONLCR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index 7aa610b..a48b68a 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -150,9 +150,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x2 ONLCR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index 92af771..ea00e85 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -150,9 +150,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x2 ONLCR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index b27ef5e..91c6468 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -150,9 +150,14 @@ const ( NFDBITS = 0x20 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x2 ONLCR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go index 237a2ce..8cbf38d 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go @@ -152,9 +152,14 @@ const ( NL3 = 0x300 NLDLY = 0x300 NOFLSH = 0x80000000 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x4 ONLCR = 0x2 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index 4a5c555..a2df734 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -152,9 +152,14 @@ const ( NL3 = 0x300 NLDLY = 0x300 NOFLSH = 0x80000000 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x4 ONLCR = 0x2 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index a02fb49..2479137 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -152,9 +152,14 @@ const ( NL3 = 0x300 NLDLY = 0x300 NOFLSH = 0x80000000 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x4 ONLCR = 0x2 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go index e26a7c6..d265f14 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -150,9 +150,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x8008b705 NS_GET_NSTYPE = 0xb703 NS_GET_OWNER_UID = 0xb704 NS_GET_PARENT = 0xb702 + NS_GET_PID_FROM_PIDNS = 0x8004b706 + NS_GET_PID_IN_PIDNS = 0x8004b708 + NS_GET_TGID_FROM_PIDNS = 0x8004b707 + NS_GET_TGID_IN_PIDNS = 0x8004b709 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index c48f7c2..3f2d644 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -150,9 +150,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x8008b705 NS_GET_NSTYPE = 0xb703 NS_GET_OWNER_UID = 0xb704 NS_GET_PARENT = 0xb702 + NS_GET_PID_FROM_PIDNS = 0x8004b706 + NS_GET_PID_IN_PIDNS = 0x8004b708 + NS_GET_TGID_FROM_PIDNS = 0x8004b707 + NS_GET_TGID_IN_PIDNS = 0x8004b709 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index ad4b9aa..5d8b727 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -155,9 +155,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x2 ONLCR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go index 1bc1a5a..af30da5 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go @@ -971,23 +971,6 @@ func Getpriority(which int, who int) (prio int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Getrandom(buf []byte, flags int) (n int, err error) { - var _p0 unsafe.Pointer - if len(buf) > 0 { - _p0 = unsafe.Pointer(&buf[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_GETRANDOM, uintptr(_p0), uintptr(len(buf)), uintptr(flags)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Getrusage(who int, rusage *Rusage) (err error) { _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go index d3e38f6..f485dbf 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go @@ -341,6 +341,7 @@ const ( SYS_STATX = 332 SYS_IO_PGETEVENTS = 333 SYS_RSEQ = 334 + SYS_URETPROBE = 335 SYS_PIDFD_SEND_SIGNAL = 424 SYS_IO_URING_SETUP = 425 SYS_IO_URING_ENTER = 426 diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go index 6c778c2..1893e2f 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go @@ -85,7 +85,7 @@ const ( SYS_SPLICE = 76 SYS_TEE = 77 SYS_READLINKAT = 78 - SYS_FSTATAT = 79 + SYS_NEWFSTATAT = 79 SYS_FSTAT = 80 SYS_SYNC = 81 SYS_FSYNC = 82 diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go index 37281cf..16a4017 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go @@ -84,6 +84,8 @@ const ( SYS_SPLICE = 76 SYS_TEE = 77 SYS_READLINKAT = 78 + SYS_NEWFSTATAT = 79 + SYS_FSTAT = 80 SYS_SYNC = 81 SYS_FSYNC = 82 SYS_FDATASYNC = 83 diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go index 9889f6a..a5459e7 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go @@ -84,7 +84,7 @@ const ( SYS_SPLICE = 76 SYS_TEE = 77 SYS_READLINKAT = 78 - SYS_FSTATAT = 79 + SYS_NEWFSTATAT = 79 SYS_FSTAT = 80 SYS_SYNC = 81 SYS_FSYNC = 82 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index 9f2550d..3a69e45 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -87,31 +87,35 @@ type StatxTimestamp struct { } type Statx_t struct { - Mask uint32 - Blksize uint32 - Attributes uint64 - Nlink uint32 - Uid uint32 - Gid uint32 - Mode uint16 - _ [1]uint16 - Ino uint64 - Size uint64 - Blocks uint64 - Attributes_mask uint64 - Atime StatxTimestamp - Btime StatxTimestamp - Ctime StatxTimestamp - Mtime StatxTimestamp - Rdev_major uint32 - Rdev_minor uint32 - Dev_major uint32 - Dev_minor uint32 - Mnt_id uint64 - Dio_mem_align uint32 - Dio_offset_align uint32 - Subvol uint64 - _ [11]uint64 + Mask uint32 + Blksize uint32 + Attributes uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Mode uint16 + _ [1]uint16 + Ino uint64 + Size uint64 + Blocks uint64 + Attributes_mask uint64 + Atime StatxTimestamp + Btime StatxTimestamp + Ctime StatxTimestamp + Mtime StatxTimestamp + Rdev_major uint32 + Rdev_minor uint32 + Dev_major uint32 + Dev_minor uint32 + Mnt_id uint64 + Dio_mem_align uint32 + Dio_offset_align uint32 + Subvol uint64 + Atomic_write_unit_min uint32 + Atomic_write_unit_max uint32 + Atomic_write_segments_max uint32 + _ [1]uint32 + _ [9]uint64 } type Fsid struct { @@ -516,6 +520,29 @@ type TCPInfo struct { Total_rto_time uint32 } +type TCPVegasInfo struct { + Enabled uint32 + Rttcnt uint32 + Rtt uint32 + Minrtt uint32 +} + +type TCPDCTCPInfo struct { + Enabled uint16 + Ce_state uint16 + Alpha uint32 + Ab_ecn uint32 + Ab_tot uint32 +} + +type TCPBBRInfo struct { + Bw_lo uint32 + Bw_hi uint32 + Min_rtt uint32 + Pacing_gain uint32 + Cwnd_gain uint32 +} + type CanFilter struct { Id uint32 Mask uint32 @@ -557,6 +584,7 @@ const ( SizeofICMPv6Filter = 0x20 SizeofUcred = 0xc SizeofTCPInfo = 0xf8 + SizeofTCPCCInfo = 0x14 SizeofCanFilter = 0x8 SizeofTCPRepairOpt = 0x8 ) @@ -3766,7 +3794,7 @@ const ( ETHTOOL_MSG_PSE_GET = 0x24 ETHTOOL_MSG_PSE_SET = 0x25 ETHTOOL_MSG_RSS_GET = 0x26 - ETHTOOL_MSG_USER_MAX = 0x2b + ETHTOOL_MSG_USER_MAX = 0x2c ETHTOOL_MSG_KERNEL_NONE = 0x0 ETHTOOL_MSG_STRSET_GET_REPLY = 0x1 ETHTOOL_MSG_LINKINFO_GET_REPLY = 0x2 @@ -3806,7 +3834,7 @@ const ( ETHTOOL_MSG_MODULE_NTF = 0x24 ETHTOOL_MSG_PSE_GET_REPLY = 0x25 ETHTOOL_MSG_RSS_GET_REPLY = 0x26 - ETHTOOL_MSG_KERNEL_MAX = 0x2b + ETHTOOL_MSG_KERNEL_MAX = 0x2c ETHTOOL_FLAG_COMPACT_BITSETS = 0x1 ETHTOOL_FLAG_OMIT_REPLY = 0x2 ETHTOOL_FLAG_STATS = 0x4 @@ -3951,7 +3979,7 @@ const ( ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL = 0x17 ETHTOOL_A_COALESCE_USE_CQE_MODE_TX = 0x18 ETHTOOL_A_COALESCE_USE_CQE_MODE_RX = 0x19 - ETHTOOL_A_COALESCE_MAX = 0x1c + ETHTOOL_A_COALESCE_MAX = 0x1e ETHTOOL_A_PAUSE_UNSPEC = 0x0 ETHTOOL_A_PAUSE_HEADER = 0x1 ETHTOOL_A_PAUSE_AUTONEG = 0x2 @@ -4609,7 +4637,7 @@ const ( NL80211_ATTR_MAC_HINT = 0xc8 NL80211_ATTR_MAC_MASK = 0xd7 NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca - NL80211_ATTR_MAX = 0x14a + NL80211_ATTR_MAX = 0x14c NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4 NL80211_ATTR_MAX_CSA_COUNTERS = 0xce NL80211_ATTR_MAX_MATCH_SETS = 0x85 @@ -5213,7 +5241,7 @@ const ( NL80211_FREQUENCY_ATTR_GO_CONCURRENT = 0xf NL80211_FREQUENCY_ATTR_INDOOR_ONLY = 0xe NL80211_FREQUENCY_ATTR_IR_CONCURRENT = 0xf - NL80211_FREQUENCY_ATTR_MAX = 0x20 + NL80211_FREQUENCY_ATTR_MAX = 0x21 NL80211_FREQUENCY_ATTR_MAX_TX_POWER = 0x6 NL80211_FREQUENCY_ATTR_NO_10MHZ = 0x11 NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc diff --git a/vendor/modules.txt b/vendor/modules.txt index 8884e74..a06debc 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -23,7 +23,7 @@ github.com/decred/dcrd/dcrec/secp256k1/v4/schnorr # github.com/fasthttp/websocket v1.5.10 ## explicit; go 1.20 github.com/fasthttp/websocket -# github.com/fiatjaf/eventstore v0.9.1 +# github.com/fiatjaf/eventstore v0.11.0 ## explicit; go 1.23.0 github.com/fiatjaf/eventstore github.com/fiatjaf/eventstore/postgresql @@ -81,7 +81,7 @@ github.com/mattn/go-colorable # github.com/mattn/go-isatty v0.0.20 ## explicit; go 1.15 github.com/mattn/go-isatty -# github.com/nbd-wtf/go-nostr v0.37.3 +# github.com/nbd-wtf/go-nostr v0.38.1 ## explicit; go 1.23.0 github.com/nbd-wtf/go-nostr github.com/nbd-wtf/go-nostr/nip11 @@ -102,7 +102,7 @@ github.com/rs/zerolog/internal/json # github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 ## explicit; go 1.20 github.com/savsgio/gotils/strconv -# github.com/tidwall/gjson v1.17.3 +# github.com/tidwall/gjson v1.18.0 ## explicit; go 1.12 github.com/tidwall/gjson # github.com/tidwall/match v1.1.1 @@ -119,13 +119,13 @@ github.com/valyala/bytebufferpool github.com/valyala/fasthttp github.com/valyala/fasthttp/fasthttputil github.com/valyala/fasthttp/stackless -# golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 +# golang.org/x/exp v0.0.0-20241004190924-225e2abe05e6 ## explicit; go 1.22.0 golang.org/x/exp/constraints -# golang.org/x/net v0.29.0 +# golang.org/x/net v0.30.0 ## explicit; go 1.18 golang.org/x/net/internal/socks golang.org/x/net/proxy -# golang.org/x/sys v0.25.0 +# golang.org/x/sys v0.26.0 ## explicit; go 1.18 golang.org/x/sys/unix