diff --git a/go.mod b/go.mod index a8ebda2d9..09ec38b7c 100644 --- a/go.mod +++ b/go.mod @@ -19,18 +19,14 @@ require ( require ( filippo.io/hpke v0.4.0 // indirect - github.com/bits-and-blooms/bitset v1.24.4 // indirect github.com/btcsuite/btcd/btcutil v1.1.6 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/consensys/gnark-crypto v0.20.1 // indirect - github.com/crate-crypto/go-eth-kzg v1.5.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.1 // indirect github.com/dgraph-io/ristretto/v2 v2.4.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/emicklei/go-restful/v3 v3.12.2 // indirect - github.com/ethereum/c-kzg-4844/v2 v2.1.7 // indirect github.com/fxamacker/cbor/v2 v2.9.1 // indirect github.com/go-ini/ini v1.67.0 // indirect github.com/go-logr/logr v1.4.3 // indirect @@ -57,7 +53,6 @@ require ( github.com/luxfi/constants v1.6.2 // indirect github.com/luxfi/container v0.2.1 // indirect github.com/luxfi/crypto v1.20.2 // indirect - github.com/luxfi/crypto/ipa v1.2.4 // indirect github.com/luxfi/formatting v1.1.1 // indirect github.com/luxfi/geth v1.20.1 // indirect github.com/luxfi/go-bip32 v1.1.0 // indirect @@ -66,8 +61,6 @@ require ( github.com/luxfi/mdns v0.1.1 // indirect github.com/luxfi/metric v1.8.1 // indirect github.com/luxfi/mock v0.1.1 // indirect - github.com/luxfi/pq v1.1.0 // indirect - github.com/luxfi/proto v1.4.2 // indirect github.com/luxfi/protocol v0.0.2 // indirect github.com/luxfi/sampler v1.1.0 // indirect github.com/luxfi/tls v1.1.1 // indirect diff --git a/go.sum b/go.sum index 4fe27635b..f6862f1cc 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,10 @@ +c2sp.org/CCTV/age v0.0.0-20251208015420-e9274a7bdbfd h1:ZLsPO6WdZ5zatV4UfVpr7oAwLGRZ+sebTUruuM4Ra3M= +c2sp.org/CCTV/age v0.0.0-20251208015420-e9274a7bdbfd/go.mod h1:SrHC2C7r5GkDk8R+NFVzYy/sdj0Ypg9htaPXQq5Cqeo= filippo.io/hpke v0.4.0 h1:p575VVQ6ted4pL+it6M00V/f2qTZITO0zgmdKCkd5+A= filippo.io/hpke v0.4.0/go.mod h1:EmAN849/P3qdeK+PCMkDpDm83vRHM5cDipBJ8xbQLVY= +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/bits-and-blooms/bitset v1.24.4 h1:95H15Og1clikBrKr/DuzMXkQzECs1M6hhoGXLwLQOZE= -github.com/bits-and-blooms/bitset v1.24.4/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6zh6bWP60UxwoT5LzdGJsQJaPo6HjduXq9p6A= @@ -32,29 +34,30 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8= github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4= -github.com/consensys/gnark-crypto v0.20.1 h1:PXDUBvk8AzhvWowHLWBEAfUQcV1/aZgWIqD6eMpXmDg= -github.com/consensys/gnark-crypto v0.20.1/go.mod h1:RBWrSgy+IDbGR69RRV313th3M/aZU1ubk2om+qHuTSc= -github.com/crate-crypto/go-eth-kzg v1.5.0 h1:FYRiJMJG2iv+2Dy3fi14SVGjcPteZ5HAAUe4YWlJygc= -github.com/crate-crypto/go-eth-kzg v1.5.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8= +github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.1 h1:5RVFMOWjMyRy8cARdy79nAmgYw3hK/4HUq48LQ6Wwqo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.1/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/dgraph-io/ristretto/v2 v2.4.0 h1:I/w09yLjhdcVD2QV192UJcq8dPBaAJb9pOuMyNy0XlU= github.com/dgraph-io/ristretto/v2 v2.4.0/go.mod h1:0KsrXtXvnv0EqnzyowllbVJB8yBonswa2lTCK2gGo9E= +github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da h1:aIftn67I1fkbMa512G+w+Pxci9hJPB8oMnkcP3iZF38= +github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/ethereum/c-kzg-4844/v2 v2.1.7 h1:aat3CuITdDbPC6pmEGRT0zJ5eOxzrZj8TJT5z7Xk//M= -github.com/ethereum/c-kzg-4844/v2 v2.1.7/go.mod h1:8HMkUZ5JRv4hpw/XUrYWSQNAUzhHMg2UDb/U+5m+XNw= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fxamacker/cbor/v2 v2.9.1 h1:2rWm8B193Ll4VdjsJY28jxs70IdDsHRWgQYAI80+rMQ= github.com/fxamacker/cbor/v2 v2.9.1/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= @@ -66,10 +69,16 @@ github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ4 github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -81,11 +90,16 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/flatbuffers v25.12.19+incompatible h1:haMV2JRRJCe1998HeW/p0X9UaMTK6SDo0ffLn2+DbLs= github.com/google/flatbuffers v25.12.19+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20260302011040-a15ffb7f9dcc h1:VBbFa1lDYWEeV5FZKUiYKYT0VxCp9twUmmaq9eb8sXw= +github.com/google/pprof v0.0.0-20260302011040-a15ffb7f9dcc/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/rpc v1.2.1 h1:yC+LMV5esttgpVvNORL/xX4jvTTEUE30UZhZ5JF7K9k= @@ -98,8 +112,10 @@ github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXei github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +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/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -112,89 +128,65 @@ github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu github.com/klauspost/crc32 v1.3.0 h1:sSmTt3gUt81RP655XGZPElI0PelVTZ6YwCRnPSupoFM= github.com/klauspost/crc32 v1.3.0/go.mod h1:D7kQaZhnkX/Y0tstFGf8VUzv2UofNGqCjnC3zdHB0Hw= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/luxfi/accel v1.2.4 h1:5VbIHyEvvfobn2zBiTFODxDw1CeqxCepZOLlvkuf9yQ= github.com/luxfi/accel v1.2.4/go.mod h1:ISIwAX+ZfsL/S5nsP2JvfldXN6Nc+QzoWf6Jtaq+xsQ= -github.com/luxfi/address v1.0.1/go.mod h1:5j3Eh66v9zvv1GbNdZwt+23krV8JlSDaRzmWZU8ZRM0= github.com/luxfi/address v1.1.1 h1:4afWzyBWzTiZN7RenBtdMC9LIvP9L4CSBzSquwKEAgI= github.com/luxfi/address v1.1.1/go.mod h1:KG0jUBcgoJYeieKP5jboCq9UewwDBIOus8ZCqUMVlw8= -github.com/luxfi/age v1.5.0/go.mod h1:iAYAxgvrXxcy746+Ovh/eWWDuF9teJLNcCSSOX9RYW0= github.com/luxfi/age v1.6.0 h1:KMD8gSOP4NVCb7NWSlRcgBZNV2xm2a+qQWPyPmiX6f4= github.com/luxfi/age v1.6.0/go.mod h1:7cu9CIyikgyAvr5MlXFapEDQ15yBaHOSdKkK5lG04WE= -github.com/luxfi/cache v1.2.1 h1:kAzOS55/hmYeNKR+0HAKv4ma48Y6JjkI8UQeqdZ8bfI= -github.com/luxfi/cache v1.2.1/go.mod h1:co7JTxZZHpKT31Yh01LFp5aZOxmoUg157FhBLQdQHVU= github.com/luxfi/cache v1.3.1 h1:grQhi/B5GKypG7avDMeY143QTgFbfEvQICKNIh1Cw6U= github.com/luxfi/cache v1.3.1/go.mod h1:2MokdbeNUy/9O3mdREWkE6BiN7tRvePkXiKkcb+4M7g= -github.com/luxfi/constants v1.5.8/go.mod h1:Pu5jWHdnUtQRbWC43yTUjU/pbIIKMDOd2a2yroSfo48= github.com/luxfi/constants v1.6.2 h1:pXHdKIFbfE9qX4xOjq2LxYvagNhhNvspUVEbPcIEKfA= github.com/luxfi/constants v1.6.2/go.mod h1:r0oH8C/+r/XFYBq1AJxt6zWRKKRKgDzrEMop/CCs9rI= -github.com/luxfi/container v0.0.4 h1:BXhF82WyfqVP5mjlNcr7tP0Fcnvl0Ap1rkiu+rq5XuM= -github.com/luxfi/container v0.0.4/go.mod h1:Z3SpmMF5d4t77MM0nHYXURpn+EMVaeu1fhbd/3BGaek= github.com/luxfi/container v0.2.1 h1:MTnfKXzS5+oxV5jKZerdOxSA6iMPaQI9/FWGufizzaw= github.com/luxfi/container v0.2.1/go.mod h1:B+uM0wP0lGvt/SSK7QOEn/qBcsHzILVHlKikdCyzSgM= -github.com/luxfi/crypto v1.19.27 h1:K4l9nsnB0t61zHO5u8si06zVzW5WTjWW+/6+KRb/bfo= -github.com/luxfi/crypto v1.19.27/go.mod h1:0DCU62kX8+zhYU2qeM07A4pifJyPkPujnUOfgc8TOFQ= github.com/luxfi/crypto v1.20.2 h1:L81WEsU/hs2A76F5PWBusG0yU74QqkDdUqqgexWUxh4= github.com/luxfi/crypto v1.20.2/go.mod h1:qYHOM0lO4PRh7LEaObxFQUIMjmT1/paVm/WgZkobT1k= -github.com/luxfi/crypto/ipa v1.2.4 h1:6xfwhI9/HrcDkF3Ti5/NxsNQIWbwYDJmRSNIHRQ/xfU= -github.com/luxfi/crypto/ipa v1.2.4/go.mod h1:43J6f6rcfUMrZt4cQectMOZb6Ps+fAEj8ZTPC3Kk+gE= -github.com/luxfi/formatting v1.0.1/go.mod h1:mYzNf5DJOiqSSKUPzNj5dKy4tstFbN3pZlkI5716eKc= github.com/luxfi/formatting v1.1.1 h1:MJhVXIPh1dbysvYEjtaEA/Z0FUTiI7n0DwOF54FS08c= github.com/luxfi/formatting v1.1.1/go.mod h1:zhBWp6fLZduhpiAdPgVDdPVOyhw4FvwRUksF6+xKQCE= -github.com/luxfi/geth v1.17.12 h1:UP/fhpcfbGPTrkOCwX3d88Oc3jVm5gTOgfjgq+lek6s= -github.com/luxfi/geth v1.17.12/go.mod h1:3vQfQJd9JC+AVBjxNXa9PYQOqpbE2dKu8E3jqhPZ3LU= github.com/luxfi/geth v1.20.1 h1:QUGQr4AKvADjwMi7t8a0OfoyxShgEcI9pwie1jFYfm0= github.com/luxfi/geth v1.20.1/go.mod h1:GV5bIMEgWviRN+jPXERyVpI16H3iHqPcdIokDoZdrvU= -github.com/luxfi/go-bip32 v1.0.2/go.mod h1:bc7/LXDKAJQZ/F0Xjf5yXaTZxY9/ssLb4FC+Hxn/cDk= github.com/luxfi/go-bip32 v1.1.0 h1:zjy19WKa1KJnGamRNyOZM3l/MPtV/sax7M4NMPwLHZQ= github.com/luxfi/go-bip32 v1.1.0/go.mod h1:QyDXlzWL3xRiCbMUi4Z3J52Q/SMoCvdRLXXlYvSZor8= -github.com/luxfi/go-bip39 v1.1.2/go.mod h1:96de9VkR2kY/ASAnhMtvt3TSh+PZkAFAngNj0GjRGDo= github.com/luxfi/go-bip39 v1.2.0 h1:fx3pFuSGawCG4In6pA4OLLStqbgIqD1j8EygFskoHzY= github.com/luxfi/go-bip39 v1.2.0/go.mod h1:if+2OVbG4k4jKIuBt/Rse1KV1kgWQM5j5xFbUtwbNtc= -github.com/luxfi/ids v1.2.15 h1:omE+E4+0Poj9DzM11ejSFgteaSQ3KDHi5g54iH6jcxI= -github.com/luxfi/ids v1.2.15/go.mod h1:Fj73K5xcblvdE0SxU/ip+jE8VqNdu+80548su5KJ7xI= github.com/luxfi/ids v1.3.2 h1:c6Rft5kZB4XqiCtWaGH47bfhaNFm3FGRfhEzI01GVeI= github.com/luxfi/ids v1.3.2/go.mod h1:+5l8cYMbKpORJbQ2r98CYJo9TQATgUdnmzpYFZWMwwc= -github.com/luxfi/keys v1.1.0/go.mod h1:U3tZNDmv3nXkPoZwLtq9RNjwyN0XyoN29worigfT+c0= github.com/luxfi/keys v1.4.1 h1:2Zcoovaz9OLPz7m7VGXfRrGnrlqt0GeUpJclsPBi4EU= github.com/luxfi/keys v1.4.1/go.mod h1:P8EUP5DKrR1SUZBGZjDT3rWcp2P1miUlVh7IBRNBphU= github.com/luxfi/log v1.4.3 h1:xkUKRWvQ4ZwvlUC2e0/RTtHYZOYSMvSQ9W9lbjwBmiI= github.com/luxfi/log v1.4.3/go.mod h1:myIkufyiQomSQH34K981kbz6cG4WUoerRUh7F4XhlQI= -github.com/luxfi/math v1.4.1 h1:1t9bCCsEqnl9yIKrShlbs80DBKyYTWdnzkVfBqEeO7Q= -github.com/luxfi/math v1.4.1/go.mod h1:QvbRxauQyE1w4lvbcLSe6c8yeJz2Zj1Bq1rayGgs2tA= github.com/luxfi/math v1.5.1 h1:FDOY75e4vn/Xra1ij99xOS/9XdxQGCPP6HONHRkCwfg= github.com/luxfi/math v1.5.1/go.mod h1:3j9R24hVfPhrbvs45YSJP7jAyVNfwx/cj/+lAO8IGro= github.com/luxfi/math/big v0.1.0 h1:Vz4c0RsZVPdIKPsHPgAJChH/R3p15WHRUz7LkLf+NIQ= github.com/luxfi/math/big v0.1.0/go.mod h1:BuxSu22RbO93xBLk5Eam5nldFponoJ73xDFz4uJ3Huk= github.com/luxfi/mdns v0.1.1 h1:g2eRr9AXcziPkkcd24M+Qu9ApEpoKKjfI79QSNqv0rQ= github.com/luxfi/mdns v0.1.1/go.mod h1:dbp5f3h3aE7CGzwbaWzBM9cwdcekhmSrWhQevgYhhNA= -github.com/luxfi/metric v1.5.8 h1:axPwfq+erOlIue7IJp5g+hMcMtVhYHja9gJAaT3+KNA= -github.com/luxfi/metric v1.5.8/go.mod h1:fO2giazkg4NDtr72JM/QXJBYebplAMeWC1JoZyNDvKw= github.com/luxfi/metric v1.8.1 h1:v58GgPFAOLPVxSa/JiNLwqJQNEFHdWbXZV28piMXX4s= github.com/luxfi/metric v1.8.1/go.mod h1:R1OPAIeW4UBW3osK7j2r3/XPmczfNRFTXg4bnlemTuE= github.com/luxfi/mock v0.1.1 h1:0HEtIjg1J6CWz+IUyP6rsGqNWTcmxjFnSQIhaDuARwY= github.com/luxfi/mock v0.1.1/go.mod h1:jo35akl3Vtd8LbzDts8VJ0jmSVycrd1/eBi6g6t5hKU= -github.com/luxfi/pq v1.0.3 h1:ksw1dmfTR0dqqNMRS7BjGcprCO2Fhc+3Iiq2/NMuONw= -github.com/luxfi/pq v1.0.3/go.mod h1:8bppZcRElfrVt0n3nYCZW3iX1TvhvzNbdjNdK1irgIE= -github.com/luxfi/proto v1.3.4/go.mod h1:S80KrTzISCktptit/pWLzk6nHgagjJS86qbQL6gHutE= +github.com/luxfi/pq v1.1.0 h1:ADplfUSyirLymSxs3Ix0HeDTyl5oswCNUpXJt/5vLY8= +github.com/luxfi/pq v1.1.0/go.mod h1:KT5rG9ztpzIkT9QSnXK4WFqBBLzKCLjY7l1c/unBi8I= github.com/luxfi/protocol v0.0.2 h1:TAuXMm1K4VDpG3B3brq1EE9Lb7XlbhQmVBObskgNhmc= github.com/luxfi/protocol v0.0.2/go.mod h1:Yjn2VRwn5PXim0+JTalAyrVG6YbmuSnYOfeUXSbAsqA= github.com/luxfi/sampler v1.1.0 h1:u3iRDl7V06ARh0e85h3HT+aZ1saCFo2yMMsh+dCJbqk= github.com/luxfi/sampler v1.1.0/go.mod h1:kJa53S3tC9+VSbuV3RFu68MmbCCBlr2UM39LOClQ/Hs= -github.com/luxfi/tls v1.0.3/go.mod h1:dQqSiGE7YxXUxOwICoReUuIitBms9DYOaCeteBwmIWw= github.com/luxfi/tls v1.1.1 h1:BSZ0gHSp7U8vzlmzx7WSSCz+b7Ky4JtD9HDDhn7vrDg= github.com/luxfi/tls v1.1.1/go.mod h1:+5TDy8UtLL+tz124brZzpUDBRj+sKrq0JFqdmpMUHgw= -github.com/luxfi/vm v1.2.3/go.mod h1:ZXmw1sKA6GL3Ma3BfYUv5Fzvx3aWu2QMtkxF3lL/3R4= github.com/luxfi/vm v1.3.1 h1:rLCbygaajehVkUoJ5czwhpUAJaC5J5okq3p+j2QSPSo= github.com/luxfi/vm v1.3.1/go.mod h1:uViH3COP8hhCbj42v1MTohkPCDwYQCZanNIOb/StWqY= -github.com/luxfi/zap v0.7.2 h1:YecWTWNE5PPJXL56sLIkzS8b23bprUwZ5lPAQuLUtTE= -github.com/luxfi/zap v0.7.2/go.mod h1:1k+nwT+JW802YzuPAuf7CxMSGr/qxvbGgGwi5k6X9Ok= github.com/luxfi/zap v1.2.6 h1:NBpbm9Gib41Oi/XAkAZKQ3hb+xCafo7JsrUjw+bKiAc= github.com/luxfi/zap v1.2.6/go.mod h1:sTAe/AMMamoE85cVoe81+NbqHJkgvqS0LhY9ByHEmr0= github.com/luxfi/zapdb v1.10.0 h1:1lLHEmkyC0BucnA/zjQYsMkUVxuEo2vQkEaQGjYfuuc= github.com/luxfi/zapdb v1.10.0/go.mod h1:Qukh3hDRD0MnxA6z+a28JTnXhN85AiLLgp6TYr4QAMc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.1.15 h1:+u9SLTRGnXv73cEsnsmoZBom+dMU88B2M0aDcWy0/jY= github.com/mattn/go-colorable v0.1.15/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= @@ -210,33 +202,47 @@ github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEp github.com/minio/minio-go/v7 v7.0.100 h1:ShkWi8Tyj9RtU57OQB2HIXKz4bFgtVib0bbT1sbtLI8= github.com/minio/minio-go/v7 v7.0.100/go.mod h1:EtGNKtlX20iL2yaYnxEigaIvj0G0GwSDnifnG8ClIdw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mr-tron/base58 v1.3.0 h1:K6Y13R2h+dku0wOqKtecgRnBUBPrZzLZy5aIj8lCcJI= github.com/mr-tron/base58 v1.3.0/go.mod h1:2BuubE67DCSWwVfx37JWNG8emOC0sHEU4/HpcYgCLX8= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo/v2 v2.28.1 h1:S4hj+HbZp40fNKuLUQOYLDgZLwNUVn19N3Atb98NCyI= github.com/onsi/ginkgo/v2 v2.28.1/go.mod h1:CLtbVInNckU3/+gC8LzkGUb9oF+e8W8TdUsxPwvdOgE= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28= github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg= github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM= github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM= +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/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/quic-go/quic-go v0.59.1 h1:0Gmua0HW1Tv7ANR7hUYwRyD0MG5OJfgvYSZasGZzBic= +github.com/quic-go/quic-go v0.59.1/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4= github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -244,28 +250,28 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/supranational/blst v0.3.16 h1:bTDadT+3fK497EvLdWRQEjiGnUtzJ7jjIUMF0jqwYhE= github.com/supranational/blst v0.3.16/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= -github.com/tinylib/msgp v1.6.3/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA= github.com/tinylib/msgp v1.6.4 h1:mOwYbyYDLPj35mkA2BjjYejgJk9BuHxDdvRnb6v2ZcQ= github.com/tinylib/msgp v1.6.4/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= -go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= -go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= +go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= @@ -294,6 +300,7 @@ golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -314,12 +321,14 @@ golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4= golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= +golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -343,9 +352,12 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= @@ -354,14 +366,25 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/api v0.34.0 h1:L+JtP2wDbEYPUeNGbeSa/5GwFtIA662EmT2YSLOkAVE= k8s.io/api v0.34.0/go.mod h1:YzgkIzOOlhl9uwWCZNqpw6RJy9L2FK4dlJeayUoydug= +k8s.io/apimachinery v0.34.0 h1:eR1WO5fo0HyoQZt1wdISpFDffnWOvFLOOeJ7MgIv4z0= k8s.io/apimachinery v0.34.0/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/client-go v0.34.0 h1:YoWv5r7bsBfb0Hs2jh8SOvFbKzzxyNo0nSb0zC19KZo= k8s.io/client-go v0.34.0/go.mod h1:ozgMnEKXkRjeMvBZdV1AijMHLTh3pbACPvK7zFR+QQY= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA= k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts= +k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco= sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/vendor/github.com/luxfi/proto/LICENSE b/vendor/github.com/luxfi/address/LICENSE similarity index 100% rename from vendor/github.com/luxfi/proto/LICENSE rename to vendor/github.com/luxfi/address/LICENSE diff --git a/vendor/github.com/luxfi/keys/LICENSING.md b/vendor/github.com/luxfi/address/LICENSING.md similarity index 100% rename from vendor/github.com/luxfi/keys/LICENSING.md rename to vendor/github.com/luxfi/address/LICENSING.md diff --git a/vendor/github.com/luxfi/address/LLM.md b/vendor/github.com/luxfi/address/LLM.md new file mode 100644 index 000000000..faaf1f2bd --- /dev/null +++ b/vendor/github.com/luxfi/address/LLM.md @@ -0,0 +1,26 @@ +# Hanzo Address + +## Overview +Go module: github.com/luxfi/address + +## Tech Stack +- **Language**: Go + +## Build & Run +```bash +go build ./... +go test ./... +``` + +## Structure +``` +address/ + LICENSE + address.go + converter.go + go.mod + go.sum +``` + +## Key Files +- `go.mod` -- Go module definition diff --git a/vendor/github.com/luxfi/age/LICENSING.md b/vendor/github.com/luxfi/age/LICENSING.md new file mode 100644 index 000000000..d96eecd3c --- /dev/null +++ b/vendor/github.com/luxfi/age/LICENSING.md @@ -0,0 +1,8 @@ +# Licensing + +This repository is licensed under the **BSD-3-Clause License** (see [LICENSE](LICENSE)). It belongs to the **public** tier of the Lux three-tier IP strategy: anyone may use, fork, or redistribute it, including for commercial purposes, subject to the BSD-3-Clause License terms. + +For the canonical Lux IP and licensing strategy, see: + + +For commercial inquiries that go beyond the public tier (e.g. private moat acceleration kernels, Eco-tier patent-protected primitives outside Authorized Networks), contact `licensing@lux.network`. diff --git a/vendor/github.com/luxfi/age/LLM.md b/vendor/github.com/luxfi/age/LLM.md new file mode 100644 index 000000000..b9e3ef635 --- /dev/null +++ b/vendor/github.com/luxfi/age/LLM.md @@ -0,0 +1,19 @@ +# age + +**Org:** luxfi · **Ecosystem:** lux · **Path:** `/Users/a/work/lux/luxfi/age` +**Origin:** https://github.com/luxfi/age.git + +## Discovery + +This file (`CLAUDE.md`) is the canonical agent-facing readme; `LLM.md` is a symlink to it. Update either name and both stay in sync. + +## Where to look first + +- `README.md` — human-facing overview (if present) +- `package.json` / `Cargo.toml` / `pyproject.toml` / `go.mod` — language & deps +- `.github/workflows/` — CI surface +- `docs/` — extended docs (if present) + +## Sibling repos + +See the org-level `LLM.md` at `/Users/a/work/lux/luxfi/LLM.md` for the full inventory of sibling repos and inter-repo dependencies. diff --git a/vendor/github.com/luxfi/age/PQ-ROADMAP.md b/vendor/github.com/luxfi/age/PQ-ROADMAP.md index 618d01858..1ce40be68 100644 --- a/vendor/github.com/luxfi/age/PQ-ROADMAP.md +++ b/vendor/github.com/luxfi/age/PQ-ROADMAP.md @@ -74,8 +74,8 @@ REPLICATE_AGE_RECIPIENTS_FALLBACK=age1pq1... # comma-separated, multi-recipi ### E. Operator CRD ```yaml -apiVersion: liquidity.io/v1 -kind: LiquidReplicate +apiVersion: lux.network/v1 +kind: ReplicateConfig spec: encryption: kem: xwing # enum: hpke-mlkem768x25519 | xwing diff --git a/vendor/github.com/luxfi/age/README.md b/vendor/github.com/luxfi/age/README.md index 7242a6117..ee341869d 100644 --- a/vendor/github.com/luxfi/age/README.md +++ b/vendor/github.com/luxfi/age/README.md @@ -1,3 +1,5 @@ +

age

+

diff --git a/vendor/github.com/luxfi/age/pq.go b/vendor/github.com/luxfi/age/pq.go index 60d5f9701..d34048cac 100644 --- a/vendor/github.com/luxfi/age/pq.go +++ b/vendor/github.com/luxfi/age/pq.go @@ -9,9 +9,9 @@ import ( "fmt" "strings" + "filippo.io/hpke" "github.com/luxfi/age/internal/bech32" "github.com/luxfi/age/internal/format" - "filippo.io/hpke" "golang.org/x/crypto/chacha20poly1305" ) diff --git a/vendor/github.com/luxfi/cache/LICENSE b/vendor/github.com/luxfi/cache/LICENSE new file mode 100644 index 000000000..fbc776e31 --- /dev/null +++ b/vendor/github.com/luxfi/cache/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2024, Lux Partners Limited +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/luxfi/cache/LICENSING.md b/vendor/github.com/luxfi/cache/LICENSING.md new file mode 100644 index 000000000..67d9be8aa --- /dev/null +++ b/vendor/github.com/luxfi/cache/LICENSING.md @@ -0,0 +1,12 @@ +# Licensing + +This repository is licensed under the **BSD 3-Clause License** (see +[LICENSE](LICENSE)). It belongs to the **public** tier of the Lux +three-tier IP strategy: anyone may use, fork, or redistribute it, +including for commercial purposes, subject to the BSD-3 terms. + +For the canonical Lux IP and licensing strategy, see: + + +For commercial inquiries that go beyond BSD-3 (e.g. private moat +acceleration kernels), contact `licensing@lux.network`. diff --git a/vendor/github.com/luxfi/constants/chain_registry.go b/vendor/github.com/luxfi/constants/chain_registry.go index 3643d6b4d..764f1f120 100644 --- a/vendor/github.com/luxfi/constants/chain_registry.go +++ b/vendor/github.com/luxfi/constants/chain_registry.go @@ -21,7 +21,8 @@ type ChainConfig struct { QChainID ids.ID // Quantum chain - post-quantum cryptography AChainID ids.ID // Attestation chain - oracles, compute attestation BChainID ids.ID // Bridge chain - cross-chain interop - TChainID ids.ID // Threshold chain - FHE, threshold crypto + MChainID ids.ID // MPC chain - threshold signing / bridge custody (consumes mpcvm library) + FChainID ids.ID // FHE chain - confidential compute / encrypted state (consumes mpcvm library) ZChainID ids.ID // ZK chain - zero-knowledge proofs GChainID ids.ID // Graph chain - dgraph KChainID ids.ID // KMS chain - key management @@ -109,8 +110,10 @@ func (r *ChainRegistry) MigrateChain(networkID uint32, chainName string, newChai config.AChainID = newChainID case "B", "bridge": config.BChainID = newChainID - case "T", "threshold": - config.TChainID = newChainID + case "M", "mpc": + config.MChainID = newChainID + case "F", "fhe": + config.FChainID = newChainID case "Z", "zk": config.ZChainID = newChainID case "D", "dex": @@ -166,9 +169,14 @@ func (r *ChainRegistry) GetBChainID(networkID uint32) ids.ID { return r.GetOrDefault(networkID).BChainID } -// GetTChainID returns the T-chain ID for the given network. -func (r *ChainRegistry) GetTChainID(networkID uint32) ids.ID { - return r.GetOrDefault(networkID).TChainID +// GetMChainID returns the M-chain ID for the given network. +func (r *ChainRegistry) GetMChainID(networkID uint32) ids.ID { + return r.GetOrDefault(networkID).MChainID +} + +// GetFChainID returns the F-chain ID for the given network. +func (r *ChainRegistry) GetFChainID(networkID uint32) ids.ID { + return r.GetOrDefault(networkID).FChainID } // GetZChainID returns the Z-chain ID for the given network. @@ -192,7 +200,8 @@ func defaultMainnetConfig() *ChainConfig { QChainID: ids.QChainID, AChainID: ids.AChainID, BChainID: ids.BChainID, - TChainID: ids.TChainID, + MChainID: ids.MChainID, + FChainID: ids.FChainID, ZChainID: ids.ZChainID, DChainID: ids.DChainID, } @@ -207,7 +216,8 @@ func defaultTestnetConfig() *ChainConfig { QChainID: ids.QChainID, AChainID: ids.AChainID, BChainID: ids.BChainID, - TChainID: ids.TChainID, + MChainID: ids.MChainID, + FChainID: ids.FChainID, ZChainID: ids.ZChainID, DChainID: ids.DChainID, } @@ -222,7 +232,8 @@ func defaultDevnetConfig() *ChainConfig { QChainID: ids.QChainID, AChainID: ids.AChainID, BChainID: ids.BChainID, - TChainID: ids.TChainID, + MChainID: ids.MChainID, + FChainID: ids.FChainID, ZChainID: ids.ZChainID, DChainID: ids.DChainID, } @@ -237,7 +248,8 @@ func defaultCustomConfig() *ChainConfig { QChainID: ids.QChainID, AChainID: ids.AChainID, BChainID: ids.BChainID, - TChainID: ids.TChainID, + MChainID: ids.MChainID, + FChainID: ids.FChainID, ZChainID: ids.ZChainID, DChainID: ids.DChainID, } diff --git a/vendor/github.com/luxfi/constants/network_ids.go b/vendor/github.com/luxfi/constants/network_ids.go index 31f768730..d4d2e8979 100644 --- a/vendor/github.com/luxfi/constants/network_ids.go +++ b/vendor/github.com/luxfi/constants/network_ids.go @@ -73,7 +73,8 @@ var ( QChainID = ids.QChainID // Q-Chain: 11111111111111111111111111111111Q AChainID = ids.AChainID // A-Chain: 11111111111111111111111111111111A BChainID = ids.BChainID // B-Chain: 11111111111111111111111111111111B - TChainID = ids.TChainID // T-Chain: 11111111111111111111111111111111T + MChainID = ids.MChainID // M-Chain: 11111111111111111111111111111111M (MPC — threshold signing / bridge custody) + FChainID = ids.FChainID // F-Chain: 11111111111111111111111111111111F (FHE — confidential compute) ZChainID = ids.ZChainID // Z-Chain: 11111111111111111111111111111111Z (Zero-knowledge) GChainID = ids.GChainID // G-Chain: 11111111111111111111111111111111G (Graph/dgraph) KChainID = ids.KChainID // K-Chain: 11111111111111111111111111111111K (KMS) diff --git a/vendor/github.com/luxfi/constants/vm_ids.go b/vendor/github.com/luxfi/constants/vm_ids.go index c7eb76e23..970eebff3 100644 --- a/vendor/github.com/luxfi/constants/vm_ids.go +++ b/vendor/github.com/luxfi/constants/vm_ids.go @@ -18,7 +18,8 @@ const ( QuantumVMName = "quantumvm" // Q-Chain: Quantum-resistant security AIVMName = "aivm" // A-Chain: AI Virtual Machine BridgeVMName = "bridgevm" // B-Chain: Bridge/Cross-chain - ThresholdVMName = "thresholdvm" // T-Chain: Threshold signatures + MPCVMName = "mpcvm" // M-Chain: MPC threshold signing / bridge custody (LP-7100) + FHEVMName = "fhevm" // F-Chain: FHE confidential compute / encrypted state (LP-8200) KeyVMName = "keyvm" // K-Chain: Key Management ZKVMName = "zkvm" // Z-Chain: Zero-Knowledge proofs GraphVMName = "graphvm" // G-Chain: GraphQL/DGraph unified data layer @@ -40,7 +41,8 @@ var ( AttestationVMID = ids.ID{'a', 'i', 'v', 'm'} // A-Chain: Attestation/AI VM AIVMID = AttestationVMID // Alias for AttestationVMID BridgeVMID = ids.ID{'b', 'r', 'i', 'd', 'g', 'e', 'v', 'm'} - ThresholdVMID = ids.ID{'t', 'h', 'r', 'e', 's', 'h', 'o', 'l', 'd', 'v', 'm'} + MPCVMID = ids.ID{'m', 'p', 'c', 'v', 'm'} // M-Chain: MPC threshold signing / bridge custody + FHEVMID = ids.ID{'f', 'h', 'e', 'v', 'm'} // F-Chain: FHE confidential compute KeyVMID = ids.ID{'k', 'e', 'y', 'v', 'm'} // K-Chain: Key Management KVMID = KeyVMID // Alias for KeyVMID ZKVMID = ids.ID{'z', 'k', 'v', 'm'} @@ -107,8 +109,10 @@ func VMName(vmID ids.ID) string { return AIVMName case BridgeVMID: return BridgeVMName - case ThresholdVMID: - return ThresholdVMName + case MPCVMID: + return MPCVMName + case FHEVMID: + return FHEVMName case KeyVMID: return KeyVMName case ZKVMID: diff --git a/vendor/github.com/luxfi/container/LICENSE b/vendor/github.com/luxfi/container/LICENSE new file mode 100644 index 000000000..fbc776e31 --- /dev/null +++ b/vendor/github.com/luxfi/container/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2024, Lux Partners Limited +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/luxfi/container/LICENSING.md b/vendor/github.com/luxfi/container/LICENSING.md new file mode 100644 index 000000000..d96eecd3c --- /dev/null +++ b/vendor/github.com/luxfi/container/LICENSING.md @@ -0,0 +1,8 @@ +# Licensing + +This repository is licensed under the **BSD-3-Clause License** (see [LICENSE](LICENSE)). It belongs to the **public** tier of the Lux three-tier IP strategy: anyone may use, fork, or redistribute it, including for commercial purposes, subject to the BSD-3-Clause License terms. + +For the canonical Lux IP and licensing strategy, see: + + +For commercial inquiries that go beyond the public tier (e.g. private moat acceleration kernels, Eco-tier patent-protected primitives outside Authorized Networks), contact `licensing@lux.network`. diff --git a/vendor/github.com/luxfi/container/LLM.md b/vendor/github.com/luxfi/container/LLM.md new file mode 100644 index 000000000..cb9638409 --- /dev/null +++ b/vendor/github.com/luxfi/container/LLM.md @@ -0,0 +1,36 @@ +# Hanzo Container + +## Overview +Go module: github.com/luxfi/container + +## Tech Stack +- **Language**: Go + +## Build & Run +```bash +go build ./... +go test ./... +``` + +## Structure +``` +container/ + LICENSE + bimap/ + bloom/ + buffer/ + cache.go + container.go + go.mod + go.sum + heap/ + iterator/ + linked/ + linkedhashmap/ + maybe/ + pool/ + sampler/ +``` + +## Key Files +- `go.mod` -- Go module definition diff --git a/vendor/github.com/luxfi/container/cache.go b/vendor/github.com/luxfi/container/cache.go index 69ce06985..4dc1b4363 100644 --- a/vendor/github.com/luxfi/container/cache.go +++ b/vendor/github.com/luxfi/container/cache.go @@ -50,7 +50,7 @@ func (c *LRUCache[K, V]) Put(key K, value V) { elem.Value.(*cacheEntry[K, V]).value = value return } - + if len(c.elements) >= c.capacity { back := c.lru.Back() if back != nil { @@ -58,7 +58,7 @@ func (c *LRUCache[K, V]) Put(key K, value V) { delete(c.elements, back.Value.(*cacheEntry[K, V]).key) } } - + elem := c.lru.PushFront(&cacheEntry[K, V]{key, value}) c.elements[key] = elem } @@ -76,4 +76,4 @@ func (c *LRUCache[K, V]) Len() int { func (c *LRUCache[K, V]) Evict(key K) { c.Delete(key) -} \ No newline at end of file +} diff --git a/vendor/github.com/luxfi/container/container.go b/vendor/github.com/luxfi/container/container.go index c0f88ca07..cd4dd9929 100644 --- a/vendor/github.com/luxfi/container/container.go +++ b/vendor/github.com/luxfi/container/container.go @@ -31,4 +31,4 @@ type Cache[K comparable, V any] interface { Delete(K) Len() int Evict(K) -} \ No newline at end of file +} diff --git a/vendor/github.com/luxfi/crypto/README.md b/vendor/github.com/luxfi/crypto/README.md index 7e93c4c5b..cb1d36e39 100644 --- a/vendor/github.com/luxfi/crypto/README.md +++ b/vendor/github.com/luxfi/crypto/README.md @@ -1,3 +1,5 @@ +

crypto

+ # Lux Crypto Cryptographic primitives for the Lux Network -- post-quantum signatures, key encapsulation, BLS aggregation, threshold signing, ring signatures, and EVM-compatible secp256k1. diff --git a/vendor/github.com/luxfi/formatting/LICENSE b/vendor/github.com/luxfi/formatting/LICENSE new file mode 100644 index 000000000..fbc776e31 --- /dev/null +++ b/vendor/github.com/luxfi/formatting/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2024, Lux Partners Limited +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/luxfi/formatting/LICENSING.md b/vendor/github.com/luxfi/formatting/LICENSING.md new file mode 100644 index 000000000..d96eecd3c --- /dev/null +++ b/vendor/github.com/luxfi/formatting/LICENSING.md @@ -0,0 +1,8 @@ +# Licensing + +This repository is licensed under the **BSD-3-Clause License** (see [LICENSE](LICENSE)). It belongs to the **public** tier of the Lux three-tier IP strategy: anyone may use, fork, or redistribute it, including for commercial purposes, subject to the BSD-3-Clause License terms. + +For the canonical Lux IP and licensing strategy, see: + + +For commercial inquiries that go beyond the public tier (e.g. private moat acceleration kernels, Eco-tier patent-protected primitives outside Authorized Networks), contact `licensing@lux.network`. diff --git a/vendor/github.com/luxfi/formatting/LLM.md b/vendor/github.com/luxfi/formatting/LLM.md new file mode 100644 index 000000000..f8d0ea14b --- /dev/null +++ b/vendor/github.com/luxfi/formatting/LLM.md @@ -0,0 +1,30 @@ +# Hanzo Formatting + +## Overview +Go module: github.com/luxfi/formatting + +## Tech Stack +- **Language**: Go + +## Build & Run +```bash +go build ./... +go test ./... +``` + +## Structure +``` +formatting/ + LICENSE + encoding.go + encoding_benchmark_test.go + encoding_test.go + go.mod + go.sum + int_format.go + int_format_test.go + prefixed_stringer.go +``` + +## Key Files +- `go.mod` -- Go module definition diff --git a/vendor/github.com/luxfi/formatting/encoding.go b/vendor/github.com/luxfi/formatting/encoding.go index 0cdf51137..845c61242 100644 --- a/vendor/github.com/luxfi/formatting/encoding.go +++ b/vendor/github.com/luxfi/formatting/encoding.go @@ -11,7 +11,7 @@ import ( "math" "strings" - hashing "github.com/luxfi/crypto/hash" + "github.com/luxfi/crypto/hash" ) const ( @@ -107,7 +107,7 @@ func Encode(encoding Encoding, bytes []byte) (string, error) { } checked := make([]byte, bytesLen+checksumLen) copy(checked, bytes) - copy(checked[len(bytes):], hashing.Checksum(bytes, checksumLen)) + copy(checked[len(bytes):], hash.Checksum(bytes, checksumLen)) bytes = checked } @@ -163,7 +163,7 @@ func Decode(encoding Encoding, str string) ([]byte, error) { // Verify the checksum rawBytes := decodedBytes[:len(decodedBytes)-checksumLen] checksum := decodedBytes[len(decodedBytes)-checksumLen:] - if !bytes.Equal(checksum, hashing.Checksum(rawBytes, checksumLen)) { + if !bytes.Equal(checksum, hash.Checksum(rawBytes, checksumLen)) { return nil, errBadChecksum } decodedBytes = rawBytes diff --git a/vendor/github.com/luxfi/go-bip32/LICENSE b/vendor/github.com/luxfi/go-bip32/LICENSE new file mode 100644 index 000000000..fbc776e31 --- /dev/null +++ b/vendor/github.com/luxfi/go-bip32/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2024, Lux Partners Limited +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/luxfi/go-bip32/LICENSING.md b/vendor/github.com/luxfi/go-bip32/LICENSING.md new file mode 100644 index 000000000..d96eecd3c --- /dev/null +++ b/vendor/github.com/luxfi/go-bip32/LICENSING.md @@ -0,0 +1,8 @@ +# Licensing + +This repository is licensed under the **BSD-3-Clause License** (see [LICENSE](LICENSE)). It belongs to the **public** tier of the Lux three-tier IP strategy: anyone may use, fork, or redistribute it, including for commercial purposes, subject to the BSD-3-Clause License terms. + +For the canonical Lux IP and licensing strategy, see: + + +For commercial inquiries that go beyond the public tier (e.g. private moat acceleration kernels, Eco-tier patent-protected primitives outside Authorized Networks), contact `licensing@lux.network`. diff --git a/vendor/github.com/luxfi/go-bip32/README.md b/vendor/github.com/luxfi/go-bip32/README.md index a92b6022c..79ef5d017 100644 --- a/vendor/github.com/luxfi/go-bip32/README.md +++ b/vendor/github.com/luxfi/go-bip32/README.md @@ -1,3 +1,5 @@ +

go-bip32

+ # GO-BIP32 This repository contains a local copy of the original ``github.com/tyler-smith/go-bip32`` library. diff --git a/vendor/github.com/luxfi/go-bip32/utils.go b/vendor/github.com/luxfi/go-bip32/utils.go index 933e1705e..bb074e953 100644 --- a/vendor/github.com/luxfi/go-bip32/utils.go +++ b/vendor/github.com/luxfi/go-bip32/utils.go @@ -263,9 +263,7 @@ func validateChildPublicKey(key []byte) error { return nil } -// // Numerical -// func uint32Bytes(i uint32) []byte { bytes := make([]byte, 4) binary.BigEndian.PutUint32(bytes, i) diff --git a/vendor/github.com/luxfi/go-bip39/.gitignore b/vendor/github.com/luxfi/go-bip39/.gitignore index 0c3f333b0..d9d647a63 100644 --- a/vendor/github.com/luxfi/go-bip39/.gitignore +++ b/vendor/github.com/luxfi/go-bip39/.gitignore @@ -135,3 +135,11 @@ fabric.properties .idea/**/azureSettings.xml # End of https://www.toptal.com/developers/gitignore/api/goland,go + + + +AGENTS.md +CLAUDE.md +GEMINI.md +GROK.md +QWEN.md diff --git a/vendor/github.com/luxfi/go-bip39/LICENSE b/vendor/github.com/luxfi/go-bip39/LICENSE new file mode 100644 index 000000000..fbc776e31 --- /dev/null +++ b/vendor/github.com/luxfi/go-bip39/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2024, Lux Partners Limited +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/luxfi/go-bip39/LICENSING.md b/vendor/github.com/luxfi/go-bip39/LICENSING.md new file mode 100644 index 000000000..d96eecd3c --- /dev/null +++ b/vendor/github.com/luxfi/go-bip39/LICENSING.md @@ -0,0 +1,8 @@ +# Licensing + +This repository is licensed under the **BSD-3-Clause License** (see [LICENSE](LICENSE)). It belongs to the **public** tier of the Lux three-tier IP strategy: anyone may use, fork, or redistribute it, including for commercial purposes, subject to the BSD-3-Clause License terms. + +For the canonical Lux IP and licensing strategy, see: + + +For commercial inquiries that go beyond the public tier (e.g. private moat acceleration kernels, Eco-tier patent-protected primitives outside Authorized Networks), contact `licensing@lux.network`. diff --git a/vendor/github.com/luxfi/go-bip39/LLM.md b/vendor/github.com/luxfi/go-bip39/LLM.md new file mode 100644 index 000000000..011652b8b --- /dev/null +++ b/vendor/github.com/luxfi/go-bip39/LLM.md @@ -0,0 +1,42 @@ +# AI Assistant Knowledge Base + +**Last Updated**: $(date +%Y-%m-%d) +**Project**: $(basename "$REPO_PATH") +**Organization**: $(basename "$(dirname "$REPO_PATH")") + +## Project Overview + +This repository is part of the $(basename "$(dirname "$REPO_PATH")") organization. + +## Essential Commands + +### Development +```bash +# Add common commands here +``` + +## Architecture + +## Key Technologies + +## Development Workflow + +## Context for All AI Assistants + +This file (`LLM.md`) is symlinked as: +- `.AGENTS.md` +- `CLAUDE.md` +- `QWEN.md` +- `GEMINI.md` + +All files reference the same knowledge base. Updates here propagate to all AI systems. + +## Rules for AI Assistants + +1. **ALWAYS** update LLM.md with significant discoveries +2. **NEVER** commit symlinked files (.AGENTS.md, CLAUDE.md, etc.) - they're in .gitignore +3. **NEVER** create random summary files - update THIS file + +--- + +**Note**: This file serves as the single source of truth for all AI assistants working on this project. diff --git a/vendor/github.com/luxfi/go-bip39/README.md b/vendor/github.com/luxfi/go-bip39/README.md index 0fc57a446..a7d994f2f 100644 --- a/vendor/github.com/luxfi/go-bip39/README.md +++ b/vendor/github.com/luxfi/go-bip39/README.md @@ -1,3 +1,5 @@ +

go-bip39

+ # GO-BIP39 This repository contains a local copy of the original ``github.com/tyler-smith/go-bip39`` library. diff --git a/vendor/github.com/luxfi/ids/README.md b/vendor/github.com/luxfi/ids/README.md index d3ddc6552..d1c9c5802 100644 --- a/vendor/github.com/luxfi/ids/README.md +++ b/vendor/github.com/luxfi/ids/README.md @@ -1,3 +1,5 @@ +

ids

+ # Lux IDs Package [![Go Reference](https://pkg.go.dev/badge/github.com/luxfi/ids.svg)](https://pkg.go.dev/github.com/luxfi/ids) diff --git a/vendor/github.com/luxfi/ids/native_chains.go b/vendor/github.com/luxfi/ids/native_chains.go index 2fcc0166d..8fa8c7538 100644 --- a/vendor/github.com/luxfi/ids/native_chains.go +++ b/vendor/github.com/luxfi/ids/native_chains.go @@ -13,9 +13,10 @@ package ids // C-Chain: 11111111111111111111111111111111C (Contract/EVM) // X-Chain: 11111111111111111111111111111111X (Exchange/DAG) // Q-Chain: 11111111111111111111111111111111Q (Quantum) -// A-Chain: 11111111111111111111111111111111A (AI) +// A-Chain: 11111111111111111111111111111111A (AI/Attestation) // B-Chain: 11111111111111111111111111111111B (Bridge) -// T-Chain: 11111111111111111111111111111111T (Threshold) +// M-Chain: 11111111111111111111111111111111M (MPC — threshold signing / bridge custody) +// F-Chain: 11111111111111111111111111111111F (FHE — confidential compute) // Z-Chain: 11111111111111111111111111111111Z (Zero-knowledge) // G-Chain: 11111111111111111111111111111111G (Graph/dgraph) // K-Chain: 11111111111111111111111111111111K (KMS) @@ -42,7 +43,8 @@ const ( QChainIDStr = nativeChainPrefix + "Q" AChainIDStr = nativeChainPrefix + "A" BChainIDStr = nativeChainPrefix + "B" - TChainIDStr = nativeChainPrefix + "T" + MChainIDStr = nativeChainPrefix + "M" + FChainIDStr = nativeChainPrefix + "F" ZChainIDStr = nativeChainPrefix + "Z" GChainIDStr = nativeChainPrefix + "G" // Coming soon IChainIDStr = nativeChainPrefix + "I" // Identity - Coming soon @@ -69,8 +71,11 @@ var ( // BChainID is the well-known B-Chain (Bridge) ID BChainID ID - // TChainID is the well-known T-Chain (Threshold) ID - TChainID ID + // MChainID is the well-known M-Chain (MPC — threshold signing, bridge custody) ID + MChainID ID + + // FChainID is the well-known F-Chain (FHE — confidential compute) ID + FChainID ID // ZChainID is the well-known Z-Chain (Zero-knowledge) ID ZChainID ID @@ -96,7 +101,8 @@ func init() { QChainID[nativeChainLetterPos] = 'Q' AChainID[nativeChainLetterPos] = 'A' BChainID[nativeChainLetterPos] = 'B' - TChainID[nativeChainLetterPos] = 'T' + MChainID[nativeChainLetterPos] = 'M' + FChainID[nativeChainLetterPos] = 'F' ZChainID[nativeChainLetterPos] = 'Z' GChainID[nativeChainLetterPos] = 'G' IChainID[nativeChainLetterPos] = 'I' @@ -138,8 +144,10 @@ func NativeChainString(id ID) string { return AChainIDStr case 'B': return BChainIDStr - case 'T': - return TChainIDStr + case 'M': + return MChainIDStr + case 'F': + return FChainIDStr case 'Z': return ZChainIDStr case 'G': @@ -187,8 +195,10 @@ func NativeChainFromString(s string) (ID, bool) { return AChainID, true case 'B', 'b': return BChainID, true - case 'T', 't': - return TChainID, true + case 'M', 'm': + return MChainID, true + case 'F', 'f': + return FChainID, true case 'Z', 'z': return ZChainID, true case 'G', 'g': @@ -227,8 +237,10 @@ func NativeChainFromString(s string) (ID, bool) { return AChainID, true case 'B': return BChainID, true - case 'T': - return TChainID, true + case 'M': + return MChainID, true + case 'F': + return FChainID, true case 'Z': return ZChainID, true case 'G': @@ -256,7 +268,7 @@ func NativeChainAlias(id ID) string { // AllNativeChainIDs returns all well-known native chain IDs. func AllNativeChainIDs() []ID { - return []ID{PChainID, CChainID, XChainID, QChainID, AChainID, BChainID, TChainID, ZChainID, GChainID, IChainID, KChainID, DChainID} + return []ID{PChainID, CChainID, XChainID, QChainID, AChainID, BChainID, MChainID, FChainID, ZChainID, GChainID, IChainID, KChainID, DChainID} } // NativeChainIDFromLetter returns the chain ID for a given letter. @@ -277,8 +289,10 @@ func NativeChainIDFromLetter(letter byte) (ID, bool) { return AChainID, true case 'B', 'b': return BChainID, true - case 'T', 't': - return TChainID, true + case 'M', 'm': + return MChainID, true + case 'F', 'f': + return FChainID, true case 'Z', 'z': return ZChainID, true case 'G', 'g': diff --git a/vendor/github.com/luxfi/keys/allocations.go b/vendor/github.com/luxfi/keys/allocations.go index 941c6c59b..401f250f1 100644 --- a/vendor/github.com/luxfi/keys/allocations.go +++ b/vendor/github.com/luxfi/keys/allocations.go @@ -33,10 +33,10 @@ const ( // Allocation represents a P-chain genesis allocation type Allocation struct { // ETHAddr is the C-chain compatible address (0x...) - ETHAddr string `json:"evmAddr"` + ETHAddr string `json:"ethAddr"` // LUXAddr is the P/X-chain address (P-lux1...) - LUXAddr string `json:"utxoAddr"` + LUXAddr string `json:"luxAddr"` // InitialAmount is immediately available on X-chain (usually 0) InitialAmount uint64 `json:"initialAmount"` diff --git a/vendor/github.com/luxfi/keys/keys.go b/vendor/github.com/luxfi/keys/keys.go index 1e63e8635..ba45b97da 100644 --- a/vendor/github.com/luxfi/keys/keys.go +++ b/vendor/github.com/luxfi/keys/keys.go @@ -24,7 +24,7 @@ import ( "github.com/luxfi/go-bip32" "github.com/luxfi/go-bip39" "github.com/luxfi/ids" - "github.com/luxfi/proto/p/signer" + "github.com/luxfi/protocol/p/signer" luxtls "github.com/luxfi/tls" "golang.org/x/crypto/sha3" ) @@ -546,7 +546,7 @@ func deriveMnemonicKeyForPath(mnemonic string, account, index uint32) ([]byte, e } // m/44'/60' (coin type for LUX) - key, err = key.NewChildKey(bip32.FirstHardenedChild + CoinTypeEVM) + key, err = key.NewChildKey(bip32.FirstHardenedChild + LUXCoinType) if err != nil { return nil, fmt.Errorf("failed to derive coin type: %w", err) } @@ -572,9 +572,8 @@ func deriveMnemonicKeyForPath(mnemonic string, account, index uint32) ([]byte, e return key.Key, nil } -// CoinTypeEVM is the SLIP-0044 coin_type for EVM chains (60', shared with -// Ethereum). C-Chain and any non-Lux L1 EVM derive under this tree. -const CoinTypeEVM = 60 +// LUXCoinType is the BIP-44 coin type for LUX (60' = standard Ethereum) +const LUXCoinType = 60 // deriveMnemonicKey derives an EC private key from mnemonic using BIP44 path m/44'/60'/0'/0/{index} func deriveMnemonicKey(mnemonic string, accountIndex uint32) ([]byte, error) { @@ -597,7 +596,7 @@ func deriveMnemonicKey(mnemonic string, accountIndex uint32) ([]byte, error) { } // m/44'/60' (coin type for LUX) - key, err = key.NewChildKey(bip32.FirstHardenedChild + CoinTypeEVM) + key, err = key.NewChildKey(bip32.FirstHardenedChild + LUXCoinType) if err != nil { return nil, fmt.Errorf("failed to derive coin type: %w", err) } diff --git a/vendor/github.com/luxfi/keys/zap.go b/vendor/github.com/luxfi/keys/zap.go deleted file mode 100644 index fada0b7fc..000000000 --- a/vendor/github.com/luxfi/keys/zap.go +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -// zap.go — load a BIP-39 mnemonic from Liquid KMS over native ZAP. -// -// This file is the one canonical path every Lux-derived service uses -// to resolve the bootstrap mnemonic: luxd, netrunner, lux/cli, and any -// descending L1's bootstrap (liquidity/network-bootstrap, hanzo-bootstrap, -// zoo-bootstrap, …). No file mount, no projected volume, no per-consumer -// copy of the env-vs-KMS precedence chain. -// -// Separation of concerns: -// -// - zap (the protocol) → github.com/zap-proto/zap -// - luxfi/kms (secret store) → opaque Get/Put/List over ZAP -// - luxfi/keys (THIS PACKAGE) → BIP-39, BIP44 derivation, mnemonic -// semantics. Composes luxfi/kms with -// bip39 validation. KMS knows nothing -// about mnemonics; this layer does. -// -// Precedence (env wins; KMS is the production fallback): -// -// 1. MNEMONIC env var local dev + CI test seam -// 2. KMS at (addr, env, path) native ZAP from Liquid KMS - -package keys - -import ( - "context" - "errors" - "fmt" - "os" - "strings" - - bip39 "github.com/luxfi/go-bip39" - "github.com/luxfi/kms/pkg/envelope" - "github.com/luxfi/kms/pkg/zapclient" -) - -// MnemonicReader is the minimum surface LoadMnemonicFromKMS needs from -// a KMS client. The real *zapclient.Client satisfies it; tests inject -// fakes via the dialKMS seam below. -type MnemonicReader interface { - GetAt(ctx context.Context, path, name, env string) (string, error) - Close() -} - -// dialKMS is the production seam. Tests override to inject a fake -// without touching the network. -// -// identity is REQUIRED for the production path (the KMS server's -// consensus-auth gate rejects envelopes without a signed identity). -// Passing nil dials anonymously — accepted only by legacy KMS peers -// that have explicitly disabled the auth gate (dev / loopback only). -var dialKMS = func(ctx context.Context, addr string, identity *ServiceIdentity) (MnemonicReader, error) { - cfg := zapclient.Config{PeerAddr: addr} - if identity != nil { - cfg.IdentityHeader = envelope.IdentityHeader{ - NodeID: identity.NodeID, - FullDigest: identity.FullDigest, - ServicePath: identity.ServicePath, - PublicKey: identity.PublicKey, - } - cfg.Signer = identity - } - c, err := zapclient.DialWithConfig(ctx, cfg) - if err != nil { - return nil, err - } - return c, nil -} - -// LoadMnemonic returns the BIP-39 mnemonic for the calling service. -// MNEMONIC env wins when set; otherwise dials KMS over native ZAP at -// `addr` and reads the secret at `path` under `env`. -// -// ctx cancellable context -// addr KMS host:port (e.g. "kms.internal.svc:9999") -// env KMS env scope ("mainnet" | "testnet" | "devnet") -// path KMS secret path (e.g. "/mnemonic" or "/foo/master") -// identity ServiceIdentity to sign the secret-opcode envelope. May -// be nil for legacy peers and the env-win short-circuit -// (the KMS dial is never reached); required for production -// peers whose consensus-auth gate is engaged. -// -// Returns the validated BIP-39 phrase. Caller is responsible for -// keeping it on the goroutine stack and not logging / persisting it. -func LoadMnemonic(ctx context.Context, addr, env, path string, identity *ServiceIdentity) (string, error) { - if e := strings.TrimSpace(os.Getenv("MNEMONIC")); e != "" { - if !bip39.IsMnemonicValid(e) { - return "", errors.New("MNEMONIC env is not a valid BIP-39 phrase") - } - return e, nil - } - return LoadMnemonicFromKMS(ctx, addr, env, path, identity) -} - -// LoadMnemonicFromKMS is the production-only path (no MNEMONIC env -// short-circuit). Useful when a caller wants to force the KMS read -// regardless of ambient env — e.g., a regression test pinning the -// production code path. -// -// identity is the *ServiceIdentity threaded into the ZAP dial: its -// IdentityHeader becomes envelope.Identity and the same identity -// signs every secret-opcode envelope. Pass nil only when dialling a -// legacy KMS peer that has not enabled the consensus-auth gate -// (dev / loopback fakes — see zap_test.go's withDial seam). -func LoadMnemonicFromKMS(ctx context.Context, addr, env, path string, identity *ServiceIdentity) (string, error) { - if addr == "" { - return "", errors.New("keys.LoadMnemonicFromKMS: KMS addr is required") - } - if env == "" { - return "", errors.New("keys.LoadMnemonicFromKMS: KMS env is required") - } - if path == "" { - return "", errors.New("keys.LoadMnemonicFromKMS: KMS path is required") - } - - c, err := dialKMS(ctx, addr, identity) - if err != nil { - return "", fmt.Errorf("dial KMS %s: %w", addr, err) - } - defer c.Close() - - dir, name := SplitSecretPath(path) - v, err := c.GetAt(ctx, dir, name, env) - if err != nil { - return "", fmt.Errorf("read mnemonic (path=%q name=%q env=%q): %w", - dir, name, env, err) - } - m := strings.TrimSpace(v) - if m == "" { - return "", fmt.Errorf("mnemonic at %q is empty", path) - } - if !bip39.IsMnemonicValid(m) { - return "", errors.New("mnemonic from KMS is not a valid BIP-39 phrase") - } - return m, nil -} - -// SplitSecretPath turns "/foo/bar/baz" into ("/foo/bar/", "baz"). When -// there is no '/' or only a leading one, the directory is "" and the -// whole remainder is the name (e.g., "/mnemonic" → ("", "mnemonic")). -// -// Exported so every consumer can address secrets with the same -// convention — one and only one addressing scheme across mnemonic, -// staking keys, gas-payer keys, etc. -func SplitSecretPath(full string) (dir, name string) { - full = strings.TrimSpace(full) - full = strings.TrimPrefix(full, "/") - i := strings.LastIndex(full, "/") - if i < 0 { - return "", full - } - return "/" + full[:i+1], full[i+1:] -} diff --git a/vendor/github.com/luxfi/math/LICENSING.md b/vendor/github.com/luxfi/math/LICENSING.md new file mode 100644 index 000000000..d96eecd3c --- /dev/null +++ b/vendor/github.com/luxfi/math/LICENSING.md @@ -0,0 +1,8 @@ +# Licensing + +This repository is licensed under the **BSD-3-Clause License** (see [LICENSE](LICENSE)). It belongs to the **public** tier of the Lux three-tier IP strategy: anyone may use, fork, or redistribute it, including for commercial purposes, subject to the BSD-3-Clause License terms. + +For the canonical Lux IP and licensing strategy, see: + + +For commercial inquiries that go beyond the public tier (e.g. private moat acceleration kernels, Eco-tier patent-protected primitives outside Authorized Networks), contact `licensing@lux.network`. diff --git a/vendor/github.com/luxfi/math/README.md b/vendor/github.com/luxfi/math/README.md index a87a6ee06..cdc565723 100644 --- a/vendor/github.com/luxfi/math/README.md +++ b/vendor/github.com/luxfi/math/README.md @@ -1,3 +1,5 @@ +

math

+ # Lux Math Library A comprehensive mathematical utilities library for the Lux ecosystem. diff --git a/vendor/github.com/luxfi/math/SUBSTRATE.md b/vendor/github.com/luxfi/math/SUBSTRATE.md index 2eeca6b45..afedc86e0 100644 --- a/vendor/github.com/luxfi/math/SUBSTRATE.md +++ b/vendor/github.com/luxfi/math/SUBSTRATE.md @@ -73,5 +73,5 @@ GOWORK=off go test ./... * [`lattice/v7/ring`](https://github.com/luxfi/lattice/tree/main/ring) — canonical Lattigo-derived NTT/Montgomery body that this module delegates to. -* [`luxcpp/crypto/ringtail`](https://github.com/luxcpp/crypto/tree/main/ringtail) +* [`luxcpp/crypto/corona`](https://github.com/luxcpp/crypto/tree/main/corona) — native C++ Montgomery NTT that Phase 6 mirrors as `math` C++. diff --git a/vendor/github.com/luxfi/metric/README.md b/vendor/github.com/luxfi/metric/README.md index 09d945d03..76584d3a7 100644 --- a/vendor/github.com/luxfi/metric/README.md +++ b/vendor/github.com/luxfi/metric/README.md @@ -1,3 +1,5 @@ +

metric

+ # Lux Metrics Library `github.com/luxfi/metric` is the native metrics library for Lux. It produces a diff --git a/vendor/github.com/luxfi/metric/curry.go b/vendor/github.com/luxfi/metric/curry.go new file mode 100644 index 000000000..193ed6120 --- /dev/null +++ b/vendor/github.com/luxfi/metric/curry.go @@ -0,0 +1,127 @@ +// Copyright (C) 2026, Lux Industries Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package metric + +// Currying support for the *Vec families. Mirrors prometheus/client_golang's +// MetricVec.MustCurryWith: it binds a subset of label values up front and +// returns a vec that only needs the remaining labels. Implemented natively — +// the returned vec delegates to the base vec with the fixed labels merged in, +// so children are still created and registered on the base registry exactly +// once per full label set. + +// mergeLabels returns a new Labels with b overlaid on a. +func mergeLabels(a, b Labels) Labels { + out := make(Labels, len(a)+len(b)) + for k, v := range a { + out[k] = v + } + for k, v := range b { + out[k] = v + } + return out +} + +// curryRemaining returns the label names from all that are not fixed, in +// declared order — these are the names WithLabelValues maps positionally. +func curryRemaining(all []string, fixed Labels) []string { + rem := make([]string, 0, len(all)) + for _, n := range all { + if _, ok := fixed[n]; !ok { + rem = append(rem, n) + } + } + return rem +} + +// --- counter --- + +func (v *counterVec) MustCurryWith(labels Labels) CounterVec { + return &curriedCounterVec{base: v, fixed: cloneLabels(labels), remaining: curryRemaining(v.labelNames, labels)} +} + +type curriedCounterVec struct { + base *counterVec + fixed Labels + remaining []string +} + +func (c *curriedCounterVec) With(labels Labels) Counter { + return c.base.With(mergeLabels(c.fixed, labels)) +} +func (c *curriedCounterVec) WithLabelValues(values ...string) Counter { + return c.base.With(mergeLabels(c.fixed, labelsFromValues(c.remaining, values))) +} +func (c *curriedCounterVec) MustCurryWith(labels Labels) CounterVec { + return c.base.MustCurryWith(mergeLabels(c.fixed, labels)) +} +func (c *curriedCounterVec) Reset() { c.base.Reset() } + +// --- gauge --- + +func (v *gaugeVec) MustCurryWith(labels Labels) GaugeVec { + return &curriedGaugeVec{base: v, fixed: cloneLabels(labels), remaining: curryRemaining(v.labelNames, labels)} +} + +type curriedGaugeVec struct { + base *gaugeVec + fixed Labels + remaining []string +} + +func (c *curriedGaugeVec) With(labels Labels) Gauge { + return c.base.With(mergeLabels(c.fixed, labels)) +} +func (c *curriedGaugeVec) WithLabelValues(values ...string) Gauge { + return c.base.With(mergeLabels(c.fixed, labelsFromValues(c.remaining, values))) +} +func (c *curriedGaugeVec) MustCurryWith(labels Labels) GaugeVec { + return c.base.MustCurryWith(mergeLabels(c.fixed, labels)) +} +func (c *curriedGaugeVec) Reset() { c.base.Reset() } + +// --- histogram --- + +func (v *histogramVec) MustCurryWith(labels Labels) HistogramVec { + return &curriedHistogramVec{base: v, fixed: cloneLabels(labels), remaining: curryRemaining(v.labelNames, labels)} +} + +type curriedHistogramVec struct { + base *histogramVec + fixed Labels + remaining []string +} + +func (c *curriedHistogramVec) With(labels Labels) Histogram { + return c.base.With(mergeLabels(c.fixed, labels)) +} +func (c *curriedHistogramVec) WithLabelValues(values ...string) Histogram { + return c.base.With(mergeLabels(c.fixed, labelsFromValues(c.remaining, values))) +} +func (c *curriedHistogramVec) MustCurryWith(labels Labels) HistogramVec { + return c.base.MustCurryWith(mergeLabels(c.fixed, labels)) +} +func (c *curriedHistogramVec) Reset() { c.base.Reset() } + +// --- summary --- + +func (v *summaryVec) MustCurryWith(labels Labels) SummaryVec { + return &curriedSummaryVec{base: v, fixed: cloneLabels(labels), remaining: curryRemaining(v.labelNames, labels)} +} + +type curriedSummaryVec struct { + base *summaryVec + fixed Labels + remaining []string +} + +func (c *curriedSummaryVec) With(labels Labels) Summary { + return c.base.With(mergeLabels(c.fixed, labels)) +} +func (c *curriedSummaryVec) WithLabelValues(values ...string) Summary { + return c.base.With(mergeLabels(c.fixed, labelsFromValues(c.remaining, values))) +} +func (c *curriedSummaryVec) MustCurryWith(labels Labels) SummaryVec { + return c.base.MustCurryWith(mergeLabels(c.fixed, labels)) +} +func (c *curriedSummaryVec) Reset() { c.base.Reset() } diff --git a/vendor/github.com/luxfi/metric/defaults_noop.go b/vendor/github.com/luxfi/metric/defaults_noop.go index e97a3ee55..ded3004cb 100644 --- a/vendor/github.com/luxfi/metric/defaults_noop.go +++ b/vendor/github.com/luxfi/metric/defaults_noop.go @@ -6,6 +6,9 @@ package metric func init() { - DefaultRegistry = NewNoOpRegistry() + r := NewNoOpRegistry() + DefaultRegistry = r + DefaultRegisterer = r + DefaultGatherer = r defaultFactory = NewNoOpFactory() } diff --git a/vendor/github.com/luxfi/metric/export.go b/vendor/github.com/luxfi/metric/export.go index 4b7e29d67..84ef5e666 100644 --- a/vendor/github.com/luxfi/metric/export.go +++ b/vendor/github.com/luxfi/metric/export.go @@ -39,3 +39,24 @@ type MetricFamilies = []*MetricFamily func NewHTTPHandler(gatherer Gatherer, opts HandlerOpts) http.Handler { return HandlerForWithOpts(gatherer, opts) } + +// InstrumentMetricHandler wraps handler so each scrape is observed on reg. +// It registers promhttp_metric_handler_requests_total (scrape count) and +// promhttp_metric_handler_requests_in_flight (concurrent scrapes) and updates +// them around each call. Mirrors prometheus/client_golang/promhttp.InstrumentMetricHandler. +func InstrumentMetricHandler(reg Registerer, handler http.Handler) http.Handler { + requests := reg.NewCounter( + "promhttp_metric_handler_requests_total", + "Total number of scrapes served.", + ) + inFlight := reg.NewGauge( + "promhttp_metric_handler_requests_in_flight", + "Current number of scrapes being served.", + ) + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + inFlight.Inc() + defer inFlight.Dec() + requests.Inc() + handler.ServeHTTP(w, r) + }) +} diff --git a/vendor/github.com/luxfi/metric/exporter_zap.go b/vendor/github.com/luxfi/metric/exporter_zap.go index 8d9896d74..55a3d3ba9 100644 --- a/vendor/github.com/luxfi/metric/exporter_zap.go +++ b/vendor/github.com/luxfi/metric/exporter_zap.go @@ -47,10 +47,10 @@ const MsgMetricBatch uint16 = 2 // payload field. One batch per Export call (typically one Gather() // snapshot per scrape interval). type MetricBatch struct { - AppName string `json:"appName,omitempty"` - Version string `json:"version,omitempty"` - Resource map[string]string `json:"resource,omitempty"` - TimestampNs int64 `json:"timestampNs"` + AppName string `json:"appName,omitempty"` + Version string `json:"version,omitempty"` + Resource map[string]string `json:"resource,omitempty"` + TimestampNs int64 `json:"timestampNs"` Families []MetricFamilyWire `json:"families"` } diff --git a/vendor/github.com/luxfi/metric/handler.go b/vendor/github.com/luxfi/metric/handler.go index d4c9c2ae3..a1a1c7dd8 100644 --- a/vendor/github.com/luxfi/metric/handler.go +++ b/vendor/github.com/luxfi/metric/handler.go @@ -32,6 +32,10 @@ type HandlerOpts struct { ErrorHandling HandlerErrorHandling // ErrorLog is used when ErrorHandling is Continue. ErrorLog interface{ Println(...any) } + // DisableCompression mirrors prometheus/client_golang/promhttp.HandlerOpts. + // The native handler serves uncompressed exposition, so this is always + // effectively honored; the field exists for source compatibility. + DisableCompression bool } // HTTPHandlerOpts is an alias for HandlerOpts for compatibility. diff --git a/vendor/github.com/luxfi/metric/metric.go b/vendor/github.com/luxfi/metric/metric.go index e7894d378..f28e35b18 100644 --- a/vendor/github.com/luxfi/metric/metric.go +++ b/vendor/github.com/luxfi/metric/metric.go @@ -106,6 +106,7 @@ type Factory interface { type CounterVec interface { With(Labels) Counter WithLabelValues(...string) Counter + MustCurryWith(Labels) CounterVec Reset() } @@ -113,6 +114,7 @@ type CounterVec interface { type GaugeVec interface { With(Labels) Gauge WithLabelValues(...string) Gauge + MustCurryWith(Labels) GaugeVec Reset() } @@ -120,6 +122,7 @@ type GaugeVec interface { type HistogramVec interface { With(Labels) Histogram WithLabelValues(...string) Histogram + MustCurryWith(Labels) HistogramVec Reset() } @@ -127,6 +130,7 @@ type HistogramVec interface { type SummaryVec interface { With(Labels) Summary WithLabelValues(...string) Summary + MustCurryWith(Labels) SummaryVec Reset() } @@ -152,6 +156,15 @@ type Request interface { // DefaultRegistry is the default in-process registry used by package-level helpers. var DefaultRegistry Registry = NewRegistry() +// DefaultRegisterer is the default Registerer, backed by DefaultRegistry. +// Mirrors prometheus.DefaultRegisterer so call sites that pass a package-level +// registerer (e.g. metric.Register(metric.DefaultRegisterer)) keep working. +var DefaultRegisterer Registerer = DefaultRegistry + +// DefaultGatherer is the default Gatherer, backed by DefaultRegistry. +// Mirrors prometheus.DefaultGatherer for HTTP exposition of the default registry. +var DefaultGatherer Gatherer = DefaultRegistry + // Global factory instance. var defaultFactory Factory = NewFactoryWithRegistry(DefaultRegistry) diff --git a/vendor/github.com/luxfi/metric/metrics_impl.go b/vendor/github.com/luxfi/metric/metrics_impl.go index 53ede0992..d40c801b6 100644 --- a/vendor/github.com/luxfi/metric/metrics_impl.go +++ b/vendor/github.com/luxfi/metric/metrics_impl.go @@ -776,6 +776,25 @@ func (hpr *registry) MustRegister(cs ...Collector) { } } +// Unregister drops the collector's metric family (all label permutations) and +// frees its name for re-registration. Returns true if the name was registered. +// Mirrors prometheus.Registerer.Unregister. +func (hpr *registry) Unregister(c Collector) bool { + name, _, ok := collectorIdentity(c) + if !ok { + return false + } + hpr.mu.Lock() + defer hpr.mu.Unlock() + _, had := hpr.registered[name] + delete(hpr.registered, name) + delete(hpr.counters, name) + delete(hpr.gauges, name) + delete(hpr.histograms, name) + delete(hpr.summaries, name) + return had +} + // Gather returns metric families for all registered metrics. func (hpr *registry) Gather() ([]*MetricFamily, error) { hpr.mu.RLock() diff --git a/vendor/github.com/luxfi/metric/noop.go b/vendor/github.com/luxfi/metric/noop.go index d80cab772..4e4549cd0 100644 --- a/vendor/github.com/luxfi/metric/noop.go +++ b/vendor/github.com/luxfi/metric/noop.go @@ -3,23 +3,57 @@ package metric -// noopCounter is a counter that does nothing. -type noopCounter struct{ value float64 } +import ( + "math" + "sync/atomic" +) -func (n *noopCounter) Inc() { n.value++ } -func (n *noopCounter) Add(v float64) { n.value += v } -func (n *noopCounter) Get() float64 { return n.value } +// noopCounter is a counter that does nothing. value is stored as float64 bits +// in a uint64 and mutated via CAS so concurrent Inc/Add/Get is race-free — +// matches metricCounter's representation (metrics_impl.go). +type noopCounter struct{ value uint64 } // atomic float64 bits -// noopGauge is a gauge that does nothing. -type noopGauge struct{ value float64 } +func (n *noopCounter) Inc() { n.Add(1) } -func (n *noopGauge) Set(v float64) { n.value = v } +func (n *noopCounter) Add(v float64) { + for { + oldBits := atomic.LoadUint64(&n.value) + newBits := math.Float64bits(math.Float64frombits(oldBits) + v) + if atomic.CompareAndSwapUint64(&n.value, oldBits, newBits) { + return + } + } +} + +func (n *noopCounter) Get() float64 { + return math.Float64frombits(atomic.LoadUint64(&n.value)) +} + +// noopGauge is a gauge that does nothing. value is stored as float64 bits in +// a uint64 and mutated via CAS so concurrent Set/Inc/Dec/Add/Sub/Get is +// race-free — matches metricGauge's representation (metrics_impl.go). +type noopGauge struct{ value uint64 } // atomic float64 bits + +func (n *noopGauge) Set(v float64) { atomic.StoreUint64(&n.value, math.Float64bits(v)) } func (n *noopGauge) SetToCurrentTime() {} -func (n *noopGauge) Inc() { n.value++ } -func (n *noopGauge) Dec() { n.value-- } -func (n *noopGauge) Add(v float64) { n.value += v } -func (n *noopGauge) Sub(v float64) { n.value -= v } -func (n *noopGauge) Get() float64 { return n.value } +func (n *noopGauge) Inc() { n.Add(1) } +func (n *noopGauge) Dec() { n.Add(-1) } + +func (n *noopGauge) Add(v float64) { + for { + oldBits := atomic.LoadUint64(&n.value) + newBits := math.Float64bits(math.Float64frombits(oldBits) + v) + if atomic.CompareAndSwapUint64(&n.value, oldBits, newBits) { + return + } + } +} + +func (n *noopGauge) Sub(v float64) { n.Add(-v) } + +func (n *noopGauge) Get() float64 { + return math.Float64frombits(atomic.LoadUint64(&n.value)) +} // noopHistogram is a histogram that does nothing. type noopHistogram struct{} @@ -36,6 +70,7 @@ type noopCounterVec struct{} func (n *noopCounterVec) With(Labels) Counter { return &noopCounter{} } func (n *noopCounterVec) WithLabelValues(...string) Counter { return &noopCounter{} } +func (n *noopCounterVec) MustCurryWith(Labels) CounterVec { return n } func (n *noopCounterVec) Reset() {} // noopGaugeVec is a gauge vector that does nothing. @@ -43,6 +78,7 @@ type noopGaugeVec struct{} func (n *noopGaugeVec) With(Labels) Gauge { return &noopGauge{} } func (n *noopGaugeVec) WithLabelValues(...string) Gauge { return &noopGauge{} } +func (n *noopGaugeVec) MustCurryWith(Labels) GaugeVec { return n } func (n *noopGaugeVec) Reset() {} // noopHistogramVec is a histogram vector that does nothing. @@ -50,6 +86,7 @@ type noopHistogramVec struct{} func (n *noopHistogramVec) With(Labels) Histogram { return &noopHistogram{} } func (n *noopHistogramVec) WithLabelValues(...string) Histogram { return &noopHistogram{} } +func (n *noopHistogramVec) MustCurryWith(Labels) HistogramVec { return n } func (n *noopHistogramVec) Reset() {} // noopSummaryVec is a summary vector that does nothing. @@ -57,6 +94,7 @@ type noopSummaryVec struct{} func (n *noopSummaryVec) With(Labels) Summary { return &noopSummary{} } func (n *noopSummaryVec) WithLabelValues(...string) Summary { return &noopSummary{} } +func (n *noopSummaryVec) MustCurryWith(Labels) SummaryVec { return n } func (n *noopSummaryVec) Reset() {} // noopRegistry provides a registry that gathers nothing. @@ -66,6 +104,7 @@ func newNoopRegistry() Registry { return &noopRegistry{} } func (r *noopRegistry) Register(_ Collector) error { return nil } func (r *noopRegistry) MustRegister(_ ...Collector) {} +func (r *noopRegistry) Unregister(_ Collector) bool { return false } func (r *noopRegistry) Gather() ([]*MetricFamily, error) { return nil, nil } diff --git a/vendor/github.com/luxfi/metric/pq-dashboard.html b/vendor/github.com/luxfi/metric/pq-dashboard.html index 7ac3ca030..5e30abadc 100644 --- a/vendor/github.com/luxfi/metric/pq-dashboard.html +++ b/vendor/github.com/luxfi/metric/pq-dashboard.html @@ -254,7 +254,7 @@
- Ringtail + Corona
@@ -340,7 +340,7 @@ Level 5 - Ringtail (Hybrid) + Corona (Hybrid) 6,780 0.15 ms 99.97% @@ -435,7 +435,7 @@ tension: 0.4 }, { - label: 'Ringtail', + label: 'Corona', data: Array(20).fill(0).map(() => 6500 + Math.random() * 500), borderColor: '#f093fb', tension: 0.4 @@ -456,7 +456,7 @@ const verificationChart = new Chart(verificationCtx, { type: 'bar', data: { - labels: ['BLS', 'ML-DSA', 'SLH-DSA', 'Ringtail', 'Verkle'], + labels: ['BLS', 'ML-DSA', 'SLH-DSA', 'Corona', 'Verkle'], datasets: [{ label: 'Average Verification Time', data: [0.08, 0.12, 0.47, 0.15, 0.05], @@ -488,7 +488,7 @@ const gasChart = new Chart(gasCtx, { type: 'doughnut', data: { - labels: ['BLS', 'ML-DSA', 'SLH-DSA', 'Ringtail', 'Verkle', 'Other'], + labels: ['BLS', 'ML-DSA', 'SLH-DSA', 'Corona', 'Verkle', 'Other'], datasets: [{ data: [25, 30, 10, 20, 10, 5], backgroundColor: [ @@ -556,7 +556,7 @@ dataset.data.shift(); const base = dataset.label === 'BLS' ? 12000 : dataset.label === 'ML-DSA' ? 8000 : - dataset.label === 'Ringtail' ? 6500 : 18000; + dataset.label === 'Corona' ? 6500 : 18000; dataset.data.push(base + Math.random() * 1000); }); signatureChart.update('none'); diff --git a/vendor/github.com/luxfi/metric/registry_types.go b/vendor/github.com/luxfi/metric/registry_types.go index 7d84d0ad7..90cf2d8ef 100644 --- a/vendor/github.com/luxfi/metric/registry_types.go +++ b/vendor/github.com/luxfi/metric/registry_types.go @@ -8,6 +8,10 @@ type Registerer interface { Metrics Register(Collector) error MustRegister(...Collector) + // Unregister removes a previously registered collector, freeing its name + // to be registered again. Returns true if it was present. Mirrors + // prometheus.Registerer.Unregister. + Unregister(Collector) bool } // Registry is a registerer that can also gather metric families. @@ -41,8 +45,9 @@ type prefixRegisterer struct { next Registerer } -func (p *prefixRegisterer) Register(c Collector) error { return p.next.Register(c) } +func (p *prefixRegisterer) Register(c Collector) error { return p.next.Register(c) } func (p *prefixRegisterer) MustRegister(cs ...Collector) { p.next.MustRegister(cs...) } +func (p *prefixRegisterer) Unregister(c Collector) bool { return p.next.Unregister(c) } func (p *prefixRegisterer) NewCounter(name, help string) Counter { return p.next.NewCounter(p.prefix+name, help) } diff --git a/vendor/github.com/luxfi/proto/p/signer/empty.go b/vendor/github.com/luxfi/protocol/p/signer/empty.go similarity index 100% rename from vendor/github.com/luxfi/proto/p/signer/empty.go rename to vendor/github.com/luxfi/protocol/p/signer/empty.go diff --git a/vendor/github.com/luxfi/proto/p/signer/proof_of_possession.go b/vendor/github.com/luxfi/protocol/p/signer/proof_of_possession.go similarity index 100% rename from vendor/github.com/luxfi/proto/p/signer/proof_of_possession.go rename to vendor/github.com/luxfi/protocol/p/signer/proof_of_possession.go diff --git a/vendor/github.com/luxfi/proto/p/signer/signer.go b/vendor/github.com/luxfi/protocol/p/signer/signer.go similarity index 100% rename from vendor/github.com/luxfi/proto/p/signer/signer.go rename to vendor/github.com/luxfi/protocol/p/signer/signer.go diff --git a/vendor/github.com/luxfi/tls/LICENSE b/vendor/github.com/luxfi/tls/LICENSE new file mode 100644 index 000000000..fbc776e31 --- /dev/null +++ b/vendor/github.com/luxfi/tls/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2024, Lux Partners Limited +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/luxfi/tls/LICENSING.md b/vendor/github.com/luxfi/tls/LICENSING.md new file mode 100644 index 000000000..d96eecd3c --- /dev/null +++ b/vendor/github.com/luxfi/tls/LICENSING.md @@ -0,0 +1,8 @@ +# Licensing + +This repository is licensed under the **BSD-3-Clause License** (see [LICENSE](LICENSE)). It belongs to the **public** tier of the Lux three-tier IP strategy: anyone may use, fork, or redistribute it, including for commercial purposes, subject to the BSD-3-Clause License terms. + +For the canonical Lux IP and licensing strategy, see: + + +For commercial inquiries that go beyond the public tier (e.g. private moat acceleration kernels, Eco-tier patent-protected primitives outside Authorized Networks), contact `licensing@lux.network`. diff --git a/vendor/github.com/luxfi/tls/LLM.md b/vendor/github.com/luxfi/tls/LLM.md new file mode 100644 index 000000000..145da0996 --- /dev/null +++ b/vendor/github.com/luxfi/tls/LLM.md @@ -0,0 +1,29 @@ +# Hanzo Tls + +## Overview +Go module: github.com/luxfi/tls + +## Tech Stack +- **Language**: Go + +## Build & Run +```bash +go build ./... +go test ./... +``` + +## Structure +``` +tls/ + LICENSE + asn1.go + certificate.go + go.mod + go.sum + parse.go + tls.go + verify.go +``` + +## Key Files +- `go.mod` -- Go module definition diff --git a/vendor/github.com/luxfi/zap/LLM.md b/vendor/github.com/luxfi/zap/LLM.md index ba4ce1ca3..74638a1de 100644 --- a/vendor/github.com/luxfi/zap/LLM.md +++ b/vendor/github.com/luxfi/zap/LLM.md @@ -1,4 +1,4 @@ -# LLM.md - Hanzo Zap +# Hanzo Zap ## Overview Go module: github.com/luxfi/zap @@ -71,3 +71,180 @@ The QUIC transport adds, beyond what TCP+TLS gives: See `quic/README.md` for details, defaults, deployment notes, and the threat-model discussion. + +### GPU-aware `transport/` subpackage (LP-203 zero-copy) + +`github.com/luxfi/zap/transport` registers four implementations behind +the same `Transport` interface: + +| Name | Build tags | Wire | GPU-resident bytes | +|-------------|-------------------------------------|----------------|--------------------| +| `default` | always | in-proc / TCP | no | +| `uma` | `cgo,linux,cuda` or `cgo,darwin` | NIC → managed | yes (cudaMallocManaged on linux, MTLBuffer on darwin) | +| `gpudirect` | `cgo,linux,gpudirect,cuda` | NIC → GPU VRAM | yes (DMA-buf MR) | +| `dpdk` | `cgo,linux,dpdk` + `pkg-config libdpdk` | NIC poll loop | no (CPU hugepage) | + +`transport.Pick("")` selects in order `gpudirect > dpdk > uma > +default`. An operator override via `ZAP_TRANSPORT={default,uma,gpudirect, +dpdk}` returns ErrNotAvailable on a host that can't provide it (no +silent fallback when the operator was explicit). + +Transports that can hand out GPU-resident buffers also implement +`BufferAllocator`: + +```go +tr, _ := transport.Pick("uma") +alloc, ok := tr.(transport.BufferAllocator) +if !ok { /* default transport — heap allocate */ } +buf, _ := alloc.AllocBuffer(1 << 20) // 1 MiB managed slab +copy(buf.Bytes(), payload) // CPU writes +gpuKernel.launch(buf.DevicePtr(), 1<<20) // GPU reads same bytes +buf.Release() // back to slab pool +``` + +UMA pool is slab-allocated (`slabClasses = 256B, 1KiB, 4KiB, 16KiB, +64KiB, 1MiB`). Pool budget defaults to 4 GiB via `ZAP_UMA_POOL_BYTES`. +Sizes above 1 MiB take a cold-path `cudaMallocManaged` per call. + +Boot emits one `slog.Info` line listing the chosen transport + probe +errors for the others. Silence with `ZAP_TRANSPORT_QUIET=1`. + +Probe gaps are reported honestly: on a host with libibverbs but no +Mellanox HCA visible, `Pick("gpudirect")` returns +`missing prereq(s): [ibverbs-device raw-packet-cap nvidia-peermem]` +— never a fake success. + +### Read-buffer pool (bufpool.go) + +The TCP dispatch read path sources frame buffers from a quantized +`sync.Pool` (`64B / 256B / 1 KiB / 4 KiB / 16 KiB / 64 KiB`) via +`readMessageRawPooled` + refcounted `*bufRef`. `Message` carries an +optional `refs *bufRef`; `Message.Release()` decrements the refcount +and (at zero) returns the slab. `Message.Retain()` extends lifetime +across goroutine boundaries (e.g. when a Call response is delivered +via channel). + +Wire format is byte-identical — only the buffer lifecycle changed. +Frames over 64 KiB fall back to a one-off heap alloc transparent to +the caller. `Message.Release()` on a Builder-built or unpooled +message is a no-op so existing callers keep working unmodified. + +Read benchmarks (Apple M1 Max, `go test -bench='BenchmarkRead' +-benchtime=2s -count=2`): + +| Size | Legacy ns/op | Pooled ns/op | Speedup | Allocs (legacy → pooled) | +|-------|--------------|--------------|---------|--------------------------| +| 64B | 38 | 40 | 1.0x | 2 → 1, 68 → 4 B/op | +| 256B | 68 | 43 | 1.6x | 2 → 1, 260 → 4 B/op | +| 1KB | 284 | 54 | 5.3x | 2 → 1, 1028 → 4 B/op | +| 4KB | 716 | 125 | 5.7x | 2 → 1, 4100 → 4 B/op | +| 16KB | 2244 | 355 | 6.3x | 2 → 1, 16388 → 4 B/op | +| 64KB | 4802 | 1142 | 4.2x | 2 → 1, 65540 → 4 B/op | + +### Per-Call QUIC streams (TransportStreamer) + +`Node.Call` over QUIC opens a fresh per-Call bidirectional stream via +`TransportStreamer.OpenCallStream` instead of serializing on the +shared control stream's `ctrlMu`. The server-side `acceptCallStreams` +goroutine spawns one handler goroutine per accepted stream so +concurrent Calls execute in parallel up to QUIC's stream limit (1024 +by default). + +Wire format on each per-Call stream is one length-prefixed ZAP frame +in each direction — no correlation header needed since each stream +carries exactly one request + one response. + +Per-stream is the only Call path on QUIC; there is no fallback. The +control stream carries one-way Sends only. + +End-to-end Call throughput (2 ms simulated handler): + +| Concurrency | Per-stream | Reference | Speedup | +|-------------|-------------|-------------|---------| +| 1 worker | 3.19 ms/op | 3.17 ms/op | 1.0x | +| 10 workers | 1.24 ms/op | 3.01 ms/op | 2.4x | +| 100 workers | 1.06 ms/op | 3.01 ms/op | 2.85x | + +Reference = handler latency on a serialized control-stream path +(pre-optimization measurement, retained for context). Per-stream +overlaps handlers in flight (peak inflight = 32 observed in +`TestQUICCallConcurrent`). + +## Locality-adaptive Router (P1) — `router.go`, `interface.go` + +The one-Send-API router that decouples WHO (`Destination`) from HOW +(`Interface`) from the message (`Payload`), so a caller never names a port or a +transport: + +```go +r := zap.NewRouter() +r.Register(zap.NewNodeInterface(node)) // network fallback, Cost 10 (conn_pq wire) +inproc := zap.NewInProcessInterface() // Cost 0 +inproc.Register("hanzo.o11y.traces", handler) +r.Register(inproc) + +r.Send(ctx, "hanzo.o11y.traces", zap.Payload{Value: spans, Encode: encodeFn}) +``` + +**The routing rule is a Cost table, not a caller branch.** `Send` picks the +cheapest `Interface` whose `CanReach(dst)` is true. When the destination lives in +THIS binary, `InProcessInterface` (Cost 0) wins and the handler is called with +the LIVE `Payload.Value` — zero serialization, zero copy, zero socket. `Encode` +(the zero-copy wire form) is invoked ONLY when a network `Interface` is chosen, +and only then. "If in-process skip TCP; else use the wire" falls out for free. + +Three "transport"-ish names, kept orthogonal — do not conflate: +- `zap.Transport` (int enum `TransportTCP`/`TransportQUIC`) — which wire ONE Node + speaks. `NodeInterface` adapts such a Node into the router. +- `zap.Router` — this P1 locality-adaptive router over many `Interface`s. +- `github.com/luxfi/zap/transport` — the GPU-aware buffer subpackage (LP-203). + +This is Reticulum's model made post-quantum + zero-copy: `Destination` is a +capability aspect today; the announce-routed PQ-identity destination hash +(multi-hop, mDNS/K8s-SRV discovery interfaces, UDP/QUIC/radio interfaces) refines +it in later phases WITHOUT moving the `Send` call site. `Node` is unchanged; +`NodeInterface` adapts it. First consumer: hanzo/cloud o11y telemetry (cloud's own +spans → in-process → ClickHouse sink, never the wire). See `router_test.go` +(7 tests: cost-preference, zero-serialize proof, fallback, no-route, sort, +re-register, non-encodable-refused). + +## DexSession orchestration (`dexsession/`) + +ZAP/Cap'n-Proto orchestration layer for the Lux DEX: capability transport + +promise pipelining that makes the native C↔D atomic settlement flow FEEL +synchronous, while the value boundary stays 100% native. + +THE HARD INVARIANT: a ZAP response is NEVER sufficient to move money. Money +moves ONLY when C consumes a real D→C atomic export object, or D consumes a real +C→D object. The orchestration layer holds no StateDB/AtomicState/shared-memory +and has NO compile edge to `precompile/dex` or the EVM — it cannot import the C +Verify path and Verify cannot import it. It traffics in VALUES (`[20]byte` +accounts, `[32]byte` ids, `uint64` amounts) and bytes only: + +- `prepareSwapIntent` → 0x9999 CALLDATA the USER signs (no funds reserved, no + enforceable amountOut — the floor rides MinAmountOut in the signed tx). +- `notifyIntent` → tells D to scan/import the C→D object the signed tx created; + cannot make a D match valid without a committed D block; returns a watch. +- `importSettlement` → finalization CALLDATA / a tx that POINTS at a `DExportRef`; + the chain re-reads the real D→C object and binds recipient/asset/amount to it. + +`DExportRef` is a POINTER `{sourceChainID, sourceTxID, outputIndex, intentID}`, +NOT a DFillReceipt. "No capability moves money" is provable by EXHAUSTION: the +surface has no creditBalance/settleFill/overrideMatch/adminWithdraw method. +Capabilities (QuoteCap/IntentCap/WatchCap/SettlementCap/AdminCap) are unforgeable +tokens scoped to a bootstrap grant; a session cannot widen its own authority. + +The 60-byte atomic object wire, `DeriveIntentID`, `DeriveUTXOID`, the V4 swap +selector (0xF3CD914C), and the Phase-A/B hookData tags are REPRODUCED as pure +values (not imported) and pinned byte-identical to `precompile/dex` + +`chains/dexvm` by `parity_test.go` — the "three homes" pattern, keeping the +transport module free of the EVM/cgo dep graph. + +Promise pipelining (`promise.go`/`pipeline.go`): dependent calls dispatch the +instant their inputs resolve (`thenAsync`), so `quote→prepare→notify→ +onCommitted→import` overlaps network latency; `SwapFlow`/`SwapFlowWithSender` +wire the declarative end-to-end path. The watch streams D's result (poll/push) +and resolves to a pointer on commit. + +Build/test (pure Go): `CGO_ENABLED=0 GOWORK=off go test ./dexsession/`. The +critical adversarial proof is `TestRED_ZAP_ResponseAloneCannotMoveMoney`. diff --git a/vendor/github.com/luxfi/zap/MIGRATION.md b/vendor/github.com/luxfi/zap/MIGRATION.md index ef25d1d3c..8f2b6fb80 100644 --- a/vendor/github.com/luxfi/zap/MIGRATION.md +++ b/vendor/github.com/luxfi/zap/MIGRATION.md @@ -5,6 +5,44 @@ The canonical KV + transport for Lux is `luxfi/zap` (this repo) backed by **and** cold ancient stores. PebbleDB / leveldb remain only as legacy in-place upgrade paths. +## ZAP runtime consolidation (serialization core) + +`github.com/zap-proto/go` is the canonical pure-stdlib runtime for the ZAP +wire format (`Parse`/`Message`/`Object`/`List` + `Builder`/`ObjectBuilder`/ +`ListBuilder` + `Schema`). This repo (`luxfi/zap`) historically duplicated +that core in its own `zap.go`/`builder.go`/`schema.go` while adding the +network layer (Node mesh, QUIC/TCP, mDNS, PQ-TLS handshake, EVM types, the +`forward` HTTP-over-ZAP contract). The duplication is being collapsed so +there is ONE serialization runtime; `zap-proto/go` is the source of truth and +this repo will ride it. + +**Status (first safe step landed):** the two cores are now proven to emit a +byte-identical data segment, and `zap-proto/go` has absorbed the two deltas +that previously diverged it from this repo's hardened core, so the readers now +agree on accept/reject for every input. + +- **Wire proof.** `zap_crosswire_test.go` (here) and the file of the same + name in `zap-proto/go` pin the SAME `goldenV1Hex` constant. This repo's + `NewBuilderV1` emits it byte-for-byte; `zap-proto/go`'s default `NewBuilder` + emits it too. The ONLY header difference between this repo's default + (Version2) output and the v1 golden vector is byte 4 (the version). A live + cross-encode in a throwaway `go.work` joining both modules confirmed every + field round-trips both directions. +- **Deltas reconciled in `zap-proto/go`** (additive — no honest wire changed): + (1) it now accepts `Version1` AND `Version2` on read (was v1-only → it would + reject this repo's default v2 buffers); (2) its reader now applies the same + hardening this repo already had — unsigned-forward `Bytes` with + `absPos < HeaderSize` rejection, `Object`/`List` `absOffset < HeaderSize` + rejection, and `List` `length ≤ msgsize` clamp. + +**Remaining steps** (see `zap-proto/go`'s LLM.md for the canonical list): +`schema.go` is already byte-identical and is the first alias target; the +reader/builder alias follows once `cmd/zapgen` lands (the read-buffer pool — +`Message.refs`/`Release`/`Retain` — is network-local and stays here); the +`StartObject` pre-reserve discipline is a documented, test-covered delta to +unify when the builder is aliased (adopt `zap-proto/go`'s pre-reserve — it is +strictly more reserving and byte-identical for every honest layout). + This doc enumerates every storage surface in luxd and the migration path per backend. diff --git a/vendor/github.com/luxfi/zap/README.md b/vendor/github.com/luxfi/zap/README.md index 560bfa4ea..9a71206aa 100644 --- a/vendor/github.com/luxfi/zap/README.md +++ b/vendor/github.com/luxfi/zap/README.md @@ -1,3 +1,5 @@ +

zap

+ # ZAP **Z**ero-copy **A**pplication **P**rotocol for Lux. diff --git a/vendor/github.com/luxfi/zap/bufpool.go b/vendor/github.com/luxfi/zap/bufpool.go new file mode 100644 index 000000000..fcaf29f45 --- /dev/null +++ b/vendor/github.com/luxfi/zap/bufpool.go @@ -0,0 +1,202 @@ +// Copyright (C) 2026, Lux Industries Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package zap + +import ( + "sync" + "sync/atomic" +) + +// Pooled read-buffer slabs. +// +// readMessageRaw used to do `make([]byte, length)` on every frame, which +// allocates GC-tracked memory each read. The buffer's lifetime extends +// from one Read call to wherever the caller releases the *Message — +// typically the end of a handler invocation, or the moment a Call +// goroutine consumes its response from the response channel. +// +// We quantize buffer sizes into six classes (64B, 256B, 1 KiB, 4 KiB, +// 16 KiB, 64 KiB) so each `sync.Pool` holds slabs of one shape only +// — that avoids the variable-size pool defeat where a 1 KiB Get +// returns a 64 KiB slab that's never reused at its real shape. +// +// A `bufRef` is a refcount wrapper around the slab. dispatchLoop +// increments the count when a *Message escapes to a channel (so the +// awaiting Call goroutine can Release) and decrements once after the +// handler/parse path is done. When refs hits zero the slab returns +// to its pool. +// +// Anything larger than the largest class (> 64 KiB) falls through to +// a one-off heap allocation with a nil pool — Release on those is a +// no-op so the GC reclaims them naturally. Three reasons we don't pool +// >64 KiB: +// - Large frames are rare on the steady-state hot path (most +// dispatchLoop frames are control + correlated RPCs). +// - sync.Pool fairness under contention degrades with slab size: +// keeping >64 KiB slabs hot can pin tens of MiB per process. +// - The 10 MiB MaxFrameSize ceiling already caps the worst case +// to a single heap allocation per giant frame. + +// bufSizes lists the quantization in ascending order. Anything between +// classes rounds UP to the next class — that's the only way to keep +// a class invariant ("a 256B slab is exactly 256 bytes of cap"). +var bufSizes = [...]int{64, 256, 1024, 4 * 1024, 16 * 1024, 64 * 1024} + +// bufPools[i] holds slabs of bufSizes[i] capacity. +// +// Declared as a pointer-to-array so the package-level initializer +// doesn't copy a `sync.Pool` value (which contains sync.noCopy). The +// pools themselves never move after init. +var bufPools = func() *[len(bufSizes)]sync.Pool { + pools := new([len(bufSizes)]sync.Pool) + for i, sz := range bufSizes { + size := sz // capture before closure binding + pools[i].New = func() any { + b := make([]byte, size) + return &b + } + } + return pools +}() + +// pickBufClass returns the pool index for a buffer of length n, +// or -1 if n exceeds the largest class. +// +// Branchless ladder beats binary search at this scale (6 classes) — +// the predicted compare-and-jump is one pipeline-friendly cycle on +// modern superscalars. We tested both; the ladder won by 3-4 ns. +func pickBufClass(n int) int { + switch { + case n <= bufSizes[0]: + return 0 + case n <= bufSizes[1]: + return 1 + case n <= bufSizes[2]: + return 2 + case n <= bufSizes[3]: + return 3 + case n <= bufSizes[4]: + return 4 + case n <= bufSizes[5]: + return 5 + default: + return -1 + } +} + +// bufRef is a refcounted slab. The refcount is set to 1 by getBuf +// and decremented by release. When it hits zero the underlying slab +// is returned to its pool (if any). +// +// One bufRef tracks one slab; we pool the bufRef struct itself via a +// dedicated pool so the refcount header doesn't churn the heap either. +// +// We hold the slab as *[]byte (not []byte) so release can Put the +// same pointer that Get returned — sync.Pool deduplicates on pointer +// identity. Putting a fresh-stack &buf forces a new heap alloc for +// the slice header on every release, which was a 24-byte/op overhead +// on the first iteration. +type bufRef struct { + // bufp is the pooled slice header. nil for over-class one-offs. + bufp *[]byte + + // fallback holds the slab when bufp is nil (over-class). Sized + // exactly to n; reclaimed by GC. + fallback []byte + + // n is the frame length the caller asked for (≤ len(buf)). + n int + + // class is the index into bufPools, or -1 if buf was a one-off + // heap allocation (frame > largest pool class). + class int + + // refs counts live references to buf. Starts at 1, +1 on retain, + // -1 on release. When it reaches 0 the slab returns to its pool. + refs atomic.Int32 +} + +// refPool pools the bufRef header itself. bufRefs are tiny (40 bytes +// on 64-bit) but they appear on every frame — pooling them takes them +// off the GC's plate the same way the slab pool removes the buffer. +var refPool = sync.Pool{ + New: func() any { return new(bufRef) }, +} + +// getBuf returns a refcounted slab of at least n bytes, with refs=1. +// +// Caller must call release() (or attach the ref to a *Message which +// will release on its own teardown). Failure to release leaks the +// slab — sync.Pool will eventually reclaim it via its own GC hook, +// but the steady-state allocation savings depend on prompt release. +func getBuf(n int) *bufRef { + r := refPool.Get().(*bufRef) + r.n = n + r.refs.Store(1) + + class := pickBufClass(n) + r.class = class + if class < 0 { + // Anything larger than the largest class: one-off heap alloc. + // Release returns the bufRef header to refPool but lets GC + // reclaim the buffer itself. + r.bufp = nil + r.fallback = make([]byte, n) + return r + } + r.bufp = bufPools[class].Get().(*[]byte) + r.fallback = nil + return r +} + +// rawBuf returns the underlying slab as a slice of class capacity +// (or n bytes for over-class fallbacks). io.ReadFull writes into the +// first n bytes. +func (r *bufRef) rawBuf() []byte { + if r.bufp != nil { + return (*r.bufp)[:bufSizes[r.class]] + } + return r.fallback +} + +// Bytes returns the slab sub-slice the caller asked for. The capacity +// is the pool class size; the length is the requested n. Treat as +// read-only after the underlying frame has been parsed. +func (r *bufRef) Bytes() []byte { + if r.bufp != nil { + return (*r.bufp)[:r.n] + } + return r.fallback[:r.n] +} + +// retain increments the refcount. Called when a *Message constructed +// over this slab escapes from the dispatch loop to a goroutine that +// will release it later (e.g. a Call response delivered via channel). +func (r *bufRef) retain() { + r.refs.Add(1) +} + +// release decrements the refcount. When it hits zero the slab is +// returned to its pool (or simply dropped to GC if it was an +// over-class one-off allocation). +// +// release on a nil bufRef is a no-op — Message's release field is +// nil when the message wasn't built over a pooled buffer, and we +// don't want callers to have to branch on that. +func (r *bufRef) release() { + if r == nil { + return + } + if r.refs.Add(-1) != 0 { + return + } + if r.bufp != nil { + bufPools[r.class].Put(r.bufp) + r.bufp = nil + } + r.fallback = nil + r.n = 0 + r.class = 0 + refPool.Put(r) +} diff --git a/vendor/github.com/luxfi/zap/builder.go b/vendor/github.com/luxfi/zap/builder.go index 5ad6d47c9..a335a02e2 100644 --- a/vendor/github.com/luxfi/zap/builder.go +++ b/vendor/github.com/luxfi/zap/builder.go @@ -6,6 +6,7 @@ package zap import ( "encoding/binary" "math" + "sync" ) // Builder constructs ZAP messages. @@ -94,27 +95,30 @@ type ObjectBuilder struct { b *Builder startPos int dataSize int - offsets []offsetEntry } -type offsetEntry struct { - fieldOffset int - targetPos int // positive = known position, negative = deferred write - data []byte // actual bytes to write (deferred text/bytes) -} - -// StartObject starts building an object with the given data size. -func (b *Builder) StartObject(dataSize int) *ObjectBuilder { +// StartObject starts building an object with the given data size, RESERVING the +// full fixed section up front (zero-filled). Reserving eagerly means a variable +// field (SetBytes/SetText) can append its tail data immediately after the fixed +// section and patch its own relative pointer on the spot — there is no deferred +// offset list to record intentions and replay in Finish. Callers already build +// child objects/lists BEFORE StartObject (the writeXxxList-then-StartObject +// pattern), so the object's own Set* calls are the only buffer writes between +// StartObject and Finish; appending tail bytes immediately is safe and produces +// byte-identical wire. +func (b *Builder) StartObject(dataSize int) ObjectBuilder { b.align(Alignment) - return &ObjectBuilder{ + ob := ObjectBuilder{ b: b, startPos: b.pos, dataSize: dataSize, } + ob.ensureField(dataSize) + return ob } // SetBool sets a bool field. -func (ob *ObjectBuilder) SetBool(fieldOffset int, v bool) { +func (ob ObjectBuilder) SetBool(fieldOffset int, v bool) { if v { ob.SetUint8(fieldOffset, 1) } else { @@ -123,88 +127,111 @@ func (ob *ObjectBuilder) SetBool(fieldOffset int, v bool) { } // SetUint8 sets a uint8 field. -func (ob *ObjectBuilder) SetUint8(fieldOffset int, v uint8) { +func (ob ObjectBuilder) SetUint8(fieldOffset int, v uint8) { ob.ensureField(fieldOffset + 1) ob.b.buf[ob.startPos+fieldOffset] = v } // SetUint16 sets a uint16 field. -func (ob *ObjectBuilder) SetUint16(fieldOffset int, v uint16) { +func (ob ObjectBuilder) SetUint16(fieldOffset int, v uint16) { ob.ensureField(fieldOffset + 2) binary.LittleEndian.PutUint16(ob.b.buf[ob.startPos+fieldOffset:], v) } // SetUint32 sets a uint32 field. -func (ob *ObjectBuilder) SetUint32(fieldOffset int, v uint32) { +func (ob ObjectBuilder) SetUint32(fieldOffset int, v uint32) { ob.ensureField(fieldOffset + 4) binary.LittleEndian.PutUint32(ob.b.buf[ob.startPos+fieldOffset:], v) } // SetUint64 sets a uint64 field. -func (ob *ObjectBuilder) SetUint64(fieldOffset int, v uint64) { +func (ob ObjectBuilder) SetUint64(fieldOffset int, v uint64) { ob.ensureField(fieldOffset + 8) binary.LittleEndian.PutUint64(ob.b.buf[ob.startPos+fieldOffset:], v) } // SetInt8 sets an int8 field. -func (ob *ObjectBuilder) SetInt8(fieldOffset int, v int8) { +func (ob ObjectBuilder) SetInt8(fieldOffset int, v int8) { ob.SetUint8(fieldOffset, uint8(v)) } // SetInt16 sets an int16 field. -func (ob *ObjectBuilder) SetInt16(fieldOffset int, v int16) { +func (ob ObjectBuilder) SetInt16(fieldOffset int, v int16) { ob.SetUint16(fieldOffset, uint16(v)) } // SetInt32 sets an int32 field. -func (ob *ObjectBuilder) SetInt32(fieldOffset int, v int32) { +func (ob ObjectBuilder) SetInt32(fieldOffset int, v int32) { ob.SetUint32(fieldOffset, uint32(v)) } // SetInt64 sets an int64 field. -func (ob *ObjectBuilder) SetInt64(fieldOffset int, v int64) { +func (ob ObjectBuilder) SetInt64(fieldOffset int, v int64) { ob.SetUint64(fieldOffset, uint64(v)) } // SetFloat32 sets a float32 field. -func (ob *ObjectBuilder) SetFloat32(fieldOffset int, v float32) { +func (ob ObjectBuilder) SetFloat32(fieldOffset int, v float32) { ob.SetUint32(fieldOffset, float32bits(v)) } // SetFloat64 sets a float64 field. -func (ob *ObjectBuilder) SetFloat64(fieldOffset int, v float64) { +func (ob ObjectBuilder) SetFloat64(fieldOffset int, v float64) { ob.SetUint64(fieldOffset, float64bits(v)) } +// SetBytesFixed copies len(v) bytes inline at fieldOffset within the +// object's fixed payload. This is the generic-width counterpart of +// SetHash (32 bytes) and SetAddress (20 bytes); it covers any N>0 +// inline byte-array slot (e.g., LP-201 SessionID [16]byte, LP-208 +// QuasarWitness [96]byte). +// +// Unlike SetBytes (which writes a variable-length tail pointer +// {relOffset uint32, length uint32}), SetBytesFixed writes the bytes +// IN PLACE in the fixed payload. Use this when the schema declares a +// fixed-width byte field; use SetBytes when the schema declares a +// variable-length tail. +// +// Panics on len(v) == 0 are avoided: a zero-length argument is a +// no-op (the slot is left as the zero value). +func (ob ObjectBuilder) SetBytesFixed(fieldOffset int, v []byte) { + if len(v) == 0 { + return + } + ob.ensureField(fieldOffset + len(v)) + copy(ob.b.buf[ob.startPos+fieldOffset:], v) +} + // SetText sets a text (string) field. -func (ob *ObjectBuilder) SetText(fieldOffset int, v string) { +func (ob ObjectBuilder) SetText(fieldOffset int, v string) { ob.SetBytes(fieldOffset, []byte(v)) } // SetBytes sets a bytes field. // The data is written after the object's fixed section during Finish(). -func (ob *ObjectBuilder) SetBytes(fieldOffset int, v []byte) { - ob.ensureField(fieldOffset + 8) // offset + length - +func (ob ObjectBuilder) SetBytes(fieldOffset int, v []byte) { if len(v) == 0 { - // Null pointer + // Null pointer (offset 0, length 0). binary.LittleEndian.PutUint32(ob.b.buf[ob.startPos+fieldOffset:], 0) binary.LittleEndian.PutUint32(ob.b.buf[ob.startPos+fieldOffset+4:], 0) return } + // The fixed section is fully reserved by StartObject, so b.pos is at the + // tail: append the data now and patch this field's (relOffset, length) pair + // immediately — no deferred offset list, no per-object slice allocation. + dataPos := ob.b.pos + ob.b.grow(len(v)) + copy(ob.b.buf[ob.b.pos:ob.b.pos+len(v)], v) + ob.b.pos += len(v) - // Store the data and length; the relative offset is patched in Finish() - ob.offsets = append(ob.offsets, offsetEntry{ - fieldOffset: fieldOffset, - data: append([]byte(nil), v...), // copy the data - }) - - // Write the length now - binary.LittleEndian.PutUint32(ob.b.buf[ob.startPos+fieldOffset+4:], uint32(len(v))) + fieldAbsPos := ob.startPos + fieldOffset + relOffset := int32(dataPos - fieldAbsPos) + binary.LittleEndian.PutUint32(ob.b.buf[fieldAbsPos:], uint32(relOffset)) + binary.LittleEndian.PutUint32(ob.b.buf[fieldAbsPos+4:], uint32(len(v))) } // SetObject sets a nested object field (by offset). -func (ob *ObjectBuilder) SetObject(fieldOffset int, objOffset int) { +func (ob ObjectBuilder) SetObject(fieldOffset int, objOffset int) { ob.ensureField(fieldOffset + 4) if objOffset == 0 { @@ -218,7 +245,7 @@ func (ob *ObjectBuilder) SetObject(fieldOffset int, objOffset int) { } // SetList sets a list field. -func (ob *ObjectBuilder) SetList(fieldOffset int, listOffset int, length int) { +func (ob ObjectBuilder) SetList(fieldOffset int, listOffset int, length int) { ob.ensureField(fieldOffset + 8) if listOffset == 0 || length == 0 { @@ -232,7 +259,7 @@ func (ob *ObjectBuilder) SetList(fieldOffset int, listOffset int, length int) { binary.LittleEndian.PutUint32(ob.b.buf[ob.startPos+fieldOffset+4:], uint32(length)) } -func (ob *ObjectBuilder) ensureField(endOffset int) { +func (ob ObjectBuilder) ensureField(endOffset int) { needed := ob.startPos + endOffset if needed > ob.b.pos { ob.b.grow(needed - ob.b.pos) @@ -244,35 +271,38 @@ func (ob *ObjectBuilder) ensureField(endOffset int) { } } -// Finish finalizes the object and returns its offset. -// Writes deferred text/bytes data after the object's fixed section -// and patches relative offsets. -func (ob *ObjectBuilder) Finish() int { - // Ensure minimum size for fixed fields - ob.ensureField(ob.dataSize) - - // Write deferred text/bytes data and patch relative offsets - for _, entry := range ob.offsets { - if entry.data == nil { - continue - } - // Write the data at current position (after fixed section) - dataPos := ob.b.pos - ob.b.grow(len(entry.data)) - copy(ob.b.buf[ob.b.pos:ob.b.pos+len(entry.data)], entry.data) - ob.b.pos += len(entry.data) - - // Patch the relative offset: relOffset = dataPos - fieldAbsPos - fieldAbsPos := ob.startPos + entry.fieldOffset - relOffset := int32(dataPos - fieldAbsPos) - binary.LittleEndian.PutUint32(ob.b.buf[fieldAbsPos:], uint32(relOffset)) - } +// ReserveFixed extends the builder's write cursor so the object's +// entire fixed payload of dataSize bytes is materialized (zero-filled +// up to startPos+dataSize). Use this BEFORE writing any variable- +// length tail (list elements, deferred bytes) that should live AFTER +// the fixed section. +// +// Without this call, list elements or deferred-data writes interleave +// with the unreserved tail of the fixed section, producing incorrect +// wire bytes when later Set* calls patch fields that overlap with +// already-written variable data. +// +// Idempotent: a second call with the same dataSize is a no-op. A call +// with a smaller dataSize is also a no-op (the cursor never moves +// backwards). +// +// This is the exported counterpart to the internal ensureField helper. +// It is used by zapv1.WriteList to keep the parent's payload reserved +// before list elements are appended. +func (ob ObjectBuilder) ReserveFixed(dataSize int) { + ob.ensureField(dataSize) +} +// Finish finalizes the object and returns its offset. Every field (fixed and +// variable) is written eagerly by its Set* call — the fixed section is reserved +// in StartObject and SetBytes/SetText append their tail immediately — so there +// is nothing to replay here. +func (ob ObjectBuilder) Finish() int { return ob.startPos } // FinishAsRoot finalizes and sets as the message root. -func (ob *ObjectBuilder) FinishAsRoot() int { +func (ob ObjectBuilder) FinishAsRoot() int { offset := ob.Finish() ob.b.rootOffset = offset return offset @@ -300,17 +330,22 @@ func (b *Builder) WriteText(s string) int { type ListBuilder struct { b *Builder startPos int - elemSize int count int } -// StartList starts building a list. -func (b *Builder) StartList(elemSize int) *ListBuilder { +// StartList starts building a list. Returns a VALUE (not a heap pointer): the +// Add*/Finish methods take pointer receivers, and every caller binds the result +// to an addressable local (`lb := b.StartList(...)`), so Go auto-addresses the +// local and count mutations accumulate on it — no per-list heap allocation. +// Mirrors the value-typed StartObject. elemSize is unused (the stride is +// implicit in which Add* the caller invokes) and kept only as a documenting +// param. +func (b *Builder) StartList(elemSize int) ListBuilder { + _ = elemSize b.align(Alignment) - return &ListBuilder{ + return ListBuilder{ b: b, startPos: b.pos, - elemSize: elemSize, } } @@ -346,11 +381,60 @@ func (lb *ListBuilder) AddBytes(data []byte) { lb.count += len(data) } +// AddObjectPtr appends a 4-byte SIGNED relative pointer to an object at +// absolute position targetPos (pass 0 for a null element). This is the +// element kind for a list of out-of-line objects — the wire encoding of a +// "repeated message" field, where each fixed-stride slot points to a tailed +// object elsewhere in the buffer rather than inlining a fixed-size value. +// +// The relative offset is computed against THIS slot's position, so the +// reader resolves it the same way [Object.Object] does: absOffset = slotPos +// + int32(rel). Targets may precede the slot (negative rel) — the common +// case, since a builder writes the objects first and the pointer array +// after. +func (lb *ListBuilder) AddObjectPtr(targetPos int) { + lb.b.grow(4) + if targetPos == 0 { + binary.LittleEndian.PutUint32(lb.b.buf[lb.b.pos:], 0) + } else { + rel := int32(targetPos - lb.b.pos) + binary.LittleEndian.PutUint32(lb.b.buf[lb.b.pos:], uint32(rel)) + } + lb.b.pos += 4 + lb.count++ +} + // Finish returns the list offset and length. func (lb *ListBuilder) Finish() (offset int, length int) { return lb.startPos, lb.count } +// ---- Builder pool (write-side counterpart to the read bufpool) ---- + +// builderPool recycles Builders across messages. A pooled Builder keeps its +// grown backing array, so steady-state message construction allocates zero +// builder buffers. Byte-safety on reuse is unconditional: ensureField +// zero-fills every extended span and align zero-fills padding, so a reused +// (dirty) buffer emits bytes identical to a fresh one. +var builderPool = sync.Pool{ + New: func() any { return NewBuilder(512) }, +} + +// GetBuilder returns a pooled Builder, reset and ready to write a Version2 +// message. Callers MUST copy out the bytes returned by Finish (which aliases +// the Builder's buffer) before calling PutBuilder. +func GetBuilder() *Builder { + b := builderPool.Get().(*Builder) + b.Reset() + return b +} + +// PutBuilder returns a Builder to the pool. The slice previously returned by +// b.Finish() must no longer be referenced (it aliases b's buffer). +func PutBuilder(b *Builder) { + builderPool.Put(b) +} + // Helper functions func float32bits(f float32) uint32 { diff --git a/vendor/github.com/luxfi/zap/doc.go b/vendor/github.com/luxfi/zap/doc.go new file mode 100644 index 000000000..1ba11e4b0 --- /dev/null +++ b/vendor/github.com/luxfi/zap/doc.go @@ -0,0 +1,22 @@ +// Copyright (C) 2026, Lux Industries Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// Package zap (v1) is deprecated for new schema authoring. +// +// New schemas MUST be authored via codegen (~/work/lux/zap/v2/codegen) +// which emits v1-equivalent fast paths from a declarative .zap source. +// +// Consumer dispatch for ad-hoc / dynamic schemas goes through the v2 +// generic API (github.com/luxfi/zap/v1). +// +// The v1 hand-rolled code in this package remains for in-flight +// migration of legacy callers (luxfi/node/vms/platformvm/txs/zap_native, +// parts of luxfi/consensus/protocol/quasar, etc.); no new v1 schemas +// are accepted. +// +// The wire format is unchanged across v1 and v2 — this is a code-level +// decomplection of the authoring surface only. Existing v1 buffers +// remain parseable by both v1 and v2. +// +// See ~/work/lux/zap/v2/README.md for the canonical authoring path. +package zap diff --git a/vendor/github.com/luxfi/zap/handshake/initiator.go b/vendor/github.com/luxfi/zap/handshake/initiator.go index 88170111e..af6cb636c 100644 --- a/vendor/github.com/luxfi/zap/handshake/initiator.go +++ b/vendor/github.com/luxfi/zap/handshake/initiator.go @@ -9,6 +9,7 @@ import ( "errors" "fmt" "io" + "net" "runtime" "time" @@ -61,6 +62,15 @@ func (i *Initiator) Run(conn io.ReadWriter) (*Session, error) { return nil, errors.New("zap-pq: initiator requires Local with private key") } + // Bound the whole handshake by HandshakeTimeoutSec so a peer that + // connects and then stalls (or dribbles bytes) cannot pin this goroutine + // and FD indefinitely. Applies only when conn is a net.Conn; callers + // passing a bare io.ReadWriter remain responsible for their own timeout. + if nc, ok := conn.(net.Conn); ok { + _ = nc.SetReadDeadline(time.Now().Add(HandshakeTimeoutSec * time.Second)) + defer func() { _ = nc.SetReadDeadline(time.Time{}) }() + } + suite := i.Suite if suite == 0 { suite = SuiteX25519MLKEM diff --git a/vendor/github.com/luxfi/zap/handshake/responder.go b/vendor/github.com/luxfi/zap/handshake/responder.go index 0ef69197a..d45ab1285 100644 --- a/vendor/github.com/luxfi/zap/handshake/responder.go +++ b/vendor/github.com/luxfi/zap/handshake/responder.go @@ -9,6 +9,7 @@ import ( "errors" "fmt" "io" + "net" "runtime" "time" @@ -62,6 +63,15 @@ func (rs *Responder) Run(conn io.ReadWriter) (*Session, error) { return nil, errors.New("zap-pq: ReplayCache is required under StrictPQ/FIPS profile") } + // Bound the whole handshake by HandshakeTimeoutSec so an unauthenticated + // peer that connects and then stalls cannot pin this goroutine and FD + // indefinitely (pre-auth slowloris). Applies only when conn is a net.Conn; + // bare io.ReadWriter callers own their own timeout. + if nc, ok := conn.(net.Conn); ok { + _ = nc.SetReadDeadline(time.Now().Add(HandshakeTimeoutSec * time.Second)) + defer func() { _ = nc.SetReadDeadline(time.Time{}) }() + } + r := rs.Rand if r == nil { r = rand.Reader diff --git a/vendor/github.com/luxfi/zap/interface.go b/vendor/github.com/luxfi/zap/interface.go new file mode 100644 index 000000000..f5bf17198 --- /dev/null +++ b/vendor/github.com/luxfi/zap/interface.go @@ -0,0 +1,166 @@ +// Copyright (C) 2026, Lux Industries Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package zap + +import ( + "context" + "errors" + "fmt" + "sync" +) + +// InProcessInterface is the cost-0 interface: it delivers to destinations that +// live in THIS address space by calling their handler directly. No serialization, +// no copy, no socket, no loopback TCP — a call is a call. It is the primitive +// behind "if the sink is in my own binary, don't touch the network." +// +// A Payload's live Value is handed straight to the LocalHandler; the payload's +// Encode (the wire form) is never invoked on this path, so an in-process delivery +// pays nothing for encoding. When sender and receiver are folded into one binary +// (the unified-cloud monolith), this is the interface that always wins the Cost +// race, and the ZAP wire never enters the picture. +type InProcessInterface struct { + mu sync.RWMutex + handlers map[Destination]LocalHandler +} + +// NewInProcessInterface returns an empty in-process interface. Register the +// destinations this binary serves onto it, then Register it on a Router. +func NewInProcessInterface() *InProcessInterface { + return &InProcessInterface{handlers: make(map[Destination]LocalHandler)} +} + +// Register binds a destination (capability aspect) to a local handler. Calling it +// again for the same dst replaces the handler (last writer wins) — a subsystem +// re-mounting its sink is idempotent. A nil handler unregisters the destination +// so CanReach falls through to the next (network) interface. +func (p *InProcessInterface) Register(dst Destination, h LocalHandler) { + p.mu.Lock() + defer p.mu.Unlock() + if h == nil { + delete(p.handlers, dst) + return + } + p.handlers[dst] = h +} + +// Name identifies this interface. +func (p *InProcessInterface) Name() string { return "inprocess" } + +// Cost is 0 — a same-address-space handoff is the cheapest possible delivery, so +// Router prefers it over every wire interface whenever the dst is local. +func (p *InProcessInterface) Cost() int { return 0 } + +// CanReach reports whether dst has a handler registered in THIS process. +func (p *InProcessInterface) CanReach(dst Destination) bool { + p.mu.RLock() + _, ok := p.handlers[dst] + p.mu.RUnlock() + return ok +} + +// Deliver dispatches the live payload to the local handler. The sender identity +// is left empty for a same-process call (the caller is us); a handler that needs +// provenance reads it from the Payload.Value it defines. Returns the handler's +// reply Payload (nil-Value ⇒ none). +func (p *InProcessInterface) Deliver(ctx context.Context, dst Destination, pl Payload) (Payload, error) { + p.mu.RLock() + h, ok := p.handlers[dst] + p.mu.RUnlock() + if !ok { + // CanReach guards this; a lost race (handler unregistered between the + // two calls) is reported honestly rather than silently dropped. + return Payload{}, fmt.Errorf("zap: in-process destination %q not registered", dst) + } + return h(ctx, "", pl) +} + +// NodeInterface adapts the existing *Node (TCP/QUIC + conn_pq PQ session + mDNS +// discovery) to the Interface seam, WITHOUT changing Node. It is the network +// fallback: whenever a destination is not served in-process, Router routes here +// and the Node discovers/dials the peer and ships the ZAP wire Message. +// +// This is where the wire actually happens — and ONLY here. The Payload's live +// Value never crosses a socket; Deliver calls Payload.Encode() to materialize the +// zero-copy Message exactly once, at the moment a network hop is unavoidable. +// +// P1 scope: one-way delivery (Node.Send) — sufficient for telemetry and event +// fan-out, which is what folds first. Request/reply over the wire (Node.Call) and +// announce-driven multi-hop reachability are P2 refinements that slot in behind +// this same Interface without moving the Router.Send call site. +type NodeInterface struct { + node *Node + cost int + // connectedOnly restricts CanReach to peers with a live connection. Default + // (false) is optimistic: the interface is the network catch-all and lets + // Node.Send discover+dial on demand, surfacing a real error if the peer is + // genuinely unreachable rather than silently declining the route. + connectedOnly bool +} + +// compile-time proof the interfaces satisfy the seam. +var ( + _ Interface = (*InProcessInterface)(nil) + _ Interface = (*NodeInterface)(nil) +) + +// DefaultNodeCost is the Cost of a LAN/cluster TCP hop — above in-process (0) and +// same-host IPC (1), below multi-hop routed (100+). +const DefaultNodeCost = 10 + +// NewNodeInterface wraps n as the network interface at DefaultNodeCost. +func NewNodeInterface(n *Node) *NodeInterface { + return &NodeInterface{node: n, cost: DefaultNodeCost} +} + +// WithCost overrides the interface cost (e.g. a metered/slow link ranks higher). +func (i *NodeInterface) WithCost(c int) *NodeInterface { i.cost = c; return i } + +// ConnectedOnly makes CanReach report true only for already-connected peers, +// turning the interface from an optimistic catch-all into a strict "route only +// where a session already exists" interface. Useful when a higher-cost interface +// should own first-contact. +func (i *NodeInterface) ConnectedOnly() *NodeInterface { i.connectedOnly = true; return i } + +// Name identifies this interface. +func (i *NodeInterface) Name() string { return "node-tcp" } + +// Cost ranks this interface (default DefaultNodeCost). +func (i *NodeInterface) Cost() int { return i.cost } + +// CanReach reports whether the Node can deliver to dst. Optimistic by default (the +// network catch-all); strict when ConnectedOnly is set. +func (i *NodeInterface) CanReach(dst Destination) bool { + if i.node == nil { + return false + } + if !i.connectedOnly { + return true // catch-all: let Deliver discover+dial and error honestly + } + for _, p := range i.node.Peers() { + if p == string(dst) { + return true + } + } + return false +} + +// ErrNotEncodable is returned when a network interface is asked to deliver a +// payload that carries no wire form (Encode == nil) — an in-process-only value +// that must not silently cross a socket. +var ErrNotEncodable = errors.New("zap: payload has no wire encoding (in-process only)") + +// Deliver ships the payload to dst (peer ID) over the Node's ZAP wire. It +// materializes the wire Message lazily — the encode cost is paid here and nowhere +// else — then hands it to Node.Send. A nil Encode is a hard error, never a silent +// drop: an in-process-only payload reaching the wire is a routing bug. +func (i *NodeInterface) Deliver(ctx context.Context, dst Destination, p Payload) (Payload, error) { + if p.Encode == nil { + return Payload{}, ErrNotEncodable + } + if err := i.node.Send(ctx, string(dst), p.Encode()); err != nil { + return Payload{}, err + } + return Payload{}, nil // one-way delivery; no reply in P1 +} diff --git a/vendor/github.com/luxfi/zap/node.go b/vendor/github.com/luxfi/zap/node.go index c35a3203e..56a772612 100644 --- a/vendor/github.com/luxfi/zap/node.go +++ b/vendor/github.com/luxfi/zap/node.go @@ -12,6 +12,7 @@ import ( "io" "log/slog" "net" + "runtime/debug" "sync" "time" @@ -36,13 +37,11 @@ type Node struct { discovery *mdns.Discovery // Network - listener net.Listener - transports map[string]TransportConn // peerID -> transport conn (QUIC path) - transClose func() error // closer for the QUIC listener - reqIDQuic uint32 // QUIC-path request-ID counter - reqIDQuicMu sync.Mutex - conns map[string]*Conn - connsMu sync.RWMutex + listener net.Listener + transports map[string]TransportConn // peerID -> transport conn (QUIC path) + transClose func() error // closer for the QUIC listener + conns map[string]*Conn + connsMu sync.RWMutex // Handlers handlers map[uint16]Handler @@ -145,9 +144,18 @@ func (n *Node) Start() error { n.discovery.OnPeer(n.handlePeerEvent) + // mDNS advertise/browse is BEST-EFFORT. It lets peers find each + // other zero-config on a LAN, but it is not required for service: + // the node is already accepting on its listener, and in-cluster + // peers reach it by address (Service DNS at the fixed port). On + // networks without multicast (most Kubernetes pod overlays, + // restricted hosts) discovery fails to start — the node MUST keep + // serving regardless. Log and continue rather than tearing down + // the listener. if err := n.discovery.Start(); err != nil { - n.listener.Close() - return fmt.Errorf("failed to start discovery: %w", err) + n.logger.Warn("ZAP mDNS discovery unavailable; serving without it (peers reach this node by address)", + "nodeID", n.nodeID, "service", n.serviceType, "err", err) + n.discovery = nil } } @@ -254,9 +262,11 @@ func (n *Node) Call(ctx context.Context, peerID string, msg *Message) (*Message, conn.pendMu.Unlock() }() - // Send wrapped request (one canonical encoder via WrapCorrelated). + // Send wrapped request via writeCorrelated — scatter-gather + // (header + body) so the body slice is never copied on the hot + // Call path. conn.mu.Lock() - err = writeMessage(conn.conn, WrapCorrelated(reqID, ReqFlagReq, msg.Bytes())) + err = writeCorrelated(conn.conn, reqID, ReqFlagReq, msg.Bytes()) conn.mu.Unlock() if err != nil { return nil, err @@ -409,6 +419,19 @@ func (n *Node) handleConn(netConn net.Conn) { // Returns when the underlying conn errors (non-timeout) or ctx is // cancelled. The caller is responsible for the per-connection // cleanup (conns-map delete, log). +// +// Buffer lifecycle (post pool-aware read path): +// - Each iteration pulls one frame into a pooled *bufRef. The frame +// payload is sliced (no copy) into the Message returned by Parse. +// - For uncorrelated frames and Call requests (ReqFlagReq), the +// Message is consumed inside the iteration — handler runs, response +// is written, and the bufRef is released before the next read. +// - For Call responses (ReqFlagResp), the Message is handed off to a +// channel the Call goroutine awaits. We Retain the ref before the +// send and the receiver Releases when it consumes the response. +// +// The result is two allocations saved per dispatch: the body slab and +// the bufRef header (both pooled). func (n *Node) dispatchLoop(netConn net.Conn, conn *Conn, peerID string) { for { select { @@ -418,7 +441,7 @@ func (n *Node) dispatchLoop(netConn net.Conn, conn *Conn, peerID string) { } netConn.SetReadDeadline(time.Now().Add(1 * time.Second)) - data, err := readMessageRaw(netConn) + ref, err := readMessageRawPooled(netConn) if err != nil { if errors.Is(err, io.EOF) { return @@ -429,23 +452,39 @@ func (n *Node) dispatchLoop(netConn net.Conn, conn *Conn, peerID string) { n.logger.Debug("Read error", "peerID", peerID, "error", err) return } + data := ref.Bytes() if reqID, flag, body, isCall := UnwrapCorrelated(data); isCall { switch flag { case ReqFlagResp: if msg, err := Parse(body); err == nil { + // Hand the slab off to the awaiting Call goroutine. + // Retain holds the refcount across the channel; the + // receiver Releases on consumption. If nobody is + // listening we Release here to avoid leaking. + attachToMessage(msg, ref) + ref.retain() // matched by msg.Release() at Call site conn.pendMu.Lock() - if ch, ok := conn.pending[reqID]; ok { + ch, ok := conn.pending[reqID] + if ok { select { case ch <- msg: default: + ok = false // delivery failed } } conn.pendMu.Unlock() + if !ok { + msg.Release() // drop the retain we just took + } } + // Drop our local hold; the retain above keeps the slab + // alive for the channel consumer. + ref.release() case ReqFlagReq: msg, err := Parse(body) if err != nil { + ref.release() continue } msgType := msg.Flags() >> 8 @@ -453,22 +492,28 @@ func (n *Node) dispatchLoop(netConn net.Conn, conn *Conn, peerID string) { handler, ok := n.handlers[msgType] n.handlersMu.RUnlock() if !ok { + ref.release() continue } - resp, herr := handler(n.ctx, peerID, msg) + resp, herr := n.safeHandle(handler, peerID, msgType, msg) if herr != nil { n.logger.Error("Handler error", "peerID", peerID, "msgType", msgType, "error", herr) + ref.release() continue } if resp != nil { conn.mu.Lock() - writeErr := writeMessage(netConn, WrapCorrelated(reqID, ReqFlagResp, resp.Bytes())) + writeErr := writeCorrelated(netConn, reqID, ReqFlagResp, resp.Bytes()) conn.mu.Unlock() if writeErr != nil { n.logger.Debug("Write error", "peerID", peerID, "error", writeErr) + ref.release() return } } + ref.release() + default: + ref.release() } continue } @@ -476,6 +521,7 @@ func (n *Node) dispatchLoop(netConn net.Conn, conn *Conn, peerID string) { // Uncorrelated message — direct handler dispatch. msg, err := Parse(data) if err != nil { + ref.release() continue } msgType := msg.Flags() >> 8 @@ -483,11 +529,13 @@ func (n *Node) dispatchLoop(netConn net.Conn, conn *Conn, peerID string) { handler, ok := n.handlers[msgType] n.handlersMu.RUnlock() if !ok { + ref.release() continue } - resp, herr := handler(n.ctx, peerID, msg) + resp, herr := n.safeHandle(handler, peerID, msgType, msg) if herr != nil { n.logger.Error("Handler error", "peerID", peerID, "msgType", msgType, "error", herr) + ref.release() continue } if resp != nil { @@ -496,9 +544,11 @@ func (n *Node) dispatchLoop(netConn net.Conn, conn *Conn, peerID string) { conn.mu.Unlock() if writeErr != nil { n.logger.Debug("Write error", "peerID", peerID, "error", writeErr) + ref.release() return } } + ref.release() } } @@ -623,15 +673,19 @@ func (n *Node) getOrConnect(peerID string) (*Conn, error) { default: } - // Set read deadline so we can check for context cancellation + // Set read deadline so we can check for context cancellation. + // Buffer lifecycle mirrors dispatchLoop: response frames hand + // off the slab to the awaiting Call goroutine via Retain; + // everything else releases at end of iteration. netConn.SetReadDeadline(time.Now().Add(1 * time.Second)) - data, err := readMessageRaw(netConn) + ref, err := readMessageRawPooled(netConn) if err != nil { if netErr, ok := err.(net.Error); ok && netErr.Timeout() { continue } return } + data := ref.Bytes() // Check if this is a Call response (has 8-byte header with response flag) if len(data) >= 8 { @@ -641,15 +695,23 @@ func (n *Node) getOrConnect(peerID string) (*Conn, error) { reqID := binary.LittleEndian.Uint32(data[0:4]) msg, err := Parse(data[8:]) if err == nil { + attachToMessage(msg, ref) + ref.retain() // matched by msg.Release() at Call site conn.pendMu.Lock() - if ch, ok := conn.pending[reqID]; ok { + ch, ok := conn.pending[reqID] + if ok { select { case ch <- msg: default: + ok = false } } conn.pendMu.Unlock() + if !ok { + msg.Release() + } } + ref.release() continue } } @@ -657,6 +719,7 @@ func (n *Node) getOrConnect(peerID string) (*Conn, error) { // Regular message - use standard handler msg, err := Parse(data) if err != nil { + ref.release() continue } @@ -666,22 +729,40 @@ func (n *Node) getOrConnect(peerID string) (*Conn, error) { n.handlersMu.RUnlock() if ok { - handler(n.ctx, peerID, msg) + // Guarded: a handler panic here must not kill this receive + // goroutine / the node. The error return is intentionally + // dropped — this is the fire-and-forget receive path for an + // outbound-dialed peer; safeHandle has already logged. + _, _ = n.safeHandle(handler, peerID, msgType, msg) } + ref.release() } }() return conn, nil } -// ConnectDirect connects directly to a peer at the given address (bypasses mDNS). +// ConnectDirect connects directly to a peer at the given address +// (bypasses mDNS). Use ConnectDirectID when you need the handshake- +// learned peer NodeID back — e.g. to address subsequent Calls to a +// static peer whose advertised NodeID is only a placeholder. func (n *Node) ConnectDirect(addr string) error { + _, err := n.ConnectDirectID(addr) + return err +} + +// ConnectDirectID dials addr, performs the NodeID handshake, registers +// the connection, and returns the peer's learned NodeID. Idempotent: if +// a connection to that peer already exists it returns the existing +// peer's NodeID and drops the duplicate dial. (TCP transport; the QUIC +// path registers the peer internally and returns an empty id.) +func (n *Node) ConnectDirectID(addr string) (string, error) { if n.transport == TransportQUIC { - return n.quicConnectDirect(n.ctx, addr) + return "", n.quicConnectDirect(n.ctx, addr) } netConn, err := net.DialTimeout("tcp", addr, 5*time.Second) if err != nil { - return fmt.Errorf("failed to connect to %s: %w", addr, err) + return "", fmt.Errorf("failed to connect to %s: %w", addr, err) } if n.tlsCfg != nil { netConn = tls.Client(netConn, n.tlsCfg) @@ -690,19 +771,19 @@ func (n *Node) ConnectDirect(addr string) error { // Send handshake. if err := writeMessage(netConn, EncodeNodeIDHandshake(n.nodeID)); err != nil { netConn.Close() - return err + return "", err } // Read handshake response. data, err := readMessageRaw(netConn) if err != nil { netConn.Close() - return err + return "", err } peerID, ok := DecodeNodeIDHandshake(data) if !ok { netConn.Close() - return fmt.Errorf("invalid peer handshake") + return "", fmt.Errorf("invalid peer handshake") } conn := &Conn{ @@ -717,7 +798,7 @@ func (n *Node) ConnectDirect(addr string) error { if _, ok := n.conns[peerID]; ok { n.connsMu.Unlock() netConn.Close() - return nil // Already connected, that's fine + return peerID, nil // Already connected, that's fine } n.conns[peerID] = conn n.connsMu.Unlock() @@ -741,7 +822,7 @@ func (n *Node) ConnectDirect(addr string) error { n.dispatchLoop(netConn, conn, peerID) }() - return nil + return peerID, nil } // Send sends a message over the connection. @@ -758,11 +839,23 @@ func (c *Conn) Recv() (*Message, error) { return readMessage(c.conn) } -// Wire format: [4 bytes length][message bytes] +// Wire format: [4 bytes length][message bytes]. +// +// writeMessage emits the frame using a single (*net.Buffers).WriteTo when +// w is a *net.TCPConn — that's one writev(2) syscall instead of two Write +// calls, and the body slice is referenced rather than copied. For other +// writers (TLS, pipes, tests) the path falls back to two sequential writes, +// which is correctness-equivalent. func writeMessage(w io.Writer, data []byte) error { var lenBuf [4]byte binary.LittleEndian.PutUint32(lenBuf[:], uint32(len(data))) + if tc, ok := w.(*net.TCPConn); ok { + bufs := net.Buffers{lenBuf[:], data} + _, err := bufs.WriteTo(tc) + return err + } + if _, err := w.Write(lenBuf[:]); err != nil { return err } @@ -770,6 +863,36 @@ func writeMessage(w io.Writer, data []byte) error { return err } +// writeCorrelated emits a Call request/response frame without copying +// the body buffer. Equivalent to writeMessage(w, WrapCorrelated(...)) but +// the 8-byte correlation header is sent as a separate IO vector — for +// TCPConn this is a single writev(2), for other writers it's three +// sequential writes (still no body copy). This replaces the per-Call +// allocation + copy WrapCorrelated() performs. +// +// reqID and flag are LE uint32 (matches WrapCorrelated wire layout). +func writeCorrelated(w io.Writer, reqID uint32, flag uint32, body []byte) error { + var hdr [12]byte + binary.LittleEndian.PutUint32(hdr[0:4], uint32(correlatedHeaderSize+len(body))) + binary.LittleEndian.PutUint32(hdr[4:8], reqID) + binary.LittleEndian.PutUint32(hdr[8:12], flag) + + if tc, ok := w.(*net.TCPConn); ok { + bufs := net.Buffers{hdr[:], body} + _, err := bufs.WriteTo(tc) + return err + } + + if _, err := w.Write(hdr[:]); err != nil { + return err + } + if len(body) == 0 { + return nil + } + _, err := w.Write(body) + return err +} + func readMessage(r io.Reader) (*Message, error) { data, err := readMessageRaw(r) if err != nil { @@ -796,3 +919,72 @@ func readMessageRaw(r io.Reader) ([]byte, error) { return data, nil } + +// readMessageRawPooled is the pool-aware variant of readMessageRaw. +// +// It reads one length-prefixed ZAP frame from r and returns a *bufRef +// whose Bytes() slice is the payload. The slab is sourced from a +// quantized sync.Pool — see bufpool.go for the size classes. Frames +// larger than the largest pool class fall back to a one-off heap +// allocation, transparent to the caller. +// +// Caller MUST eventually release() the *bufRef (directly, or by +// transferring ownership to a *Message via attachToMessage and then +// calling Message.Release()). Failure to release leaks the slab into +// sync.Pool's GC reclaim cycle — correct but defeats the pool. +// +// Wire format is byte-identical to readMessageRaw. The only difference +// is the buffer's lifecycle. +func readMessageRawPooled(r io.Reader) (*bufRef, error) { + var lenBuf [4]byte + if _, err := io.ReadFull(r, lenBuf[:]); err != nil { + return nil, err + } + + length := binary.LittleEndian.Uint32(lenBuf[:]) + if length > 10*1024*1024 { // 10MB max + return nil, errors.New("message too large") + } + + ref := getBuf(int(length)) + if _, err := io.ReadFull(r, ref.rawBuf()[:length]); err != nil { + ref.release() + return nil, err + } + return ref, nil +} + +// attachToMessage stamps the *bufRef onto a *Message so that +// Message.Release() returns the slab to the pool. Used by dispatch +// loops that build a Message from a pooled buffer they're handing +// off to a response channel. +func attachToMessage(m *Message, ref *bufRef) { + if m != nil { + m.refs = ref + } +} + +// safeHandle invokes a registered handler with a recover() guard. A handler +// is application code (e.g. forward.Serve's HTTP bridge) reachable directly +// from attacker-controlled bytes on the wire; a panic inside it — out-of- +// range index on a malformed envelope, a nil deref, a third-party library +// fault — must NEVER unwind into the per-connection dispatch goroutine and +// crash the whole node/process. On panic we log with the peer and message +// type and return an error so the dispatch loop drops that one connection; +// every other connection and the node itself survive. +// +// This is the single recover boundary for ALL handler dispatch in this +// node (correlated Call requests and uncorrelated messages alike). It is +// the one-and-only place a handler panic is contained. +func (n *Node) safeHandle(handler Handler, peerID string, msgType uint16, msg *Message) (resp *Message, err error) { + defer func() { + if r := recover(); r != nil { + n.logger.Error("ZAP handler panic recovered", + "peerID", peerID, "msgType", msgType, "panic", r, + "stack", string(debug.Stack())) + resp = nil + err = fmt.Errorf("handler panic (msgType=%d): %v", msgType, r) + } + }() + return handler(n.ctx, peerID, msg) +} diff --git a/vendor/github.com/luxfi/zap/node_codec.go b/vendor/github.com/luxfi/zap/node_codec.go index 719a8c644..7698d1478 100644 --- a/vendor/github.com/luxfi/zap/node_codec.go +++ b/vendor/github.com/luxfi/zap/node_codec.go @@ -101,3 +101,19 @@ func UnwrapCorrelated(data []byte) (reqID uint32, flag uint32, body []byte, ok b } return reqID, flag, data[correlatedHeaderSize:], true } + +// makeCorrelatedFrame builds a single-slice correlation frame +// (header + body) for transports that take []byte (notably the QUIC +// TransportConn.Send shape). TCP callers should prefer writeCorrelated +// which avoids the body copy entirely via scatter-gather. +// +// One allocation per call. A pooled variant requires the transport +// interface to expose a "buffer consumed" callback so the slab can +// be returned safely; that's a cross-module change and is deferred. +func makeCorrelatedFrame(reqID uint32, flag uint32, body []byte) []byte { + buf := make([]byte, correlatedHeaderSize+len(body)) + binary.LittleEndian.PutUint32(buf[0:4], reqID) + binary.LittleEndian.PutUint32(buf[4:8], flag) + copy(buf[correlatedHeaderSize:], body) + return buf +} diff --git a/vendor/github.com/luxfi/zap/node_quic.go b/vendor/github.com/luxfi/zap/node_quic.go index fbceddf68..36d346f8c 100644 --- a/vendor/github.com/luxfi/zap/node_quic.go +++ b/vendor/github.com/luxfi/zap/node_quic.go @@ -5,12 +5,10 @@ package zap import ( "context" - "encoding/binary" "errors" "fmt" "io" "net" - "sync" "time" "github.com/luxfi/mdns" @@ -91,8 +89,22 @@ func (n *Node) onAcceptedTransportConn(peerID string, tc TransportConn) { go n.serveTransportConn(peerID, tc) } -// serveTransportConn is the QUIC equivalent of handleConn — it -// drives the read loop and dispatches incoming frames to handlers. +// serveTransportConn drives the read loops on a QUIC peer connection. +// +// Two parallel read loops run on each connection: +// +// 1. Control-stream loop (tc.Recv): handles one-way Sends only. +// 2. Per-Call stream accept loop (AcceptCallStream): handles every +// Call. Each accepted stream carries exactly one request + one +// response, so the dispatch goroutine reads, handles, writes, +// and closes the stream in one shot. +// +// The two loops are independent: each runs in its own goroutine, and +// both terminate when the connection closes or n.ctx is cancelled. +// +// The QUIC transport always implements TransportStreamer; if a +// connection somehow lacks it we close it — the per-stream Call path +// is the only Call path. func (n *Node) serveTransportConn(peerID string, tc TransportConn) { defer n.wg.Done() defer func() { @@ -105,6 +117,14 @@ func (n *Node) serveTransportConn(peerID string, tc TransportConn) { n.logger.Info("Peer disconnected (QUIC)", "peerID", peerID) }() + streamer, ok := tc.(TransportStreamer) + if !ok { + n.logger.Error("QUIC TransportConn missing TransportStreamer", "peerID", peerID) + return + } + n.wg.Add(1) + go n.acceptCallStreams(peerID, streamer) + for { select { case <-n.ctx.Done(): @@ -123,41 +143,81 @@ func (n *Node) serveTransportConn(peerID string, tc TransportConn) { n.logger.Debug("QUIC Recv error", "peerID", peerID, "error", err) return } - n.dispatchFrame(peerID, data, tc) + // Control stream carries one-way Sends only. Calls ride + // per-Call streams. + msg, err := Parse(data) + if err != nil { + continue + } + n.invokeHandlerOneWay(peerID, msg) } } -// dispatchFrame routes a single ZAP frame to either the pending-Call -// channel (if it has a response correlation header) or to the -// registered handler. Mirrors the TCP path in node.go's handleConn. -func (n *Node) dispatchFrame(peerID string, data []byte, tc TransportConn) { - if len(data) >= 8 { - reqFlag := binary.LittleEndian.Uint32(data[4:8]) - if reqFlag == ReqFlagResp { - reqID := binary.LittleEndian.Uint32(data[0:4]) - msg, err := Parse(data[8:]) - if err == nil { - n.routeQUICResponse(peerID, reqID, msg) - } +// acceptCallStreams runs in its own goroutine for each QUIC peer and +// processes inbound per-Call streams. Each stream gets its own handler +// goroutine so multiple in-flight Calls from the same peer execute +// concurrently — the headline parallelism win. +// +// Termination: AcceptCallStream returns a non-nil err when the +// connection is torn down. The loop exits without logging — the +// peer-disconnected line is already emitted by serveTransportConn's +// deferred close. +func (n *Node) acceptCallStreams(peerID string, s TransportStreamer) { + defer n.wg.Done() + for { + select { + case <-n.ctx.Done(): return + default: } - if reqFlag == ReqFlagReq { - reqID := binary.LittleEndian.Uint32(data[0:4]) - msg, err := Parse(data[8:]) - if err != nil { - return - } - n.handleQUICRequest(peerID, tc, reqID, msg) + stream, err := s.AcceptCallStream(n.ctx) + if err != nil { return } + n.wg.Add(1) + go n.handleCallStream(peerID, stream) } +} - // Regular one-way message. - msg, err := Parse(data) +// handleCallStream serves exactly one inbound per-Call stream: +// read one frame as the request, run the registered handler, and +// write the response back on the same stream. The stream is closed +// when this function returns. +func (n *Node) handleCallStream(peerID string, stream TransportStream) { + defer n.wg.Done() + defer stream.Close() + + reqBytes, err := stream.ReadFrame() if err != nil { return } - n.invokeHandlerOneWay(peerID, msg) + msg, err := Parse(reqBytes) + if err != nil { + return + } + + msgType := msg.Flags() >> 8 + n.handlersMu.RLock() + handler, ok := n.handlers[msgType] + n.handlersMu.RUnlock() + if !ok { + return + } + + // Guarded: a handler panic on the QUIC per-Call stream must not crash + // the node any more than on the TCP path. safeHandle recovers, logs, + // and converts the panic to an error; the stream is then closed. + resp, herr := n.safeHandle(handler, peerID, msgType, msg) + if herr != nil { + n.logger.Error("Handler error (stream)", "peerID", peerID, "msgType", msgType, "error", herr) + return + } + if resp == nil { + return + } + if err := stream.WriteFrame(resp.Bytes()); err != nil { + n.logger.Debug("QUIC stream write error", "peerID", peerID, "error", err) + } } // invokeHandlerOneWay runs the registered handler and discards the @@ -170,96 +230,77 @@ func (n *Node) invokeHandlerOneWay(peerID string, msg *Message) { if !ok { return } - _, _ = handler(n.ctx, peerID, msg) -} - -// handleQUICRequest dispatches a Call request and writes back the -// correlation-tagged response on the same transport conn. -func (n *Node) handleQUICRequest(peerID string, tc TransportConn, reqID uint32, msg *Message) { - msgType := msg.Flags() >> 8 - n.handlersMu.RLock() - handler, ok := n.handlers[msgType] - n.handlersMu.RUnlock() - if !ok { - return - } - resp, err := handler(n.ctx, peerID, msg) - if err != nil { - n.logger.Error("Handler error", "peerID", peerID, "msgType", msgType, "error", err) - return - } - if resp == nil { - return - } - respBytes := resp.Bytes() - wrapped := make([]byte, len(respBytes)+8) - binary.LittleEndian.PutUint32(wrapped[0:4], reqID) - binary.LittleEndian.PutUint32(wrapped[4:8], ReqFlagResp) - copy(wrapped[8:], respBytes) - if err := tc.Send(wrapped); err != nil { - n.logger.Debug("QUIC Send error", "peerID", peerID, "error", err) - } -} - -// quicPendingMu / quicPending hold the per-peer pending Call response -// channels for the QUIC transport. We keep them on the Node (not on -// each TransportConn) because TransportConn is an interface and we -// don't want to require implementors to carry the pending map. -var ( - quicPendingMu sync.Mutex - quicPending = map[string]map[uint32]chan *Message{} -) - -func (n *Node) routeQUICResponse(peerID string, reqID uint32, msg *Message) { - quicPendingMu.Lock() - defer quicPendingMu.Unlock() - if peerMap, ok := quicPending[n.nodeID+":"+peerID]; ok { - if ch, ok := peerMap[reqID]; ok { - select { - case ch <- msg: - default: - } - } - } + // Guarded: same recover boundary as every other dispatch path so a + // panicking one-way handler cannot kill the node. + _, _ = n.safeHandle(handler, peerID, msgType, msg) } // quicCall is the QUIC path for Node.Call. +// +// Every Call gets its own fresh bidirectional QUIC stream. The +// request goes out on the new stream, the response comes back on the +// same stream, and the stream is torn down. Concurrent Calls run in +// parallel up to the peer-advertised stream limit (1024 for ZAP's +// QUIC config) — no shared write mutex, no correlation header. +// +// QUIC's TransportConn always implements TransportStreamer; if it +// somehow does not, that is a programmer error and we surface it. func (n *Node) quicCall(ctx context.Context, peerID string, msg *Message) (*Message, error) { tc, err := n.getOrConnectQUIC(ctx, peerID) if err != nil { return nil, err } - - reqID := nextReqID(n) - - respCh := make(chan *Message, 1) - key := n.nodeID + ":" + peerID - quicPendingMu.Lock() - if quicPending[key] == nil { - quicPending[key] = make(map[uint32]chan *Message) + streamer, ok := tc.(TransportStreamer) + if !ok { + return nil, fmt.Errorf("zap: QUIC TransportConn for %s missing TransportStreamer", peerID) } - quicPending[key][reqID] = respCh - quicPendingMu.Unlock() + return n.quicCallStream(ctx, streamer, msg) +} - defer func() { - quicPendingMu.Lock() - delete(quicPending[key], reqID) - quicPendingMu.Unlock() - }() +// quicCallStream runs one Call on a fresh per-Call QUIC stream. +// +// The stream lifecycle is: +// 1. OpenCallStream — server peer's AcceptCallStream wakes. +// 2. WriteFrame(req) — single length-prefixed ZAP frame. +// 3. ReadFrame() — single length-prefixed ZAP frame (response). +// 4. Close — stream ID returns to the QUIC pool. +// +// No correlation header is needed on the wire: each stream carries +// exactly one request + one response. The response payload is the raw +// ZAP frame; we Parse it directly. +// +// Each stream gets cancelled if ctx fires before the response +// arrives; the QUIC layer will surface ErrStreamCanceled into +// ReadFrame so the goroutine exits cleanly. +func (n *Node) quicCallStream(ctx context.Context, s TransportStreamer, msg *Message) (*Message, error) { + stream, err := s.OpenCallStream(ctx) + if err != nil { + return nil, err + } + defer stream.Close() - orig := msg.Bytes() - wrapped := make([]byte, len(orig)+8) - binary.LittleEndian.PutUint32(wrapped[0:4], reqID) - binary.LittleEndian.PutUint32(wrapped[4:8], ReqFlagReq) - copy(wrapped[8:], orig) - - if err := tc.Send(wrapped); err != nil { + if err := stream.WriteFrame(msg.Bytes()); err != nil { return nil, err } + // Read response on this stream. The QUIC layer respects the + // stream's own deadline; we set one from ctx so a cancelled + // context tears the read down. + type result struct { + resp []byte + err error + } + out := make(chan result, 1) + go func() { + resp, err := stream.ReadFrame() + out <- result{resp, err} + }() select { - case resp := <-respCh: - return resp, nil + case r := <-out: + if r.err != nil { + return nil, r.err + } + return Parse(r.resp) case <-ctx.Done(): return nil, ctx.Err() } @@ -343,14 +384,3 @@ func (n *Node) getOrConnectQUIC(ctx context.Context, peerID string) (TransportCo go n.serveTransportConn(peerID, newTC) return newTC, nil } - -// nextReqID returns the next request ID for a QUIC peer. We piggy- -// back on the existing Conn.reqID counter pattern but use a per-node -// global because the TransportConn interface is opaque about its own -// state. Atomicity is provided by the Node struct's reqIDMu. -func nextReqID(n *Node) uint32 { - n.reqIDQuicMu.Lock() - defer n.reqIDQuicMu.Unlock() - n.reqIDQuic++ - return n.reqIDQuic -} diff --git a/vendor/github.com/luxfi/zap/router.go b/vendor/github.com/luxfi/zap/router.go new file mode 100644 index 000000000..4a8024b84 --- /dev/null +++ b/vendor/github.com/luxfi/zap/router.go @@ -0,0 +1,128 @@ +// Copyright (C) 2026, Lux Industries Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package zap + +import ( + "context" + "errors" + "sort" + "sync" +) + +// Router is ZAP's locality-adaptive router: ONE Send API over many interfaces. +// +// The complected thing in classic RPC is `Send(host:port, msg)` — WHO you are +// talking to, HOW the bytes travel, and WHERE the peer lives are braided into a +// single address. Router pulls them apart (Reticulum's model, made +// post-quantum and zero-copy): +// +// - Destination — WHO/WHAT (a capability aspect, later a PQ-identity hash). +// - Interface — HOW one hop travels (in-process memory, TCP, UDP, radio…). +// - Payload — the message, dual-form so each medium pays only for itself. +// - Router — routes: the cheapest Interface that can currently reach dst. +// +// "If in-process, skip TCP; else use the network" is therefore NOT a branch any +// caller writes — it is the Cost table (InProcess 0 < UDS 1 < TCP 10 < routed +// 100+). A caller only ever says: +// +// router.Send(ctx, dst, payload) +// +// and never names a port or a transport again. Router is distinct from the +// wire-level Transport enum (TransportTCP/TransportQUIC), which selects HOW one +// Node's socket speaks; a NodeInterface adapts such a Node into this router. +type Router struct { + mu sync.RWMutex + ifaces []Interface // kept sorted ascending by Cost() +} + +// Destination names WHO/WHAT a message is for, decoupled from HOW it is reached. +// In P1 it is a dotted capability aspect ("hanzo.o11y.traces"); the announce- +// routed PQ-identity destination hash (multi-hop) refines this in the transport +// HIP WITHOUT changing this call site — that is the whole point of the seam. +type Destination string + +// Payload is the value a Router delivers. It is deliberately dual-form so the +// interface the router picks pays only for what that medium needs: +// +// - Value is the LIVE native value. The in-process interface hands it to the +// local handler by pointer — zero serialization, zero copy, zero TCP. This +// is the "skip the wire entirely when we share an address space" fast path. +// - Encode lazily produces the zero-copy wire Message; a NETWORK interface +// calls it (and only then, so an in-process delivery never encodes). A nil +// Encode means the payload is in-process-only and cannot cross a wire. +type Payload struct { + Value any + Encode func() *Message +} + +// LocalHandler consumes a Payload delivered IN-PROCESS. It receives the live +// Value (type-assert to the concrete type the aspect defines) and may return a +// reply Payload (nil Value ⇒ no reply). This is the handler an InProcessInterface +// dispatches to — distinct from Node's wire Handler, which decodes bytes first. +type LocalHandler func(ctx context.Context, from Destination, p Payload) (Payload, error) + +// Interface moves a Payload one hop toward a Destination over a single medium. +// Interfaces are ranked by Cost; Router always prefers the cheapest one that +// can currently reach the destination. Implementations are the ONLY place a +// transport detail (a socket, a serial line, a memory handoff) lives. +type Interface interface { + // Name identifies the interface for logs/metrics ("inprocess", "node-tcp"). + Name() string + // Cost ranks interfaces; lower is preferred. Convention: in-process 0, + // same-host IPC 1, LAN/cluster TCP 10, multi-hop routed 100+. + Cost() int + // CanReach reports whether this interface can deliver to dst RIGHT NOW + // (destination registered locally, peer connected/discovered, path known). + CanReach(dst Destination) bool + // Deliver hands the payload to dst over this medium and returns an optional + // reply (nil-Value Payload ⇒ none). It must not be called unless CanReach. + Deliver(ctx context.Context, dst Destination, p Payload) (Payload, error) +} + +// ErrNoRoute is returned when no registered interface can reach the destination. +var ErrNoRoute = errors.New("zap: no interface can reach destination") + +// NewRouter returns an empty Router. Register interfaces onto it; the cheapest +// reachable one wins per Send. A Router with no interfaces routes nothing (Send +// returns ErrNoRoute) — safe, never panics. +func NewRouter() *Router { return &Router{} } + +// Register adds an interface, keeping the set sorted ascending by Cost so Send is +// a linear scan that stops at the first (cheapest) interface that CanReach. Ties +// keep registration order (stable), so an earlier-registered interface of equal +// cost is preferred. +func (t *Router) Register(i Interface) { + t.mu.Lock() + defer t.mu.Unlock() + t.ifaces = append(t.ifaces, i) + sort.SliceStable(t.ifaces, func(a, b int) bool { + return t.ifaces[a].Cost() < t.ifaces[b].Cost() + }) +} + +// Interfaces returns a snapshot of the registered interfaces, cheapest first. +func (t *Router) Interfaces() []Interface { + t.mu.RLock() + defer t.mu.RUnlock() + out := make([]Interface, len(t.ifaces)) + copy(out, t.ifaces) + return out +} + +// Send routes payload to dst over the cheapest interface that can reach it. It is +// the whole public contract: the caller expresses intent (dst + payload) and the +// locality decision (memory vs. wire) is the router's, made from the live Cost/ +// CanReach table — never the caller's branch. Returns ErrNoRoute if nothing can +// currently reach dst. +func (t *Router) Send(ctx context.Context, dst Destination, p Payload) (Payload, error) { + t.mu.RLock() + ifaces := t.ifaces // slice header copy under lock; entries are immutable + t.mu.RUnlock() + for _, i := range ifaces { + if i.CanReach(dst) { + return i.Deliver(ctx, dst, p) + } + } + return Payload{}, ErrNoRoute +} diff --git a/vendor/github.com/luxfi/zap/transport.go b/vendor/github.com/luxfi/zap/transport.go index 01195907c..6fc8c134d 100644 --- a/vendor/github.com/luxfi/zap/transport.go +++ b/vendor/github.com/luxfi/zap/transport.go @@ -91,6 +91,43 @@ type TransportConn interface { RemoteAddr() string } +// TransportStreamer is an optional capability extension to +// TransportConn for transports that natively multiplex independent +// bidirectional streams (notably QUIC). When a TransportConn also +// implements TransportStreamer, Node.Call routes each request onto a +// fresh per-Call stream instead of serializing on the shared control +// stream — this lets concurrent Calls progress in parallel up to the +// peer-advertised stream limit (1024 for ZAP's QUIC config). +// +// TCP transport does NOT implement TransportStreamer; Node.Call +// transparently falls back to control-stream serialization on TCP. +type TransportStreamer interface { + // OpenCallStream opens a fresh bidirectional stream for a single + // request/response exchange. The caller writes exactly one frame + // (request) then reads exactly one frame (response) then closes. + OpenCallStream(ctx context.Context) (TransportStream, error) + + // AcceptCallStream blocks until the peer opens a per-Call stream. + // Used by the server-side dispatch loop to fan out to handlers + // without blocking on a single serialized read. + AcceptCallStream(ctx context.Context) (TransportStream, error) +} + +// TransportStream is one per-Call stream. Stream lifecycle: +// +// WriteFrame(req) // single request +// ReadFrame() // single response +// Close() // release stream ID back to the QUIC pool +// +// Both directions are length-prefixed ZAP frames identical to the +// control-stream wire format — so byte-for-byte interop with the +// TCP transport and with control-stream Call paths is preserved. +type TransportStream interface { + WriteFrame(frame []byte) error + ReadFrame() ([]byte, error) + Close() error +} + // transportRegistry holds the registered factories, keyed by // Transport. Read-only after init. var transportRegistry = map[Transport]TransportFactory{} diff --git a/vendor/github.com/luxfi/zap/zap.go b/vendor/github.com/luxfi/zap/zap.go index a22b9b6d2..cf42f375d 100644 --- a/vendor/github.com/luxfi/zap/zap.go +++ b/vendor/github.com/luxfi/zap/zap.go @@ -96,8 +96,15 @@ var ( ) // Message is a ZAP message that can be read zero-copy. +// +// When the message's backing storage was sourced from the pooled read +// buffer (see bufpool.go), refs is non-nil and Release returns the +// slab to its pool. For messages built via Builder.Finish() / Parse() +// of caller-owned bytes, refs is nil and Release is a no-op — those +// buffers are GC-managed as before. type Message struct { data []byte + refs *bufRef // optional pool handle; nil = GC-managed } // Parse parses a ZAP message from bytes without copying. @@ -143,11 +150,109 @@ func (m *Message) Version() uint16 { return binary.LittleEndian.Uint16(m.data[4:6]) } +// ParseHeader validates a ZAP wire frame and returns the (validated +// data slice, root offset) WITHOUT allocating a [*Message]. Same checks +// as [Parse] — magic, version, size — but the result is two values, not +// a pointer. Intended for generic wrappers (zapv1) that build their own +// value-typed accessors and never need a *Message. +// +// Returns (data[:size], rootOff, nil) on success. +// +// The wire validation steps mirror [Parse] exactly (magic + version + +// size + bounds). The implementation is intentionally written as one +// linear sequence (no intermediate function calls) so the inliner +// folds the whole body into the caller. Combined with the value- +// typed [zapv1.View], this is what makes the v2 read path match v1's +// 2 ns hand-rolled per-Read cost — zero function calls, zero heap. +func ParseHeader(data []byte) ([]byte, int, error) { + return parseHeaderImpl(data) +} + +// parseHeaderImpl is the actual validation body. Kept as a separate +// function so ParseHeader stays inlineable (delegates a single call) +// and per-schema WrapX shims can absorb the whole pipeline. The body +// itself is one cost unit over the inline budget — that's fine; it +// becomes ONE real function call per Wrap, comparable to v1's pattern +// where Parse runs inline and the only call is the implicit message +// constructor. +func parseHeaderImpl(data []byte) ([]byte, int, error) { + if len(data) < HeaderSize { + return nil, 0, ErrBufferTooSmall + } + if string(data[0:4]) != Magic { + return nil, 0, ErrInvalidMagic + } + version := binary.LittleEndian.Uint16(data[4:6]) + if version != Version1 && version != Version2 { + return nil, 0, ErrInvalidVersion + } + size := binary.LittleEndian.Uint32(data[12:16]) + if int(size) < HeaderSize || int(size) > len(data) { + return nil, 0, ErrBufferTooSmall + } + rootOff := int(binary.LittleEndian.Uint32(data[8:12])) + return data[:size], rootOff, nil +} + +// WrapBuffer constructs a [*Message] over an already-built ZAP buffer +// WITHOUT re-running [Parse]'s validation checks (magic, version, +// size bounds). Use ONLY for buffers you just emitted via [Builder] +// — they are valid by construction, and skipping the recheck is a +// 14ns hot-path saving per Build call. +// +// External / untrusted bytes MUST go through Parse, never WrapBuffer. +func WrapBuffer(data []byte) *Message { + return &Message{data: data} +} + +// RootObjectAt returns a [zap.Object] anchored at absolute offset +// `off` within this message. Used by zapv1.Build to avoid a redundant +// header-read after [Builder.FinishAsRoot] already returned the root +// position. +func (m *Message) RootObjectAt(off int) Object { + return Object{msg: m, offset: off} +} + // Bytes returns the underlying byte slice. func (m *Message) Bytes() []byte { return m.data } +// Release returns this message's backing slab to the read-buffer pool +// when the message was sourced via the pooled read path. Safe to call +// on any *Message — when the buffer is GC-managed (Builder, Parse of +// caller bytes) Release is a no-op. +// +// After Release the underlying bytes MAY be overwritten by the next +// pool consumer. Callers must not use Bytes() / Root() / accessors on +// a released message. +// +// Release on a nil receiver is a no-op so callers can defer it +// without nil-checking. +func (m *Message) Release() { + if m == nil { + return + } + r := m.refs + m.refs = nil + m.data = nil + r.release() +} + +// Retain increments the reference count on this message's backing +// slab, allowing the caller to hand the message off to a goroutine +// that will Release it later. No-op when refs is nil. +// +// Pair every Retain with exactly one Release. The dispatch loop calls +// Retain before pushing a response *Message onto a Call's response +// channel; the Call goroutine then Releases when it consumes the +// response. +func (m *Message) Retain() { + if m != nil && m.refs != nil { + m.refs.retain() + } +} + // Size returns the total message size. func (m *Message) Size() int { return len(m.data) @@ -175,6 +280,26 @@ func (o Object) IsNull() bool { return o.offset == 0 } +// Offset returns the object's absolute byte offset within its +// underlying message. Exposed so external generic wrappers (zapv1) +// can construct typed sub-views into the same buffer without +// re-walking the parent pointers. +// +// SAFETY: callers MUST treat the returned offset as opaque — it's +// load-bearing for unsafe-pointer arithmetic, so any out-of-range +// usage is the caller's responsibility. The matching message bytes +// are reachable via Message.Bytes() on this object's message. +func (o Object) Offset() int { + return o.offset +} + +// Message returns the underlying [*Message] this Object is a view +// into. Used by zapv1 to alias the message's bytes for direct +// payload indexing. +func (o Object) Message() *Message { + return o.msg +} + // Bool reads a bool at the given field offset. func (o Object) Bool(fieldOffset int) bool { return o.Uint8(fieldOffset) != 0 @@ -246,6 +371,28 @@ func (o Object) Float64(fieldOffset int) float64 { return math.Float64frombits(o.Uint64(fieldOffset)) } +// BytesFixedSlice returns a zero-copy slice of n inline bytes at +// fieldOffset within the object's fixed payload. This is the generic- +// width counterpart of HashSlice (32 bytes) and AddressSlice (20 +// bytes); it covers any N>0 inline byte-array slot (e.g., LP-201 +// SessionID [16]byte, LP-208 QuasarWitness [96]byte). +// +// Returns nil if the requested span falls outside the buffer. The +// returned slice aliases the underlying message data; the caller MUST +// NOT mutate it. +// +// This is the symmetric reader for ObjectBuilder.SetBytesFixed. +func (o Object) BytesFixedSlice(fieldOffset, n int) []byte { + if n <= 0 { + return nil + } + pos := o.offset + fieldOffset + if pos+n > len(o.msg.data) { + return nil + } + return o.msg.data[pos : pos+n] +} + // Text reads a string at the given field offset (zero-copy). func (o Object) Text(fieldOffset int) string { b := o.Bytes(fieldOffset) @@ -490,7 +637,8 @@ func (l List) Uint64(i int) uint64 { return binary.LittleEndian.Uint64(l.msg.data[pos:]) } -// Object returns an object list element. +// Object returns an INLINE object list element — element i is a fixed-stride +// object of elemSize bytes living at l.offset + i*elemSize. func (l List) Object(i int, elemSize int) Object { if i < 0 || i >= l.length { return Object{} @@ -498,6 +646,33 @@ func (l List) Object(i int, elemSize int) Object { return Object{msg: l.msg, offset: l.offset + i*elemSize} } +// ObjectPtr returns the i'th element of an OUT-OF-LINE object list — the read +// counterpart to [ListBuilder.AddObjectPtr]. Element i is a 4-byte SIGNED +// relative pointer at l.offset + i*4; it is dereferenced as absOffset = +// slotPos + int32(rel), exactly like [Object.Object]. A null (0) element or an +// out-of-range target yields the zero Object (IsNull). This is the canonical +// way to read a "repeated message" field where each element is a tailed object +// rather than a fixed-size inline value — the decomplected replacement for the +// byte-blob envelope-concat pattern. +func (l List) ObjectPtr(i int) Object { + if i < 0 || i >= l.length { + return Object{} + } + pos := l.offset + i*4 + if pos+4 > len(l.msg.data) { + return Object{} + } + rel := int32(binary.LittleEndian.Uint32(l.msg.data[pos:])) + if rel == 0 { + return Object{} // null element + } + absOffset := pos + int(rel) + if absOffset < HeaderSize || absOffset >= len(l.msg.data) { + return Object{} + } + return Object{msg: l.msg, offset: absOffset} +} + // Bytes returns the raw bytes of the list (for byte lists). func (l List) Bytes() []byte { if l.msg == nil || l.offset+l.length > len(l.msg.data) { diff --git a/vendor/github.com/tinylib/msgp/msgp/json.go b/vendor/github.com/tinylib/msgp/msgp/json.go index 896d690ba..49bd54bf1 100644 --- a/vendor/github.com/tinylib/msgp/msgp/json.go +++ b/vendor/github.com/tinylib/msgp/msgp/json.go @@ -131,11 +131,35 @@ func rwMap(dst jsWriter, src *Reader) (n int, err error) { n++ } - field, err = src.ReadMapKeyPtr() + var kt Type + kt, err = src.NextType() if err != nil { return } - nn, err = rwquoted(dst, field) + switch kt { + case IntType: + var i64 int64 + i64, err = src.ReadInt64() + if err != nil { + return + } + src.scratch = strconv.AppendInt(src.scratch[:0], i64, 10) + nn, err = rwquoted(dst, src.scratch) + case UintType: + var u64 uint64 + u64, err = src.ReadUint64() + if err != nil { + return + } + src.scratch = strconv.AppendUint(src.scratch[:0], u64, 10) + nn, err = rwquoted(dst, src.scratch) + default: + field, err = src.ReadMapKeyPtr() + if err != nil { + return + } + nn, err = rwquoted(dst, field) + } n += nn if err != nil { return diff --git a/vendor/github.com/tinylib/msgp/msgp/json_bytes.go b/vendor/github.com/tinylib/msgp/msgp/json_bytes.go index 7efd162f1..4aced1b16 100644 --- a/vendor/github.com/tinylib/msgp/msgp/json_bytes.go +++ b/vendor/github.com/tinylib/msgp/msgp/json_bytes.go @@ -144,6 +144,27 @@ func rwMapBytes(w jsWriter, msg []byte, scratch []byte, depth int) ([]byte, []by } func rwMapKeyBytes(w jsWriter, msg []byte, scratch []byte, depth int) ([]byte, []byte, error) { + if len(msg) < 1 { + return msg, scratch, ErrShortBytes + } + switch getType(msg[0]) { + case IntType: + i, msg, err := ReadInt64Bytes(msg) + if err != nil { + return msg, scratch, err + } + scratch = strconv.AppendInt(scratch[:0], i, 10) + _, err = rwquoted(w, scratch) + return msg, scratch, err + case UintType: + u, msg, err := ReadUint64Bytes(msg) + if err != nil { + return msg, scratch, err + } + scratch = strconv.AppendUint(scratch[:0], u, 10) + _, err = rwquoted(w, scratch) + return msg, scratch, err + } msg, scratch, err := rwStringBytes(w, msg, scratch, depth) if err != nil { if tperr, ok := err.(TypeError); ok && tperr.Encoded == BinType { diff --git a/vendor/github.com/tinylib/msgp/msgp/read.go b/vendor/github.com/tinylib/msgp/msgp/read.go index 9b7b7042f..b029e5740 100644 --- a/vendor/github.com/tinylib/msgp/msgp/read.go +++ b/vendor/github.com/tinylib/msgp/msgp/read.go @@ -121,6 +121,10 @@ func Decode(r io.Reader, d Decodable) error { // reader will be buffered. func NewReader(r io.Reader) *Reader { p := readerPool.Get().(*Reader) + p.recursionDepth = 0 + p.maxElements = 0 + p.maxRecursionDepth = 0 + p.maxStrLen = 0 if p.R == nil { p.R = fwd.NewReader(r) } else { diff --git a/vendor/go.opentelemetry.io/otel/.golangci.yml b/vendor/go.opentelemetry.io/otel/.golangci.yml index db1f55101..645c7e6af 100644 --- a/vendor/go.opentelemetry.io/otel/.golangci.yml +++ b/vendor/go.opentelemetry.io/otel/.golangci.yml @@ -96,9 +96,9 @@ linters: - "!**/exporters/zipkin/**" deny: - pkg: go.opentelemetry.io/otel/semconv - desc: "Use go.opentelemetry.io/otel/semconv/v1.40.0 instead. If a newer semconv version has been released, update the depguard rule." + desc: "Use go.opentelemetry.io/otel/semconv/v1.41.0 instead. If a newer semconv version has been released, update the depguard rule." allow: - - go.opentelemetry.io/otel/semconv/v1.40.0 + - go.opentelemetry.io/otel/semconv/v1.41.0 gocritic: disabled-checks: - appendAssign @@ -134,13 +134,16 @@ linters: strconcat: true revive: confidence: 0.01 + enable-all-rules: false + enable-default-rules: true + max-open-files: 2048 rules: - name: blank-imports - name: bool-literal-in-expr - name: constant-logical-expr - name: context-as-argument arguments: - - allowTypesBefore: '*testing.T' + - allow-types-before: '*testing.T' disabled: true - name: context-keys-type - name: deep-exit @@ -152,7 +155,7 @@ linters: - name: duplicated-imports - name: early-return arguments: - - preserveScope + - preserve-scope - name: empty-block - name: empty-lines - name: error-naming @@ -161,7 +164,7 @@ linters: - name: errorf - name: exported arguments: - - sayRepetitiveInsteadOfStutters + - say-repetitive-instead-of-stutters - name: flag-parameter - name: identical-branches - name: if-return @@ -169,11 +172,12 @@ linters: - name: increment-decrement - name: indent-error-flow arguments: - - preserveScope + - preserve-scope - name: package-comments - name: range - name: range-val-in-closure - name: range-val-address + - name: receiver-naming - name: redefines-builtin-id - name: string-format arguments: @@ -183,7 +187,7 @@ linters: - name: struct-tag - name: superfluous-else arguments: - - preserveScope + - preserve-scope - name: time-equal - name: unconditional-recursion - name: unexported-return diff --git a/vendor/go.opentelemetry.io/otel/AGENTS.md b/vendor/go.opentelemetry.io/otel/AGENTS.md new file mode 100644 index 000000000..26c0fc4dd --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/AGENTS.md @@ -0,0 +1,109 @@ +# Agent Guide for opentelemetry-go + +This file contains active, task-oriented instructions for autonomous and semi-autonomous coding agents working in this repository. + +Before starting any task, read `.github/copilot-instructions.md`, `CONTRIBUTING.md`, and this file. +Treat `.github/copilot-instructions.md` as global passive guidance for every task, including docs-only and review-only work. + +## Core expectations + +- Preserve OpenTelemetry specification compliance, API stability, and idiomatic Go. +- Prefer minimal, surgical changes over broad refactors or speculative cleanup. +- Read the package you are editing and match its existing naming, option types, error handling, comments, tests, and concurrency patterns. +- Keep public APIs backward compatible unless the task explicitly requires a breaking change. +- Keep telemetry resilient and loosely coupled. Do not introduce behavior that can unexpectedly interfere with host applications. +- Inspect boundaries carefully: input validation, resource limits, cancellation, shutdown, error propagation, concurrency, and memory growth. +- Prefer fail-safe behavior and explicit invariants over implicit assumptions. +- Keep dependencies minimal and justified. +- Preserve host-application safety: telemetry should not panic, block indefinitely, or amplify attacker-controlled input. +- Be conservative on hot paths. Avoid unnecessary allocations, reflection, interface churn, blocking, global state, and high-cardinality telemetry. +- Write comments only for intent, invariants, and non-obvious constraints. Do not add comments that restate the code. + +## Default workflow + +For new features and behavior changes, use this order unless the task explicitly says otherwise: + +1. Read the relevant package, its tests, and any package docs or `README.md`. +2. Add or update a failing unit test that captures the required behavior or regression. +3. Implement the smallest change that makes the test pass. +4. Refactor only after the behavior is locked in, and only if the refactor keeps the diff focused. +5. If the changed code is on a hot path or performance-sensitive, inspect existing benchmarks and run them. Add a benchmark if coverage is missing. +6. Update documentation artifacts as needed while the context is fresh. Follow the documentation and changelog conventions below for the specific updates required. +7. Run `make precommit` each time before considering the work complete. + +For docs-only, test-only, or review-only tasks, still start with the required repository guidance above, then skip the workflow steps that do not apply while keeping the same discipline around scope, verification, and repository conventions. + +## Verification + +- Use `make` as the canonical repository verification command. The default target is `precommit`. +- `make precommit` is the expected final verification step for linting, generation, README checks, module checks, and tests. +- During iteration, targeted commands are fine for fast feedback, but do not stop there if the task changes code. +- If you touch performance-sensitive code, run focused benchmarks and compare the results using `benchstat` in addition to `make`. + +## Documentation and changelog + +- Non-internal, non-test packages should have Go doc comments, usually in `doc.go`. +- Non-internal, non-test, non-documentation packages should also have a `README.md` with at least a title and a `pkg.go.dev` badge. +- Prefer examples over long code snippets in GoDoc when practical. +- Keep docs aligned with actual behavior. Do not leave stale comments, stale examples, or stale package documentation behind. +- For user-visible changes, update `CHANGELOG.md` under the appropriate `Added`, `Changed`, `Deprecated`, `Fixed`, or `Removed` section within `## [Unreleased]`. + +## Repository habits + +- Prefer focused diffs. Avoid drive-by cleanup. +- Follow existing option patterns and exported API conventions instead of inventing new abstractions. +- Generated files are checked in. If your change affects generation, keep generated output up to date. +- Prefer fast local search tools such as `rg` when exploring the repository. +- When changing behavior, make the invariants explicit in tests. + +## Personas + +### Feature Agent + +Use this persona for new behavior, new API surface, or spec-driven feature work. + +- Start with a failing unit test. +- Confirm the expected behavior against the spec, existing package behavior, and public API compatibility. +- Implement the smallest viable change. +- Update GoDoc, examples, `README.md`, and `CHANGELOG.md` when the change is user-visible. +- If the feature touches a hot path, check benchmarks and add one if the coverage is missing. + +### Refactoring Agent + +Use this persona when improving structure without intentionally changing behavior. + +- Treat behavior preservation as the default contract. +- Add or tighten tests before moving code if current behavior is not already pinned down. +- Avoid broad rewrites, clever abstractions, or package-wide cleanup unless explicitly requested. +- If a refactor touches a hot path, benchmark before and after. +- Keep API shape, semantics, concurrency guarantees, and failure modes unchanged unless the task says otherwise. + +### Test Agent + +Use this persona when adding missing coverage, reproducing bugs, or hardening regressions. + +- Reproduce the bug or missing behavior with the smallest failing test you can. +- Prefer testing public behavior and externally visible invariants. +- Add targeted regression tests before changing production code. +- Only change production code when it is required to make the tested behavior correct or testable. +- Keep tests deterministic, readable, and aligned with package patterns. + +### Performance Agent + +Use this persona for hot-path work, allocation reduction, or throughput and latency improvements. + +- Benchmark first to establish a baseline. +- Prefer changes that reduce allocations, copying, interface churn, and unnecessary synchronization. +- Do not trade away correctness, spec compliance, or API stability for micro-optimizations. +- Add or update benchmarks when performance-sensitive coverage is missing. +- If you materially change a hot path, capture before-and-after results, preferably with `benchstat`. + +### Review Agent + +Use this persona when asked to review code, patches, or pull requests. + +- Lead with findings, not summaries. +- Order findings by severity and include precise file and line references when available. +- Focus on correctness, spec compliance, API compatibility, concurrency safety, resilience, performance regressions, missing tests, missing benchmarks, documentation gaps, and changelog gaps. +- Call out when a diff is broader than necessary. +- If you find no issues, say that explicitly and note any residual risks or verification gaps. diff --git a/vendor/go.opentelemetry.io/otel/CHANGELOG.md b/vendor/go.opentelemetry.io/otel/CHANGELOG.md index 20edda441..6a90451f5 100644 --- a/vendor/go.opentelemetry.io/otel/CHANGELOG.md +++ b/vendor/go.opentelemetry.io/otel/CHANGELOG.md @@ -11,6 +11,100 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm +## [1.44.0/0.66.0/0.20.0/0.0.17] 2026-05-27 + +### Added + +- Add `ByteSlice` and `ByteSliceValue` functions for new `BYTESLICE` attribute type in `go.opentelemetry.io/otel/attribute`. (#7948) +- Apply attribute value limit to the `KindBytes` attribute type in `go.opentelemetry.io/otel/sdk/log`. (#7990) +- Apply attribute value limit to the `BYTESLICE` attribute type in `go.opentelemetry.io/otel/sdk/trace`. (#7990) +- Support `BYTESLICE` attributes in `go.opentelemetry.io/otel/trace`. (#8153) +- Support `BYTESLICE` attributes in `go.opentelemetry.io/otel/exporters/otlp/otlptrace`. (#8153) +- Support `BYTESLICE` attributes in `go.opentelemetry.io/otel/exporters/otlp/otlplog`. (#8153) +- Support `BYTESLICE` attributes in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric`. (#8153) +- Support `BYTESLICE` attributes in `go.opentelemetry.io/otel/exporters/zipkin`. (#8153) +- Add `String` method for `Value` type in `go.opentelemetry.io/otel/attribute`. (#8142) +- Add `Slice` and `SliceValue` functions for new `SLICE` attribute type in `go.opentelemetry.io/otel/attribute`. (#8166) +- Support `SLICE` attributes in `go.opentelemetry.io/otel/exporters/otlp/otlptrace`. (#8216) +- Support `SLICE` attributes in `go.opentelemetry.io/otel/exporters/otlp/otlplog`. (#8216) +- Support `SLICE` attributes in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric`. (#8216) +- Support `SLICE` attributes in `go.opentelemetry.io/otel/exporters/zipkin`. (#8216) +- Apply `AttributeValueLengthLimit` to `attribute.SLICE` type attribute values in `go.opentelemetry.io/otel/sdk/trace`, recursively truncating contained string values. (#8217) +- Add `Error` field on `Record` type in `go.opentelemetry.io/otel/log/logtest`. (#8148) +- Add `WithMaxRequestSize` option in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`. (#8157) +- Add `WithMaxRequestSize` option in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#8157) +- Add `WithMaxRequestSize` option in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#8157) +- Add `WithMaxRequestSize` option in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#8157) +- Add `WithMaxRequestSize` option in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`. (#8157) +- Add `WithMaxRequestSize` option in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8157) +- Add `Settable` to `go.opentelemetry.io/otel/metric/x` to allow reusing attribute options. (#8178) +- Add experimental support for splitting metric data across multiple batches in `go.opentelemetry.io/otel/sdk/metric`. + Set `OTEL_GO_X_METRIC_EXPORT_BATCH_SIZE=` to enable for all periodic readers. + See `go.opentelemetry.io/otel/sdk/metric/internal/x` for feature documentation. (#8071) +- Add experimental self-observability metrics in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. + Enable with `OTEL_GO_X_SELF_OBSERVABILITY=true` environment variable. + See `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/x` for feature documentation. (#8192) +- Add experimental self-observability metrics in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. + Enable with `OTEL_GO_X_SELF_OBSERVABILITY=true` environment variable. + See `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/x` for feature documentation. (#8194) +- Add experimental self-observability metrics in `go.opentelemetry.io/otel/exporters/stdout/stdoutlog`. + Enable with `OTEL_GO_X_SELF_OBSERVABILITY=true` environment variable. + See `go.opentelemetry.io/otel/stdout/stdoutlog/internal/x` for feature documentation. (#8263) +- Add `WithDefaultAttributes` to `go.opentelemetry.io/otel/metric/x` to support setting default attributes on instruments. (#8135) +- Add `go.opentelemetry.io/otel/semconv/v1.41.0` package. + The package contains semantic conventions from the `v1.41.0` version of the OpenTelemetry Semantic Conventions. + See the [migration documentation](./semconv/v1.41.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.40.0`. (#8324) +- Add Observable variants of instruments to `go.opentelemetry.io/otel/semconv/v1.41.0` package. (#8350) +- Generate explicit histogram bucket boundaries from weaver configuration for HTTP and RPC duration instruments in `go.opentelemetry.io/otel/semconv/v1.41.0`. (#8002) + +### Changed + +- ⚠️ **Breaking Change:** `go.opentelemetry.io/otel/sdk/metric` now applies a default cardinality limit of 2000 to comply with the Metrics SDK specification recommendation. + New attribute sets are dropped when the cardinality limit is reached. The measurement of these sets are aggregated into a special attribute set containing `attribute.Bool("otel.metric.overflow", true)`. + This can break users who relied on the previous unlimited default. + Set `WithCardinalityLimit(0)` or the deprecated `OTEL_GO_X_CARDINALITY_LIMIT=0` environment variable to preserve unlimited cardinality. + Note that support for `OTEL_GO_X_CARDINALITY_LIMIT` may be removed in a future release. (#8247) +- `ErrorType` in `go.opentelemetry.io/otel/semconv` now unwraps errors created with `fmt.Errorf` when deriving the `error.type` attribute. (#8133) +- `go.opentelemetry.io/otel/sdk/log` now unwraps error chains created with `fmt.Errorf` when deriving the `error.type` attribute from errors on log records. (#8133) +- `Set.MarshalLog` method in `go.opentelemetry.io/otel/attribute` now uses `Value.String` formatting following the [OpenTelemetry AnyValue representation for non-OTLP protocols](https://opentelemetry.io/docs/specs/otel/common/#anyvalue). (#8169) +- Optimize `go.opentelemetry.io/otel/sdk/metric` to return a drop reservoir and short-circuit `Offer` calls to the exemplar reservoir when `exemplar.AlwaysOffFilter` is configured. (#8211) (#8267) +- Optimize `go.opentelemetry.io/otel/sdk/metric` to return a drop reservoir for asynchronous instruments when `exemplar.TraceBasedFilter` is configured. (#8286) + +### Deprecated + +- Deprecate `Value.Emit` method in `go.opentelemetry.io/otel/attribute`. + Use `Value.String` instead. (#8176) + +### Fixed + +- Limit OTLP request size to 64 MiB by default in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`. + The limit applies before compression, oversized requests are treated as non-retryable errors, and the limit can be configured with the new `WithMaxRequestSize` option. (#8157, #8365) +- Limit OTLP request size to 64 MiB by default in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. + The limit applies before compression, oversized requests are treated as non-retryable errors, and the limit can be configured with the new `WithMaxRequestSize` option. (#8157, #8365) +- Limit OTLP request size to 64 MiB by default in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. + The limit applies before compression, oversized requests are treated as non-retryable errors, and the limit can be configured with the new `WithMaxRequestSize` option. (#8157, #8365) +- Limit OTLP request size to 64 MiB by default in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. + The limit applies before compression, oversized requests are treated as non-retryable errors, and the limit can be configured with the new `WithMaxRequestSize` option. (#8157, #8365) +- Limit OTLP request size to 64 MiB by default in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`. + The limit applies before compression, oversized requests are treated as non-retryable errors, and the limit can be configured with the new `WithMaxRequestSize` option. (#8157, #8365) +- Limit OTLP request size to 64 MiB by default in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. + The limit applies before compression, oversized requests are treated as non-retryable errors, and the limit can be configured with the new `WithMaxRequestSize` option. (#8157, #8365) +- Fix gzipped request body replay on redirect in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#8135) +- Fix gzipped request body replay on redirect in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8152) +- `go.opentelemetry.io/otel/exporters/prometheus` now uses `Value.String` formatting for label values following the [OpenTelemetry AnyValue representation for non-OTLP protocols](https://opentelemetry.io/docs/specs/otel/common/#anyvalue). (#8170) +- Propagate errors from the exporter when calling `Shutdown` on `BatchSpanProcessor` in `go.opentelemetry.io/otel/sdk/trace`. (#8197) +- Fix stale status code reporting on self-observability metrics in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` and `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8226) +- Fix a concurrent `Collect` data race and potential panic in `go.opentelemetry.io/otel/exporters/prometheus` when `WithResourceAsConstantLabels` option is used. (#8227) +- Fix race condition in `FixedSizeReservoir` in `go.opentelemetry.io/otel/sdk/metric/exemplar` by reverting #7447. (#8249) +- Fix `FixedSizeReservoir` in `go.opentelemetry.io/otel/sdk/metric/exemplar` to safely handle zero size. + A capacity check in the constructor initializes the reservoir safely and skips initialization for zero-cap; early returns in `Offer()` and `Collect()` ensure no-op behavior. (#8295) +- Fix counting of spans and logs in self-observability metrics in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`, `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`, `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`, and `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8254) +- Drop conflicting scope attributes named `name`, `version`, or `schema_url` from metric labels in `go.opentelemetry.io/otel/exporters/prometheus`, preserving the dedicated `otel_scope_name`, `otel_scope_version`, and `otel_scope_schema_url` labels. (#8264) +- Close schema files opened by `ParseFile` in `go.opentelemetry.io/otel/schema/v1.0` and `go.opentelemetry.io/otel/schema/v1.1`. ([GHSA-995v-fvrw-c78m](https://github.com/open-telemetry/opentelemetry-go/security/advisories/GHSA-995v-fvrw-c78m)) +- Enforce the 8192-byte baggage size limit during extraction/parsing, changing behavior when the limit is exceeded in `go.opentelemetry.io/otel/baggage` and `go.opentelemetry.io/otel/propagation`. (#8222) +- Fix `go.opentelemetry.io/otel/semconv/v1.41.0` to include `Attr*` helper methods for required attributes on observable instruments. (#8361) +- Limit baggage extraction error reporting in `go.opentelemetry.io/otel/propagation` to prevent malformed or oversized baggage headers from flooding logs. ([GHSA-5wrp-cwcj-q835](https://github.com/open-telemetry/opentelemetry-go/security/advisories/GHSA-5wrp-cwcj-q835)) + ## [1.43.0/0.65.0/0.19.0] 2026-04-02 ### Added @@ -3619,7 +3713,8 @@ It contains api and sdk for trace and meter. - CircleCI build CI manifest files. - CODEOWNERS file to track owners of this project. -[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.43.0...HEAD +[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.44.0...HEAD +[1.44.0/0.66.0/0.20.0/0.0.17]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.44.0 [1.43.0/0.65.0/0.19.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.43.0 [1.42.0/0.64.0/0.18.0/0.0.16]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.42.0 [1.41.0/0.63.0/0.17.0/0.0.15]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.41.0 diff --git a/vendor/go.opentelemetry.io/otel/CLAUDE.md b/vendor/go.opentelemetry.io/otel/CLAUDE.md new file mode 100644 index 000000000..dd3c4594f --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/CLAUDE.md @@ -0,0 +1,3 @@ +# Instructions for Claude Code + +@AGENTS.md diff --git a/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md b/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md index 12de3607a..3ec17d683 100644 --- a/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md +++ b/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md @@ -11,6 +11,12 @@ for a summary description of past meetings. To request edit access, join the meeting or get in touch on [Slack](https://cloud-native.slack.com/archives/C01NPAXACKT). +The meeting is open for all to join. We invite everyone to join our +meeting, regardless of your experience level. Whether you're a +seasoned OpenTelemetry developer, just starting your journey, or +simply curious about the work we do, you're more than welcome to +participate! + ## Development You can view and edit the source code by cloning this repository: @@ -746,8 +752,8 @@ Encapsulate setup in constructor functions, ensuring clear ownership and scope: import ( "errors" - semconv "go.opentelemetry.io/otel/semconv/v1.40.0" - "go.opentelemetry.io/otel/semconv/v1.40.0/otelconv" + semconv "go.opentelemetry.io/otel/semconv/v1.41.0" + "go.opentelemetry.io/otel/semconv/v1.41.0/otelconv" ) type SDKComponent struct { @@ -808,11 +814,11 @@ func (c *Component) initObservability() { #### Performance -When observability is disabled there should be little to no overhead. +When observability is disabled or the instrument is not `Enabled`, there should be little to no overhead. ```go func (e *Exporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) error { - if e.inst != nil { + if e.inst != nil && e.inst.Enabled(ctx) { attrs := expensiveOperation() e.inst.recordSpanInflight(ctx, int64(len(spans)), attrs...) } @@ -829,7 +835,7 @@ func (e *Exporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) } func (i *instrumentation) recordSpanInflight(ctx context.Context, count int64, attrs ...attribute.KeyValue) { - if i == nil || i.inflight == nil { + if i == nil || i.inflight == nil || !i.inflight.Enabled(ctx) { return } i.inflight.Add(ctx, count, metric.WithAttributes(attrs...)) @@ -865,8 +871,12 @@ var ( ) func (i *instrumentation) record(ctx context.Context, value int64, baseAttrs ...attribute.KeyValue) { + if !i.counter.Enabled(ctx) { + return + } attrs := attrPool.Get().(*[]attribute.KeyValue) defer func() { + clear(*attrs) // Clear references to strings/etc to let GC collect them. *attrs = (*attrs)[:0] // Reset. attrPool.Put(attrs) }() @@ -877,6 +887,7 @@ func (i *instrumentation) record(ctx context.Context, value int64, baseAttrs ... addOpt := addOptPool.Get().(*[]metric.AddOption) defer func() { + clear(*addOpt) *addOpt = (*addOpt)[:0] addOptPool.Put(addOpt) }() @@ -1007,16 +1018,20 @@ Ensure observability measurements receive the correct context, especially for tr ```go func (e *Exporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) error { // Use the provided context for observability measurements - e.inst.recordSpanExportStarted(ctx, len(spans)) + if e.inst.Enabled(ctx) { + e.inst.recordSpanExportStarted(ctx, len(spans)) + } err := e.doExport(ctx, spans) - if err != nil { - e.inst.recordSpanExportFailed(ctx, len(spans), err) - } else { - e.inst.recordSpanExportSucceeded(ctx, len(spans)) + if e.inst.Enabled(ctx) { + if err != nil { + e.inst.recordSpanExportFailed(ctx, len(spans), err) + } else { + e.inst.recordSpanExportSucceeded(ctx, len(spans)) + } } - + return err } ``` @@ -1039,7 +1054,7 @@ func (e *Exporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) All observability metrics should follow the [OpenTelemetry Semantic Conventions for SDK metrics](https://github.com/open-telemetry/semantic-conventions/blob/1cf2476ae5e518225a766990a28a6d5602bd5a30/docs/otel/sdk-metrics.md). -Use the metric semantic conventions convenience package [otelconv](./semconv/v1.40.0/otelconv/metric.go). +Use the metric semantic conventions convenience package [otelconv](./semconv/v1.41.0/otelconv/metric.go). ##### Component Identification @@ -1109,6 +1124,68 @@ func TestObservability(t *testing.T) { Test order should not affect results. Ensure that any global state (e.g. component ID counters) is reset between tests. +### Experimental Features + +To support the development of new features in the specification, we use the following patterns to implement in-development features without adding new public artifacts in stable modules. + +#### Experimental behavior with no API artifacts + +Features that change behavior without changing the API (e.g., exemplar collection, auto-generation of identifiers) are implemented behind a feature gate. +The implementation resides in an `/internal/x` package and is activated through environment variables with the `OTEL_GO_X_` prefix (e.g., `OTEL_GO_X_OBSERVABILITY`). +The feature must be documented in a `README.md` file in the `/internal/x` package. + +#### Experimental methods on SDK-only interfaces + +Features that require new methods on SDK interfaces are defined as a new interface in an experimental module (e.g., `go.opentelemetry.io/otel/sdk/x`). +The SDK uses type assertions (without importing the unstable package) to check if passing types implement these experimental interfaces. +The SDK must not depend on the experimental module. + +#### Experimental structs, functions, or interfaces + +Features that don't need any changes to the existing stable package are implemented in an experimental module (e.g., `go.opentelemetry.io/otel/sdk/x`). + +#### Experimental signals and components + +New telemetry signals (e.g., Logs before stabilization) and components (e.g. bridges) are hosted in new, unstable modules (e.g., `go.opentelemetry.io/otel/log` before 1.0.0). +The package should have the final name it will use once stabilized (i.e. not `/x`), and is released at a v0.x.y version to indicate it is not stable. +Most new components are hosted in [opentelemetry-go-contrib](https://github.com/open-telemetry/opentelemetry-go-contrib). + +#### Experimental options for API or SDK functions + +Experimental Options functions are implemented in an experimental module (e.g., `go.opentelemetry.io/otel/sdk/x`). +The return type of the Option function must embed the option's type (e.g. `metric.InstrumentOption`), and have an `Experimental()` method to prevent the API from panicking when the option is used. +The SDK uses type assertions (without importing the unstable package) to check if passing types implement these experimental interfaces. +The SDK must not depend on the experimental module. + +For example: + +```go +type myOption struct { + // Embed the stable option type. + metric.InstrumentOption + value string +} + +// Experimental prevents the API from panicking when the option is used. +func (o myOption) Experimental() {} + +// The SDK can use type assertions to use this function. +func (o myOption) Value() string { return o.value } + +func WithMyOption(value string) metric.InstrumentOption { + return myOption{value: value} +} +``` + +#### Not Supported + +The following kinds of experimental features are **not currently supported** on stable interfaces: + +- Experimental methods on API interfaces +- Experimental fields for API or SDK exported structs + +In some cases forks or long-lived branches may be used for prototyping these features. + ## Approvers and Maintainers ### Maintainers diff --git a/vendor/go.opentelemetry.io/otel/Makefile b/vendor/go.opentelemetry.io/otel/Makefile index 42466f2d6..de63a5e9b 100644 --- a/vendor/go.opentelemetry.io/otel/Makefile +++ b/vendor/go.opentelemetry.io/otel/Makefile @@ -191,8 +191,16 @@ benchmark: $(OTEL_GO_MOD_DIRS:%=benchmark/%) benchmark/%: cd $* && $(GO) test -run='^$$' -bench=. $(ARGS) ./... +# sdk/metric is split into two shards to work around CodSpeed limitations. +# See https://github.com/CodSpeedHQ/codspeed-go/issues/56 +BENCHMARK_SHARDS := $(filter-out ./sdk/metric,$(OTEL_GO_MOD_DIRS)) ./sdk/metric/root ./sdk/metric/internal +benchmark/./sdk/metric/root: + cd ./sdk/metric && $(GO) test -run='^$$' -bench=. $(ARGS) . ./exemplar/... +benchmark/./sdk/metric/internal: + cd ./sdk/metric && $(GO) test -run='^$$' -bench=. $(ARGS) ./internal/... + print-sharded-benchmarks: - @echo $(OTEL_GO_MOD_DIRS) | jq -cR 'split(" ")' + @echo $(BENCHMARK_SHARDS) | jq -cR 'split(" ")' .PHONY: golangci-lint golangci-lint-fix golangci-lint-fix: ARGS=--fix diff --git a/vendor/go.opentelemetry.io/otel/attribute/encoder.go b/vendor/go.opentelemetry.io/otel/attribute/encoder.go index 771dd69c5..ca186d8ac 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/encoder.go +++ b/vendor/go.opentelemetry.io/otel/attribute/encoder.go @@ -105,7 +105,9 @@ func (d *defaultAttrEncoder) Encode(iter Iterator) string { if keyValue.Value.Type() == STRING { copyAndEscape(buf, keyValue.Value.AsString()) } else { - _, _ = buf.WriteString(keyValue.Value.Emit()) + _, _ = buf.WriteString( + keyValue.Value.Emit(), + ) //nolint:staticcheck // Preserve the existing default encoder output. } } return buf.String() diff --git a/vendor/go.opentelemetry.io/otel/attribute/hash.go b/vendor/go.opentelemetry.io/otel/attribute/hash.go index b09caaa6d..92f39ffe7 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/hash.go +++ b/vendor/go.opentelemetry.io/otel/attribute/hash.go @@ -27,6 +27,8 @@ const ( int64SliceID uint64 = 3762322556277578591 // "_[]int64" (little endian) float64SliceID uint64 = 7308324551835016539 // "[]double" (little endian) stringSliceID uint64 = 7453010373645655387 // "[]string" (little endian) + byteSliceID uint64 = 6874028470941080415 // "_[]byte_" (little endian) + sliceID uint64 = 7883494272577650031 // "__slice_" (little endian) emptyID uint64 = 7305809155345288421 // "__empty_" (little endian) ) @@ -42,53 +44,87 @@ func hashKVs(kvs []KeyValue) uint64 { // hashKV returns the xxHash64 hash of kv with h as the base. func hashKV(h xxhash.Hash, kv KeyValue) xxhash.Hash { h = h.String(string(kv.Key)) + return hashValue(h, kv.Value) +} - switch kv.Value.Type() { +func hashValue(h xxhash.Hash, v Value) xxhash.Hash { + switch v.Type() { case BOOL: h = h.Uint64(boolID) - h = h.Uint64(kv.Value.numeric) + h = h.Uint64(v.numeric) case INT64: h = h.Uint64(int64ID) - h = h.Uint64(kv.Value.numeric) + h = h.Uint64(v.numeric) case FLOAT64: h = h.Uint64(float64ID) // Assumes numeric stored with math.Float64bits. - h = h.Uint64(kv.Value.numeric) + h = h.Uint64(v.numeric) case STRING: h = h.Uint64(stringID) - h = h.String(kv.Value.stringly) + h = h.String(v.stringly) case BOOLSLICE: h = h.Uint64(boolSliceID) - rv := reflect.ValueOf(kv.Value.slice) + rv := reflect.ValueOf(v.slice) for i := 0; i < rv.Len(); i++ { h = h.Bool(rv.Index(i).Bool()) } case INT64SLICE: h = h.Uint64(int64SliceID) - rv := reflect.ValueOf(kv.Value.slice) + rv := reflect.ValueOf(v.slice) for i := 0; i < rv.Len(); i++ { h = h.Int64(rv.Index(i).Int()) } case FLOAT64SLICE: h = h.Uint64(float64SliceID) - rv := reflect.ValueOf(kv.Value.slice) + rv := reflect.ValueOf(v.slice) for i := 0; i < rv.Len(); i++ { h = h.Float64(rv.Index(i).Float()) } case STRINGSLICE: h = h.Uint64(stringSliceID) - rv := reflect.ValueOf(kv.Value.slice) + rv := reflect.ValueOf(v.slice) for i := 0; i < rv.Len(); i++ { h = h.String(rv.Index(i).String()) } + case BYTESLICE: + h = h.Uint64(byteSliceID) + h = h.String(v.stringly) + case SLICE: + h = h.Uint64(sliceID) + switch vals := v.slice.(type) { + case [0]Value: + // No values to hash, but the type identifier is still hashed above. + case [1]Value: + h = hashValueSlice(h, vals[:]) + case [2]Value: + h = hashValueSlice(h, vals[:]) + case [3]Value: + h = hashValueSlice(h, vals[:]) + case [4]Value: + h = hashValueSlice(h, vals[:]) + case [5]Value: + h = hashValueSlice(h, vals[:]) + default: + rv := reflect.ValueOf(v.slice) + for i := 0; i < rv.Len(); i++ { + h = hashValue(h, rv.Index(i).Interface().(Value)) + } + } case EMPTY: h = h.Uint64(emptyID) default: // Logging is an alternative, but using the internal logger here // causes an import cycle so it is not done. - v := kv.Value.AsInterface() - msg := fmt.Sprintf("unknown value type: %[1]v (%[1]T)", v) + val := v.AsInterface() + msg := fmt.Sprintf("unknown value type: %[1]v (%[1]T)", val) panic(msg) } return h } + +func hashValueSlice(h xxhash.Hash, vals []Value) xxhash.Hash { + for _, v := range vals { + h = hashValue(h, v) + } + return h +} diff --git a/vendor/go.opentelemetry.io/otel/attribute/key.go b/vendor/go.opentelemetry.io/otel/attribute/key.go index 80a9e5643..cdc7089e8 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/key.go +++ b/vendor/go.opentelemetry.io/otel/attribute/key.go @@ -117,6 +117,28 @@ func (k Key) StringSlice(v []string) KeyValue { } } +// ByteSlice creates a KeyValue instance with a BYTESLICE Value. +// +// If creating both a key and value at the same time, use the provided +// convenience function instead -- ByteSlice(name, value). +func (k Key) ByteSlice(v []byte) KeyValue { + return KeyValue{ + Key: k, + Value: ByteSliceValue(v), + } +} + +// Slice creates a KeyValue instance with a SLICE Value. +// +// If creating both a key and value at the same time, use the provided +// convenience function instead -- Slice(name, values...). +func (k Key) Slice(v ...Value) KeyValue { + return KeyValue{ + Key: k, + Value: SliceValue(v...), + } +} + // Defined reports whether the key is not empty. func (k Key) Defined() bool { return len(k) != 0 diff --git a/vendor/go.opentelemetry.io/otel/attribute/kv.go b/vendor/go.opentelemetry.io/otel/attribute/kv.go index 0cc368018..eeb76a134 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/kv.go +++ b/vendor/go.opentelemetry.io/otel/attribute/kv.go @@ -68,6 +68,16 @@ func StringSlice(k string, v []string) KeyValue { return Key(k).StringSlice(v) } +// ByteSlice creates a KeyValue with a BYTESLICE Value type. +func ByteSlice(k string, v []byte) KeyValue { + return Key(k).ByteSlice(v) +} + +// Slice creates a KeyValue with a SLICE Value type. +func Slice(k string, v ...Value) KeyValue { + return Key(k).Slice(v...) +} + // Stringer creates a new key-value pair with a passed name and a string // value generated by the passed Stringer interface. func Stringer(k string, v fmt.Stringer) KeyValue { diff --git a/vendor/go.opentelemetry.io/otel/attribute/set.go b/vendor/go.opentelemetry.io/otel/attribute/set.go index 6572c98b1..a4b6ce81d 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/set.go +++ b/vendor/go.opentelemetry.io/otel/attribute/set.go @@ -401,7 +401,7 @@ func computeDataFixed(kvs []KeyValue) any { func computeDataReflect(kvs []KeyValue) any { at := reflect.New(reflect.ArrayOf(len(kvs), keyValueType)).Elem() for i, keyValue := range kvs { - *(at.Index(i).Addr().Interface().(*KeyValue)) = keyValue + *at.Index(i).Addr().Interface().(*KeyValue) = keyValue } return at.Interface() } @@ -415,7 +415,7 @@ func (l *Set) MarshalJSON() ([]byte, error) { func (l Set) MarshalLog() any { kvs := make(map[string]string) for _, kv := range l.ToSlice() { - kvs[string(kv.Key)] = kv.Value.Emit() + kvs[string(kv.Key)] = kv.Value.String() } return kvs } diff --git a/vendor/go.opentelemetry.io/otel/attribute/type_string.go b/vendor/go.opentelemetry.io/otel/attribute/type_string.go index 6c04448d6..dbc01d324 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/type_string.go +++ b/vendor/go.opentelemetry.io/otel/attribute/type_string.go @@ -17,11 +17,13 @@ func _() { _ = x[INT64SLICE-6] _ = x[FLOAT64SLICE-7] _ = x[STRINGSLICE-8] + _ = x[BYTESLICE-9] + _ = x[SLICE-10] } -const _Type_name = "EMPTYBOOLINT64FLOAT64STRINGBOOLSLICEINT64SLICEFLOAT64SLICESTRINGSLICE" +const _Type_name = "EMPTYBOOLINT64FLOAT64STRINGBOOLSLICEINT64SLICEFLOAT64SLICESTRINGSLICEBYTESLICESLICE" -var _Type_index = [...]uint8{0, 5, 9, 14, 21, 27, 36, 46, 58, 69} +var _Type_index = [...]uint8{0, 5, 9, 14, 21, 27, 36, 46, 58, 69, 78, 83} func (i Type) String() string { idx := int(i) - 0 diff --git a/vendor/go.opentelemetry.io/otel/attribute/value.go b/vendor/go.opentelemetry.io/otel/attribute/value.go index db04b1326..0529fefae 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/value.go +++ b/vendor/go.opentelemetry.io/otel/attribute/value.go @@ -4,9 +4,14 @@ package attribute // import "go.opentelemetry.io/otel/attribute" import ( + "encoding/base64" "encoding/json" "fmt" + "math" + "reflect" "strconv" + "strings" + "unicode/utf8" attribute "go.opentelemetry.io/otel/attribute/internal" ) @@ -45,6 +50,10 @@ const ( FLOAT64SLICE // STRINGSLICE is a slice of strings Type Value. STRINGSLICE + // BYTESLICE is a slice of bytes Type Value. + BYTESLICE + // SLICE is a slice of Value Type values. + SLICE // INVALID is used for a Value with no value set. // // Deprecated: Use EMPTY instead as an empty value is a valid value. @@ -134,6 +143,19 @@ func StringSliceValue(v []string) Value { return Value{vtype: STRINGSLICE, slice: attribute.SliceValue(v)} } +// ByteSliceValue creates a BYTESLICE Value. +func ByteSliceValue(v []byte) Value { + return Value{ + vtype: BYTESLICE, + stringly: string(v), + } +} + +// SliceValue creates a SLICE Value. +func SliceValue(v ...Value) Value { + return Value{vtype: SLICE, slice: sliceValue(v)} +} + // Type returns a type of the Value. func (v Value) Type() Type { return v.vtype @@ -215,6 +237,59 @@ func (v Value) asStringSlice() []string { return attribute.AsSlice[string](v.slice) } +// AsSlice returns the []Value value. Make sure that the Value's type is +// SLICE. +func (v Value) AsSlice() []Value { + if v.vtype != SLICE { + return nil + } + return v.asSlice() +} + +func (v Value) asSlice() []Value { + switch vals := v.slice.(type) { + case [0]Value: + return []Value{} + case [1]Value: + return []Value{vals[0]} + case [2]Value: + return []Value{vals[0], vals[1]} + case [3]Value: + return []Value{vals[0], vals[1], vals[2]} + case [4]Value: + return []Value{vals[0], vals[1], vals[2], vals[3]} + case [5]Value: + return []Value{vals[0], vals[1], vals[2], vals[3], vals[4]} + default: + return asValueSliceReflect(v.slice) + } +} + +func asValueSliceReflect(v any) []Value { + rv := reflect.ValueOf(v) + if !rv.IsValid() || rv.Kind() != reflect.Array || rv.Type().Elem() != reflect.TypeFor[Value]() { + return nil + } + cpy := make([]Value, rv.Len()) + if len(cpy) > 0 { + _ = reflect.Copy(reflect.ValueOf(cpy), rv) + } + return cpy +} + +// AsByteSlice returns the bytes value. Make sure that the Value's type +// is BYTESLICE. +func (v Value) AsByteSlice() []byte { + if v.vtype != BYTESLICE { + return nil + } + return v.asByteSlice() +} + +func (v Value) asByteSlice() []byte { + return []byte(v.stringly) +} + type unknownValueType struct{} // AsInterface returns Value's data as any. @@ -236,13 +311,60 @@ func (v Value) AsInterface() any { return v.stringly case STRINGSLICE: return v.asStringSlice() + case BYTESLICE: + return v.asByteSlice() + case SLICE: + return v.asSlice() case EMPTY: return nil } return unknownValueType{} } +// String returns a string representation of Value using the +// [OpenTelemetry AnyValue representation for non-OTLP protocols] rules. +// +// Strings are returned as-is without JSON quoting, booleans and integers use +// JSON literals, floating-point values use JSON numbers except that NaN and +// ±Inf are rendered as NaN, Infinity, and -Infinity, byte slices are +// base64-encoded, empty values are the empty string, and slices are encoded as +// JSON arrays. String, byte, and special floating-point values inside arrays +// are encoded as JSON strings, and empty values inside arrays are encoded as +// null. +// +// [OpenTelemetry AnyValue representation for non-OTLP protocols]: https://opentelemetry.io/docs/specs/otel/common/#anyvalue-representation-for-non-otlp-protocols +func (v Value) String() string { + switch v.Type() { + case BOOL: + return strconv.FormatBool(v.AsBool()) + case BOOLSLICE: + return formatBoolSliceValue(v.slice) + case INT64: + return strconv.FormatInt(v.AsInt64(), 10) + case INT64SLICE: + return formatInt64SliceValue(v.slice) + case FLOAT64: + return formatFloat64(v.AsFloat64()) + case FLOAT64SLICE: + return formatFloat64SliceValue(v.slice) + case STRING: + return v.stringly + case STRINGSLICE: + return formatStringSliceValue(v.slice) + case BYTESLICE: + return formatByteSlice(v.stringly) + case SLICE: + return formatValueSliceValue(v.slice) + case EMPTY: + return "" + default: + return "unknown" + } +} + // Emit returns a string representation of Value's data. +// +// Deprecated: Use [Value.String] instead. func (v Value) Emit() string { switch v.Type() { case BOOLSLICE: @@ -273,6 +395,10 @@ func (v Value) Emit() string { return string(j) case STRING: return v.stringly + case BYTESLICE: + return formatByteSlice(v.stringly) + case SLICE: + return formatValueSliceValue(v.slice) case EMPTY: return "" default: @@ -280,6 +406,622 @@ func (v Value) Emit() string { } } +const ( + jsonArrayBracketsLen = len("[]") + boolArrayElemMaxLen = len("false") + int64ArrayElemMaxLen = len("-9223372036854775808") + float64ArrayElemMaxLen = len("-1.7976931348623157e+308") + commaLen = len(",") +) + +func sliceValue(v []Value) any { + switch len(v) { + case 0: + return [0]Value{} + case 1: + return [1]Value{v[0]} + case 2: + return [2]Value{v[0], v[1]} + case 3: + return [3]Value{v[0], v[1], v[2]} + case 4: + return [4]Value{v[0], v[1], v[2], v[3]} + case 5: + return [5]Value{v[0], v[1], v[2], v[3], v[4]} + default: + return sliceValueReflect(v) + } +} + +func sliceValueReflect(v []Value) any { + cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeFor[Value]())).Elem() + reflect.Copy(cp, reflect.ValueOf(v)) + return cp.Interface() +} + +func formatBoolSliceValue(v any) string { + switch vals := v.(type) { + case [0]bool: + return "[]" + case [1]bool: + return formatBoolSlice(vals[:]) + case [2]bool: + return formatBoolSlice(vals[:]) + case [3]bool: + return formatBoolSlice(vals[:]) + default: + return formatBoolSliceReflect(v) + } +} + +func formatBoolSlice(vals []bool) string { + var b strings.Builder + appendBoolSlice(&b, vals) + return b.String() +} + +func formatBoolSliceReflect(v any) string { + var b strings.Builder + appendBoolSliceReflect(&b, reflect.ValueOf(v)) + return b.String() +} + +func appendBoolSliceValue(dst *strings.Builder, v any) { + switch vals := v.(type) { + case [0]bool: + _, _ = dst.WriteString("[]") + case [1]bool: + appendBoolSlice(dst, vals[:]) + case [2]bool: + appendBoolSlice(dst, vals[:]) + case [3]bool: + appendBoolSlice(dst, vals[:]) + default: + appendBoolSliceReflect(dst, reflect.ValueOf(v)) + } +} + +func appendBoolSlice(dst *strings.Builder, vals []bool) { + dst.Grow(jsonArrayBracketsLen + len(vals)*(boolArrayElemMaxLen+commaLen)) + _ = dst.WriteByte('[') + for i, val := range vals { + if i > 0 { + _ = dst.WriteByte(',') + } + if val { + _, _ = dst.WriteString("true") + } else { + _, _ = dst.WriteString("false") + } + } + _ = dst.WriteByte(']') +} + +func appendBoolSliceReflect(dst *strings.Builder, rv reflect.Value) { + dst.Grow(jsonArrayBracketsLen + rv.Len()*(boolArrayElemMaxLen+commaLen)) + _ = dst.WriteByte('[') + for i := 0; i < rv.Len(); i++ { + if i > 0 { + _ = dst.WriteByte(',') + } + if rv.Index(i).Bool() { + _, _ = dst.WriteString("true") + } else { + _, _ = dst.WriteString("false") + } + } + _ = dst.WriteByte(']') +} + +func formatInt64SliceValue(v any) string { + switch vals := v.(type) { + case [0]int64: + return "[]" + case [1]int64: + return formatInt64Slice(vals[:]) + case [2]int64: + return formatInt64Slice(vals[:]) + case [3]int64: + return formatInt64Slice(vals[:]) + default: + return formatInt64SliceReflect(v) + } +} + +func formatInt64Slice(vals []int64) string { + var b strings.Builder + appendInt64Slice(&b, vals) + return b.String() +} + +func formatInt64SliceReflect(v any) string { + var b strings.Builder + appendInt64SliceReflect(&b, reflect.ValueOf(v)) + return b.String() +} + +func appendInt64SliceValue(dst *strings.Builder, v any) { + switch vals := v.(type) { + case [0]int64: + _, _ = dst.WriteString("[]") + case [1]int64: + appendInt64Slice(dst, vals[:]) + case [2]int64: + appendInt64Slice(dst, vals[:]) + case [3]int64: + appendInt64Slice(dst, vals[:]) + default: + appendInt64SliceReflect(dst, reflect.ValueOf(v)) + } +} + +func appendInt64Slice(dst *strings.Builder, vals []int64) { + dst.Grow(jsonArrayBracketsLen + len(vals)*(int64ArrayElemMaxLen+commaLen)) + _ = dst.WriteByte('[') + + var buf [int64ArrayElemMaxLen]byte + for i, val := range vals { + if i > 0 { + _ = dst.WriteByte(',') + } + out := strconv.AppendInt(buf[:0], val, 10) + _, _ = dst.Write(out) + } + + _ = dst.WriteByte(']') +} + +func appendInt64SliceReflect(dst *strings.Builder, rv reflect.Value) { + dst.Grow(jsonArrayBracketsLen + rv.Len()*(int64ArrayElemMaxLen+commaLen)) + _ = dst.WriteByte('[') + + var scratch [int64ArrayElemMaxLen]byte + for i := 0; i < rv.Len(); i++ { + if i > 0 { + _ = dst.WriteByte(',') + } + out := strconv.AppendInt(scratch[:0], rv.Index(i).Int(), 10) + _, _ = dst.Write(out) + } + + _ = dst.WriteByte(']') +} + +func formatFloat64(v float64) string { + switch { + case math.IsNaN(v): + return "NaN" + case math.IsInf(v, 1): + return "Infinity" + case math.IsInf(v, -1): + return "-Infinity" + default: + return strconv.FormatFloat(v, 'g', -1, 64) + } +} + +func formatFloat64SliceValue(v any) string { + switch vals := v.(type) { + case [0]float64: + return "[]" + case [1]float64: + return formatFloat64Slice(vals[:]) + case [2]float64: + return formatFloat64Slice(vals[:]) + case [3]float64: + return formatFloat64Slice(vals[:]) + default: + return formatFloat64SliceReflect(v) + } +} + +func formatFloat64Slice(vals []float64) string { + var b strings.Builder + appendFloat64Slice(&b, vals) + return b.String() +} + +func formatFloat64SliceReflect(v any) string { + var b strings.Builder + appendFloat64SliceReflect(&b, reflect.ValueOf(v)) + return b.String() +} + +func appendFloat64SliceValue(dst *strings.Builder, v any) { + switch vals := v.(type) { + case [0]float64: + _, _ = dst.WriteString("[]") + case [1]float64: + appendFloat64Slice(dst, vals[:]) + case [2]float64: + appendFloat64Slice(dst, vals[:]) + case [3]float64: + appendFloat64Slice(dst, vals[:]) + default: + appendFloat64SliceReflect(dst, reflect.ValueOf(v)) + } +} + +func appendFloat64Slice(dst *strings.Builder, vals []float64) { + dst.Grow(jsonArrayBracketsLen + len(vals)*(float64ArrayElemMaxLen+commaLen)) + _ = dst.WriteByte('[') + + var buf [float64ArrayElemMaxLen]byte + for i, val := range vals { + if i > 0 { + _ = dst.WriteByte(',') + } + + switch { + case math.IsNaN(val): + _, _ = dst.WriteString(`"NaN"`) + case math.IsInf(val, 1): + _, _ = dst.WriteString(`"Infinity"`) + case math.IsInf(val, -1): + _, _ = dst.WriteString(`"-Infinity"`) + default: + out := strconv.AppendFloat(buf[:0], val, 'g', -1, 64) + _, _ = dst.Write(out) + } + } + + _ = dst.WriteByte(']') +} + +func appendFloat64SliceReflect(dst *strings.Builder, rv reflect.Value) { + dst.Grow(jsonArrayBracketsLen + rv.Len()*(float64ArrayElemMaxLen+commaLen)) + _ = dst.WriteByte('[') + + var scratch [float64ArrayElemMaxLen]byte + for i := 0; i < rv.Len(); i++ { + if i > 0 { + _ = dst.WriteByte(',') + } + val := rv.Index(i).Float() + switch { + case math.IsNaN(val): + _, _ = dst.WriteString(`"NaN"`) + case math.IsInf(val, 1): + _, _ = dst.WriteString(`"Infinity"`) + case math.IsInf(val, -1): + _, _ = dst.WriteString(`"-Infinity"`) + default: + out := strconv.AppendFloat(scratch[:0], val, 'g', -1, 64) + _, _ = dst.Write(out) + } + } + + _ = dst.WriteByte(']') +} + +func formatStringSliceValue(v any) string { + switch vals := v.(type) { + case [0]string: + return "[]" + case [1]string: + return formatStringSlice(vals[:]) + case [2]string: + return formatStringSlice(vals[:]) + case [3]string: + return formatStringSlice(vals[:]) + default: + return formatStringSliceReflect(v) + } +} + +func formatStringSlice(vals []string) string { + var b strings.Builder + appendStringSlice(&b, vals) + return b.String() +} + +func formatStringSliceReflect(v any) string { + var b strings.Builder + appendStringSliceReflect(&b, reflect.ValueOf(v)) + return b.String() +} + +func appendStringSliceValue(dst *strings.Builder, v any) { + switch vals := v.(type) { + case [0]string: + _, _ = dst.WriteString("[]") + case [1]string: + appendStringSlice(dst, vals[:]) + case [2]string: + appendStringSlice(dst, vals[:]) + case [3]string: + appendStringSlice(dst, vals[:]) + default: + appendStringSliceReflect(dst, reflect.ValueOf(v)) + } +} + +func appendStringSlice(dst *strings.Builder, vals []string) { + size := jsonArrayBracketsLen + for _, val := range vals { + size += len(val) + commaLen + 2 // Account for JSON string quotes and comma. + } + + dst.Grow(size) + _ = dst.WriteByte('[') + for i, val := range vals { + if i > 0 { + _ = dst.WriteByte(',') + } + appendJSONString(dst, val) + } + _ = dst.WriteByte(']') +} + +func appendStringSliceReflect(dst *strings.Builder, rv reflect.Value) { + size := jsonArrayBracketsLen + for i := 0; i < rv.Len(); i++ { + size += len(rv.Index(i).String()) + commaLen + 2 // Account for JSON string quotes and comma. + } + + dst.Grow(size) + _ = dst.WriteByte('[') + for i := 0; i < rv.Len(); i++ { + if i > 0 { + _ = dst.WriteByte(',') + } + appendJSONString(dst, rv.Index(i).String()) + } + _ = dst.WriteByte(']') +} + +func formatByteSlice(v string) string { + var b strings.Builder + appendBase64(&b, v) + return b.String() +} + +func formatValueSliceValue(v any) string { + switch vals := v.(type) { + case [0]Value: + return "[]" + case [1]Value: + return formatValueSlice(vals[:]) + case [2]Value: + return formatValueSlice(vals[:]) + case [3]Value: + return formatValueSlice(vals[:]) + case [4]Value: + return formatValueSlice(vals[:]) + case [5]Value: + return formatValueSlice(vals[:]) + default: + return formatValueSliceReflect(v) + } +} + +func formatValueSlice(vals []Value) string { + var b strings.Builder + appendValueSlice(&b, vals) + return b.String() +} + +func formatValueSliceReflect(v any) string { + var b strings.Builder + appendValueSliceReflect(&b, reflect.ValueOf(v)) + return b.String() +} + +func appendValueSliceValue(dst *strings.Builder, v any) { + switch vals := v.(type) { + case [0]Value: + _, _ = dst.WriteString("[]") + case [1]Value: + appendValueSlice(dst, vals[:]) + case [2]Value: + appendValueSlice(dst, vals[:]) + case [3]Value: + appendValueSlice(dst, vals[:]) + case [4]Value: + appendValueSlice(dst, vals[:]) + case [5]Value: + appendValueSlice(dst, vals[:]) + default: + appendValueSliceReflect(dst, reflect.ValueOf(v)) + } +} + +func appendValueSlice(dst *strings.Builder, vals []Value) { + // Estimate 10 bytes per value for small values and commas. + dst.Grow(jsonArrayBracketsLen + len(vals)*commaLen + len(vals)*10) + _ = dst.WriteByte('[') + for i, val := range vals { + if i > 0 { + _ = dst.WriteByte(',') + } + appendJSONValue(dst, val) + } + _ = dst.WriteByte(']') +} + +func appendValueSliceReflect(dst *strings.Builder, rv reflect.Value) { + // Estimate 10 bytes per value for small values and commas. + dst.Grow(jsonArrayBracketsLen + rv.Len()*commaLen + rv.Len()*10) + _ = dst.WriteByte('[') + for i := 0; i < rv.Len(); i++ { + if i > 0 { + _ = dst.WriteByte(',') + } + appendJSONValue(dst, rv.Index(i).Interface().(Value)) + } + _ = dst.WriteByte(']') +} + +func appendJSONValue(dst *strings.Builder, v Value) { + switch v.Type() { + case BOOL: + if v.AsBool() { + _, _ = dst.WriteString("true") + } else { + _, _ = dst.WriteString("false") + } + case BOOLSLICE: + appendBoolSliceValue(dst, v.slice) + case INT64: + var buf [int64ArrayElemMaxLen]byte + out := strconv.AppendInt(buf[:0], v.AsInt64(), 10) + _, _ = dst.Write(out) + case INT64SLICE: + appendInt64SliceValue(dst, v.slice) + case FLOAT64: + val := v.AsFloat64() + switch { + case math.IsNaN(val): + appendJSONString(dst, "NaN") + case math.IsInf(val, 1): + appendJSONString(dst, "Infinity") + case math.IsInf(val, -1): + appendJSONString(dst, "-Infinity") + default: + var buf [float64ArrayElemMaxLen]byte + out := strconv.AppendFloat(buf[:0], val, 'g', -1, 64) + _, _ = dst.Write(out) + } + case FLOAT64SLICE: + appendFloat64SliceValue(dst, v.slice) + case STRING: + appendJSONString(dst, v.stringly) + case STRINGSLICE: + appendStringSliceValue(dst, v.slice) + case BYTESLICE: + _ = dst.WriteByte('"') + appendBase64(dst, v.stringly) + _ = dst.WriteByte('"') + case SLICE: + appendValueSliceValue(dst, v.slice) + case EMPTY: + _, _ = dst.WriteString("null") + default: + appendJSONString(dst, "unknown") + } +} + +// appendJSONString appends s to dst as a JSON string literal. +// +// This is adapted from the Go standard library's encoding/json +// [appendString implementation]. It keeps the same escaping behavior we need +// here, but writes directly into a strings.Builder and intentionally does not +// apply HTML escaping because the OpenTelemetry non-OTLP AnyValue representation +// only requires JSON array string encoding. We inline this instead of using +// encoding/json so slice formatting avoids allocations and reflection. +// +// [appendString implementation]: https://github.com/golang/go/blob/3b5954c6349d31465dca409b45ab6597e0942d9f/src/encoding/json/encode.go#L998-L1064 +func appendJSONString(dst *strings.Builder, s string) { + const hex = "0123456789abcdef" // For escaping bytes to hex. + + _ = dst.WriteByte('"') + start := 0 + + for i := 0; i < len(s); { + if c := s[i]; c < utf8.RuneSelf { + if c >= 0x20 && c != '\\' && c != '"' { + i++ + continue + } + + if start < i { + _, _ = dst.WriteString(s[start:i]) + } + + switch c { + case '\\', '"': + _ = dst.WriteByte('\\') + _ = dst.WriteByte(c) + case '\b': + _, _ = dst.WriteString(`\b`) + case '\f': + _, _ = dst.WriteString(`\f`) + case '\n': + _, _ = dst.WriteString(`\n`) + case '\r': + _, _ = dst.WriteString(`\r`) + case '\t': + _, _ = dst.WriteString(`\t`) + default: + _, _ = dst.WriteString(`\u00`) + _ = dst.WriteByte(hex[c>>4]) + _ = dst.WriteByte(hex[c&0x0f]) + } + + i++ + start = i + continue + } + + r, size := utf8.DecodeRuneInString(s[i:]) + if r == utf8.RuneError && size == 1 { + if start < i { + _, _ = dst.WriteString(s[start:i]) + } + // Match encoding/json by replacing invalid UTF-8 with U+FFFD. + _, _ = dst.WriteString(`\ufffd`) + i++ + start = i + continue + } + + if r == '\u2028' || r == '\u2029' { + if start < i { + _, _ = dst.WriteString(s[start:i]) + } + // Escape JSONP-sensitive separators unconditionally, like encoding/json. + _, _ = dst.WriteString(`\u202`) + _ = dst.WriteByte(hex[r&0x0f]) + i += size + start = i + continue + } + + i += size + } + + if start < len(s) { + _, _ = dst.WriteString(s[start:]) + } + _ = dst.WriteByte('"') +} + +// This is adapted from the Go standard library's encoding/base64 +// [Encoding.Encode implementation]. It keeps the same encoding behavior we need +// here, but writes directly into a strings.Builder. We inline this instead of using +// encoding/base64 to avoid allocations. +// +// [Encoding.Encode implementation]: https://github.com/golang/go/blob/3b5954c6349d31465dca409b45ab6597e0942d9f/src/encoding/base64/base64.go#L139-L189 +func appendBase64(dst *strings.Builder, s string) { + const encode = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + + dst.Grow(base64.StdEncoding.EncodedLen(len(s))) + + i := 0 + for ; i+2 < len(s); i += 3 { + n := uint32(s[i])<<16 | uint32(s[i+1])<<8 | uint32(s[i+2]) + _ = dst.WriteByte(encode[n>>18&0x3f]) + _ = dst.WriteByte(encode[n>>12&0x3f]) + _ = dst.WriteByte(encode[n>>6&0x3f]) + _ = dst.WriteByte(encode[n&0x3f]) + } + + switch len(s) - i { + case 1: + n := uint32(s[i]) << 16 + _ = dst.WriteByte(encode[n>>18&0x3f]) + _ = dst.WriteByte(encode[n>>12&0x3f]) + _ = dst.WriteByte('=') + _ = dst.WriteByte('=') + case 2: + n := uint32(s[i])<<16 | uint32(s[i+1])<<8 + _ = dst.WriteByte(encode[n>>18&0x3f]) + _ = dst.WriteByte(encode[n>>12&0x3f]) + _ = dst.WriteByte(encode[n>>6&0x3f]) + _ = dst.WriteByte('=') + } +} + // MarshalJSON returns the JSON encoding of the Value. func (v Value) MarshalJSON() ([]byte, error) { var jsonVal struct { diff --git a/vendor/go.opentelemetry.io/otel/baggage/baggage.go b/vendor/go.opentelemetry.io/otel/baggage/baggage.go index 878ffbe43..b290c6d6c 100644 --- a/vendor/go.opentelemetry.io/otel/baggage/baggage.go +++ b/vendor/go.opentelemetry.io/otel/baggage/baggage.go @@ -14,6 +14,10 @@ import ( ) const ( + maxParseErrors = 5 + + // W3C Baggage specification limits. + // https://www.w3.org/TR/baggage/#limits maxMembers = 64 maxBytesPerBaggageString = 8192 @@ -493,9 +497,15 @@ func New(members ...Member) (Baggage, error) { // from the W3C Baggage specification which allows duplicate list-members, but // conforms to the OpenTelemetry Baggage specification. // -// If the baggage-string exceeds the maximum allowed members (64) or bytes -// (8192), members are dropped until the limits are satisfied and an error is -// returned along with the partial result. +// If the raw baggage-string exceeds the maximum allowed bytes (8192), an +// empty Baggage and an error are returned. +// +// Otherwise, members are parsed left-to-right and accumulated until one of +// the following conditions is reached, at which point parsing stops and an +// error is returned alongside the partial result: +// - accepting the next member would cause the encoded baggage to exceed +// 8192 bytes, or +// - the baggage already contains 64 distinct keys. // // Invalid members are skipped and the error is returned along with the // partial result containing the valid members. @@ -504,9 +514,14 @@ func Parse(bStr string) (Baggage, error) { return Baggage{}, nil } + if n := len(bStr); n > maxBytesPerBaggageString { + return Baggage{}, fmt.Errorf("%w: %d", errBaggageBytes, n) + } + b := make(baggage.List) sizes := make(map[string]int) // Track per-key byte sizes var totalBytes int + var parseErrors int var truncateErr error for memberStr := range strings.SplitSeq(bStr, listDelimiter) { // Check member count limit. @@ -517,7 +532,10 @@ func Parse(bStr string) (Baggage, error) { m, err := parseMember(memberStr) if err != nil { - truncateErr = errors.Join(truncateErr, err) + parseErrors++ + if parseErrors <= maxParseErrors { + truncateErr = errors.Join(truncateErr, err) + } continue // skip invalid member, keep processing } @@ -553,6 +571,10 @@ func Parse(bStr string) (Baggage, error) { totalBytes = newTotalBytes } + if dropped := parseErrors - maxParseErrors; dropped > 0 { + truncateErr = errors.Join(truncateErr, fmt.Errorf("and %d more invalid member(s)", dropped)) + } + if len(b) == 0 { return Baggage{}, truncateErr } diff --git a/vendor/go.opentelemetry.io/otel/dependencies.Dockerfile b/vendor/go.opentelemetry.io/otel/dependencies.Dockerfile index 7a9b3c055..74fa510bc 100644 --- a/vendor/go.opentelemetry.io/otel/dependencies.Dockerfile +++ b/vendor/go.opentelemetry.io/otel/dependencies.Dockerfile @@ -1,4 +1,4 @@ # This is a renovate-friendly source of Docker images. FROM python:3.13.6-slim-bullseye@sha256:e98b521460ee75bca92175c16247bdf7275637a8faaeb2bcfa19d879ae5c4b9a AS python -FROM otel/weaver:v0.22.1@sha256:33ae522ae4b71c1c562563c1d81f46aa0f79f088a0873199143a1f11ac30e5c9 AS weaver +FROM otel/weaver:v0.23.0@sha256:7984ecb55b859eb3034ae9d836c4eeda137e2bdd0873b7ba2bb6c3d24d6ff457 AS weaver FROM avtodev/markdown-lint:v1@sha256:6aeedc2f49138ce7a1cd0adffc1b1c0321b841dc2102408967d9301c031949ee AS markdown diff --git a/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go b/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go index 466812d34..1d21e2eb7 100644 --- a/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go +++ b/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go @@ -51,6 +51,9 @@ type Float64ObservableCounterConfig struct { func NewFloat64ObservableCounterConfig(opts ...Float64ObservableCounterOption) Float64ObservableCounterConfig { var config Float64ObservableCounterConfig for _, o := range opts { + if _, ok := o.(experimentalOption); ok { + continue + } config = o.applyFloat64ObservableCounter(config) } return config @@ -111,6 +114,9 @@ func NewFloat64ObservableUpDownCounterConfig( ) Float64ObservableUpDownCounterConfig { var config Float64ObservableUpDownCounterConfig for _, o := range opts { + if _, ok := o.(experimentalOption); ok { + continue + } config = o.applyFloat64ObservableUpDownCounter(config) } return config @@ -168,6 +174,9 @@ type Float64ObservableGaugeConfig struct { func NewFloat64ObservableGaugeConfig(opts ...Float64ObservableGaugeOption) Float64ObservableGaugeConfig { var config Float64ObservableGaugeConfig for _, o := range opts { + if _, ok := o.(experimentalOption); ok { + continue + } config = o.applyFloat64ObservableGauge(config) } return config diff --git a/vendor/go.opentelemetry.io/otel/metric/asyncint64.go b/vendor/go.opentelemetry.io/otel/metric/asyncint64.go index 66c971bd8..9d45a4d41 100644 --- a/vendor/go.opentelemetry.io/otel/metric/asyncint64.go +++ b/vendor/go.opentelemetry.io/otel/metric/asyncint64.go @@ -50,6 +50,9 @@ type Int64ObservableCounterConfig struct { func NewInt64ObservableCounterConfig(opts ...Int64ObservableCounterOption) Int64ObservableCounterConfig { var config Int64ObservableCounterConfig for _, o := range opts { + if _, ok := o.(experimentalOption); ok { + continue + } config = o.applyInt64ObservableCounter(config) } return config @@ -110,6 +113,9 @@ func NewInt64ObservableUpDownCounterConfig( ) Int64ObservableUpDownCounterConfig { var config Int64ObservableUpDownCounterConfig for _, o := range opts { + if _, ok := o.(experimentalOption); ok { + continue + } config = o.applyInt64ObservableUpDownCounter(config) } return config @@ -167,6 +173,9 @@ type Int64ObservableGaugeConfig struct { func NewInt64ObservableGaugeConfig(opts ...Int64ObservableGaugeOption) Int64ObservableGaugeConfig { var config Int64ObservableGaugeConfig for _, o := range opts { + if _, ok := o.(experimentalOption); ok { + continue + } config = o.applyInt64ObservableGauge(config) } return config diff --git a/vendor/go.opentelemetry.io/otel/metric/config.go b/vendor/go.opentelemetry.io/otel/metric/config.go index e42dd6e70..889545e23 100644 --- a/vendor/go.opentelemetry.io/otel/metric/config.go +++ b/vendor/go.opentelemetry.io/otel/metric/config.go @@ -42,11 +42,18 @@ type MeterOption interface { applyMeter(MeterConfig) MeterConfig } +type experimentalOption interface { + Experimental() +} + // NewMeterConfig creates a new MeterConfig and applies // all the given options. func NewMeterConfig(opts ...MeterOption) MeterConfig { var config MeterConfig for _, o := range opts { + if _, ok := o.(experimentalOption); ok { + continue + } config = o.applyMeter(config) } return config diff --git a/vendor/go.opentelemetry.io/otel/metric/doc.go b/vendor/go.opentelemetry.io/otel/metric/doc.go index f153745b0..794e1a8ba 100644 --- a/vendor/go.opentelemetry.io/otel/metric/doc.go +++ b/vendor/go.opentelemetry.io/otel/metric/doc.go @@ -24,10 +24,10 @@ all instruments fall into two overlapping logical categories: asynchronous or synchronous, and int64 or float64. All synchronous instruments ([Int64Counter], [Int64UpDownCounter], -[Int64Histogram], [Float64Counter], [Float64UpDownCounter], and -[Float64Histogram]) are used to measure the operation and performance of source -code during the source code execution. These instruments only make measurements -when the source code they instrument is run. +[Int64Histogram], [Int64Gauge], [Float64Counter], [Float64UpDownCounter], +[Float64Histogram], and [Float64Gauge]) are used to measure the operation and +performance of source code during the source code execution. These instruments +only make measurements when the source code they instrument is run. All asynchronous instruments ([Int64ObservableCounter], [Int64ObservableUpDownCounter], [Int64ObservableGauge], @@ -50,9 +50,11 @@ incrementally increase in value. UpDownCounters ([Int64UpDownCounter], values that can increase and decrease. When more information needs to be conveyed about all the synchronous measurements made during a collection cycle, a Histogram ([Int64Histogram] and [Float64Histogram]) should be used. Finally, -when just the most recent measurement needs to be conveyed about an -asynchronous measurement, a Gauge ([Int64ObservableGauge] and -[Float64ObservableGauge]) should be used. +when just the most recent measurement needs to be conveyed, a Gauge +([Int64Gauge], [Float64Gauge], [Int64ObservableGauge], and +[Float64ObservableGauge]) should be used: the synchronous variants record an +instantaneous value at a specific point in code, while the observable variants +sample the value via a callback once per collection cycle. See the [OpenTelemetry documentation] for more information about instruments and their intended use. @@ -80,11 +82,11 @@ Measurements are made by recording values and information about the values with an instrument. How these measurements are recorded depends on the instrument. Measurements for synchronous instruments ([Int64Counter], [Int64UpDownCounter], -[Int64Histogram], [Float64Counter], [Float64UpDownCounter], and -[Float64Histogram]) are recorded using the instrument methods directly. All -counter instruments have an Add method that is used to measure an increment -value, and all histogram instruments have a Record method to measure a data -point. +[Int64Histogram], [Int64Gauge], [Float64Counter], [Float64UpDownCounter], +[Float64Histogram], and [Float64Gauge]) are recorded using the instrument +methods directly. All counter instruments have an Add method that is used to +measure an increment value, and all histogram and synchronous gauge +instruments have a Record method to measure a data point. Asynchronous instruments ([Int64ObservableCounter], [Int64ObservableUpDownCounter], [Int64ObservableGauge], @@ -107,6 +109,31 @@ respectively): If the criteria are not met, use the RegisterCallback method of the [Meter] that created the instrument to register a [Callback]. +# Avoiding Expensive Computations + +All synchronous instruments provide an Enabled method that reports whether the +instrument will process measurements for the given context. When no SDK is +registered or the instrument is otherwise disabled, Enabled returns false. This +can be used to avoid expensive measurement work when a measurement will not be +recorded: + + if counter.Enabled(ctx) { + counter.Add(ctx, 1, metric.WithAttributes(expensiveAttributes()...)) + } + +This is especially valuable when computing attributes is expensive. +[WithAttributes] performs non-trivial work on every call to build an +[attribute.Set] from the provided attributes, and that work is wasted if the +measurement is not recorded. + +For performance sensitive code where the same attribute set is used repeatedly, +prefer [WithAttributeSet]. It accepts a pre-built [attribute.Set], letting you +pay the construction cost once and reuse it across many measurements: + + attrs := attribute.NewSet(attribute.String("key", "val")) + // ... later, on each call: + counter.Add(ctx, 1, metric.WithAttributeSet(attrs)) + # API Implementations This package does not conform to the standard Go versioning policy, all of its diff --git a/vendor/go.opentelemetry.io/otel/metric/instrument.go b/vendor/go.opentelemetry.io/otel/metric/instrument.go index 9f48d5f11..2e79ab568 100644 --- a/vendor/go.opentelemetry.io/otel/metric/instrument.go +++ b/vendor/go.opentelemetry.io/otel/metric/instrument.go @@ -3,7 +3,9 @@ package metric // import "go.opentelemetry.io/otel/metric" -import "go.opentelemetry.io/otel/attribute" +import ( + "go.opentelemetry.io/otel/attribute" +) // Observable is used as a grouping mechanism for all instruments that are // updated within a Callback. @@ -228,6 +230,9 @@ type AddConfig struct { func NewAddConfig(opts []AddOption) AddConfig { config := AddConfig{attrs: *attribute.EmptySet()} for _, o := range opts { + if _, ok := o.(experimentalOption); ok { + continue + } config = o.applyAdd(config) } return config @@ -253,6 +258,9 @@ type RecordConfig struct { func NewRecordConfig(opts []RecordOption) RecordConfig { config := RecordConfig{attrs: *attribute.EmptySet()} for _, o := range opts { + if _, ok := o.(experimentalOption); ok { + continue + } config = o.applyRecord(config) } return config @@ -278,6 +286,9 @@ type ObserveConfig struct { func NewObserveConfig(opts []ObserveOption) ObserveConfig { config := ObserveConfig{attrs: *attribute.EmptySet()} for _, o := range opts { + if _, ok := o.(experimentalOption); ok { + continue + } config = o.applyObserve(config) } return config @@ -299,6 +310,10 @@ type attrOpt struct { set attribute.Set } +func (o *attrOpt) Set(set attribute.Set) { + o.set = set +} + // mergeSets returns the union of keys between a and b. Any duplicate keys will // use the value associated with b. func mergeSets(a, b attribute.Set) attribute.Set { @@ -311,7 +326,7 @@ func mergeSets(a, b attribute.Set) attribute.Set { return attribute.NewSet(merged...) } -func (o attrOpt) applyAdd(c AddConfig) AddConfig { +func (o *attrOpt) applyAdd(c AddConfig) AddConfig { switch { case o.set.Len() == 0: case c.attrs.Len() == 0: @@ -322,7 +337,7 @@ func (o attrOpt) applyAdd(c AddConfig) AddConfig { return c } -func (o attrOpt) applyRecord(c RecordConfig) RecordConfig { +func (o *attrOpt) applyRecord(c RecordConfig) RecordConfig { switch { case o.set.Len() == 0: case c.attrs.Len() == 0: @@ -333,7 +348,7 @@ func (o attrOpt) applyRecord(c RecordConfig) RecordConfig { return c } -func (o attrOpt) applyObserve(c ObserveConfig) ObserveConfig { +func (o *attrOpt) applyObserve(c ObserveConfig) ObserveConfig { switch { case o.set.Len() == 0: case c.attrs.Len() == 0: @@ -350,8 +365,14 @@ func (o attrOpt) applyObserve(c ObserveConfig) ObserveConfig { // If multiple WithAttributeSet or WithAttributes options are passed the // attributes will be merged together in the order they are passed. Attributes // with duplicate keys will use the last value passed. +// +// Experimental: The returned option may implement +// [go.opentelemetry.io/otel/metric/x.Settable][attribute.Set], which can be +// used to replace the option's attribute set and reuse the option without +// additional allocations. This behavior is experimental and may be changed or +// removed in a future release without notice. func WithAttributeSet(attributes attribute.Set) MeasurementOption { - return attrOpt{set: attributes} + return &attrOpt{set: attributes} } // WithAttributes converts attributes into an attribute Set and sets the Set to @@ -369,8 +390,14 @@ func WithAttributeSet(attributes attribute.Set) MeasurementOption { // // See [WithAttributeSet] for information about how multiple WithAttributes are // merged. +// +// Experimental: The returned option may implement +// [go.opentelemetry.io/otel/metric/x.Settable][[]attribute.KeyValue], which can be +// used to replace the option's attributes and reuse the option without +// additional allocations. This behavior is experimental and may be changed or +// removed in a future release without notice. func WithAttributes(attributes ...attribute.KeyValue) MeasurementOption { cp := make([]attribute.KeyValue, len(attributes)) copy(cp, attributes) - return attrOpt{set: attribute.NewSet(cp...)} + return &attrOpt{set: attribute.NewSet(cp...)} } diff --git a/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go b/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go index abb3051d7..2101f686a 100644 --- a/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go +++ b/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go @@ -51,6 +51,9 @@ type Float64CounterConfig struct { func NewFloat64CounterConfig(opts ...Float64CounterOption) Float64CounterConfig { var config Float64CounterConfig for _, o := range opts { + if _, ok := o.(experimentalOption); ok { + continue + } config = o.applyFloat64Counter(config) } return config @@ -116,6 +119,9 @@ type Float64UpDownCounterConfig struct { func NewFloat64UpDownCounterConfig(opts ...Float64UpDownCounterOption) Float64UpDownCounterConfig { var config Float64UpDownCounterConfig for _, o := range opts { + if _, ok := o.(experimentalOption); ok { + continue + } config = o.applyFloat64UpDownCounter(config) } return config @@ -182,6 +188,9 @@ type Float64HistogramConfig struct { func NewFloat64HistogramConfig(opts ...Float64HistogramOption) Float64HistogramConfig { var config Float64HistogramConfig for _, o := range opts { + if _, ok := o.(experimentalOption); ok { + continue + } config = o.applyFloat64Histogram(config) } return config @@ -251,6 +260,9 @@ type Float64GaugeConfig struct { func NewFloat64GaugeConfig(opts ...Float64GaugeOption) Float64GaugeConfig { var config Float64GaugeConfig for _, o := range opts { + if _, ok := o.(experimentalOption); ok { + continue + } config = o.applyFloat64Gauge(config) } return config diff --git a/vendor/go.opentelemetry.io/otel/metric/syncint64.go b/vendor/go.opentelemetry.io/otel/metric/syncint64.go index 5bbfaf039..425c1a0d5 100644 --- a/vendor/go.opentelemetry.io/otel/metric/syncint64.go +++ b/vendor/go.opentelemetry.io/otel/metric/syncint64.go @@ -51,6 +51,9 @@ type Int64CounterConfig struct { func NewInt64CounterConfig(opts ...Int64CounterOption) Int64CounterConfig { var config Int64CounterConfig for _, o := range opts { + if _, ok := o.(experimentalOption); ok { + continue + } config = o.applyInt64Counter(config) } return config @@ -116,6 +119,9 @@ type Int64UpDownCounterConfig struct { func NewInt64UpDownCounterConfig(opts ...Int64UpDownCounterOption) Int64UpDownCounterConfig { var config Int64UpDownCounterConfig for _, o := range opts { + if _, ok := o.(experimentalOption); ok { + continue + } config = o.applyInt64UpDownCounter(config) } return config @@ -182,6 +188,9 @@ type Int64HistogramConfig struct { func NewInt64HistogramConfig(opts ...Int64HistogramOption) Int64HistogramConfig { var config Int64HistogramConfig for _, o := range opts { + if _, ok := o.(experimentalOption); ok { + continue + } config = o.applyInt64Histogram(config) } return config @@ -251,6 +260,9 @@ type Int64GaugeConfig struct { func NewInt64GaugeConfig(opts ...Int64GaugeOption) Int64GaugeConfig { var config Int64GaugeConfig for _, o := range opts { + if _, ok := o.(experimentalOption); ok { + continue + } config = o.applyInt64Gauge(config) } return config diff --git a/vendor/go.opentelemetry.io/otel/propagation/baggage.go b/vendor/go.opentelemetry.io/otel/propagation/baggage.go index 2ecca3fed..d81b709a2 100644 --- a/vendor/go.opentelemetry.io/otel/propagation/baggage.go +++ b/vendor/go.opentelemetry.io/otel/propagation/baggage.go @@ -5,6 +5,9 @@ package propagation // import "go.opentelemetry.io/otel/propagation" import ( "context" + "errors" + "fmt" + "sync" "go.opentelemetry.io/otel/baggage" "go.opentelemetry.io/otel/internal/errorhandler" @@ -13,11 +16,18 @@ import ( const ( baggageHeader = "baggage" + maxParseErrors = 5 + // W3C Baggage specification limits. // https://www.w3.org/TR/baggage/#limits - maxMembers = 64 + maxMembers = 64 + maxBytesPerBaggageString = 8192 ) +// handleExtractErrOnce limits error reporting for attacker-controlled baggage headers +// to one process-wide emission, preventing repeated extraction from flooding logs. +var handleExtractErrOnce sync.Once + // Baggage is a propagator that supports the W3C Baggage format. // // This propagates user-defined baggage associated with a trace. The complete @@ -57,7 +67,9 @@ func extractSingleBaggage(parent context.Context, carrier TextMapCarrier) contex bag, err := baggage.Parse(bStr) if err != nil { - errorhandler.GetErrorHandler().Handle(err) + handleExtractErrOnce.Do(func() { + errorhandler.GetErrorHandler().Handle(err) + }) } if bag.Len() == 0 { return parent @@ -72,24 +84,60 @@ func extractMultiBaggage(parent context.Context, carrier ValuesGetter) context.C } var members []baggage.Member - for _, bStr := range bVals { - currBag, err := baggage.Parse(bStr) - if err != nil { - errorhandler.GetErrorHandler().Handle(err) + var totalBytes int + var parseErrors int + var truncateErr error + for i, bStr := range bVals { + if i > 0 { + totalBytes++ // comma separator between combined header values } - if currBag.Len() == 0 { - continue + totalBytes += len(bStr) + if totalBytes > maxBytesPerBaggageString { + // Per the W3C Baggage spec, the byte limit applies to the + // combination of all baggage headers, not each header + // individually. Mirror the single-header behavior of + // reporting the error and returning the parent context + // with no baggage attached. + handleExtractErrOnce.Do(func() { + errorhandler.GetErrorHandler().Handle(fmt.Errorf( + "baggage: aggregate header size %d exceeds %d byte limit", + totalBytes, + maxBytesPerBaggageString, + )) + }) + return parent } - members = append(members, currBag.Members()...) - if len(members) >= maxMembers { - break + + // If members exceed the limit, stop parsing baggage. + if len(members) <= maxMembers { + currBag, err := baggage.Parse(bStr) + if err != nil { + parseErrors++ + if parseErrors <= maxParseErrors { + truncateErr = errors.Join(truncateErr, err) + } + } + if currBag.Len() == 0 { + continue + } + members = append(members, currBag.Members()...) } } + if dropped := parseErrors - maxParseErrors; dropped > 0 { + truncateErr = errors.Join(truncateErr, fmt.Errorf("and %d more error(s)", dropped)) + } + b, err := baggage.New(members...) if err != nil { - errorhandler.GetErrorHandler().Handle(err) + truncateErr = errors.Join(truncateErr, err) } + if truncateErr != nil { + handleExtractErrOnce.Do(func() { + errorhandler.GetErrorHandler().Handle(truncateErr) + }) + } + if b.Len() == 0 { return parent } diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/attribute_group.go b/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/attribute_group.go index b6b27498f..2fcab2435 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/attribute_group.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/attribute_group.go @@ -1447,9 +1447,11 @@ func AWSExtendedRequestID(val string) attribute.KeyValue { // AWSKinesisStreamName returns an attribute KeyValue conforming to the // "aws.kinesis.stream_name" semantic conventions. It represents the name of the // AWS Kinesis [stream] the request refers to. Corresponds to the `--stream-name` -// parameter of the Kinesis [describe-stream] operation. +// +// parameter of the Kinesis [describe-stream] operation. // // [stream]: https://docs.aws.amazon.com/streams/latest/dev/introduction.html +// // [describe-stream]: https://docs.aws.amazon.com/cli/latest/reference/kinesis/describe-stream.html func AWSKinesisStreamName(val string) attribute.KeyValue { return AWSKinesisStreamNameKey.String(val) @@ -1459,7 +1461,8 @@ func AWSKinesisStreamName(val string) attribute.KeyValue { // "aws.lambda.invoked_arn" semantic conventions. It represents the full invoked // ARN as provided on the `Context` passed to the function ( // `Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next` -// applicable). +// +// applicable). func AWSLambdaInvokedARN(val string) attribute.KeyValue { return AWSLambdaInvokedARNKey.String(val) } @@ -2635,7 +2638,8 @@ func CloudRegion(val string) attribute.KeyValue { // "cloud.resource_id" semantic conventions. It represents the cloud // provider-specific native identifier of the monitored cloud resource (e.g. an // [ARN] on AWS, a [fully qualified resource ID] on Azure, a [full resource name] -// on GCP). +// +// on GCP). // // [ARN]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html // [fully qualified resource ID]: https://learn.microsoft.com/rest/api/resources/resources/get-by-id @@ -15190,4 +15194,4 @@ func ZOSSmfID(val string) attribute.KeyValue { // to which the z/OS system belongs too. func ZOSSysplexName(val string) attribute.KeyValue { return ZOSSysplexNameKey.String(val) -} \ No newline at end of file +} diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/README.md b/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/README.md deleted file mode 100644 index c51b7fb7b..000000000 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Semconv v1.40.0 - -[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/semconv/v1.40.0)](https://pkg.go.dev/go.opentelemetry.io/otel/semconv/v1.40.0) diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/MIGRATION.md b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/MIGRATION.md similarity index 63% rename from vendor/go.opentelemetry.io/otel/semconv/v1.40.0/MIGRATION.md rename to vendor/go.opentelemetry.io/otel/semconv/v1.41.0/MIGRATION.md index e246b1692..ba52cadf7 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/MIGRATION.md +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/MIGRATION.md @@ -1,7 +1,7 @@ -# Migration from v1.39.0 to v1.40.0 +# Migration from v1.40.0 to v1.41.0 -The `go.opentelemetry.io/otel/semconv/v1.40.0` package should be a drop-in replacement for `go.opentelemetry.io/otel/semconv/v1.39.0` with the following exceptions. +The `go.opentelemetry.io/otel/semconv/v1.41.0` package should be a drop-in replacement for `go.opentelemetry.io/otel/semconv/v1.40.0` with the following exceptions. ## Removed @@ -11,17 +11,7 @@ Refer to the [OpenTelemetry Semantic Conventions documentation] for deprecation If the type is not listed in the documentation as deprecated, it has been removed in this version due to lack of applicability or use. If you use any of these non-deprecated declarations in your Go application, please [open an issue] describing your use-case. -- `ErrorMessage` -- `ErrorMessageKey` -- `RPCMessageCompressedSize` -- `RPCMessageCompressedSizeKey` -- `RPCMessageID` -- `RPCMessageIDKey` -- `RPCMessageTypeKey` -- `RPCMessageTypeReceived` -- `RPCMessageTypeSent` -- `RPCMessageUncompressedSize` -- `RPCMessageUncompressedSizeKey` +- `DeploymentEnvironmentName` [OpenTelemetry Semantic Conventions documentation]: https://github.com/open-telemetry/semantic-conventions [open an issue]: https://github.com/open-telemetry/opentelemetry-go/issues/new?template=Blank+issue diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/README.md b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/README.md new file mode 100644 index 000000000..8353bb715 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/README.md @@ -0,0 +1,3 @@ +# Semconv v1.41.0 + +[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/semconv/v1.41.0)](https://pkg.go.dev/go.opentelemetry.io/otel/semconv/v1.41.0) diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/attribute_group.go b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/attribute_group.go similarity index 96% rename from vendor/go.opentelemetry.io/otel/semconv/v1.40.0/attribute_group.go rename to vendor/go.opentelemetry.io/otel/semconv/v1.41.0/attribute_group.go index ee6b1f79d..7cee08680 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/attribute_group.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/attribute_group.go @@ -3,7 +3,7 @@ // Code generated from semantic convention specification. DO NOT EDIT. -package semconv // import "go.opentelemetry.io/otel/semconv/v1.40.0" +package semconv // import "go.opentelemetry.io/otel/semconv/v1.41.0" import "go.opentelemetry.io/otel/attribute" @@ -950,7 +950,7 @@ const ( // of the [AWS Lambda EvenSource Mapping]. An event source is mapped to a lambda // function. It's contents are read by Lambda and used to trigger a function. // This isn't available in the lambda execution context or the lambda runtime - // environtment. This is going to be populated by the AWS SDK for each language + // environment. This is going to be populated by the AWS SDK for each language // when that UUID is present. Some of these operations are // Create/Delete/Get/List/Update EventSourceMapping. // @@ -1186,7 +1186,7 @@ const ( // AWSSecretsmanagerSecretARNKey is the attribute Key conforming to the // "aws.secretsmanager.secret.arn" semantic conventions. It represents the ARN - // of the Secret stored in the Secrets Mangger. + // of the Secret stored in the Secrets Manager. // // Type: string // RequirementLevel: Recommended @@ -1515,7 +1515,7 @@ func AWSLambdaInvokedARN(val string) attribute.KeyValue { // of the [AWS Lambda EvenSource Mapping]. An event source is mapped to a lambda // function. It's contents are read by Lambda and used to trigger a function. // This isn't available in the lambda execution context or the lambda runtime -// environtment. This is going to be populated by the AWS SDK for each language +// environment. This is going to be populated by the AWS SDK for each language // when that UUID is present. Some of these operations are // Create/Delete/Get/List/Update EventSourceMapping. // @@ -1609,7 +1609,7 @@ func AWSS3UploadID(val string) attribute.KeyValue { // AWSSecretsmanagerSecretARN returns an attribute KeyValue conforming to the // "aws.secretsmanager.secret.arn" semantic conventions. It represents the ARN of -// the Secret stored in the Secrets Mangger. +// the Secret stored in the Secrets Manager. func AWSSecretsmanagerSecretARN(val string) attribute.KeyValue { return AWSSecretsmanagerSecretARNKey.String(val) } @@ -2196,6 +2196,11 @@ const ( // Stability: Development // // Examples: "12097" + // Note: For a given pipeline run and task, the `cicd.pipeline.task.run.id` MUST + // be unique within that run. For the same task across different runs of the + // same pipeline, the `cicd.pipeline.task.run.id` MAY remain the same, enabling + // correlation of `cicd.pipeline.task.run.result` values across multiple + // pipeline runs. CICDPipelineTaskRunIDKey = attribute.Key("cicd.pipeline.task.run.id") // CICDPipelineTaskRunResultKey is the attribute Key conforming to the @@ -3431,7 +3436,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "a3bf90e006b2" // @@ -3467,7 +3472,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "gcr.io/opentelemetry/operator" ContainerImageNameKey = attribute.Key("container.image.name") @@ -3478,7 +3483,7 @@ const ( // // Type: string[] // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: // "example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb", @@ -3497,7 +3502,7 @@ const ( // // Type: string[] // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "v1.27.1", "3.5.7-0" // @@ -3518,7 +3523,7 @@ const ( // ContainerRuntimeDescriptionKey is the attribute Key conforming to the // "container.runtime.description" semantic conventions. It represents a // description about the runtime which could include, for example details about - // the CRI/API version being used or other customisations. + // the CRI/API version being used or other customizations. // // Type: string // RequirementLevel: Recommended @@ -3649,7 +3654,7 @@ func ContainerName(val string) attribute.KeyValue { // ContainerRuntimeDescription returns an attribute KeyValue conforming to the // "container.runtime.description" semantic conventions. It represents a // description about the runtime which could include, for example details about -// the CRI/API version being used or other customisations. +// the CRI/API version being used or other customizations. func ContainerRuntimeDescription(val string) attribute.KeyValue { return ContainerRuntimeDescriptionKey.String(val) } @@ -4260,9 +4265,9 @@ const ( // "deployment.environment.name" semantic conventions. It represents the name of // the [deployment environment] (aka deployment tier). // - // Type: string + // Type: Enum // RequirementLevel: Recommended - // Stability: Development + // Stability: Stable // // Examples: "staging", "production" // Note: `deployment.environment.name` does not affect the uniqueness @@ -4312,15 +4317,6 @@ const ( DeploymentStatusKey = attribute.Key("deployment.status") ) -// DeploymentEnvironmentName returns an attribute KeyValue conforming to the -// "deployment.environment.name" semantic conventions. It represents the name of -// the [deployment environment] (aka deployment tier). -// -// [deployment environment]: https://wikipedia.org/wiki/Deployment_environment -func DeploymentEnvironmentName(val string) attribute.KeyValue { - return DeploymentEnvironmentNameKey.String(val) -} - // DeploymentID returns an attribute KeyValue conforming to the "deployment.id" // semantic conventions. It represents the id of the deployment. func DeploymentID(val string) attribute.KeyValue { @@ -4334,6 +4330,22 @@ func DeploymentName(val string) attribute.KeyValue { return DeploymentNameKey.String(val) } +// Enum values for deployment.environment.name +var ( + // Production environment + // Stability: stable + DeploymentEnvironmentNameProduction = DeploymentEnvironmentNameKey.String("production") + // Staging environment + // Stability: stable + DeploymentEnvironmentNameStaging = DeploymentEnvironmentNameKey.String("staging") + // Testing environment + // Stability: stable + DeploymentEnvironmentNameTest = DeploymentEnvironmentNameKey.String("test") + // Development environment + // Stability: stable + DeploymentEnvironmentNameDevelopment = DeploymentEnvironmentNameKey.String("development") +) + // Enum values for deployment.status var ( // failed @@ -4645,6 +4657,12 @@ const ( // When `error.type` is set to a type (e.g., an exception type), its // canonical class name identifying the type within the artifact SHOULD be used. // + // If the recorded error type is a wrapper that is not meaningful for + // failure classification, instrumentation MAY use the type of the inner + // error instead. For example, in Go, errors created with `fmt.Errorf` + // using `%w` MAY be unwrapped when the wrapper type does not help + // classify the failure. + // // Instrumentations SHOULD document the list of errors they report. // // The cardinality of `error.type` within one instrumentation library SHOULD be @@ -4718,6 +4736,11 @@ const ( // Stability: Stable // // Examples: "java.net.ConnectException", "OSError" + // Note: If the recorded exception type is a wrapper that is not meaningful for + // failure classification, instrumentation MAY use the type of the inner + // exception instead. For example, in Go, errors created with `fmt.Errorf` + // using `%w` MAY be unwrapped when the wrapper type does not help + // classify the failure. ExceptionTypeKey = attribute.Key("exception.type") ) @@ -6667,6 +6690,17 @@ const ( // Examples: "forest", "lived" GenAIRequestStopSequencesKey = attribute.Key("gen_ai.request.stop_sequences") + // GenAIRequestStreamKey is the attribute Key conforming to the + // "gen_ai.request.stream" semantic conventions. It represents the indicates + // whether the GenAI request was made in streaming mode. + // + // Type: boolean + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: + GenAIRequestStreamKey = attribute.Key("gen_ai.request.stream") + // GenAIRequestTemperatureKey is the attribute Key conforming to the // "gen_ai.request.temperature" semantic conventions. It represents the // temperature setting for the GenAI request. @@ -6734,6 +6768,19 @@ const ( // Examples: "gpt-4-0613" GenAIResponseModelKey = attribute.Key("gen_ai.response.model") + // GenAIResponseTimeToFirstChunkKey is the attribute Key conforming to the + // "gen_ai.response.time_to_first_chunk" semantic conventions. It represents the + // time to first chunk in a streaming response, measured from request issuance, + // in seconds. The value is measured from when the client issues the generation + // request to when the first chunk is received in the response stream. + // + // Type: double + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: 0.5, 1.2 + GenAIResponseTimeToFirstChunkKey = attribute.Key("gen_ai.response.time_to_first_chunk") + // GenAIRetrievalDocumentsKey is the attribute Key conforming to the // "gen_ai.retrieval.documents" semantic conventions. It represents the // documents retrieved. @@ -6875,7 +6922,7 @@ const ( // GenAIToolDefinitionsKey is the attribute Key conforming to the // "gen_ai.tool.definitions" semantic conventions. It represents the list of - // source system tool definitions available to the GenAI agent or model. + // tool definitions available to the GenAI agent or model. // // Type: any // RequirementLevel: Recommended @@ -6887,19 +6934,18 @@ const ( // "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": // {\n "type": "string",\n "enum": [\n "celsius",\n "fahrenheit"\n ]\n }\n },\n // "required": [\n "location",\n "unit"\n ]\n }\n }\n]\n" - // Note: The value of this attribute matches source system tool definition - // format. + // Note: Instrumentations MUST follow [Tool Definitions JSON Schema]. // - // It's expected to be an array of objects where each object represents a tool - // definition. In case a serialized string is available - // to the instrumentation, the instrumentation SHOULD do the best effort to - // deserialize it to an array. When recorded on spans, it MAY be recorded as a - // JSON string if structured format is not supported and SHOULD be recorded in - // structured form otherwise. + // When the attribute is recorded on events, it MUST be recorded in structured + // form. When recorded on spans, it MAY be recorded as a JSON string if + // structured + // format is not supported and SHOULD be recorded in structured form otherwise. // // Since this attribute could be large, it's NOT RECOMMENDED to populate - // it by default. Instrumentations MAY provide a way to enable - // populating this attribute. + // non-required properties by default. Instrumentations MAY provide a way + // to enable populating optional properties. + // + // [Tool Definitions JSON Schema]: /docs/gen-ai/gen-ai-tool-definitions.json GenAIToolDefinitionsKey = attribute.Key("gen_ai.tool.definitions") // GenAIToolDescriptionKey is the attribute Key conforming to the @@ -6997,6 +7043,32 @@ const ( // // Examples: 180 GenAIUsageOutputTokensKey = attribute.Key("gen_ai.usage.output_tokens") + + // GenAIUsageReasoningOutputTokensKey is the attribute Key conforming to the + // "gen_ai.usage.reasoning.output_tokens" semantic conventions. It represents + // the number of output tokens used for reasoning (e.g. chain-of-thought, + // extended thinking). + // + // Type: int + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: 50 + // Note: The value SHOULD be included in `gen_ai.usage.output_tokens`. + GenAIUsageReasoningOutputTokensKey = attribute.Key("gen_ai.usage.reasoning.output_tokens") + + // GenAIWorkflowNameKey is the attribute Key conforming to the + // "gen_ai.workflow.name" semantic conventions. It represents the human-readable + // name of the GenAI workflow provided by the application. + // + // Type: string + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: "multi_agent_rag", "customer_support_pipeline" + // Note: This attribute can be populated in different frameworks eg: name of the + // first chain in LangChain OR name of the crew in CrewAI. + GenAIWorkflowNameKey = attribute.Key("gen_ai.workflow.name") ) // GenAIAgentDescription returns an attribute KeyValue conforming to the @@ -7139,6 +7211,13 @@ func GenAIRequestStopSequences(val ...string) attribute.KeyValue { return GenAIRequestStopSequencesKey.StringSlice(val) } +// GenAIRequestStream returns an attribute KeyValue conforming to the +// "gen_ai.request.stream" semantic conventions. It represents the indicates +// whether the GenAI request was made in streaming mode. +func GenAIRequestStream(val bool) attribute.KeyValue { + return GenAIRequestStreamKey.Bool(val) +} + // GenAIRequestTemperature returns an attribute KeyValue conforming to the // "gen_ai.request.temperature" semantic conventions. It represents the // temperature setting for the GenAI request. @@ -7182,6 +7261,15 @@ func GenAIResponseModel(val string) attribute.KeyValue { return GenAIResponseModelKey.String(val) } +// GenAIResponseTimeToFirstChunk returns an attribute KeyValue conforming to the +// "gen_ai.response.time_to_first_chunk" semantic conventions. It represents the +// time to first chunk in a streaming response, measured from request issuance, +// in seconds. The value is measured from when the client issues the generation +// request to when the first chunk is received in the response stream. +func GenAIResponseTimeToFirstChunk(val float64) attribute.KeyValue { + return GenAIResponseTimeToFirstChunkKey.Float64(val) +} + // GenAIRetrievalQueryText returns an attribute KeyValue conforming to the // "gen_ai.retrieval.query.text" semantic conventions. It represents the query // text used for retrieval. @@ -7245,6 +7333,21 @@ func GenAIUsageOutputTokens(val int) attribute.KeyValue { return GenAIUsageOutputTokensKey.Int(val) } +// GenAIUsageReasoningOutputTokens returns an attribute KeyValue conforming to +// the "gen_ai.usage.reasoning.output_tokens" semantic conventions. It represents +// the number of output tokens used for reasoning (e.g. chain-of-thought, +// extended thinking). +func GenAIUsageReasoningOutputTokens(val int) attribute.KeyValue { + return GenAIUsageReasoningOutputTokensKey.Int(val) +} + +// GenAIWorkflowName returns an attribute KeyValue conforming to the +// "gen_ai.workflow.name" semantic conventions. It represents the human-readable +// name of the GenAI workflow provided by the application. +func GenAIWorkflowName(val string) attribute.KeyValue { + return GenAIWorkflowNameKey.String(val) +} + // Enum values for gen_ai.operation.name var ( // Chat completion operation such as [OpenAI Chat API] @@ -7281,6 +7384,9 @@ var ( // Execute a tool // Stability: development GenAIOperationNameExecuteTool = GenAIOperationNameKey.String("execute_tool") + // Invoke GenAI workflow + // Stability: development + GenAIOperationNameInvokeWorkflow = GenAIOperationNameKey.String("invoke_workflow") ) // Enum values for gen_ai.output.type @@ -7335,7 +7441,7 @@ var ( // [Azure OpenAI] // Stability: development // - // [Azure OpenAI]: https://azure.microsoft.com/products/ai-services/openai-service/ + // [Azure OpenAI]: https://learn.microsoft.com/en-us/azure/ai-services/openai/overview GenAIProviderNameAzureAIOpenAI = GenAIProviderNameKey.String("azure.ai.openai") // [IBM Watsonx AI] // Stability: development @@ -7551,6 +7657,44 @@ var ( // Namespace: go const ( + // GoCPUDetailedStateKey is the attribute Key conforming to the + // "go.cpu.detailed_state" semantic conventions. It represents the detailed + // state of the CPU. + // + // Type: string + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: "gc/pause", "gc/mark/assist" + // Note: Value SHOULD match the specific CPU class reported by the Go runtime + // under `/cpu/classes/...`. The list of possible values is subject to change + // with the Go version used. + GoCPUDetailedStateKey = attribute.Key("go.cpu.detailed_state") + + // GoCPUStateKey is the attribute Key conforming to the "go.cpu.state" semantic + // conventions. It represents the state of the CPU. + // + // Type: Enum + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: "user", "gc" + GoCPUStateKey = attribute.Key("go.cpu.state") + + // GoMemoryDetailedTypeKey is the attribute Key conforming to the + // "go.memory.detailed_type" semantic conventions. It represents the detailed + // type of memory. + // + // Type: string + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: "heap/objects", "heap/free" + // Note: Value SHOULD match the specific memory class reported by the Go runtime + // under `/memory/classes/...`. The list of possible values is subject to change + // with the Go version used. + GoMemoryDetailedTypeKey = attribute.Key("go.memory.detailed_type") + // GoMemoryTypeKey is the attribute Key conforming to the "go.memory.type" // semantic conventions. It represents the type of memory. // @@ -7562,6 +7706,36 @@ const ( GoMemoryTypeKey = attribute.Key("go.memory.type") ) +// GoCPUDetailedState returns an attribute KeyValue conforming to the +// "go.cpu.detailed_state" semantic conventions. It represents the detailed state +// of the CPU. +func GoCPUDetailedState(val string) attribute.KeyValue { + return GoCPUDetailedStateKey.String(val) +} + +// GoMemoryDetailedType returns an attribute KeyValue conforming to the +// "go.memory.detailed_type" semantic conventions. It represents the detailed +// type of memory. +func GoMemoryDetailedType(val string) attribute.KeyValue { + return GoMemoryDetailedTypeKey.String(val) +} + +// Enum values for go.cpu.state +var ( + // CPU time spent running user Go code. + // Stability: development + GoCPUStateUser = GoCPUStateKey.String("user") + // CPU time spent performing garbage collection tasks. + // Stability: development + GoCPUStateGC = GoCPUStateKey.String("gc") + // CPU time spent returning unused memory to the underlying platform. + // Stability: development + GoCPUStateScavenge = GoCPUStateKey.String("scavenge") + // Available CPU time not spent executing any Go or Go runtime code. + // Stability: development + GoCPUStateIdle = GoCPUStateKey.String("idle") +) + // Enum values for go.memory.type var ( // Memory allocated from the heap that is reserved for stack space, whether or @@ -7584,7 +7758,8 @@ const ( // Stability: Development // // Examples: query findBookById { bookById(id: ?) { name } } - // Note: The value may be sanitized to exclude sensitive information. + // Note: If instrumentation can reliably identify and redact sensitive + // information it SHOULD do it. GraphQLDocumentKey = attribute.Key("graphql.document") // GraphQLOperationNameKey is the attribute Key conforming to the @@ -8335,7 +8510,7 @@ var ( const ( // HwBatteryCapacityKey is the attribute Key conforming to the // "hw.battery.capacity" semantic conventions. It represents the design capacity - // in Watts-hours or Amper-hours. + // in Watts-hours or Ampere-hours. // // Type: string // RequirementLevel: Recommended @@ -8637,7 +8812,7 @@ const ( // HwBatteryCapacity returns an attribute KeyValue conforming to the // "hw.battery.capacity" semantic conventions. It represents the design capacity -// in Watts-hours or Amper-hours. +// in Watts-hours or Ampere-hours. func HwBatteryCapacity(val string) attribute.KeyValue { return HwBatteryCapacityKey.String(val) } @@ -9026,7 +9201,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "opentelemetry-cluster" K8SClusterNameKey = attribute.Key("k8s.cluster.name") @@ -9037,7 +9212,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "218fc5a9-a5f1-4b54-aa05-46717d0ab26d" // Note: K8s doesn't have support for obtaining a cluster ID. If this is ever @@ -9073,7 +9248,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "redis" K8SContainerNameKey = attribute.Key("k8s.container.name") @@ -9085,7 +9260,7 @@ const ( // // Type: int // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: K8SContainerRestartCountKey = attribute.Key("k8s.container.restart_count") @@ -9136,7 +9311,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "opentelemetry" K8SCronJobNameKey = attribute.Key("k8s.cronjob.name") @@ -9146,7 +9321,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" K8SCronJobUIDKey = attribute.Key("k8s.cronjob.uid") @@ -9157,7 +9332,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "opentelemetry" K8SDaemonSetNameKey = attribute.Key("k8s.daemonset.name") @@ -9167,7 +9342,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" K8SDaemonSetUIDKey = attribute.Key("k8s.daemonset.uid") @@ -9178,7 +9353,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "opentelemetry" K8SDeploymentNameKey = attribute.Key("k8s.deployment.name") @@ -9189,7 +9364,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" K8SDeploymentUIDKey = attribute.Key("k8s.deployment.uid") @@ -9279,7 +9454,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "opentelemetry" K8SJobNameKey = attribute.Key("k8s.job.name") @@ -9289,7 +9464,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" K8SJobUIDKey = attribute.Key("k8s.job.uid") @@ -9300,7 +9475,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "default" K8SNamespaceNameKey = attribute.Key("k8s.namespace.name") @@ -9365,27 +9540,128 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "node-1" K8SNodeNameKey = attribute.Key("k8s.node.name") + // K8SNodeSystemContainerNameKey is the attribute Key conforming to the + // "k8s.node.system_container.name" semantic conventions. It represents the name + // of the system container running on the K8s Node. + // + // Type: string + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: "kubelet", "runtime", "pods", "misc" + K8SNodeSystemContainerNameKey = attribute.Key("k8s.node.system_container.name") + // K8SNodeUIDKey is the attribute Key conforming to the "k8s.node.uid" semantic // conventions. It represents the UID of the Node. // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2" K8SNodeUIDKey = attribute.Key("k8s.node.uid") + // K8SPersistentvolumeNameKey is the attribute Key conforming to the + // "k8s.persistentvolume.name" semantic conventions. It represents the name of + // the PersistentVolume. + // + // Type: string + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: "pv-data-01" + K8SPersistentvolumeNameKey = attribute.Key("k8s.persistentvolume.name") + + // K8SPersistentvolumeReclaimPolicyKey is the attribute Key conforming to the + // "k8s.persistentvolume.reclaim_policy" semantic conventions. It represents the + // reclaim policy of the PersistentVolume. + // + // Type: Enum + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: "Delete", "Retain", "Recycle" + // Note: This attribute aligns with the `persistentVolumeReclaimPolicy` field of + // the + // [K8s PersistentVolumeSpec]. + // + // [K8s PersistentVolumeSpec]: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-v1/#PersistentVolumeSpec + K8SPersistentvolumeReclaimPolicyKey = attribute.Key("k8s.persistentvolume.reclaim_policy") + + // K8SPersistentvolumeStatusPhaseKey is the attribute Key conforming to the + // "k8s.persistentvolume.status.phase" semantic conventions. It represents the + // phase of the PersistentVolume. + // + // Type: Enum + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: "Pending", "Available", "Bound", "Released", "Failed" + // Note: This attribute aligns with the `phase` field of the + // [K8s PersistentVolumeStatus]. + // + // [K8s PersistentVolumeStatus]: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-v1/#PersistentVolumeStatus + K8SPersistentvolumeStatusPhaseKey = attribute.Key("k8s.persistentvolume.status.phase") + + // K8SPersistentvolumeUIDKey is the attribute Key conforming to the + // "k8s.persistentvolume.uid" semantic conventions. It represents the UID of the + // PersistentVolume. + // + // Type: string + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" + K8SPersistentvolumeUIDKey = attribute.Key("k8s.persistentvolume.uid") + + // K8SPersistentvolumeclaimNameKey is the attribute Key conforming to the + // "k8s.persistentvolumeclaim.name" semantic conventions. It represents the name + // of the PersistentVolumeClaim. + // + // Type: string + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: "pvc-data-01" + K8SPersistentvolumeclaimNameKey = attribute.Key("k8s.persistentvolumeclaim.name") + + // K8SPersistentvolumeclaimStatusPhaseKey is the attribute Key conforming to the + // "k8s.persistentvolumeclaim.status.phase" semantic conventions. It represents + // the phase of the PersistentVolumeClaim. + // + // Type: Enum + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: "Pending", "Bound", "Lost" + // Note: This attribute aligns with the `phase` field of the + // [K8s PersistentVolumeClaimStatus]. + // + // [K8s PersistentVolumeClaimStatus]: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#PersistentVolumeClaimStatus + K8SPersistentvolumeclaimStatusPhaseKey = attribute.Key("k8s.persistentvolumeclaim.status.phase") + + // K8SPersistentvolumeclaimUIDKey is the attribute Key conforming to the + // "k8s.persistentvolumeclaim.uid" semantic conventions. It represents the UID + // of the PersistentVolumeClaim. + // + // Type: string + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" + K8SPersistentvolumeclaimUIDKey = attribute.Key("k8s.persistentvolumeclaim.uid") + // K8SPodHostnameKey is the attribute Key conforming to the "k8s.pod.hostname" // semantic conventions. It represents the specifies the hostname of the Pod. // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "collector-gateway" // Note: The K8s Pod spec has an optional hostname field, which can be used to @@ -9405,7 +9681,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "172.18.0.2" // Note: This attribute aligns with the `podIP` field of the @@ -9419,7 +9695,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "opentelemetry-pod-autoconf" K8SPodNameKey = attribute.Key("k8s.pod.name") @@ -9430,7 +9706,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "2025-12-04T08:41:03Z" // Note: Date and time at which the object was acknowledged by the Kubelet. @@ -9474,7 +9750,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" K8SPodUIDKey = attribute.Key("k8s.pod.uid") @@ -9485,7 +9761,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "opentelemetry" K8SReplicaSetNameKey = attribute.Key("k8s.replicaset.name") @@ -9496,7 +9772,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" K8SReplicaSetUIDKey = attribute.Key("k8s.replicaset.uid") @@ -9709,7 +9985,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "opentelemetry" K8SStatefulSetNameKey = attribute.Key("k8s.statefulset.name") @@ -9720,7 +9996,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Beta + // Stability: Release_Candidate // // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" K8SStatefulSetUIDKey = attribute.Key("k8s.statefulset.uid") @@ -10005,12 +10281,80 @@ func K8SNodeName(val string) attribute.KeyValue { return K8SNodeNameKey.String(val) } +// K8SNodeSystemContainerName returns an attribute KeyValue conforming to the +// "k8s.node.system_container.name" semantic conventions. It represents the name +// of the system container running on the K8s Node. +func K8SNodeSystemContainerName(val string) attribute.KeyValue { + return K8SNodeSystemContainerNameKey.String(val) +} + // K8SNodeUID returns an attribute KeyValue conforming to the "k8s.node.uid" // semantic conventions. It represents the UID of the Node. func K8SNodeUID(val string) attribute.KeyValue { return K8SNodeUIDKey.String(val) } +// K8SPersistentvolumeAnnotation returns an attribute KeyValue conforming to the +// "k8s.persistentvolume.annotation" semantic conventions. It represents the +// annotation placed on the PersistentVolume, the `` being the annotation +// name, the value being the annotation value, even if the value is empty. +func K8SPersistentvolumeAnnotation(key string, val string) attribute.KeyValue { + return attribute.String("k8s.persistentvolume.annotation."+key, val) +} + +// K8SPersistentvolumeLabel returns an attribute KeyValue conforming to the +// "k8s.persistentvolume.label" semantic conventions. It represents the label +// placed on the PersistentVolume, the `` being the label name, the value +// being the label value, even if the value is empty. +func K8SPersistentvolumeLabel(key string, val string) attribute.KeyValue { + return attribute.String("k8s.persistentvolume.label."+key, val) +} + +// K8SPersistentvolumeName returns an attribute KeyValue conforming to the +// "k8s.persistentvolume.name" semantic conventions. It represents the name of +// the PersistentVolume. +func K8SPersistentvolumeName(val string) attribute.KeyValue { + return K8SPersistentvolumeNameKey.String(val) +} + +// K8SPersistentvolumeUID returns an attribute KeyValue conforming to the +// "k8s.persistentvolume.uid" semantic conventions. It represents the UID of the +// PersistentVolume. +func K8SPersistentvolumeUID(val string) attribute.KeyValue { + return K8SPersistentvolumeUIDKey.String(val) +} + +// K8SPersistentvolumeclaimAnnotation returns an attribute KeyValue conforming to +// the "k8s.persistentvolumeclaim.annotation" semantic conventions. It represents +// the annotation placed on the PersistentVolumeClaim, the `` being the +// annotation name, the value being the annotation value, even if the value is +// empty. +func K8SPersistentvolumeclaimAnnotation(key string, val string) attribute.KeyValue { + return attribute.String("k8s.persistentvolumeclaim.annotation."+key, val) +} + +// K8SPersistentvolumeclaimLabel returns an attribute KeyValue conforming to the +// "k8s.persistentvolumeclaim.label" semantic conventions. It represents the +// label placed on the PersistentVolumeClaim, the `` being the label name, +// the value being the label value, even if the value is empty. +func K8SPersistentvolumeclaimLabel(key string, val string) attribute.KeyValue { + return attribute.String("k8s.persistentvolumeclaim.label."+key, val) +} + +// K8SPersistentvolumeclaimName returns an attribute KeyValue conforming to the +// "k8s.persistentvolumeclaim.name" semantic conventions. It represents the name +// of the PersistentVolumeClaim. +func K8SPersistentvolumeclaimName(val string) attribute.KeyValue { + return K8SPersistentvolumeclaimNameKey.String(val) +} + +// K8SPersistentvolumeclaimUID returns an attribute KeyValue conforming to the +// "k8s.persistentvolumeclaim.uid" semantic conventions. It represents the UID of +// the PersistentVolumeClaim. +func K8SPersistentvolumeclaimUID(val string) attribute.KeyValue { + return K8SPersistentvolumeclaimUIDKey.String(val) +} + // K8SPodAnnotation returns an attribute KeyValue conforming to the // "k8s.pod.annotation" semantic conventions. It represents the annotation placed // on the Pod, the `` being the annotation name, the value being the @@ -10318,6 +10662,51 @@ var ( K8SNodeConditionTypeNetworkUnavailable = K8SNodeConditionTypeKey.String("NetworkUnavailable") ) +// Enum values for k8s.persistentvolume.reclaim_policy +var ( + // The volume will be deleted when released from its claim. + // Stability: development + K8SPersistentvolumeReclaimPolicyDelete = K8SPersistentvolumeReclaimPolicyKey.String("Delete") + // The volume will be recycled (basic scrub) when released from its claim. + // Stability: development + K8SPersistentvolumeReclaimPolicyRecycle = K8SPersistentvolumeReclaimPolicyKey.String("Recycle") + // The volume will be retained when released from its claim. + // Stability: development + K8SPersistentvolumeReclaimPolicyRetain = K8SPersistentvolumeReclaimPolicyKey.String("Retain") +) + +// Enum values for k8s.persistentvolume.status.phase +var ( + // The volume is available and not yet bound to a claim. + // Stability: development + K8SPersistentvolumeStatusPhaseAvailable = K8SPersistentvolumeStatusPhaseKey.String("Available") + // The volume is bound to a claim. + // Stability: development + K8SPersistentvolumeStatusPhaseBound = K8SPersistentvolumeStatusPhaseKey.String("Bound") + // The volume has failed its automatic reclamation. + // Stability: development + K8SPersistentvolumeStatusPhaseFailed = K8SPersistentvolumeStatusPhaseKey.String("Failed") + // The volume is being provisioned. + // Stability: development + K8SPersistentvolumeStatusPhasePending = K8SPersistentvolumeStatusPhaseKey.String("Pending") + // The claim has been deleted but the volume is not yet available. + // Stability: development + K8SPersistentvolumeStatusPhaseReleased = K8SPersistentvolumeStatusPhaseKey.String("Released") +) + +// Enum values for k8s.persistentvolumeclaim.status.phase +var ( + // The claim is bound to a volume. + // Stability: development + K8SPersistentvolumeclaimStatusPhaseBound = K8SPersistentvolumeclaimStatusPhaseKey.String("Bound") + // The claim has lost its underlying volume (the volume does not exist anymore). + // Stability: development + K8SPersistentvolumeclaimStatusPhaseLost = K8SPersistentvolumeclaimStatusPhaseKey.String("Lost") + // The claim has not yet been bound to a volume. + // Stability: development + K8SPersistentvolumeclaimStatusPhasePending = K8SPersistentvolumeclaimStatusPhaseKey.String("Pending") +) + // Enum values for k8s.pod.status.phase var ( // The pod has been accepted by the system, but one or more of the containers @@ -12669,7 +13058,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Stable // // Examples: "browser.mouse.click", "device.app.lifecycle" // Note: This attribute SHOULD be used by non-OTLP exporters when destination @@ -13240,14 +13629,27 @@ const ( // ProcessExecutableBuildIDHtlhashKey is the attribute Key conforming to the // "process.executable.build_id.htlhash" semantic conventions. It represents the - // profiling specific build ID for executables. See the OTel specification for - // Profiles for more information. + // deterministic build ID for executables. // // Type: string // RequirementLevel: Recommended // Stability: Development // // Examples: "600DCAFE4A110000F2BF38C493F5FB92" + // Note: GNU and Go build IDs may be stripped or unavailable in some + // environments + // (e.g., Alpine Linux, Docker images). This attribute provides a deterministic + // build ID computed by hashing the first and last 4096 bytes of the file + // along with its length: + // + // ``` + // Input ← Concat(File[:4096], File[-4096:], BigEndianUInt64(Len(File))) + // Digest ← SHA256(Input) + // BuildID ← Digest[:16] + // ``` + // + // The result is the first 16 bytes (128 bits) of the SHA256 digest, + // represented as a hex string. ProcessExecutableBuildIDHtlhashKey = attribute.Key("process.executable.build_id.htlhash") // ProcessExecutableNameKey is the attribute Key conforming to the @@ -13603,8 +14005,7 @@ func ProcessExecutableBuildIDGo(val string) attribute.KeyValue { // ProcessExecutableBuildIDHtlhash returns an attribute KeyValue conforming to // the "process.executable.build_id.htlhash" semantic conventions. It represents -// the profiling specific build ID for executables. See the OTel specification -// for Profiles for more information. +// the deterministic build ID for executables. func ProcessExecutableBuildIDHtlhash(val string) attribute.KeyValue { return ProcessExecutableBuildIDHtlhashKey.String(val) } @@ -14317,9 +14718,11 @@ const ( // Examples: "shoppingcart" // Note: MUST be the same for all instances of horizontally scaled services. If // the value was not specified, SDKs MUST fallback to `unknown_service:` - // concatenated with [`process.executable.name`], e.g. `unknown_service:bash`. - // If `process.executable.name` is not available, the value MUST be set to + // concatenated with the process executable name, e.g. `unknown_service:bash`. + // If the process executable name is not available, the value MUST be set to // `unknown_service`. + // The process executable name is the name of the process executable, the same + // value as described by the [`process.executable.name`] resource attribute. // // [`process.executable.name`]: process.md ServiceNameKey = attribute.Key("service.name") @@ -14643,6 +15046,17 @@ const ( // Examples: "ext4" SystemFilesystemTypeKey = attribute.Key("system.filesystem.type") + // SystemMemoryLinuxHugepagesStateKey is the attribute Key conforming to the + // "system.memory.linux.hugepages.state" semantic conventions. It represents the + // Linux HugePages memory state. + // + // Type: Enum + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: "free", "used" + SystemMemoryLinuxHugepagesStateKey = attribute.Key("system.memory.linux.hugepages.state") + // SystemMemoryLinuxSlabStateKey is the attribute Key conforming to the // "system.memory.linux.slab.state" semantic conventions. It represents the // Linux Slab memory state. @@ -14753,6 +15167,16 @@ var ( SystemFilesystemTypeExt4 = SystemFilesystemTypeKey.String("ext4") ) +// Enum values for system.memory.linux.hugepages.state +var ( + // free + // Stability: development + SystemMemoryLinuxHugepagesStateFree = SystemMemoryLinuxHugepagesStateKey.String("free") + // used + // Stability: development + SystemMemoryLinuxHugepagesStateUsed = SystemMemoryLinuxHugepagesStateKey.String("used") +) + // Enum values for system.memory.linux.slab.state var ( // reclaimable @@ -14817,7 +15241,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Stable // // Examples: "parts-unlimited-java" // Note: Official auto instrumentation agents and distributions SHOULD set the @@ -14832,7 +15256,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Stable // // Examples: "1.2.3" TelemetryDistroVersionKey = attribute.Key("telemetry.distro.version") diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/doc.go b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/doc.go similarity index 82% rename from vendor/go.opentelemetry.io/otel/semconv/v1.40.0/doc.go rename to vendor/go.opentelemetry.io/otel/semconv/v1.41.0/doc.go index c5c41e4d2..a45d424d8 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/doc.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/doc.go @@ -1,9 +1,11 @@ +// Code generated from semantic convention specification. DO NOT EDIT. + // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 // Package semconv implements OpenTelemetry semantic conventions. // // OpenTelemetry semantic conventions are agreed standardized naming -// patterns for OpenTelemetry things. This package represents the v1.40.0 +// patterns for OpenTelemetry things. This package represents the v1.41.0 // version of the OpenTelemetry semantic conventions. -package semconv // import "go.opentelemetry.io/otel/semconv/v1.40.0" +package semconv // import "go.opentelemetry.io/otel/semconv/v1.41.0" diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/error_type.go b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/error_type.go similarity index 75% rename from vendor/go.opentelemetry.io/otel/semconv/v1.40.0/error_type.go rename to vendor/go.opentelemetry.io/otel/semconv/v1.41.0/error_type.go index 6d26e5282..0b13f0de8 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/error_type.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/error_type.go @@ -1,10 +1,13 @@ +// Code generated from semantic convention specification. DO NOT EDIT. + // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package semconv // import "go.opentelemetry.io/otel/semconv/v1.40.0" +package semconv // import "go.opentelemetry.io/otel/semconv/v1.41.0" import ( "errors" + "fmt" "reflect" "go.opentelemetry.io/otel/attribute" @@ -22,7 +25,8 @@ import ( // the returned attribute has that method's return value. If multiple errors in // the chain implement this method, the value from the first match found by // [errors.As] is used. Otherwise, the returned attribute has a value derived -// from the concrete type of err. +// from the concrete type of err after unwrapping any wrappers created with +// [fmt.Errorf]. // // The key of the returned attribute is [ErrorTypeKey]. func ErrorType(err error) attribute.KeyValue { @@ -50,7 +54,7 @@ func errorType(err error) string { // Fallback to reflection if the ErrorType method is not supported or // returns an empty value. - t := reflect.TypeOf(err) + t := reflect.TypeOf(unwrapFmtWrapped(err)) pkg, name := t.PkgPath(), t.Name() if pkg != "" && name != "" { s = pkg + "." + name @@ -64,3 +68,16 @@ func errorType(err error) string { } return s } + +var fmtWrapErrorType = reflect.TypeOf(fmt.Errorf("wrapped: %w", errors.New("err"))) + +func unwrapFmtWrapped(err error) error { + for reflect.TypeOf(err) == fmtWrapErrorType { + u := errors.Unwrap(err) + if u == nil { + return err // When the wrapped error is nil, use the concrete type of the wrapper. + } + err = u + } + return err +} diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/exception.go b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/exception.go similarity index 77% rename from vendor/go.opentelemetry.io/otel/semconv/v1.40.0/exception.go rename to vendor/go.opentelemetry.io/otel/semconv/v1.41.0/exception.go index 6a26231a1..5f0151aff 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/exception.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/exception.go @@ -1,7 +1,9 @@ +// Code generated from semantic convention specification. DO NOT EDIT. + // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package semconv // import "go.opentelemetry.io/otel/semconv/v1.40.0" +package semconv // import "go.opentelemetry.io/otel/semconv/v1.41.0" const ( // ExceptionEventName is the name of the Span event representing an exception. diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/schema.go b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/schema.go similarity index 73% rename from vendor/go.opentelemetry.io/otel/semconv/v1.40.0/schema.go rename to vendor/go.opentelemetry.io/otel/semconv/v1.41.0/schema.go index a07ffa336..24948a48f 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/schema.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/schema.go @@ -1,9 +1,11 @@ +// Code generated from semantic convention specification. DO NOT EDIT. + // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package semconv // import "go.opentelemetry.io/otel/semconv/v1.40.0" +package semconv // import "go.opentelemetry.io/otel/semconv/v1.41.0" // SchemaURL is the schema URL that matches the version of the semantic conventions // that this package defines. Semconv packages starting from v1.4.0 must declare // non-empty schema URL in the form https://opentelemetry.io/schemas/ -const SchemaURL = "https://opentelemetry.io/schemas/1.40.0" +const SchemaURL = "https://opentelemetry.io/schemas/1.41.0" diff --git a/vendor/go.opentelemetry.io/otel/trace/auto.go b/vendor/go.opentelemetry.io/otel/trace/auto.go index 9316fd0ac..a75cf047d 100644 --- a/vendor/go.opentelemetry.io/otel/trace/auto.go +++ b/vendor/go.opentelemetry.io/otel/trace/auto.go @@ -20,7 +20,7 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" - semconv "go.opentelemetry.io/otel/semconv/v1.40.0" + semconv "go.opentelemetry.io/otel/semconv/v1.41.0" "go.opentelemetry.io/otel/trace/embedded" "go.opentelemetry.io/otel/trace/internal/telemetry" ) @@ -314,6 +314,14 @@ func convAttrValue(value attribute.Value) telemetry.Value { case attribute.STRING: v := truncate(maxSpan.AttrValueLen, value.AsString()) return telemetry.StringValue(v) + case attribute.BYTESLICE: + // len(v.AsString()) is identical to len(v.AsByteSlice()) but + // avoids allocating the full slice before truncation. + s := value.AsString() + if maxSpan.AttrValueLen >= 0 && len(s) > maxSpan.AttrValueLen { + return telemetry.BytesValue([]byte(s[:maxSpan.AttrValueLen])) + } + return telemetry.BytesValue([]byte(s)) case attribute.BOOLSLICE: slice := value.AsBoolSlice() out := make([]telemetry.Value, 0, len(slice)) @@ -343,6 +351,13 @@ func convAttrValue(value attribute.Value) telemetry.Value { out = append(out, telemetry.StringValue(v)) } return telemetry.SliceValue(out...) + case attribute.SLICE: + slice := value.AsSlice() + out := make([]telemetry.Value, 0, len(slice)) + for _, v := range slice { + out = append(out, convAttrValue(v)) + } + return telemetry.SliceValue(out...) } return telemetry.Value{} } @@ -463,7 +478,8 @@ func (s *autoSpan) RecordError(err error, opts ...EventOption) { cfg := NewEventConfig(opts...) attrs := cfg.Attributes() - attrs = append(attrs, + attrs = append( + attrs, semconv.ExceptionType(typeStr(err)), semconv.ExceptionMessage(err.Error()), ) diff --git a/vendor/go.opentelemetry.io/otel/trace/config.go b/vendor/go.opentelemetry.io/otel/trace/config.go index d9ecef1ca..4cedba5ac 100644 --- a/vendor/go.opentelemetry.io/otel/trace/config.go +++ b/vendor/go.opentelemetry.io/otel/trace/config.go @@ -34,10 +34,17 @@ func (t *TracerConfig) SchemaURL() string { return t.schemaURL } +type experimentalOption interface { + Experimental() +} + // NewTracerConfig applies all the options to a returned TracerConfig. func NewTracerConfig(options ...TracerOption) TracerConfig { var config TracerConfig for _, option := range options { + if _, ok := option.(experimentalOption); ok { + continue + } config = option.apply(config) } return config @@ -103,6 +110,9 @@ func (cfg *SpanConfig) SpanKind() SpanKind { func NewSpanStartConfig(options ...SpanStartOption) SpanConfig { var c SpanConfig for _, option := range options { + if _, ok := option.(experimentalOption); ok { + continue + } c = option.applySpanStart(c) } return c @@ -115,6 +125,9 @@ func NewSpanStartConfig(options ...SpanStartOption) SpanConfig { func NewSpanEndConfig(options ...SpanEndOption) SpanConfig { var c SpanConfig for _, option := range options { + if _, ok := option.(experimentalOption); ok { + continue + } c = option.applySpanEnd(c) } return c @@ -167,6 +180,9 @@ func (cfg *EventConfig) StackTrace() bool { func NewEventConfig(options ...EventOption) EventConfig { var c EventConfig for _, option := range options { + if _, ok := option.(experimentalOption); ok { + continue + } c = option.applyEvent(c) } if c.timestamp.IsZero() { diff --git a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/span.go b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/span.go index e7ca62c66..61c7819a2 100644 --- a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/span.go +++ b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/span.go @@ -314,9 +314,9 @@ type SpanEvent struct { } // MarshalJSON encodes e into OTLP formatted JSON. -func (e SpanEvent) MarshalJSON() ([]byte, error) { - t := e.Time.UnixNano() - if e.Time.IsZero() || t < 0 { +func (se SpanEvent) MarshalJSON() ([]byte, error) { + t := se.Time.UnixNano() + if se.Time.IsZero() || t < 0 { t = 0 } @@ -325,7 +325,7 @@ func (e SpanEvent) MarshalJSON() ([]byte, error) { Alias Time uint64 `json:"timeUnixNano,omitempty"` }{ - Alias: Alias(e), + Alias: Alias(se), Time: uint64(t), // nolint: gosec // >0 checked above }) } diff --git a/vendor/go.opentelemetry.io/otel/version.go b/vendor/go.opentelemetry.io/otel/version.go index 1db4f47e4..72746acfd 100644 --- a/vendor/go.opentelemetry.io/otel/version.go +++ b/vendor/go.opentelemetry.io/otel/version.go @@ -5,5 +5,5 @@ package otel // import "go.opentelemetry.io/otel" // Version is the current release version of OpenTelemetry in use. func Version() string { - return "1.43.0" + return "1.44.0" } diff --git a/vendor/go.opentelemetry.io/otel/versions.yaml b/vendor/go.opentelemetry.io/otel/versions.yaml index bcc6ee78a..d6dbf803e 100644 --- a/vendor/go.opentelemetry.io/otel/versions.yaml +++ b/vendor/go.opentelemetry.io/otel/versions.yaml @@ -3,7 +3,7 @@ module-sets: stable-v1: - version: v1.43.0 + version: v1.44.0 modules: - go.opentelemetry.io/otel - go.opentelemetry.io/otel/bridge/opencensus @@ -22,11 +22,12 @@ module-sets: - go.opentelemetry.io/otel/sdk/metric - go.opentelemetry.io/otel/trace experimental-metrics: - version: v0.65.0 + version: v0.66.0 modules: - go.opentelemetry.io/otel/exporters/prometheus + - go.opentelemetry.io/otel/metric/x experimental-logs: - version: v0.19.0 + version: v0.20.0 modules: - go.opentelemetry.io/otel/log - go.opentelemetry.io/otel/log/logtest @@ -36,7 +37,7 @@ module-sets: - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp - go.opentelemetry.io/otel/exporters/stdout/stdoutlog experimental-schema: - version: v0.0.16 + version: v0.0.17 modules: - go.opentelemetry.io/otel/schema excluded-modules: @@ -55,6 +56,9 @@ modules: go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc: version-refs: - ./internal/version.go + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp: + version-refs: + - ./internal/version.go go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc: version-refs: - ./internal/version.go diff --git a/vendor/modules.txt b/vendor/modules.txt index 233c6d60a..d4462b0c5 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -4,8 +4,6 @@ filippo.io/hpke filippo.io/hpke/crypto filippo.io/hpke/crypto/ecdh filippo.io/hpke/internal/byteorder -# github.com/bits-and-blooms/bitset v1.24.4 -## explicit; go 1.16 # github.com/btcsuite/btcd/btcutil v1.1.6 ## explicit; go 1.16 github.com/btcsuite/btcd/btcutil/bech32 @@ -47,10 +45,6 @@ github.com/cloudflare/circl/sign/mldsa/mldsa87/internal github.com/cloudflare/circl/simd/keccakf1600 github.com/cloudflare/circl/xof github.com/cloudflare/circl/xof/k12 -# github.com/consensys/gnark-crypto v0.20.1 -## explicit; go 1.25.7 -# github.com/crate-crypto/go-eth-kzg v1.5.0 -## explicit; go 1.22 # github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc ## explicit github.com/davecgh/go-spew/spew @@ -70,8 +64,6 @@ github.com/dustin/go-humanize ## explicit; go 1.13 github.com/emicklei/go-restful/v3 github.com/emicklei/go-restful/v3/log -# github.com/ethereum/c-kzg-4844/v2 v2.1.7 -## explicit; go 1.19 # github.com/fxamacker/cbor/v2 v2.9.1 ## explicit; go 1.20 github.com/fxamacker/cbor/v2 @@ -156,26 +148,26 @@ github.com/klauspost/crc32 ## explicit; go 1.26.4 github.com/luxfi/accel github.com/luxfi/accel/internal/capi -# github.com/luxfi/address v1.0.1 -## explicit; go 1.25.5 +# github.com/luxfi/address v1.1.1 +## explicit; go 1.26.4 github.com/luxfi/address -# github.com/luxfi/age v1.5.0 -## explicit; go 1.24.0 +# github.com/luxfi/age v1.6.0 +## explicit; go 1.26.4 github.com/luxfi/age github.com/luxfi/age/internal/bech32 github.com/luxfi/age/internal/format github.com/luxfi/age/internal/stream -# github.com/luxfi/cache v1.2.1 -## explicit; go 1.25.5 +# github.com/luxfi/cache v1.3.1 +## explicit; go 1.26.4 github.com/luxfi/cache github.com/luxfi/cache/lru -# github.com/luxfi/constants v1.5.8 +# github.com/luxfi/constants v1.6.2 ## explicit; go 1.26.4 github.com/luxfi/constants -# github.com/luxfi/container v0.0.4 -## explicit; go 1.25.5 +# github.com/luxfi/container v0.2.1 +## explicit; go 1.26.4 github.com/luxfi/container -# github.com/luxfi/crypto v1.19.27 +# github.com/luxfi/crypto v1.20.2 ## explicit; go 1.26.4 github.com/luxfi/crypto github.com/luxfi/crypto/backend @@ -193,34 +185,32 @@ github.com/luxfi/crypto/secp256k1/libsecp256k1/include github.com/luxfi/crypto/secp256k1/libsecp256k1/src github.com/luxfi/crypto/secp256k1/libsecp256k1/src/modules/recovery github.com/luxfi/crypto/secret -# github.com/luxfi/crypto/ipa v1.2.4 -## explicit; go 1.18 -# github.com/luxfi/formatting v1.0.1 -## explicit; go 1.25.5 +# github.com/luxfi/formatting v1.1.1 +## explicit; go 1.26.4 github.com/luxfi/formatting -# github.com/luxfi/geth v1.17.12 +# github.com/luxfi/geth v1.20.1 ## explicit; go 1.26.4 github.com/luxfi/geth/common github.com/luxfi/geth/common/hexutil -# github.com/luxfi/go-bip32 v1.0.2 -## explicit; go 1.23.5 +# github.com/luxfi/go-bip32 v1.1.0 +## explicit; go 1.26.4 github.com/luxfi/go-bip32 -# github.com/luxfi/go-bip39 v1.1.2 -## explicit; go 1.25 +# github.com/luxfi/go-bip39 v1.2.0 +## explicit; go 1.26.4 github.com/luxfi/go-bip39 github.com/luxfi/go-bip39/wordlists -# github.com/luxfi/ids v1.2.15 -## explicit; go 1.26.3 +# github.com/luxfi/ids v1.3.2 +## explicit; go 1.26.4 github.com/luxfi/ids -# github.com/luxfi/keys v1.1.0 -## explicit; go 1.26.3 +# github.com/luxfi/keys v1.4.1 +## explicit; go 1.26.4 github.com/luxfi/keys # github.com/luxfi/log v1.4.3 ## explicit; go 1.26.3 github.com/luxfi/log github.com/luxfi/log/internal/json -# github.com/luxfi/math v1.4.1 -## explicit; go 1.26.3 +# github.com/luxfi/math v1.5.1 +## explicit; go 1.26.4 github.com/luxfi/math github.com/luxfi/math/heap github.com/luxfi/math/linked @@ -231,29 +221,27 @@ github.com/luxfi/math/big # github.com/luxfi/mdns v0.1.1 ## explicit; go 1.26.3 github.com/luxfi/mdns -# github.com/luxfi/metric v1.5.8 -## explicit; go 1.26.3 +# github.com/luxfi/metric v1.8.1 +## explicit; go 1.26.4 github.com/luxfi/metric github.com/luxfi/metric/client # github.com/luxfi/mock v0.1.1 ## explicit; go 1.25.5 github.com/luxfi/mock/gomock -# github.com/luxfi/pq v1.0.3 -## explicit; go 1.23.0 -# github.com/luxfi/proto v1.3.4 -## explicit; go 1.26.3 -github.com/luxfi/proto/p/signer +# github.com/luxfi/protocol v0.0.2 +## explicit; go 1.25.5 +github.com/luxfi/protocol/p/signer # github.com/luxfi/sampler v1.1.0 ## explicit; go 1.26.3 github.com/luxfi/sampler -# github.com/luxfi/tls v1.0.3 -## explicit; go 1.25.5 +# github.com/luxfi/tls v1.1.1 +## explicit; go 1.26.4 github.com/luxfi/tls -# github.com/luxfi/vm v1.2.3 +# github.com/luxfi/vm v1.3.1 ## explicit; go 1.26.4 github.com/luxfi/vm/components/verify -# github.com/luxfi/zap v0.7.2 -## explicit; go 1.26.3 +# github.com/luxfi/zap v1.2.6 +## explicit; go 1.26.4 github.com/luxfi/zap github.com/luxfi/zap/handshake # github.com/luxfi/zapdb v1.10.0 @@ -335,7 +323,7 @@ github.com/spf13/pflag # github.com/supranational/blst v0.3.16 ## explicit; go 1.11 github.com/supranational/blst/bindings/go -# github.com/tinylib/msgp v1.6.3 +# github.com/tinylib/msgp v1.6.4 ## explicit; go 1.24 github.com/tinylib/msgp/msgp github.com/tinylib/msgp/msgp/setof @@ -346,7 +334,7 @@ github.com/x448/float16 ## explicit; go 1.24.0 go.opentelemetry.io/auto/sdk go.opentelemetry.io/auto/sdk/internal/telemetry -# go.opentelemetry.io/otel v1.43.0 +# go.opentelemetry.io/otel v1.44.0 ## explicit; go 1.25.0 go.opentelemetry.io/otel go.opentelemetry.io/otel/attribute @@ -359,12 +347,12 @@ go.opentelemetry.io/otel/internal/errorhandler go.opentelemetry.io/otel/internal/global go.opentelemetry.io/otel/propagation go.opentelemetry.io/otel/semconv/v1.37.0 -go.opentelemetry.io/otel/semconv/v1.40.0 -# go.opentelemetry.io/otel/metric v1.43.0 +go.opentelemetry.io/otel/semconv/v1.41.0 +# go.opentelemetry.io/otel/metric v1.44.0 ## explicit; go 1.25.0 go.opentelemetry.io/otel/metric go.opentelemetry.io/otel/metric/embedded -# go.opentelemetry.io/otel/trace v1.43.0 +# go.opentelemetry.io/otel/trace v1.44.0 ## explicit; go 1.25.0 go.opentelemetry.io/otel/trace go.opentelemetry.io/otel/trace/embedded