diff --git a/go.mod b/go.mod index 3d1f3377..8b13021a 100644 --- a/go.mod +++ b/go.mod @@ -1,31 +1,30 @@ module github.com/smartcontractkit/libocr -go 1.24 - -toolchain go1.24.4 +go 1.24.0 require ( - github.com/cockroachdb/pebble v1.1.2 - github.com/ethereum/go-ethereum v1.15.3 + github.com/cockroachdb/pebble v1.1.5 + github.com/ethereum/go-ethereum v1.17.0 github.com/google/btree v1.1.3 github.com/leanovate/gopter v0.2.11 github.com/mr-tron/base58 v1.2.0 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.14.0 + github.com/prometheus/client_golang v1.15.0 github.com/sirupsen/logrus v1.9.3 - golang.org/x/crypto v0.41.0 + golang.org/x/crypto v0.44.0 golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f - google.golang.org/protobuf v1.36.6 + google.golang.org/protobuf v1.36.11 ) require ( github.com/DataDog/zstd v1.5.2 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 // indirect github.com/StackExchange/wmi v1.2.1 // indirect - github.com/VictoriaMetrics/fastcache v1.12.2 // indirect + github.com/VictoriaMetrics/fastcache v1.13.0 // indirect github.com/allegro/bigcache v1.2.1 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.17.0 // indirect + github.com/bits-and-blooms/bitset v1.20.0 // indirect github.com/cespare/cp v1.1.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cockroachdb/errors v1.11.3 // indirect @@ -33,33 +32,36 @@ require ( github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/consensys/bavard v0.1.22 // indirect - github.com/consensys/gnark-crypto v0.14.0 // indirect + github.com/consensys/gnark-crypto v0.18.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect - github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect - github.com/crate-crypto/go-kzg-4844 v1.1.0 // indirect + github.com/crate-crypto/go-eth-kzg v1.4.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dchest/siphash v1.2.3 // indirect github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/deepmap/oapi-codegen v1.8.2 // indirect - github.com/ethereum/c-kzg-4844 v1.0.3 // indirect - github.com/ethereum/go-verkle v0.2.2 // indirect - github.com/ferranbt/fastssz v0.1.2 // indirect + github.com/emicklei/dot v1.6.2 // indirect + github.com/ethereum/c-kzg-4844/v2 v2.1.5 // indirect + github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab // indirect + github.com/ferranbt/fastssz v0.1.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect - github.com/gofrs/flock v0.8.1 // indirect + github.com/gofrs/flock v0.12.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt/v4 v4.5.1 // indirect + github.com/golang-jwt/jwt/v4 v4.5.2 // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect - github.com/google/go-cmp v0.7.0 // indirect + github.com/golang/snappy v1.0.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.4.2 // indirect + github.com/grafana/pyroscope-go v1.2.7 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.9 // indirect github.com/graph-gophers/graphql-go v1.3.0 // indirect github.com/hashicorp/go-bexpr v0.1.10 // indirect - github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 // indirect + github.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/holiman/uint256 v1.3.2 // indirect github.com/huin/goupnp v1.3.0 // indirect @@ -78,8 +80,6 @@ require ( github.com/minio/sha256-simd v1.0.0 // indirect github.com/mitchellh/mapstructure v1.4.1 // indirect github.com/mitchellh/pointerstructure v1.2.0 // indirect - github.com/mmcloughlin/addchain v0.4.0 // indirect - github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/onsi/ginkgo v1.14.1 // indirect github.com/onsi/gomega v1.10.3 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect @@ -90,31 +90,34 @@ require ( github.com/pion/transport/v2 v2.2.1 // indirect github.com/pion/transport/v3 v3.0.1 // indirect github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.39.0 // indirect + github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect - github.com/rogpeppe/go-internal v1.13.1 // indirect + github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/rs/cors v1.7.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/smartcontractkit/go-sumtype2 v0.0.0-20250903174514-31585731b5a3 // indirect - github.com/supranational/blst v0.3.14 // indirect + github.com/supranational/blst v0.3.16-0.20250831170142-f48500c1fdbe // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/urfave/cli/v2 v2.27.5 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect - golang.org/x/mod v0.27.0 // indirect - golang.org/x/net v0.43.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/text v0.28.0 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect + golang.org/x/mod v0.29.0 // indirect + golang.org/x/net v0.47.0 // indirect + golang.org/x/sync v0.18.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/text v0.31.0 // indirect golang.org/x/time v0.9.0 // indirect - golang.org/x/tools v0.36.0 // indirect + golang.org/x/tools v0.38.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - rsc.io/tmplfunc v0.0.3 // indirect ) replace github.com/leanovate/gopter => github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a diff --git a/go.sum b/go.sum index 8c571ddf..d79d639a 100644 --- a/go.sum +++ b/go.sum @@ -2,20 +2,20 @@ github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 h1:1zYrtlhrZ6/b6SAjLSfKzWtdgqK0U+HtH/VcBWh1BaU= +github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6/go.mod h1:ioLG6R+5bUSO1oeGSDxOV3FADARuMoytZCSX6MEMQkI= github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= -github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= -github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +github.com/VictoriaMetrics/fastcache v1.13.0 h1:AW4mheMR5Vd9FkAPUv+NH6Nhw+fmbTMGMsNAoA/+4G0= +github.com/VictoriaMetrics/fastcache v1.13.0/go.mod h1:hHXhl4DA2fTL2HTZDJFXWgW0LNjo6B+4aj2Wmng3TjU= github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bits-and-blooms/bitset v1.17.0 h1:1X2TS7aHz1ELcC0yU1y2stUs/0ig5oMU6STFZGrhvHI= -github.com/bits-and-blooms/bitset v1.17.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3MdfoPyRVU= +github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= @@ -26,27 +26,25 @@ github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/e github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/pebble v1.1.2 h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA= -github.com/cockroachdb/pebble v1.1.2/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= +github.com/cockroachdb/pebble v1.1.5 h1:5AAWCBWbat0uE0blr8qzufZP5tBjkRyy/jWe1QWLnvw= +github.com/cockroachdb/pebble v1.1.5/go.mod h1:17wO9el1YEigxkP/YtV8NtCivQDgoCyBg5c4VR/eOWo= github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= -github.com/consensys/bavard v0.1.22 h1:Uw2CGvbXSZWhqK59X0VG/zOjpTFuOMcPLStrp1ihI0A= -github.com/consensys/bavard v0.1.22/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs= -github.com/consensys/gnark-crypto v0.14.0 h1:DDBdl4HaBtdQsq/wfMwJvZNE80sHidrK3Nfrefatm0E= -github.com/consensys/gnark-crypto v0.14.0/go.mod h1:CU4UijNPsHawiVGNxe9co07FkzCeWHHrb1li/n1XoU0= +github.com/consensys/gnark-crypto v0.18.1 h1:RyLV6UhPRoYYzaFnPQA4qK3DyuDgkTgskDdoGqFt3fI= +github.com/consensys/gnark-crypto v0.18.1/go.mod h1:L3mXGFTe1ZN+RSJ+CLjUt9x7PNdx8ubaYfDROyp2Z8c= github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg= -github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM= -github.com/crate-crypto/go-kzg-4844 v1.1.0 h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4= -github.com/crate-crypto/go-kzg-4844 v1.1.0/go.mod h1:JolLjpSff1tCCJKaJx4psrlEdlXuJEC996PL3tTAFks= +github.com/crate-crypto/go-eth-kzg v1.4.0 h1:WzDGjHk4gFg6YzV0rJOAsTK4z3Qkz5jd4RE3DAvPFkg= +github.com/crate-crypto/go-eth-kzg v1.4.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dchest/siphash v1.2.3 h1:QXwFc8cFOR2dSa/gE6o/HokBMWtLUaNDVd+22aKHeEA= +github.com/dchest/siphash v1.2.3/go.mod h1:0NvQU092bT0ipiFN++/rXm69QG9tVxLAlQHIXMPAkHc= github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= @@ -57,14 +55,16 @@ github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE github.com/deepmap/oapi-codegen v1.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU= github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/ethereum/c-kzg-4844 v1.0.3 h1:IEnbOHwjixW2cTvKRUlAAUOeleV7nNM/umJR+qy4WDs= -github.com/ethereum/c-kzg-4844 v1.0.3/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= -github.com/ethereum/go-ethereum v1.15.3 h1:OeTWAq6r8iR89bfJDjmmOemE74ywArl9DUViFsVj3Y8= -github.com/ethereum/go-ethereum v1.15.3/go.mod h1:jMXlpZXfSar1mGs/5sB0aEpEnPsiE1Jn6/3anlueqz8= -github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8= -github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= -github.com/ferranbt/fastssz v0.1.2 h1:Dky6dXlngF6Qjc+EfDipAkE83N5I5DE68bY6O0VLNPk= -github.com/ferranbt/fastssz v0.1.2/go.mod h1:X5UPrE2u1UJjxHA8X54u04SBwdAQjG2sFtWs39YxyWs= +github.com/emicklei/dot v1.6.2 h1:08GN+DD79cy/tzN6uLCT84+2Wk9u+wvqP+Hkx/dIR8A= +github.com/emicklei/dot v1.6.2/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= +github.com/ethereum/c-kzg-4844/v2 v2.1.5 h1:aVtoLK5xwJ6c5RiqO8g8ptJ5KU+2Hdquf6G3aXiHh5s= +github.com/ethereum/c-kzg-4844/v2 v2.1.5/go.mod h1:u59hRTTah4Co6i9fDWtiCjTrblJv0UwsqZKCc0GfgUs= +github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab h1:rvv6MJhy07IMfEKuARQ9TKojGqLVNxQajaXEp/BoqSk= +github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab/go.mod h1:IuLm4IsPipXKF7CW5Lzf68PIbZ5yl7FFd74l/E0o9A8= +github.com/ethereum/go-ethereum v1.17.0 h1:2D+1Fe23CwZ5tQoAS5DfwKFNI1HGcTwi65/kRlAVxes= +github.com/ethereum/go-ethereum v1.17.0/go.mod h1:2W3msvdosS/MCWytpqTcqgFiRYbTH59FxDJzqah120o= +github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeDY= +github.com/ferranbt/fastssz v0.1.4/go.mod h1:Ea3+oeoRGGLGm5shYAeDgu6PGUlcvQhE2fILyD9+tGg= 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/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -79,17 +79,22 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +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-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= -github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= +github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= -github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= +github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -101,8 +106,8 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= -github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= @@ -113,18 +118,21 @@ 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.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= 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/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grafana/pyroscope-go v1.2.7 h1:VWBBlqxjyR0Cwk2W6UrE8CdcdD80GOFNutj0Kb1T8ac= +github.com/grafana/pyroscope-go v1.2.7/go.mod h1:o/bpSLiJYYP6HQtvcoVKiE9s5RiNgjYTj1DhiddP2Pc= +github.com/grafana/pyroscope-go/godeltaprof v0.1.9 h1:c1Us8i6eSmkW+Ez05d3co8kasnuOY813tbMN8i/a3Og= +github.com/grafana/pyroscope-go/godeltaprof v0.1.9/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= -github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= -github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= +github.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db h1:IZUYC/xb3giYwBLMnr8d0TGTzPKFGNTCGgGLoyeX330= +github.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db/go.mod h1:xTEYN9KCHxuYHs+NmrmzFcnvHMzLLNiGFafCb1n3Mfg= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA= @@ -176,7 +184,6 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= @@ -187,15 +194,10 @@ github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxd github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= -github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= -github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= -github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= -github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.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= @@ -228,21 +230,21 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM= +github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= -github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= -github.com/prysmaticlabs/gohashtree v0.0.1-alpha.0.20220714111606-acbb2962fb48 h1:cSo6/vk8YpvkLbk9v3FO97cakNmUoxwi2KMP8hd5WIw= -github.com/prysmaticlabs/gohashtree v0.0.1-alpha.0.20220714111606-acbb2962fb48/go.mod h1:4pWaT30XoEx1j8KNJf3TV+E3mQkaufn7mf+jRNb/Fuk= +github.com/prysmaticlabs/gohashtree v0.0.4-beta h1:H/EbCuXPeTV3lpKeXGPpEV9gsUpkqOOVnWapUyeWro4= +github.com/prysmaticlabs/gohashtree v0.0.4-beta/go.mod h1:BFdtALS+Ffhg3lGQIHv9HDWuHS8cTvHZzrHWxwOtGOs= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +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/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -256,6 +258,8 @@ github.com/smartcontractkit/go-sumtype2 v0.0.0-20250903174514-31585731b5a3/go.mo 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.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -266,8 +270,8 @@ github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl 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.14 h1:xNMoHRJOTwMn63ip6qoWJ2Ymgvj7E2b9jY2FAwY+qRo= -github.com/supranational/blst v0.3.14/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/supranational/blst v0.3.16-0.20250831170142-f48500c1fdbe h1:nbdqkIGOGfUAD54q1s2YBcBz/WcsxCO9HUQ4aGV5hUw= +github.com/supranational/blst v0.3.16-0.20250831170142-f48500c1fdbe/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= @@ -284,6 +288,16 @@ github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBi github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +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.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -292,16 +306,16 @@ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= -golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= +golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= +golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= -golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= +golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= +golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -318,8 +332,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -328,8 +342,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -361,9 +375,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -379,8 +392,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= @@ -392,8 +405,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= +golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -405,8 +418,8 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +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-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= @@ -424,5 +437,3 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 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= -rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= -rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/internal/jmt/binary_tree.go b/internal/jmt/binary_tree.go index 807c0dd6..987f3bba 100644 --- a/internal/jmt/binary_tree.go +++ b/internal/jmt/binary_tree.go @@ -54,61 +54,66 @@ func sparseDigestInternalBinary(leftNode sparseMerkleNode, rightNode sparseMerkl } } -func evolveLayer(bottomLayer []sparseMerkleNode) []sparseMerkleNode { - if len(bottomLayer)%2 != 0 { - panic("") - } - - nextLayer := make([]sparseMerkleNode, 0, len(bottomLayer)/2) - - for i, j := 0, 1; j < len(bottomLayer); i, j = i+2, j+2 { - nextLayer = append(nextLayer, sparseDigestInternalBinary(bottomLayer[i], bottomLayer[j])) - } - return nextLayer +func sparseMerkleTreeDigest(bottomLayer []sparseMerkleNode) Digest { + return sparseMerkleTreeRoot(bottomLayer).digest } -func sparseMerkleTreeDigest(bottomLayer []sparseMerkleNode) Digest { +func sparseMerkleTreeRoot(bottomLayer []sparseMerkleNode) sparseMerkleNode { if len(bottomLayer) == 0 { - return SparseMerklePlaceholderDigest + return sparseMerkleNode{false, SparseMerklePlaceholderDigest} + } + if !isPowerOfTwo(len(bottomLayer)) { + panic("bottomLayer length must be a power of two if not zero") } if len(bottomLayer) == 1 { - return bottomLayer[0].digest + return bottomLayer[0] } - return sparseMerkleTreeDigest(evolveLayer(bottomLayer)) + return sparseDigestInternalBinary( + sparseMerkleTreeRoot(bottomLayer[:len(bottomLayer)/2]), + sparseMerkleTreeRoot(bottomLayer[len(bottomLayer)/2:]), + ) } -// Calling with a compactable i will return invalid proofs, because the node is really not part of the final tree. -func sparseMerkleProof(bottomLayer []sparseMerkleNode, i int) []Digest { - // find the bottommost layer where the node at index i remains after compactions - for len(bottomLayer) > 1 { - bottomLayerCandidate := evolveLayer(bottomLayer) - - if len(bottomLayerCandidate) > i/2 && bottomLayerCandidate[i/2] == bottomLayer[i] { - bottomLayer = bottomLayerCandidate - i = i / 2 - } else { - break - } +func sparseMerkleIsLeafAndProof(bottomLayer []sparseMerkleNode, i int) (singleLeaf bool, proof []Digest) { + if !isPowerOfTwo(len(bottomLayer)) { + panic("bottomLayer length must be a power of two") } - - if len(bottomLayer) <= 1 { - - return nil + if i < 0 || i >= len(bottomLayer) { + panic("i is out of bounds") + } + if bottomLayer[i].digest == SparseMerklePlaceholderDigest { + panic("bottomLayer[i] is a placeholder") + } + if len(bottomLayer) == 1 { + return bottomLayer[0].isLeaf, nil } mid := len(bottomLayer) / 2 - var ( - sibling Digest - descendantSiblings []Digest + sibling Digest + subtreeSiblings []Digest + subtreeIsSingleLeaf bool ) if i < mid { sibling = sparseMerkleTreeDigest(bottomLayer[mid:]) - descendantSiblings = sparseMerkleProof(bottomLayer[:mid], i) + subtreeIsSingleLeaf, subtreeSiblings = sparseMerkleIsLeafAndProof(bottomLayer[:mid], i) } else { // i >= mid sibling = sparseMerkleTreeDigest(bottomLayer[:mid]) - descendantSiblings = sparseMerkleProof(bottomLayer[mid:], i-mid) + subtreeIsSingleLeaf, subtreeSiblings = sparseMerkleIsLeafAndProof(bottomLayer[mid:], i-mid) } - return append(descendantSiblings, sibling) + rootIsSingleLeaf := subtreeIsSingleLeaf && sibling == SparseMerklePlaceholderDigest + if rootIsSingleLeaf { + return true, nil + } + return false, append(subtreeSiblings, sibling) +} + +func sparseMerkleProof(bottomLayer []sparseMerkleNode, i int) []Digest { + _, proof := sparseMerkleIsLeafAndProof(bottomLayer, i) + return proof +} + +func isPowerOfTwo(num int) bool { + return num > 0 && (num&(num-1)) == 0 } diff --git a/internal/jmt/jmt.go b/internal/jmt/jmt.go index c3748e9e..2a12fed1 100644 --- a/internal/jmt/jmt.go +++ b/internal/jmt/jmt.go @@ -45,6 +45,31 @@ func BatchUpdate( oldVersion Version, newVersion Version, keyValueUpdates []KeyValue, +) (NodeKey, error) { + digested := make([]digestedKeyValue, 0, len(keyValueUpdates)) + for _, kv := range keyValueUpdates { + keyDigest := DigestKey(kv.Key) + var valueDigest Digest + if kv.Value != nil { + valueDigest = DigestValue(kv.Value) + } + digested = append(digested, digestedKeyValue{ + kv.Key, + keyDigest, + kv.Value, + valueDigest, + }) + } + return batchUpdateDigested(rootReadWriter, nodeReadWriter, staleNodeWriter, oldVersion, newVersion, digested) +} + +func batchUpdateDigested( + rootReadWriter RootReadWriter, + nodeReadWriter NodeReadWriter, + staleNodeWriter StaleNodeWriter, + oldVersion Version, + newVersion Version, + keyValueUpdates []digestedKeyValue, ) (NodeKey, error) { if oldVersion > newVersion { return NodeKey{}, fmt.Errorf("old version %d is greater than new version %d", oldVersion, newVersion) @@ -67,26 +92,14 @@ func BatchUpdate( seenDigestedKeys := make(map[Digest]struct{}, len(keyValueUpdates)) - for i, keyValue := range keyValueUpdates { - keyDigest := DigestKey(keyValue.Key) + for i, dkv := range keyValueUpdates { + keyDigest := dkv.keyDigest if _, ok := seenDigestedKeys[keyDigest]; ok { - return NodeKey{}, fmt.Errorf("%d-th keyValueUpdate: duplicate key %v in keyValueUpdates", i, keyValue.Key) + return NodeKey{}, fmt.Errorf("%d-th keyValueUpdate: duplicate key %v in keyValueUpdates", i, dkv.key) } seenDigestedKeys[keyDigest] = struct{}{} - var valueDigest Digest - if keyValue.Value != nil { - valueDigest = DigestValue(keyValue.Value) - } - - dkv := digestedKeyValue{ - keyValue.Key, - keyDigest, - keyValue.Value, - valueDigest, - } - - if keyValue.Value == nil { + if dkv.value == nil { digestedDeletes = append(digestedDeletes, dkv) } else { digestedInserts = append(digestedInserts, dkv) @@ -551,6 +564,15 @@ func Read( nodeReader NodeReader, version Version, key []byte, +) ([]byte, error) { + return readDigested(rootReader, nodeReader, version, DigestKey(key)) +} + +func readDigested( + rootReader RootReader, + nodeReader NodeReader, + version Version, + keyDigest Digest, ) ([]byte, error) { rootNodeKey, err := rootReader.ReadRoot(version) if err != nil { @@ -566,7 +588,7 @@ func Read( return nil, nil } - nibblePath := NibblePathFromDigest(DigestKey(key)) + nibblePath := NibblePathFromDigest(keyDigest) for i := 0; i < nibblePath.NumNibbles(); i++ { nibble := nibblePath.Get(i) @@ -595,7 +617,7 @@ func Read( } if n, ok := rootNode.(*LeafNode); ok { - if n.KeyDigest == DigestKey(key) { + if n.KeyDigest == keyDigest { return util.NilCoalesceSlice(n.Value), nil } else { return nil, nil diff --git a/internal/jmt/nibbles.go b/internal/jmt/nibbles.go index 6be086bd..f905a339 100644 --- a/internal/jmt/nibbles.go +++ b/internal/jmt/nibbles.go @@ -60,6 +60,9 @@ func (np NibblePath) Bytes() []byte { } func (np NibblePath) Append(nibble byte) NibblePath { + if nibble&0xf0 != 0 { + panic("nibble is out of range, byte high nibble is non-zero") + } np2 := NibblePath{ np.numNibbles + 1, bytes.Clone(np.bytes), diff --git a/internal/jmt/verify.go b/internal/jmt/verify.go index e0fa7065..8f62a40d 100644 --- a/internal/jmt/verify.go +++ b/internal/jmt/verify.go @@ -66,7 +66,7 @@ func VerifySubrange( }) for i := range sortedDigestedKeyValues { if i > 0 && !(bytes.Compare(sortedDigestedKeyValues[i-1].keyDigest[:], sortedDigestedKeyValues[i].keyDigest[:]) < 0) { - return fmt.Errorf("key values contain duplicates") + return fmt.Errorf("key values contain duplicates: key digest %x", sortedDigestedKeyValues[i].keyDigest) } } @@ -310,8 +310,11 @@ func verifySubrangePadded( if len(layer) != 1 { return fmt.Errorf("unexpectedly ended with a non-singleton layer of %v nodes at the top", len(layer)) } - if !((leftBoundingLeafOrNil == nil || len(leftBoundingLeafOrNil.Siblings) == 0) && (rightBoundingLeafOrNil == nil || len(rightBoundingLeafOrNil.Siblings) == 0)) { - return fmt.Errorf("unexpectedly ended with left or right siblings remaining: left %v, right %v", len(leftBoundingLeafOrNil.Siblings), len(rightBoundingLeafOrNil.Siblings)) + if leftBoundingLeafOrNil != nil && len(leftBoundingLeafOrNil.Siblings) != 0 { + return fmt.Errorf("unexpectedly ended with left siblings remaining: %v", len(leftBoundingLeafOrNil.Siblings)) + } + if rightBoundingLeafOrNil != nil && len(rightBoundingLeafOrNil.Siblings) != 0 { + return fmt.Errorf("unexpectedly ended with right siblings remaining: %v", len(rightBoundingLeafOrNil.Siblings)) } if layer[0].sparseMerkleNode.digest != expectedRootDigest { return fmt.Errorf("computed root digest mismatch: computed %x, expected %x", layer[0].sparseMerkleNode.digest, expectedRootDigest) diff --git a/offchainreporting2/reportingplugin/median/median.go b/offchainreporting2/reportingplugin/median/median.go index 1e763298..d4c3310d 100644 --- a/offchainreporting2/reportingplugin/median/median.go +++ b/offchainreporting2/reportingplugin/median/median.go @@ -104,6 +104,14 @@ type OffchainConfig struct { // maximum age is exceeded, a new report will be created by the report // generation protocol. DeltaC time.Duration + // If TransmitDespiteContractReadError is true and MedianContract reads + // return an error, ShouldAcceptFinalizedReport and + // ShouldTransmitAcceptedReport will return that the report + // should be transmitted. "If in doubt, transmit!" + // + // Be careful setting this. It can cause increased transaction load and + // costs. + TransmitDespiteContractReadError bool } func DecodeOffchainConfig(b []byte) (OffchainConfig, error) { @@ -123,6 +131,7 @@ func DecodeOffchainConfig(b []byte) (OffchainConfig, error) { configProto.GetAlphaAcceptInfinite(), configProto.GetAlphaAcceptPpb(), time.Duration(configProto.GetDeltaCNanoseconds()), + configProto.GetTransmitDespiteContractReadError(), }, nil } @@ -138,6 +147,7 @@ func (c OffchainConfig) Encode() []byte { c.AlphaAcceptInfinite, c.AlphaAcceptPPB, uint64(c.DeltaC), + c.TransmitDespiteContractReadError, } result, err := proto.Marshal(&configProto) if err != nil { @@ -307,6 +317,15 @@ func (fac NumericalMedianFactory) NewReportingPlugin(ctx context.Context, config deviationFunc = fac.DeviationFunc } + logger.Info("NewReportingPlugin configuration values", commontypes.LogFields{ + "f": configuration.F, + "n": configuration.N, + "offchainConfig": offchainConfig, + "onchainConfig": onchainConfig, + "includeGasPriceSubunitsInObservation": fac.IncludeGasPriceSubunitsInObservation, + "hasCustomDeviationFunc": fac.DeviationFunc != nil, + }) + return &numericalMedian{ offchainConfig, onchainConfig, @@ -655,8 +674,33 @@ func (nm *numericalMedian) shouldReport(ctx context.Context, repts types.ReportT return false, nil } +type latestTransmissionDetails struct { + ConfigDigest types.ConfigDigest + EpochRound epochRound + LatestAnswer *big.Int + LatestTimestamp time.Time +} + +func (nm *numericalMedian) getLatestTransmissionDetails(ctx context.Context) (*latestTransmissionDetails, error) { + configDigest, epoch, round, latestAnswer, latestTimestamp, err := nm.contractTransmitter.LatestTransmissionDetails(ctx) + if err != nil { + return nil, fmt.Errorf("error during LatestTransmissionDetails: %w", err) + } + return &latestTransmissionDetails{ + configDigest, + epochRound{epoch, round}, + latestAnswer, + latestTimestamp, + }, nil +} + func (nm *numericalMedian) ShouldAcceptFinalizedReport(ctx context.Context, repts types.ReportTimestamp, report types.Report) (bool, error) { reportEpochRound := epochRound{repts.Epoch, repts.Round} + + if !(len(report) <= nm.maxReportLength) { + return false, fmt.Errorf("report violates MaxReportLength limit set by ReportCodec. (reportLength: %v, maxReportLength: %v)", len(report), nm.maxReportLength) + } + if !nm.latestAcceptedEpochRound.Less(reportEpochRound) { nm.logger.Debug("ShouldAcceptFinalizedReport() = false, report is stale", commontypes.LogFields{ "latestAcceptedEpochRound": nm.latestAcceptedEpochRound, @@ -665,42 +709,35 @@ func (nm *numericalMedian) ShouldAcceptFinalizedReport(ctx context.Context, rept return false, nil } - contractConfigDigest, contractEpoch, contractRound, _, _, err := nm.contractTransmitter.LatestTransmissionDetails(ctx) + reportMedian, err := nm.reportCodec.MedianFromReport(ctx, report) if err != nil { - return false, fmt.Errorf("error during LatestTransmissionDetails: %w", err) + return false, fmt.Errorf("error during MedianFromReport: %w", err) } - contractEpochRound := epochRound{contractEpoch, contractRound} - - if contractConfigDigest != nm.configDigest { - nm.logger.Debug("ShouldAcceptFinalizedReport() = false, config digest mismatch", commontypes.LogFields{ - "contractConfigDigest": contractConfigDigest, - "reportConfigDigest": nm.configDigest, - "reportEpochRound": reportEpochRound, - }) - return false, nil - } + medianContractReadErrorAcceptOverride := false + contractLatestTransmissionDetailsOrNil, err := nm.getLatestTransmissionDetails(ctx) + if err != nil { + if nm.offchainConfig.TransmitDespiteContractReadError { + medianContractReadErrorAcceptOverride = true + nm.logger.Error("error during getLatestTransmissionDetails", commontypes.LogFields{ + "error": err, + "reportEpochRound": reportEpochRound, + }) + // We intentionally do not return an error here. - if !contractEpochRound.Less(reportEpochRound) { - nm.logger.Debug("ShouldAcceptFinalizedReport() = false, report is stale", commontypes.LogFields{ - "contractEpochRound": contractEpochRound, - "reportEpochRound": reportEpochRound, - }) - return false, nil + } else { + return false, fmt.Errorf("error during getLatestTransmissionDetails: %w", err) + } } - if !(len(report) <= nm.maxReportLength) { - nm.logger.Warn("report violates MaxReportLength limit set by ReportCodec", commontypes.LogFields{ - "reportEpochRound": reportEpochRound, - "reportLength": len(report), - "maxReportLength": nm.maxReportLength, - }) - return false, nil + contractConfigDigestMatches := false + if contractLatestTransmissionDetailsOrNil != nil { + contractConfigDigestMatches = contractLatestTransmissionDetailsOrNil.ConfigDigest == nm.configDigest } - reportMedian, err := nm.reportCodec.MedianFromReport(ctx, report) - if err != nil { - return false, fmt.Errorf("error during MedianFromReport: %w", err) + reportFresh := false + if contractLatestTransmissionDetailsOrNil != nil { + reportFresh = contractLatestTransmissionDetailsOrNil.EpochRound.Less(reportEpochRound) } deviates := false @@ -711,17 +748,26 @@ func (nm *numericalMedian) ShouldAcceptFinalizedReport(ctx context.Context, rept } deviates = result } - nothingPending := !contractEpochRound.Less(nm.latestAcceptedEpochRound) - result := deviates || nothingPending + + nothingPending := false + if contractLatestTransmissionDetailsOrNil != nil { + nothingPending = !contractLatestTransmissionDetailsOrNil.EpochRound.Less(nm.latestAcceptedEpochRound) + } + + result := medianContractReadErrorAcceptOverride || (contractConfigDigestMatches && reportFresh && (deviates || nothingPending)) nm.logger.Debug("ShouldAcceptFinalizedReport() = result", commontypes.LogFields{ - "contractEpochRound": contractEpochRound, - "reportEpochRound": reportEpochRound, - "latestAcceptedEpochRound": nm.latestAcceptedEpochRound, - "alphaAcceptInfinite": nm.offchainConfig.AlphaAcceptInfinite, - "alphaAcceptPPB": nm.offchainConfig.AlphaAcceptPPB, - "deviates": deviates, - "result": result, + "contractLatestTransmissionDetailsOrNil": contractLatestTransmissionDetailsOrNil, + "reportEpochRound": reportEpochRound, + "latestAcceptedEpochRound": nm.latestAcceptedEpochRound, + "alphaAcceptInfinite": nm.offchainConfig.AlphaAcceptInfinite, + "alphaAcceptPPB": nm.offchainConfig.AlphaAcceptPPB, + "medianContractReadErrorAcceptOverride": medianContractReadErrorAcceptOverride, + "contractConfigDigestMatches": contractConfigDigestMatches, + "reportFresh": reportFresh, + "nothingPending": nothingPending, + "deviates": deviates, + "result": result, }) if result { @@ -735,31 +781,45 @@ func (nm *numericalMedian) ShouldAcceptFinalizedReport(ctx context.Context, rept func (nm *numericalMedian) ShouldTransmitAcceptedReport(ctx context.Context, repts types.ReportTimestamp, report types.Report) (bool, error) { reportEpochRound := epochRound{repts.Epoch, repts.Round} - contractConfigDigest, contractEpoch, contractRound, _, _, err := nm.contractTransmitter.LatestTransmissionDetails(ctx) + medianContractReadErrorTransmitOverride := false + contractLatestTransmissionDetailsOrNil, err := nm.getLatestTransmissionDetails(ctx) if err != nil { - return false, err - } + if nm.offchainConfig.TransmitDespiteContractReadError { + medianContractReadErrorTransmitOverride = true + nm.logger.Error("error during getLatestTransmissionDetails", commontypes.LogFields{ + "error": err, + "reportEpochRound": reportEpochRound, + }) + // We intentionally do not return an error here. - contractEpochRound := epochRound{contractEpoch, contractRound} + } else { + return false, fmt.Errorf("error during getLatestTransmissionDetails: %w", err) + } + } - if contractConfigDigest != nm.configDigest { - nm.logger.Debug("ShouldTransmitAcceptedReport() = false, config digest mismatch", commontypes.LogFields{ - "contractConfigDigest": contractConfigDigest, - "reportConfigDigest": nm.configDigest, - "reportEpochRound": reportEpochRound, - }) - return false, nil + contractConfigDigestMatches := false + if contractLatestTransmissionDetailsOrNil != nil { + contractConfigDigestMatches = contractLatestTransmissionDetailsOrNil.ConfigDigest == nm.configDigest } - if !contractEpochRound.Less(reportEpochRound) { - nm.logger.Debug("ShouldTransmitAcceptedReport() = false, report is stale", commontypes.LogFields{ - "contractEpochRound": contractEpochRound, - "reportEpochRound": reportEpochRound, - }) - return false, nil + reportFresh := false + if contractLatestTransmissionDetailsOrNil != nil { + reportFresh = contractLatestTransmissionDetailsOrNil.EpochRound.Less(reportEpochRound) } - return true, nil + result := medianContractReadErrorTransmitOverride || (contractConfigDigestMatches && reportFresh) + + nm.logger.Debug("ShouldTransmitAcceptedReport() = result", commontypes.LogFields{ + "contractLatestTransmissionDetailsOrNil": contractLatestTransmissionDetailsOrNil, + "reportEpochRound": reportEpochRound, + "latestAcceptedEpochRound": nm.latestAcceptedEpochRound, + "medianContractReadErrorTransmitOverride": medianContractReadErrorTransmitOverride, + "contractConfigDigestMatches": contractConfigDigestMatches, + "reportFresh": reportFresh, + "result": result, + }) + + return result, nil } func (nm *numericalMedian) Close() error { diff --git a/offchainreporting2/reportingplugin/median/offchainreporting2_median_config.pb.go b/offchainreporting2/reportingplugin/median/offchainreporting2_median_config.pb.go index fb12ae2b..1c13b2f6 100644 --- a/offchainreporting2/reportingplugin/median/offchainreporting2_median_config.pb.go +++ b/offchainreporting2/reportingplugin/median/offchainreporting2_median_config.pb.go @@ -25,11 +25,12 @@ type NumericalMedianConfigProto struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - AlphaReportInfinite bool `protobuf:"varint,1,opt,name=alpha_report_infinite,json=alphaReportInfinite,proto3" json:"alpha_report_infinite,omitempty"` - AlphaReportPpb uint64 `protobuf:"varint,2,opt,name=alpha_report_ppb,json=alphaReportPpb,proto3" json:"alpha_report_ppb,omitempty"` - AlphaAcceptInfinite bool `protobuf:"varint,3,opt,name=alpha_accept_infinite,json=alphaAcceptInfinite,proto3" json:"alpha_accept_infinite,omitempty"` - AlphaAcceptPpb uint64 `protobuf:"varint,4,opt,name=alpha_accept_ppb,json=alphaAcceptPpb,proto3" json:"alpha_accept_ppb,omitempty"` - DeltaCNanoseconds uint64 `protobuf:"varint,5,opt,name=delta_c_nanoseconds,json=deltaCNanoseconds,proto3" json:"delta_c_nanoseconds,omitempty"` + AlphaReportInfinite bool `protobuf:"varint,1,opt,name=alpha_report_infinite,json=alphaReportInfinite,proto3" json:"alpha_report_infinite,omitempty"` + AlphaReportPpb uint64 `protobuf:"varint,2,opt,name=alpha_report_ppb,json=alphaReportPpb,proto3" json:"alpha_report_ppb,omitempty"` + AlphaAcceptInfinite bool `protobuf:"varint,3,opt,name=alpha_accept_infinite,json=alphaAcceptInfinite,proto3" json:"alpha_accept_infinite,omitempty"` + AlphaAcceptPpb uint64 `protobuf:"varint,4,opt,name=alpha_accept_ppb,json=alphaAcceptPpb,proto3" json:"alpha_accept_ppb,omitempty"` + DeltaCNanoseconds uint64 `protobuf:"varint,5,opt,name=delta_c_nanoseconds,json=deltaCNanoseconds,proto3" json:"delta_c_nanoseconds,omitempty"` + TransmitDespiteContractReadError bool `protobuf:"varint,6,opt,name=transmit_despite_contract_read_error,json=transmitDespiteContractReadError,proto3" json:"transmit_despite_contract_read_error,omitempty"` } func (x *NumericalMedianConfigProto) Reset() { @@ -99,13 +100,20 @@ func (x *NumericalMedianConfigProto) GetDeltaCNanoseconds() uint64 { return 0 } +func (x *NumericalMedianConfigProto) GetTransmitDespiteContractReadError() bool { + if x != nil { + return x.TransmitDespiteContractReadError + } + return false +} + var File_offchainreporting2_median_config_proto protoreflect.FileDescriptor var file_offchainreporting2_median_config_proto_rawDesc = []byte{ 0x0a, 0x26, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x32, 0x5f, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x32, 0x22, 0x88, 0x02, 0x0a, + 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x32, 0x22, 0xd8, 0x02, 0x0a, 0x1a, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x32, 0x0a, 0x15, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x69, @@ -122,7 +130,12 @@ var file_offchainreporting2_median_config_proto_rawDesc = []byte{ 0x63, 0x65, 0x70, 0x74, 0x50, 0x70, 0x62, 0x12, 0x2e, 0x0a, 0x13, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x63, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x43, 0x4e, 0x61, 0x6e, 0x6f, - 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x3b, 0x6d, 0x65, 0x64, + 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x4e, 0x0a, 0x24, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x6d, 0x69, 0x74, 0x5f, 0x64, 0x65, 0x73, 0x70, 0x69, 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x61, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, 0x44, + 0x65, 0x73, 0x70, 0x69, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x52, 0x65, + 0x61, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x3b, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } diff --git a/offchainreporting2plus/confighelper/confighelper.go b/offchainreporting2plus/confighelper/confighelper.go index fa5ea2e6..36da13e3 100644 --- a/offchainreporting2plus/confighelper/confighelper.go +++ b/offchainreporting2plus/confighelper/confighelper.go @@ -142,6 +142,7 @@ func ContractSetConfigArgsForEthereumIntegrationTest( false, alphaPPB, 0, + false, }.Encode(), util.PointerTo(50 * time.Millisecond), 50 * time.Millisecond, diff --git a/offchainreporting2plus/internal/ocr3/protocol/outcome_generation_follower.go b/offchainreporting2plus/internal/ocr3/protocol/outcome_generation_follower.go index 95660283..21094f9c 100644 --- a/offchainreporting2plus/internal/ocr3/protocol/outcome_generation_follower.go +++ b/offchainreporting2plus/internal/ocr3/protocol/outcome_generation_follower.go @@ -496,7 +496,7 @@ func (outgen *outcomeGenerationState[RI]) backgroundProposalOutcome( outcomeInputsDigest := MakeOutcomeInputsDigest( ogid, - outgen.sharedState.committedOutcome, + outctx.PreviousOutcome, outctx.SeqNr, query, attributedObservations, diff --git a/offchainreporting2plus/internal/ocr3_1/blobtypes/serialization.go b/offchainreporting2plus/internal/ocr3_1/blobtypes/serialization.go index 9dc2c315..6f08e2b8 100644 --- a/offchainreporting2plus/internal/ocr3_1/blobtypes/serialization.go +++ b/offchainreporting2plus/internal/ocr3_1/blobtypes/serialization.go @@ -76,3 +76,28 @@ func (lc *LightCertifiedBlob) UnmarshalBinary(data []byte) error { } return nil } + +// Conservative upper bounds for LightCertifiedBlob marshalled size estimation. +// These are intentionally generous to accommodate future format changes. +const ( + protobufOverhead = 8 + + LightCertifiedBlobBaseBytes = protobufOverhead + + len(mt.Digest{}) + // ChunkDigestsRoot + 8 + // PayloadLength + 8 + // ExpirySeqNr + 8 // Submitter + + AttributedBlobAvailabilitySignatureBytes = protobufOverhead + + ed25519.SignatureSize + // Signature + 8 // Signer +) + +// LightCertifiedBlobMarshalledBytesUpperBound returns a conservative upper bound +// on the marshalled length of a LightCertifiedBlob with at most n signatures. +func LightCertifiedBlobMarshalledBytesUpperBound(n int) int { + if n < 0 { + n = 0 + } + return LightCertifiedBlobBaseBytes + n*AttributedBlobAvailabilitySignatureBytes +} diff --git a/offchainreporting2plus/internal/ocr3_1/blobtypes/types.go b/offchainreporting2plus/internal/ocr3_1/blobtypes/types.go index 42c89a59..0c808a0f 100644 --- a/offchainreporting2plus/internal/ocr3_1/blobtypes/types.go +++ b/offchainreporting2plus/internal/ocr3_1/blobtypes/types.go @@ -259,7 +259,25 @@ func (h *BlobHandle) UnmarshalBinary(data []byte) error { } h.blobHandleSumType = &lc default: - return fmt.Errorf("unknown BlobHandle version: %d", data[0]) + return fmt.Errorf("unknown BlobHandle variant: %v", variant) } return nil } + +const ( + // blobHandleVariantTagBytes accounts for the 1-byte variant tag that + // prefixes the marshalled BlobHandleSumType. + blobHandleVariantTagBytes = 1 +) + +// BlobHandleMarshalledBytesUpperBound returns a conservative upper bound on the +// marshalled length of a BlobHandle produced in a protocol instance with +// parameters (n, f). +// +// This computes the maximum across all possible BlobHandleSumType variants. +func BlobHandleMarshalledBytesUpperBound(n int, f int) int { + // Take max across all variants (currently only LightCertifiedBlob) + maxVariantSize := LightCertifiedBlobMarshalledBytesUpperBound(n) + + return blobHandleVariantTagBytes + maxVariantSize +} diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/blob_exchange.go b/offchainreporting2plus/internal/ocr3_1/protocol/blob_exchange.go index 23962167..b5827ac6 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/blob_exchange.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/blob_exchange.go @@ -1120,13 +1120,13 @@ func (bex *blobExchangeState[RI]) messageBlobChunkRequest(msg MessageBlobChunkRe }) tx, err := bex.kv.NewReadTransactionUnchecked() - defer tx.Discard() if err != nil { bex.logger.Error("failed to create read transaction for MessageBlobChunkRequest", commontypes.LogFields{ "error": err, }) return } + defer tx.Discard() meta, err := tx.ReadBlobMeta(msg.BlobDigest) if err != nil { diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation.go b/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation.go index dfa595d2..f178057f 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation.go @@ -298,6 +298,7 @@ func (outgen *outcomeGenerationState[RI]) run(restoredCert CertifiedPrepareOrCom "l": outgen.sharedState.l, }) outgen.subs.Wait() + outgen.ensureOpenKVTransactionDiscarded() outgen.metrics.Close() outgen.logger.Info("OutcomeGeneration: exiting", commontypes.LogFields{ "e": outgen.sharedState.e, diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation_follower.go b/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation_follower.go index ef7ffd8c..eab90fe6 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation_follower.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/outcome_generation_follower.go @@ -472,9 +472,9 @@ func (outgen *outcomeGenerationState[RI]) backgroundProposalStateTransition( asos []AttributedSignedObservation, kvReadWriteTxn KeyValueDatabaseReadWriteTransaction, ) { - shouldDiscardKVTxn := true + succeeded := false defer func() { - if shouldDiscardKVTxn { + if !succeeded { kvReadWriteTxn.Discard() } }() @@ -516,16 +516,16 @@ func (outgen *outcomeGenerationState[RI]) backgroundProposalStateTransition( writeSet, err := kvReadWriteTxn.GetWriteSet() if err != nil { - outgen.logger.Warn("failed to get write set from kv read/write transaction", commontypes.LogFields{ - "seqNr": outgen.sharedState.seqNr, + logger.Warn("failed to get write set from kv read/write transaction", commontypes.LogFields{ + "seqNr": roundCtx.SeqNr, "error": err, }) return } stateRootDigest, err := kvReadWriteTxn.CloseWriteSet() if err != nil { - outgen.logger.Warn("failed to close the transaction WriteSet", commontypes.LogFields{ - "seqNr": outgen.sharedState.seqNr, + logger.Warn("failed to close the transaction WriteSet", commontypes.LogFields{ + "seqNr": roundCtx.SeqNr, "error": err, }) return @@ -553,12 +553,19 @@ func (outgen *outcomeGenerationState[RI]) backgroundProposalStateTransition( reportsPlusPrecursor, }, }: - shouldDiscardKVTxn = false + succeeded = true case <-ctx.Done(): } } func (outgen *outcomeGenerationState[RI]) eventComputedProposalStateTransition(ev EventComputedProposalStateTransition[RI]) { + succeeded := false + defer func() { + if !succeeded { + ev.KeyValueDatabaseReadWriteTransaction.Discard() + } + }() + if ev.Epoch != outgen.sharedState.e || ev.SeqNr != outgen.sharedState.seqNr { outgen.logger.Debug("discarding EventComputedProposalStateTransition from old round", commontypes.LogFields{ "seqNr": outgen.sharedState.seqNr, @@ -576,8 +583,6 @@ func (outgen *outcomeGenerationState[RI]) eventComputedProposalStateTransition(e return } - outgen.followerState.openKVTxn = ev.KeyValueDatabaseReadWriteTransaction - var stidap stateTransitionInfoDigestsAndPreimages switch sti := ev.stateTransitionInfo.(type) { case stateTransitionInfoDigestsAndPreimages: @@ -589,8 +594,6 @@ func (outgen *outcomeGenerationState[RI]) eventComputedProposalStateTransition(e return } - outgen.followerState.stateTransitionInfo = stidap - err := outgen.persistUnattestedStateTransitionBlockAndReportsPlusPrecursor( StateTransitionBlock{ stidap.PrevHistoryDigest, @@ -612,7 +615,11 @@ func (outgen *outcomeGenerationState[RI]) eventComputedProposalStateTransition(e return } + outgen.followerState.stateTransitionInfo = stidap + outgen.followerState.openKVTxn = ev.KeyValueDatabaseReadWriteTransaction outgen.broadcastMessagePrepare() + + succeeded = true } // broadcasts MessagePrepare for outgen.sharedState.e, outgen.sharedState.seqNr @@ -1037,8 +1044,8 @@ func (outgen *outcomeGenerationState[RI]) backgroundCommitted( kvReadTxn.Discard() if !ok { - outgen.logger.Info("continuing after ReportingPlugin.Committed returned an error", commontypes.LogFields{ - "seqNr": outgen.sharedState.seqNr, + logger.Info("continuing after ReportingPlugin.Committed returned an error", commontypes.LogFields{ + "seqNr": roundCtx.SeqNr, }) } diff --git a/offchainreporting2plus/internal/ocr3_1/protocol/report_attestation.go b/offchainreporting2plus/internal/ocr3_1/protocol/report_attestation.go index 33add6c1..6f35c4c4 100644 --- a/offchainreporting2plus/internal/ocr3_1/protocol/report_attestation.go +++ b/offchainreporting2plus/internal/ocr3_1/protocol/report_attestation.go @@ -139,16 +139,7 @@ func (repatt *reportAttestationState[RI]) run() { } func (repatt *reportAttestationState[RI]) eventNewCertifiedCommit(ev EventNewCertifiedCommit[RI]) { - repatt.receivedCertifiedReportsPlusPrecursorDigest(ev.SeqNr, ev.ReportsPlusPrecursorDigest) -} - -func (repatt *reportAttestationState[RI]) receivedCertifiedReportsPlusPrecursorDigest(seqNr uint64, reportsPlusPrecursorDigest ReportsPlusPrecursorDigest) { - if repatt.rounds[seqNr] != nil && repatt.rounds[seqNr].certifiedReportsPlusPrecursorDigest != nil { - repatt.logger.Debug("dropping redundant ReportsPlusPrecursorDigest", commontypes.LogFields{ - "seqNr": seqNr, - }) - return - } + seqNr := ev.SeqNr if _, ok := repatt.rounds[seqNr]; !ok { ctx, cancel := context.WithCancel(repatt.ctx) @@ -165,7 +156,12 @@ func (repatt *reportAttestationState[RI]) receivedCertifiedReportsPlusPrecursorD } } - repatt.rounds[seqNr].certifiedReportsPlusPrecursorDigest = &reportsPlusPrecursorDigest + if repatt.rounds[seqNr].certifiedReportsPlusPrecursorDigest == nil { + repatt.rounds[seqNr].certifiedReportsPlusPrecursorDigest = &ev.ReportsPlusPrecursorDigest + } + if repatt.rounds[seqNr].certifiedReportsPlusPrecursor == nil { + repatt.rounds[seqNr].successfullyCheckedKV = false + } repatt.tryComplete(seqNr) } diff --git a/offchainreporting2plus/ocr3_1types/blob.go b/offchainreporting2plus/ocr3_1types/blob.go index 6367f05b..7dd72c7a 100644 --- a/offchainreporting2plus/ocr3_1types/blob.go +++ b/offchainreporting2plus/ocr3_1types/blob.go @@ -32,3 +32,25 @@ type BlobBroadcastFetcher interface { BlobBroadcaster BlobFetcher } + +// BlobHandleMarshalledBytesUpperBound returns a conservative upper bound on the +// marshalled length of a BlobHandle. The n & f parameters must match those in +// [ocr3types.ReportingPluginConfig]. +// +// This is useful for computing limits like MaxObservationBytes when blob +// handles will be included in observations. +// +// Example usage in a ReportingPluginFactory: +// +// func (f *Factory) NewReportingPlugin( +// ctx context.Context, +// config ocr3types.ReportingPluginConfig, +// bbf ocr3_1types.BlobBroadcastFetcher, +// ) (ocr3_1types.ReportingPlugin[RI], ocr3_1types.ReportingPluginInfo, error) { +// maxBlobHandleBytes := ocr3_1types.BlobHandleMarshalledBytesUpperBound(config.N, config.F) +// maxObservationBytes := baseObservationSize + numBlobHandles*maxBlobHandleBytes +// // ... +// } +func BlobHandleMarshalledBytesUpperBound(n int, f int) int { + return blobtypes.BlobHandleMarshalledBytesUpperBound(n, f) +}