From a27641293b55a79240a0b07221798aecc42dc9f6 Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Tue, 21 Jan 2025 14:08:29 +0200 Subject: [PATCH 01/62] Implement the RPCBlockHeaderSubscriber for indexing finalized results --- Makefile | 33 ++ bootstrap/bootstrap.go | 2 +- go.mod | 37 +- go.sum | 80 ++- services/ingestion/block_header_subscriber.go | 529 ++++++++++++++++++ services/requester/cross-spork_client.go | 18 + tests/go.mod | 37 +- tests/go.sum | 84 ++- 8 files changed, 691 insertions(+), 129 deletions(-) create mode 100644 services/ingestion/block_header_subscriber.go diff --git a/Makefile b/Makefile index ef0e054cd..b3ff2fa32 100644 --- a/Makefile +++ b/Makefile @@ -227,3 +227,36 @@ endif docker run $(MODE) -p $(HOST_PORT):8545 -p $(HOST_METRICS_PORT):8080 $(MOUNT) "$(CONTAINER_REGISTRY)/flow-evm-gateway:$(IMAGE_TAG)" $(CMD_ARGS) +.PHONY: start-testnet +start-testnet: + rm -rf testnet-db-block-headers/ + rm -rf metrics/data/ + go run cmd/main.go run \ + --database-dir=testnet-db-block-headers \ + --access-node-grpc-host=access.devnet.nodes.onflow.org:9000 \ + --access-node-spork-hosts=access-001.devnet51.nodes.onflow.org:9000 \ + --flow-network-id=flow-testnet \ + --init-cadence-height=211176670 \ + --ws-enabled=true \ + --coinbase=FACF71692421039876a5BB4F10EF7A439D8ef61E \ + --coa-address=0x62631c28c9fc5a91 \ + --coa-key=2892fba444f1d5787739708874e3b01160671924610411ac787ac1379d420f49 \ + --gas-price=100 \ + --log-level=info + +.PHONY: start-mainnet +start-mainnet: + rm -rf mainnet-db-block-headers/ + rm -rf metrics/data/ + go run cmd/main.go run \ + --database-dir=mainnet-db-block-headers \ + --access-node-grpc-host=access.mainnet.nodes.onflow.org:9000 \ + --access-node-spork-hosts=access-001.mainnet25.nodes.onflow.org:9000 \ + --flow-network-id=flow-mainnet \ + --init-cadence-height=85981135 \ + --ws-enabled=true \ + --coinbase=FACF71692421039876a5BB4F10EF7A439D8ef61E \ + --coa-address=0xf1ab99c82dee3526 \ + --coa-key=2892fba444f1d5787739708874e3b01160671924610411ac787ac1379d420f49 \ + --gas-price=100 \ + --log-level=info diff --git a/bootstrap/bootstrap.go b/bootstrap/bootstrap.go index 78a57083d..718e46671 100644 --- a/bootstrap/bootstrap.go +++ b/bootstrap/bootstrap.go @@ -142,7 +142,7 @@ func (b *Bootstrap) StartEventIngestion(ctx context.Context) error { chainID := b.config.FlowNetworkID // create event subscriber - subscriber := ingestion.NewRPCEventSubscriber( + subscriber := ingestion.NewRPCBlockHeaderSubscriber( b.logger, b.client, chainID, diff --git a/go.mod b/go.mod index af84aab9f..a4cda12f0 100644 --- a/go.mod +++ b/go.mod @@ -6,10 +6,10 @@ require ( github.com/cockroachdb/pebble v1.1.1 github.com/goccy/go-json v0.10.2 github.com/hashicorp/go-multierror v1.1.1 - github.com/onflow/atree v0.8.0 - github.com/onflow/cadence v1.2.2 + github.com/onflow/atree v0.8.1 + github.com/onflow/cadence v1.3.0 github.com/onflow/flow-go v0.38.0-preview.0.4 - github.com/onflow/flow-go-sdk v1.2.3 + github.com/onflow/flow-go-sdk v1.3.0 github.com/onflow/go-ethereum v1.14.7 github.com/prometheus/client_golang v1.18.0 github.com/rs/cors v1.8.0 @@ -18,20 +18,19 @@ require ( github.com/sethvargo/go-limiter v1.0.0 github.com/sethvargo/go-retry v0.2.3 github.com/spf13/cobra v1.8.1 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 go.uber.org/ratelimit v0.3.1 golang.org/x/exp v0.0.0-20240119083558-1b970713d09a golang.org/x/sync v0.8.0 - google.golang.org/grpc v1.63.2 + google.golang.org/grpc v1.64.1 ) require ( - cloud.google.com/go v0.112.0 // indirect - cloud.google.com/go/compute v1.24.0 // indirect - cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go v0.112.1 // indirect + cloud.google.com/go/compute/metadata v0.5.0 // indirect cloud.google.com/go/iam v1.1.6 // indirect cloud.google.com/go/kms v1.15.7 // indirect - cloud.google.com/go/storage v1.36.0 // indirect + cloud.google.com/go/storage v1.38.0 // indirect github.com/DataDog/zstd v1.5.2 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/SaveTheRbtz/mph v0.1.1-0.20240117162131-4166ec7869bc // indirect @@ -88,7 +87,7 @@ require ( github.com/google/s2a-go v0.1.7 // indirect github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect - github.com/googleapis/gax-go/v2 v2.12.0 // indirect + github.com/googleapis/gax-go/v2 v2.12.2 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -181,10 +180,10 @@ require ( github.com/vmihailenco/msgpack/v4 v4.3.11 // indirect github.com/vmihailenco/tagparser v0.1.1 // indirect github.com/x448/float16 v0.8.4 // indirect - github.com/zeebo/blake3 v0.2.3 // indirect + github.com/zeebo/blake3 v0.2.4 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect go.opentelemetry.io/otel v1.24.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect @@ -196,19 +195,19 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/crypto v0.28.0 // indirect - golang.org/x/net v0.25.0 // indirect - golang.org/x/oauth2 v0.17.0 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/oauth2 v0.18.0 // indirect golang.org/x/sys v0.26.0 // indirect golang.org/x/text v0.19.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.14.0 // indirect - google.golang.org/api v0.162.0 // indirect + google.golang.org/api v0.169.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.3.0 // indirect diff --git a/go.sum b/go.sum index f4226b2e0..f3cb76227 100644 --- a/go.sum +++ b/go.sum @@ -17,18 +17,16 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.112.0 h1:tpFCD7hpHFlQ8yPwT3x+QeXqc2T6+n6T+hmABHfDUSM= -cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4= +cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= +cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= -cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40= -cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= +cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= @@ -45,8 +43,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -cloud.google.com/go/storage v1.36.0 h1:P0mOkAcaJxhCTvAkMhxMfrTKiNcub4YmmPBtlhAyTr8= -cloud.google.com/go/storage v1.36.0/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= +cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg= +cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= @@ -102,8 +100,6 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= -github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= @@ -179,8 +175,6 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= -github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA= github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-ethereum v1.13.10 h1:Ppdil79nN+Vc+mXfge0AuUgmKWuVv4eMqzoIVSdqZek= @@ -337,8 +331,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfF github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= -github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= +github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA= +github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= @@ -424,7 +418,6 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= -github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -521,10 +514,10 @@ github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= 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/onflow/atree v0.8.0 h1:qg5c6J1gVDNObughpEeWm8oxqhPGdEyGrda121GM4u0= -github.com/onflow/atree v0.8.0/go.mod h1:yccR+LR7xc1Jdic0mrjocbHvUD7lnVvg8/Ct1AA5zBo= -github.com/onflow/cadence v1.2.2 h1:LwigF/2lPiXlwX5rFn71KeMpmW5Iu/f/JtsPLLULBCc= -github.com/onflow/cadence v1.2.2/go.mod h1:PYX1xLejqswtDsQzN93x/VpfSKNyjUk6hrkc/mpv7xs= +github.com/onflow/atree v0.8.1 h1:DAnPnL9/Ks3LaAnkQVokokTBG/znTW0DJfovDtJDhLI= +github.com/onflow/atree v0.8.1/go.mod h1:FT6udJF9Q7VQTu3wknDhFX+VV4D44ZGdqtTAE5iztck= +github.com/onflow/cadence v1.3.0 h1:COTlTqUACtTvOeFe7+jP9UDVEU3M3OZzrbzzsEbyqCk= +github.com/onflow/cadence v1.3.0/go.mod h1:638c9Zy25EwflSEE7tBFAVM9N6uwcWt77sgKpyYfSTc= github.com/onflow/crypto v0.25.2 h1:GjHunqVt+vPcdqhxxhAXiMIF3YiLX7gTuTR5O+VG2ns= github.com/onflow/crypto v0.25.2/go.mod h1:fY7eLqUdMKV8EGOw301unP8h7PvLVy8/6gVR++/g0BY= github.com/onflow/flow-core-contracts/lib/go/contracts v1.4.0 h1:R86HaOuk6vpuECZnriEUE7bw9inC2AtdSn8lL/iwQLQ= @@ -537,8 +530,8 @@ github.com/onflow/flow-ft/lib/go/templates v1.0.1 h1:FDYKAiGowABtoMNusLuRCILIZDt github.com/onflow/flow-ft/lib/go/templates v1.0.1/go.mod h1:uQ8XFqmMK2jxyBSVrmyuwdWjTEb+6zGjRYotfDJ5pAE= github.com/onflow/flow-go v0.38.0-preview.0.4 h1:vjnp6btehu3X/aYjsXYlA3r/GGYeB05so0d7ICtXbmg= github.com/onflow/flow-go v0.38.0-preview.0.4/go.mod h1:c4ubAQ2WIMYY/TOaBvbajROEFWv2HwhKeGOsEdLPIM0= -github.com/onflow/flow-go-sdk v1.2.3 h1:jb+0dIXBO12Zt8x3c2xDXYPv6k3sRTUvhe59M+EcXTI= -github.com/onflow/flow-go-sdk v1.2.3/go.mod h1:jMaffBTlAIdutx+pBhRIigLZFIBYSDDST0Uax1rW2qo= +github.com/onflow/flow-go-sdk v1.3.0 h1:17xYDaemQBoK2pb9F4S8bH7eAKJSqsuj+DlNHv/FCL0= +github.com/onflow/flow-go-sdk v1.3.0/go.mod h1:Rp424erpOcP7XaZ2zVrOEhBImn6CQIaNX7EaqXdyRa8= github.com/onflow/flow-nft/lib/go/contracts v1.2.2 h1:XFERNVUDGbZ4ViZjt7P1cGD80mO1PzUJYPfdhXFsGbQ= github.com/onflow/flow-nft/lib/go/contracts v1.2.2/go.mod h1:eZ9VMMNfCq0ho6kV25xJn1kXeCfxnkhj3MwF3ed08gY= github.com/onflow/flow-nft/lib/go/templates v1.2.1 h1:SAALMZPDw9Eb9p5kSLnmnFxjyig1MLiT4JUlLp0/bSE= @@ -676,8 +669,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 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.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= @@ -719,11 +712,10 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= -github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg= -github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ= +github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= +github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -735,10 +727,10 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 h1:UNQQKPfTDe1J81ViolILjTKPr9WetKW6uei2hFgJmFs= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0/go.mod h1:r9vWsPS/3AQItv3OSlEJ/E4mbrhUbbw18meOjArPtKQ= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 h1:sv9kVfal0MK0wBMCOGr+HeJm9v803BkJxGrk2au7j08= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0/go.mod h1:SK2UL73Zy1quvRPonmOmRDiWk1KBV3LyIeeIxcEApWw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= @@ -863,8 +855,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -874,8 +866,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= -golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= +golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= +golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1059,8 +1051,8 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513 google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.162.0 h1:Vhs54HkaEpkMBdgGdOT2P6F0csGG/vxDS0hWHJzmmps= -google.golang.org/api v0.162.0/go.mod h1:6SulDkfoBIg4NFmCuZ39XeeAgSHCPecfSUuDyYlAHs0= +google.golang.org/api v0.169.0 h1:QwWPy71FgMWqJN/l6jVlFHUa29a7dcUy02I8o799nPY= +google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1108,10 +1100,10 @@ google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= -google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0= -google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1129,8 +1121,8 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= -google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA= +google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1143,8 +1135,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 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= diff --git a/services/ingestion/block_header_subscriber.go b/services/ingestion/block_header_subscriber.go new file mode 100644 index 000000000..2ab7d46b6 --- /dev/null +++ b/services/ingestion/block_header_subscriber.go @@ -0,0 +1,529 @@ +package ingestion + +import ( + "context" + "errors" + "fmt" + "sort" + "strings" + + "github.com/onflow/cadence/common" + "github.com/onflow/flow-evm-gateway/models" + errs "github.com/onflow/flow-evm-gateway/models/errors" + "github.com/onflow/flow-evm-gateway/services/requester" + "github.com/onflow/flow-go-sdk" + "github.com/onflow/flow-go/fvm/evm/events" + "github.com/onflow/flow-go/fvm/systemcontracts" + flowGo "github.com/onflow/flow-go/model/flow" + "github.com/rs/zerolog" +) + +var _ EventSubscriber = &RPCEventSubscriber{} + +type RPCBlockHeaderSubscriber struct { + logger zerolog.Logger + + client *requester.CrossSporkClient + chain flowGo.ChainID + keyLock requester.KeyLock + height uint64 + + recovery bool + recoveredEvents []flow.Event +} + +func NewRPCBlockHeaderSubscriber( + logger zerolog.Logger, + client *requester.CrossSporkClient, + chainID flowGo.ChainID, + keyLock requester.KeyLock, + startHeight uint64, +) *RPCBlockHeaderSubscriber { + logger = logger.With().Str("component", "subscriber").Logger() + return &RPCBlockHeaderSubscriber{ + logger: logger, + + client: client, + chain: chainID, + keyLock: keyLock, + height: startHeight, + } +} + +// Subscribe will retrieve all the events from the provided height. If the height is from previous +// sporks, it will first backfill all the events in all the previous sporks, and then continue +// to listen all new events in the current spork. +// +// If error is encountered during backfill the subscription will end and the response chanel will be closed. +func (r *RPCBlockHeaderSubscriber) Subscribe(ctx context.Context) <-chan models.BlockEvents { + // buffered channel so that the decoding of the events can happen in parallel to other operations + eventsChan := make(chan models.BlockEvents, 1000) + + go func() { + defer func() { + close(eventsChan) + }() + + // if the height is from the previous spork, backfill all the eventsChan from previous sporks first + if r.client.IsPastSpork(r.height) { + r.logger.Info(). + Uint64("height", r.height). + Msg("height found in previous spork, starting to backfill") + + // backfill all the missed events, handling of context cancellation is done by the producer + for ev := range r.backfill(ctx, r.height) { + eventsChan <- ev + + if ev.Err != nil { + return + } + + // keep updating height, so after we are done back-filling + // it will be at the first height in the current spork + r.height = ev.Events.CadenceHeight() + } + + // after back-filling is done, increment height by one, + // so we start with the height in the current spork + r.height = r.height + 1 + } + + r.logger.Info(). + Uint64("next-height", r.height). + Msg("backfilling done, subscribe for live data") + + // subscribe in the current spork, handling of context cancellation is done by the producer + for ev := range r.subscribe(ctx, r.height) { + eventsChan <- ev + } + + r.logger.Warn().Msg("ended subscription for events") + }() + + return eventsChan +} + +// subscribe to events by the provided height and handle any errors. +// +// Subscribing to EVM specific events and handle any disconnection errors +// as well as context cancellations. +func (r *RPCBlockHeaderSubscriber) subscribe(ctx context.Context, height uint64) <-chan models.BlockEvents { + eventsChan := make(chan models.BlockEvents) + + _, err := r.client.GetBlockHeaderByHeight(ctx, height) + if err != nil { + err = fmt.Errorf("failed to subscribe for events, the block height %d doesn't exist: %w", height, err) + eventsChan <- models.NewBlockEventsError(err) + return eventsChan + } + + blockHeadersChan, errChan, err := r.client.SubscribeBlockHeadersFromStartHeight( + ctx, + height, + flow.BlockStatusFinalized, + ) + if err != nil { + eventsChan <- models.NewBlockEventsError( + fmt.Errorf("failed to subscribe to events by block height: %d, with: %w", height, err), + ) + return eventsChan + } + lastReceivedHeight := height + + go func() { + defer func() { + close(eventsChan) + }() + + for ctx.Err() == nil { + select { + case <-ctx.Done(): + r.logger.Info().Msg("event ingestion received done signal") + return + + case blockHeader, ok := <-blockHeadersChan: + if !ok { + var err error + err = errs.ErrDisconnected + if ctx.Err() != nil { + err = ctx.Err() + } + eventsChan <- models.NewBlockEventsError(err) + return + } + + var blockEvents flow.BlockEvents + + for _, eventType := range blocksFilter(r.chain).EventTypes { + evts, err := r.client.GetEventsForHeightRange( + ctx, + eventType, + blockHeader.Height, + blockHeader.Height, + ) + if err != nil { + return + } + + if len(evts) != 1 { + return + } + blockEvent := evts[0] + blockEvents.Events = append(blockEvents.Events, blockEvent.Events...) + } + + evmEvents := models.NewSingleBlockEvents(blockEvents) + // if events contain an error, or we are in a recovery mode + if evmEvents.Err != nil || r.recovery { + evmEvents = r.recover(ctx, blockEvents, evmEvents.Err) + // if we are still in recovery go to the next event + if r.recovery { + continue + } + } + + for _, evt := range blockEvents.Events { + r.keyLock.UnlockKey(evt.TransactionID) + } + r.keyLock.Notify(blockHeader.Height) + lastReceivedHeight = blockHeader.Height + + eventsChan <- evmEvents + + case err, ok := <-errChan: + if !ok { + var err error + err = errs.ErrDisconnected + if ctx.Err() != nil { + err = ctx.Err() + } + eventsChan <- models.NewBlockEventsError(err) + return + } + + if strings.Contains(errors.Unwrap(err).Error(), "DeadlineExceeded") || + strings.Contains(errors.Unwrap(err).Error(), "unexpected EOF") { + blockHeadersChan, errChan, err = r.client.SubscribeBlockHeadersFromStartHeight( + ctx, + lastReceivedHeight+1, + flow.BlockStatusFinalized, + ) + if err != nil { + eventsChan <- models.NewBlockEventsError( + fmt.Errorf("failed to subscribe to events by block height: %d, with: %w", height, err), + ) + return + } + } else { + eventsChan <- models.NewBlockEventsError(fmt.Errorf("%w: %w", errs.ErrDisconnected, err)) + return + } + } + } + }() + + return eventsChan +} + +// backfill returns a channel that is filled with block events from the provided fromCadenceHeight up to the first +// height in the current spork. +func (r *RPCBlockHeaderSubscriber) backfill(ctx context.Context, fromCadenceHeight uint64) <-chan models.BlockEvents { + eventsChan := make(chan models.BlockEvents) + + go func() { + defer func() { + close(eventsChan) + }() + + for { + // check if the current fromCadenceHeight is still in past sporks, and if not return since we are done with backfilling + if !r.client.IsPastSpork(fromCadenceHeight) { + r.logger.Info(). + Uint64("height", fromCadenceHeight). + Msg("completed backfilling") + + return + } + + var err error + fromCadenceHeight, err = r.backfillSporkFromHeight(ctx, fromCadenceHeight, eventsChan) + if err != nil { + r.logger.Error().Err(err).Msg("error backfilling spork") + eventsChan <- models.NewBlockEventsError(err) + return + } + + r.logger.Info(). + Uint64("next-cadence-height", fromCadenceHeight). + Msg("reached the end of spork, checking next spork") + } + }() + + return eventsChan +} + +// / backfillSporkFromHeight will fill the eventsChan with block events from the provided fromHeight up to the first height in the spork that comes +// after the spork of the provided fromHeight. +func (r *RPCBlockHeaderSubscriber) backfillSporkFromHeight(ctx context.Context, fromCadenceHeight uint64, eventsChan chan<- models.BlockEvents) (uint64, error) { + evmAddress := common.Address(systemcontracts.SystemContractsForChain(r.chain).EVMContract.Address) + + blockExecutedEvent := common.NewAddressLocation( + nil, + evmAddress, + string(events.EventTypeBlockExecuted), + ).ID() + + transactionExecutedEvent := common.NewAddressLocation( + nil, + evmAddress, + string(events.EventTypeTransactionExecuted), + ).ID() + + lastHeight, err := r.client.GetLatestHeightForSpork(ctx, fromCadenceHeight) + if err != nil { + eventsChan <- models.NewBlockEventsError(err) + return 0, err + } + + r.logger.Info(). + Uint64("start-height", fromCadenceHeight). + Uint64("last-spork-height", lastHeight). + Msg("backfilling spork") + + for fromCadenceHeight < lastHeight { + r.logger.Debug().Msg(fmt.Sprintf("backfilling [%d / %d] ...", fromCadenceHeight, lastHeight)) + + startHeight := fromCadenceHeight + endHeight := fromCadenceHeight + maxRangeForGetEvents + if endHeight > lastHeight { + endHeight = lastHeight + } + + blocks, err := r.client.GetEventsForHeightRange(ctx, blockExecutedEvent, startHeight, endHeight) + if err != nil { + return 0, fmt.Errorf("failed to get block events: %w", err) + } + + transactions, err := r.client.GetEventsForHeightRange(ctx, transactionExecutedEvent, startHeight, endHeight) + if err != nil { + return 0, fmt.Errorf("failed to get block events: %w", err) + } + + if len(transactions) != len(blocks) { + return 0, fmt.Errorf("transactions and blocks have different length") + } + + // sort both, just in case + sort.Slice(blocks, func(i, j int) bool { + return blocks[i].Height < blocks[j].Height + }) + sort.Slice(transactions, func(i, j int) bool { + return transactions[i].Height < transactions[j].Height + }) + + for i := range transactions { + if transactions[i].Height != blocks[i].Height { + return 0, fmt.Errorf("transactions and blocks have different height") + } + + // append the transaction events to the block events + blocks[i].Events = append(blocks[i].Events, transactions[i].Events...) + + evmEvents := models.NewSingleBlockEvents(blocks[i]) + if evmEvents.Err != nil && errors.Is(evmEvents.Err, errs.ErrMissingBlock) { + evmEvents, err = r.accumulateBlockEvents( + ctx, + blocks[i], + blockExecutedEvent, + transactionExecutedEvent, + ) + if err != nil { + return 0, err + } + eventsChan <- evmEvents + // advance the height + fromCadenceHeight = evmEvents.Events.CadenceHeight() + 1 + break + } + eventsChan <- evmEvents + + // advance the height + fromCadenceHeight = evmEvents.Events.CadenceHeight() + 1 + } + + } + return fromCadenceHeight, nil +} + +// accumulateBlockEvents will keep fetching `EVM.TransactionExecuted` events +// until it finds their `EVM.BlockExecuted` event. +// At that point it will return the valid models.BlockEvents. +func (r *RPCBlockHeaderSubscriber) accumulateBlockEvents( + ctx context.Context, + block flow.BlockEvents, + blockExecutedEventType string, + txExecutedEventType string, +) (models.BlockEvents, error) { + evmEvents := models.NewSingleBlockEvents(block) + currentHeight := block.Height + transactionEvents := make([]flow.Event, 0) + + for evmEvents.Err != nil && errors.Is(evmEvents.Err, errs.ErrMissingBlock) { + blocks, err := r.client.GetEventsForHeightRange( + ctx, + blockExecutedEventType, + currentHeight, + currentHeight+maxRangeForGetEvents, + ) + if err != nil { + return models.BlockEvents{}, fmt.Errorf("failed to get block events: %w", err) + } + + transactions, err := r.client.GetEventsForHeightRange( + ctx, + txExecutedEventType, + currentHeight, + currentHeight+maxRangeForGetEvents, + ) + if err != nil { + return models.BlockEvents{}, fmt.Errorf("failed to get block events: %w", err) + } + + if len(transactions) != len(blocks) { + return models.BlockEvents{}, fmt.Errorf("transactions and blocks have different length") + } + + // sort both, just in case + sort.Slice(blocks, func(i, j int) bool { + return blocks[i].Height < blocks[j].Height + }) + sort.Slice(transactions, func(i, j int) bool { + return transactions[i].Height < transactions[j].Height + }) + + for i := range blocks { + if transactions[i].Height != blocks[i].Height { + return models.BlockEvents{}, fmt.Errorf("transactions and blocks have different height") + } + + // If no EVM.BlockExecuted event found, keep accumulating the incoming + // EVM.TransactionExecuted events, until we find the EVM.BlockExecuted + // event that includes them. + if len(blocks[i].Events) == 0 { + txEvents := transactions[i].Events + // Sort `EVM.TransactionExecuted` events + sort.Slice(txEvents, func(i, j int) bool { + if txEvents[i].TransactionIndex != txEvents[j].TransactionIndex { + return txEvents[i].TransactionIndex < txEvents[j].TransactionIndex + } + return txEvents[i].EventIndex < txEvents[j].EventIndex + }) + transactionEvents = append(transactionEvents, txEvents...) + } else { + blocks[i].Events = append(blocks[i].Events, transactionEvents...) + // We use `models.NewMultiBlockEvents`, as the `transactionEvents` + // are coming from different Flow blocks. + evmEvents = models.NewMultiBlockEvents(blocks[i]) + if evmEvents.Err == nil { + return evmEvents, nil + } + } + + currentHeight = blocks[i].Height + 1 + } + } + return evmEvents, nil +} + +// fetchMissingData is used as a backup mechanism for fetching EVM-related +// events, when the event streaming API returns an inconsistent response. +// An inconsistent response could be an EVM block that references EVM +// transactions which are not present in the response. It falls back +// to using grpc requests instead of streaming. +func (r *RPCBlockHeaderSubscriber) fetchMissingData( + ctx context.Context, + blockEvents flow.BlockEvents, +) models.BlockEvents { + // remove existing events + blockEvents.Events = nil + + for _, eventType := range blocksFilter(r.chain).EventTypes { + recoveredEvents, err := r.client.GetEventsForHeightRange( + ctx, + eventType, + blockEvents.Height, + blockEvents.Height, + ) + if err != nil { + return models.NewBlockEventsError(err) + } + + if len(recoveredEvents) != 1 { + return models.NewBlockEventsError( + fmt.Errorf( + "received %d but expected 1 event for height %d", + len(recoveredEvents), + blockEvents.Height, + ), + ) + } + + blockEvents.Events = append(blockEvents.Events, recoveredEvents[0].Events...) + } + + return models.NewSingleBlockEvents(blockEvents) +} + +// accumulateEventsMissingBlock will keep receiving transaction events until it can produce a valid +// EVM block event containing a block and transactions. At that point it will reset the recovery mode +// and return the valid block events. +func (r *RPCBlockHeaderSubscriber) accumulateEventsMissingBlock(events flow.BlockEvents) models.BlockEvents { + txEvents := events.Events + // Sort `EVM.TransactionExecuted` events + sort.Slice(txEvents, func(i, j int) bool { + if txEvents[i].TransactionIndex != txEvents[j].TransactionIndex { + return txEvents[i].TransactionIndex < txEvents[j].TransactionIndex + } + return txEvents[i].EventIndex < txEvents[j].EventIndex + }) + r.recoveredEvents = append(r.recoveredEvents, txEvents...) + events.Events = r.recoveredEvents + + // We use `models.NewMultiBlockEvents`, as the `transactionEvents` + // are coming from different Flow blocks. + recovered := models.NewMultiBlockEvents(events) + r.recovery = recovered.Err != nil + + if !r.recovery { + r.recoveredEvents = nil + } + + return recovered +} + +// recover tries to recover from an invalid data sent over the event stream. +// +// An invalid data can be a cause of corrupted index or network issue from the source, +// in which case we might miss one of the events (missing transaction), or it can be +// due to a failure from the system transaction which commits an EVM block, which results +// in missing EVM block event but present transactions. +func (r *RPCBlockHeaderSubscriber) recover( + ctx context.Context, + events flow.BlockEvents, + err error, +) models.BlockEvents { + r.logger.Warn().Err(err).Msgf( + "failed to parse EVM block events for Flow height: %d, entering recovery", + events.Height, + ) + + if errors.Is(err, errs.ErrMissingBlock) || r.recovery { + return r.accumulateEventsMissingBlock(events) + } + + if errors.Is(err, errs.ErrMissingTransactions) { + return r.fetchMissingData(ctx, events) + } + + return models.NewBlockEventsError(err) +} diff --git a/services/requester/cross-spork_client.go b/services/requester/cross-spork_client.go index cddfc9297..955f3475c 100644 --- a/services/requester/cross-spork_client.go +++ b/services/requester/cross-spork_client.go @@ -9,6 +9,7 @@ import ( errs "github.com/onflow/flow-evm-gateway/models/errors" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/access" + "github.com/onflow/flow-go-sdk/access/grpc" flowGo "github.com/onflow/flow-go/model/flow" "github.com/rs/zerolog" "go.uber.org/ratelimit" @@ -249,6 +250,23 @@ func (c *CrossSporkClient) GetEventsForHeightRange( return client.GetEventsForHeightRange(ctx, eventType, startHeight, endHeight) } +func (c *CrossSporkClient) SubscribeBlockHeadersFromStartHeight( + ctx context.Context, + startHeight uint64, + blockStatus flow.BlockStatus, +) (<-chan flow.BlockHeader, <-chan error, error) { + client, err := c.getClientForHeight(startHeight) + if err != nil { + return nil, nil, err + } + grpcClient, ok := (client).(*grpc.Client) + if !ok { + return nil, nil, fmt.Errorf("unable to convert to Flow grpc.Client") + } + + return grpcClient.SubscribeBlockHeadersFromStartHeight(ctx, startHeight, blockStatus) +} + func (c *CrossSporkClient) Close() error { var merr *multierror.Error diff --git a/tests/go.mod b/tests/go.mod index 65b9c20e4..5435f864e 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -4,24 +4,23 @@ go 1.22 require ( github.com/goccy/go-json v0.10.2 - github.com/onflow/cadence v1.2.2 + github.com/onflow/cadence v1.3.0 github.com/onflow/crypto v0.25.2 github.com/onflow/flow-emulator v1.1.1-0.20241125195348-4e121ffb12af github.com/onflow/flow-evm-gateway v0.0.0-20240201154855-4d4d3d3f19c7 github.com/onflow/flow-go v0.38.0-preview.0.4 - github.com/onflow/flow-go-sdk v1.2.3 + github.com/onflow/flow-go-sdk v1.3.0 github.com/onflow/go-ethereum v1.14.7 github.com/rs/zerolog v1.33.0 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 ) require ( - cloud.google.com/go v0.112.0 // indirect - cloud.google.com/go/compute v1.24.0 // indirect - cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go v0.112.1 // indirect + cloud.google.com/go/compute/metadata v0.5.0 // indirect cloud.google.com/go/iam v1.1.6 // indirect cloud.google.com/go/kms v1.15.7 // indirect - cloud.google.com/go/storage v1.36.0 // indirect + cloud.google.com/go/storage v1.38.0 // indirect github.com/DataDog/zstd v1.5.2 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/SaveTheRbtz/mph v0.1.1-0.20240117162131-4166ec7869bc // indirect @@ -91,7 +90,7 @@ require ( github.com/google/s2a-go v0.1.7 // indirect github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect - github.com/googleapis/gax-go/v2 v2.12.0 // indirect + github.com/googleapis/gax-go/v2 v2.12.2 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/websocket v1.5.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect @@ -151,7 +150,7 @@ require ( github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/onflow/atree v0.8.0 // indirect + github.com/onflow/atree v0.8.1 // indirect github.com/onflow/flow-core-contracts/lib/go/contracts v1.4.0 // indirect github.com/onflow/flow-core-contracts/lib/go/templates v1.4.0 // indirect github.com/onflow/flow-ft/lib/go/contracts v1.0.1 // indirect @@ -205,10 +204,10 @@ require ( github.com/vmihailenco/msgpack/v4 v4.3.11 // indirect github.com/vmihailenco/tagparser v0.1.1 // indirect github.com/x448/float16 v0.8.4 // indirect - github.com/zeebo/blake3 v0.2.3 // indirect + github.com/zeebo/blake3 v0.2.4 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect go.opentelemetry.io/otel v1.24.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect @@ -222,8 +221,8 @@ require ( go.uber.org/zap v1.26.0 // indirect golang.org/x/crypto v0.28.0 // indirect golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect - golang.org/x/net v0.25.0 // indirect - golang.org/x/oauth2 v0.17.0 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/oauth2 v0.18.0 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.26.0 // indirect golang.org/x/term v0.25.0 // indirect @@ -231,13 +230,13 @@ require ( golang.org/x/time v0.5.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.14.0 // indirect - google.golang.org/api v0.162.0 // indirect + google.golang.org/api v0.169.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/grpc v1.63.2 // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/grpc v1.64.1 // indirect + google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools v2.2.0+incompatible // indirect diff --git a/tests/go.sum b/tests/go.sum index fc082fd7b..a967861ab 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -17,18 +17,16 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.112.0 h1:tpFCD7hpHFlQ8yPwT3x+QeXqc2T6+n6T+hmABHfDUSM= -cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4= +cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= +cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= -cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40= -cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= +cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= @@ -45,8 +43,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -cloud.google.com/go/storage v1.36.0 h1:P0mOkAcaJxhCTvAkMhxMfrTKiNcub4YmmPBtlhAyTr8= -cloud.google.com/go/storage v1.36.0/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= +cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg= +cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= @@ -151,8 +149,6 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= -github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= @@ -254,8 +250,6 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= -github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA= github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-ethereum v1.13.10 h1:Ppdil79nN+Vc+mXfge0AuUgmKWuVv4eMqzoIVSdqZek= @@ -466,8 +460,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfF github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= -github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= +github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA= +github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -615,7 +609,6 @@ github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= -github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -783,10 +776,10 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= 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/onflow/atree v0.8.0 h1:qg5c6J1gVDNObughpEeWm8oxqhPGdEyGrda121GM4u0= -github.com/onflow/atree v0.8.0/go.mod h1:yccR+LR7xc1Jdic0mrjocbHvUD7lnVvg8/Ct1AA5zBo= -github.com/onflow/cadence v1.2.2 h1:LwigF/2lPiXlwX5rFn71KeMpmW5Iu/f/JtsPLLULBCc= -github.com/onflow/cadence v1.2.2/go.mod h1:PYX1xLejqswtDsQzN93x/VpfSKNyjUk6hrkc/mpv7xs= +github.com/onflow/atree v0.8.1 h1:DAnPnL9/Ks3LaAnkQVokokTBG/znTW0DJfovDtJDhLI= +github.com/onflow/atree v0.8.1/go.mod h1:FT6udJF9Q7VQTu3wknDhFX+VV4D44ZGdqtTAE5iztck= +github.com/onflow/cadence v1.3.0 h1:COTlTqUACtTvOeFe7+jP9UDVEU3M3OZzrbzzsEbyqCk= +github.com/onflow/cadence v1.3.0/go.mod h1:638c9Zy25EwflSEE7tBFAVM9N6uwcWt77sgKpyYfSTc= github.com/onflow/crypto v0.25.2 h1:GjHunqVt+vPcdqhxxhAXiMIF3YiLX7gTuTR5O+VG2ns= github.com/onflow/crypto v0.25.2/go.mod h1:fY7eLqUdMKV8EGOw301unP8h7PvLVy8/6gVR++/g0BY= github.com/onflow/flow-core-contracts/lib/go/contracts v1.4.0 h1:R86HaOuk6vpuECZnriEUE7bw9inC2AtdSn8lL/iwQLQ= @@ -801,8 +794,8 @@ github.com/onflow/flow-ft/lib/go/templates v1.0.1 h1:FDYKAiGowABtoMNusLuRCILIZDt github.com/onflow/flow-ft/lib/go/templates v1.0.1/go.mod h1:uQ8XFqmMK2jxyBSVrmyuwdWjTEb+6zGjRYotfDJ5pAE= github.com/onflow/flow-go v0.38.0-preview.0.4 h1:vjnp6btehu3X/aYjsXYlA3r/GGYeB05so0d7ICtXbmg= github.com/onflow/flow-go v0.38.0-preview.0.4/go.mod h1:c4ubAQ2WIMYY/TOaBvbajROEFWv2HwhKeGOsEdLPIM0= -github.com/onflow/flow-go-sdk v1.2.3 h1:jb+0dIXBO12Zt8x3c2xDXYPv6k3sRTUvhe59M+EcXTI= -github.com/onflow/flow-go-sdk v1.2.3/go.mod h1:jMaffBTlAIdutx+pBhRIigLZFIBYSDDST0Uax1rW2qo= +github.com/onflow/flow-go-sdk v1.3.0 h1:17xYDaemQBoK2pb9F4S8bH7eAKJSqsuj+DlNHv/FCL0= +github.com/onflow/flow-go-sdk v1.3.0/go.mod h1:Rp424erpOcP7XaZ2zVrOEhBImn6CQIaNX7EaqXdyRa8= github.com/onflow/flow-nft/lib/go/contracts v1.2.2 h1:XFERNVUDGbZ4ViZjt7P1cGD80mO1PzUJYPfdhXFsGbQ= github.com/onflow/flow-nft/lib/go/contracts v1.2.2/go.mod h1:eZ9VMMNfCq0ho6kV25xJn1kXeCfxnkhj3MwF3ed08gY= github.com/onflow/flow-nft/lib/go/templates v1.2.1 h1:SAALMZPDw9Eb9p5kSLnmnFxjyig1MLiT4JUlLp0/bSE= @@ -1016,8 +1009,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 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.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= @@ -1068,11 +1061,10 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= -github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg= -github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ= +github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= +github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -1088,10 +1080,10 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 h1:UNQQKPfTDe1J81ViolILjTKPr9WetKW6uei2hFgJmFs= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0/go.mod h1:r9vWsPS/3AQItv3OSlEJ/E4mbrhUbbw18meOjArPtKQ= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 h1:sv9kVfal0MK0wBMCOGr+HeJm9v803BkJxGrk2au7j08= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0/go.mod h1:SK2UL73Zy1quvRPonmOmRDiWk1KBV3LyIeeIxcEApWw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= @@ -1240,8 +1232,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1251,8 +1243,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= -golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= +golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= +golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1454,8 +1446,8 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513 google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.162.0 h1:Vhs54HkaEpkMBdgGdOT2P6F0csGG/vxDS0hWHJzmmps= -google.golang.org/api v0.162.0/go.mod h1:6SulDkfoBIg4NFmCuZ39XeeAgSHCPecfSUuDyYlAHs0= +google.golang.org/api v0.169.0 h1:QwWPy71FgMWqJN/l6jVlFHUa29a7dcUy02I8o799nPY= +google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1507,12 +1499,12 @@ google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= -google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0= -google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8= -google.golang.org/genproto/googleapis/bytestream v0.0.0-20240125205218-1f4bbc51befe h1:weYsP+dNijSQVoLAb5bpUos3ciBpNU/NEVlHFKrk8pg= -google.golang.org/genproto/googleapis/bytestream v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:SCz6T5xjNXM4QFPRwxHcfChp7V+9DcXR3ay2TkHR8Tg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20240304161311-37d4d3c04a78 h1:YqFWYZXim8bG9v68xU8WjTZmYKb5M5dMeSOWIp6jogI= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20240304161311-37d4d3c04a78/go.mod h1:vh/N7795ftP0AkN1w8XKqN4w1OdUKXW5Eummda+ofv8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1535,8 +1527,8 @@ google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= -google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA= +google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1549,8 +1541,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 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= From 7d36012cde6f171a82e9d116bcc6f55af9f94d5d Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Thu, 23 Jan 2025 13:41:51 +0200 Subject: [PATCH 02/62] Rename RPCBlockHeaderSubscriber to RPCBlockTrackingSubscriber --- bootstrap/bootstrap.go | 2 +- ...criber.go => block_tracking_subscriber.go} | 26 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) rename services/ingestion/{block_header_subscriber.go => block_tracking_subscriber.go} (93%) diff --git a/bootstrap/bootstrap.go b/bootstrap/bootstrap.go index 718e46671..af89179df 100644 --- a/bootstrap/bootstrap.go +++ b/bootstrap/bootstrap.go @@ -142,7 +142,7 @@ func (b *Bootstrap) StartEventIngestion(ctx context.Context) error { chainID := b.config.FlowNetworkID // create event subscriber - subscriber := ingestion.NewRPCBlockHeaderSubscriber( + subscriber := ingestion.NewRPCBlockTrackingSubscriber( b.logger, b.client, chainID, diff --git a/services/ingestion/block_header_subscriber.go b/services/ingestion/block_tracking_subscriber.go similarity index 93% rename from services/ingestion/block_header_subscriber.go rename to services/ingestion/block_tracking_subscriber.go index 2ab7d46b6..feb15aac2 100644 --- a/services/ingestion/block_header_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -18,9 +18,9 @@ import ( "github.com/rs/zerolog" ) -var _ EventSubscriber = &RPCEventSubscriber{} +var _ EventSubscriber = &RPCBlockTrackingSubscriber{} -type RPCBlockHeaderSubscriber struct { +type RPCBlockTrackingSubscriber struct { logger zerolog.Logger client *requester.CrossSporkClient @@ -32,15 +32,15 @@ type RPCBlockHeaderSubscriber struct { recoveredEvents []flow.Event } -func NewRPCBlockHeaderSubscriber( +func NewRPCBlockTrackingSubscriber( logger zerolog.Logger, client *requester.CrossSporkClient, chainID flowGo.ChainID, keyLock requester.KeyLock, startHeight uint64, -) *RPCBlockHeaderSubscriber { +) *RPCBlockTrackingSubscriber { logger = logger.With().Str("component", "subscriber").Logger() - return &RPCBlockHeaderSubscriber{ + return &RPCBlockTrackingSubscriber{ logger: logger, client: client, @@ -55,7 +55,7 @@ func NewRPCBlockHeaderSubscriber( // to listen all new events in the current spork. // // If error is encountered during backfill the subscription will end and the response chanel will be closed. -func (r *RPCBlockHeaderSubscriber) Subscribe(ctx context.Context) <-chan models.BlockEvents { +func (r *RPCBlockTrackingSubscriber) Subscribe(ctx context.Context) <-chan models.BlockEvents { // buffered channel so that the decoding of the events can happen in parallel to other operations eventsChan := make(chan models.BlockEvents, 1000) @@ -107,7 +107,7 @@ func (r *RPCBlockHeaderSubscriber) Subscribe(ctx context.Context) <-chan models. // // Subscribing to EVM specific events and handle any disconnection errors // as well as context cancellations. -func (r *RPCBlockHeaderSubscriber) subscribe(ctx context.Context, height uint64) <-chan models.BlockEvents { +func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint64) <-chan models.BlockEvents { eventsChan := make(chan models.BlockEvents) _, err := r.client.GetBlockHeaderByHeight(ctx, height) @@ -227,7 +227,7 @@ func (r *RPCBlockHeaderSubscriber) subscribe(ctx context.Context, height uint64) // backfill returns a channel that is filled with block events from the provided fromCadenceHeight up to the first // height in the current spork. -func (r *RPCBlockHeaderSubscriber) backfill(ctx context.Context, fromCadenceHeight uint64) <-chan models.BlockEvents { +func (r *RPCBlockTrackingSubscriber) backfill(ctx context.Context, fromCadenceHeight uint64) <-chan models.BlockEvents { eventsChan := make(chan models.BlockEvents) go func() { @@ -264,7 +264,7 @@ func (r *RPCBlockHeaderSubscriber) backfill(ctx context.Context, fromCadenceHeig // / backfillSporkFromHeight will fill the eventsChan with block events from the provided fromHeight up to the first height in the spork that comes // after the spork of the provided fromHeight. -func (r *RPCBlockHeaderSubscriber) backfillSporkFromHeight(ctx context.Context, fromCadenceHeight uint64, eventsChan chan<- models.BlockEvents) (uint64, error) { +func (r *RPCBlockTrackingSubscriber) backfillSporkFromHeight(ctx context.Context, fromCadenceHeight uint64, eventsChan chan<- models.BlockEvents) (uint64, error) { evmAddress := common.Address(systemcontracts.SystemContractsForChain(r.chain).EVMContract.Address) blockExecutedEvent := common.NewAddressLocation( @@ -358,7 +358,7 @@ func (r *RPCBlockHeaderSubscriber) backfillSporkFromHeight(ctx context.Context, // accumulateBlockEvents will keep fetching `EVM.TransactionExecuted` events // until it finds their `EVM.BlockExecuted` event. // At that point it will return the valid models.BlockEvents. -func (r *RPCBlockHeaderSubscriber) accumulateBlockEvents( +func (r *RPCBlockTrackingSubscriber) accumulateBlockEvents( ctx context.Context, block flow.BlockEvents, blockExecutedEventType string, @@ -440,7 +440,7 @@ func (r *RPCBlockHeaderSubscriber) accumulateBlockEvents( // An inconsistent response could be an EVM block that references EVM // transactions which are not present in the response. It falls back // to using grpc requests instead of streaming. -func (r *RPCBlockHeaderSubscriber) fetchMissingData( +func (r *RPCBlockTrackingSubscriber) fetchMissingData( ctx context.Context, blockEvents flow.BlockEvents, ) models.BlockEvents { @@ -477,7 +477,7 @@ func (r *RPCBlockHeaderSubscriber) fetchMissingData( // accumulateEventsMissingBlock will keep receiving transaction events until it can produce a valid // EVM block event containing a block and transactions. At that point it will reset the recovery mode // and return the valid block events. -func (r *RPCBlockHeaderSubscriber) accumulateEventsMissingBlock(events flow.BlockEvents) models.BlockEvents { +func (r *RPCBlockTrackingSubscriber) accumulateEventsMissingBlock(events flow.BlockEvents) models.BlockEvents { txEvents := events.Events // Sort `EVM.TransactionExecuted` events sort.Slice(txEvents, func(i, j int) bool { @@ -507,7 +507,7 @@ func (r *RPCBlockHeaderSubscriber) accumulateEventsMissingBlock(events flow.Bloc // in which case we might miss one of the events (missing transaction), or it can be // due to a failure from the system transaction which commits an EVM block, which results // in missing EVM block event but present transactions. -func (r *RPCBlockHeaderSubscriber) recover( +func (r *RPCBlockTrackingSubscriber) recover( ctx context.Context, events flow.BlockEvents, err error, From 75a1d183f31aea5d115006b7e27a690215aaaa7b Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Thu, 23 Jan 2025 13:52:11 +0200 Subject: [PATCH 03/62] Remove redundant fetching of block header prior to SubscribeBlockHeadersFromStartHeight --- services/ingestion/block_tracking_subscriber.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index feb15aac2..fc317ffc2 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -110,13 +110,6 @@ func (r *RPCBlockTrackingSubscriber) Subscribe(ctx context.Context) <-chan model func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint64) <-chan models.BlockEvents { eventsChan := make(chan models.BlockEvents) - _, err := r.client.GetBlockHeaderByHeight(ctx, height) - if err != nil { - err = fmt.Errorf("failed to subscribe for events, the block height %d doesn't exist: %w", height, err) - eventsChan <- models.NewBlockEventsError(err) - return eventsChan - } - blockHeadersChan, errChan, err := r.client.SubscribeBlockHeadersFromStartHeight( ctx, height, From ce83ebb0f271b27da0f4eac808b31c093dae86e0 Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Thu, 23 Jan 2025 14:13:12 +0200 Subject: [PATCH 04/62] Improve error handling in RPCBlockTrackingSubscriber subscription --- .../ingestion/block_tracking_subscriber.go | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index fc317ffc2..79140745d 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -117,7 +117,11 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 ) if err != nil { eventsChan <- models.NewBlockEventsError( - fmt.Errorf("failed to subscribe to events by block height: %d, with: %w", height, err), + fmt.Errorf( + "failed to subscribe for finalized block headers on height: %d, with: %w", + height, + err, + ), ) return eventsChan } @@ -146,7 +150,6 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 } var blockEvents flow.BlockEvents - for _, eventType := range blocksFilter(r.chain).EventTypes { evts, err := r.client.GetEventsForHeightRange( ctx, @@ -155,10 +158,24 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 blockHeader.Height, ) if err != nil { + eventsChan <- models.NewBlockEventsError( + fmt.Errorf( + "failed to fetch EVM events for height: %d, with: %w", + blockHeader.Height, + err, + ), + ) return } if len(evts) != 1 { + eventsChan <- models.NewBlockEventsError( + fmt.Errorf( + "received unexpected number of EVM events for height: %d, got: %d, expected: 1", + blockHeader.Height, + len(evts), + ), + ) return } blockEvent := evts[0] @@ -203,7 +220,11 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 ) if err != nil { eventsChan <- models.NewBlockEventsError( - fmt.Errorf("failed to subscribe to events by block height: %d, with: %w", height, err), + fmt.Errorf( + "failed to subscribe for finalized block headers on height: %d, with: %w", + height, + err, + ), ) return } From d1594671e2c93cf489659bd4907b407e67ade004 Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Thu, 23 Jan 2025 15:45:53 +0200 Subject: [PATCH 05/62] Simplify RPCBlockTrackingSubscriber by embedding RPCEventSubscriber for function resuse --- .../ingestion/block_tracking_subscriber.go | 336 +----------------- 1 file changed, 19 insertions(+), 317 deletions(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 79140745d..a7de72e74 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -4,16 +4,12 @@ import ( "context" "errors" "fmt" - "sort" "strings" - "github.com/onflow/cadence/common" "github.com/onflow/flow-evm-gateway/models" errs "github.com/onflow/flow-evm-gateway/models/errors" "github.com/onflow/flow-evm-gateway/services/requester" "github.com/onflow/flow-go-sdk" - "github.com/onflow/flow-go/fvm/evm/events" - "github.com/onflow/flow-go/fvm/systemcontracts" flowGo "github.com/onflow/flow-go/model/flow" "github.com/rs/zerolog" ) @@ -21,15 +17,13 @@ import ( var _ EventSubscriber = &RPCBlockTrackingSubscriber{} type RPCBlockTrackingSubscriber struct { - logger zerolog.Logger + *RPCEventSubscriber + logger zerolog.Logger client *requester.CrossSporkClient chain flowGo.ChainID keyLock requester.KeyLock height uint64 - - recovery bool - recoveredEvents []flow.Event } func NewRPCBlockTrackingSubscriber( @@ -39,14 +33,22 @@ func NewRPCBlockTrackingSubscriber( keyLock requester.KeyLock, startHeight uint64, ) *RPCBlockTrackingSubscriber { + eventSubscriber := NewRPCEventSubscriber( + logger, + client, + chainID, + keyLock, + startHeight, + ) logger = logger.With().Str("component", "subscriber").Logger() - return &RPCBlockTrackingSubscriber{ - logger: logger, - client: client, - chain: chainID, - keyLock: keyLock, - height: startHeight, + return &RPCBlockTrackingSubscriber{ + RPCEventSubscriber: eventSubscriber, + logger: logger, + client: client, + chain: chainID, + keyLock: keyLock, + height: startHeight, } } @@ -179,6 +181,9 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 return } blockEvent := evts[0] + blockEvents.BlockID = blockEvent.BlockID + blockEvents.BlockTimestamp = blockEvent.BlockTimestamp + blockEvents.Height = blockEvent.Height blockEvents.Events = append(blockEvents.Events, blockEvent.Events...) } @@ -238,306 +243,3 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 return eventsChan } - -// backfill returns a channel that is filled with block events from the provided fromCadenceHeight up to the first -// height in the current spork. -func (r *RPCBlockTrackingSubscriber) backfill(ctx context.Context, fromCadenceHeight uint64) <-chan models.BlockEvents { - eventsChan := make(chan models.BlockEvents) - - go func() { - defer func() { - close(eventsChan) - }() - - for { - // check if the current fromCadenceHeight is still in past sporks, and if not return since we are done with backfilling - if !r.client.IsPastSpork(fromCadenceHeight) { - r.logger.Info(). - Uint64("height", fromCadenceHeight). - Msg("completed backfilling") - - return - } - - var err error - fromCadenceHeight, err = r.backfillSporkFromHeight(ctx, fromCadenceHeight, eventsChan) - if err != nil { - r.logger.Error().Err(err).Msg("error backfilling spork") - eventsChan <- models.NewBlockEventsError(err) - return - } - - r.logger.Info(). - Uint64("next-cadence-height", fromCadenceHeight). - Msg("reached the end of spork, checking next spork") - } - }() - - return eventsChan -} - -// / backfillSporkFromHeight will fill the eventsChan with block events from the provided fromHeight up to the first height in the spork that comes -// after the spork of the provided fromHeight. -func (r *RPCBlockTrackingSubscriber) backfillSporkFromHeight(ctx context.Context, fromCadenceHeight uint64, eventsChan chan<- models.BlockEvents) (uint64, error) { - evmAddress := common.Address(systemcontracts.SystemContractsForChain(r.chain).EVMContract.Address) - - blockExecutedEvent := common.NewAddressLocation( - nil, - evmAddress, - string(events.EventTypeBlockExecuted), - ).ID() - - transactionExecutedEvent := common.NewAddressLocation( - nil, - evmAddress, - string(events.EventTypeTransactionExecuted), - ).ID() - - lastHeight, err := r.client.GetLatestHeightForSpork(ctx, fromCadenceHeight) - if err != nil { - eventsChan <- models.NewBlockEventsError(err) - return 0, err - } - - r.logger.Info(). - Uint64("start-height", fromCadenceHeight). - Uint64("last-spork-height", lastHeight). - Msg("backfilling spork") - - for fromCadenceHeight < lastHeight { - r.logger.Debug().Msg(fmt.Sprintf("backfilling [%d / %d] ...", fromCadenceHeight, lastHeight)) - - startHeight := fromCadenceHeight - endHeight := fromCadenceHeight + maxRangeForGetEvents - if endHeight > lastHeight { - endHeight = lastHeight - } - - blocks, err := r.client.GetEventsForHeightRange(ctx, blockExecutedEvent, startHeight, endHeight) - if err != nil { - return 0, fmt.Errorf("failed to get block events: %w", err) - } - - transactions, err := r.client.GetEventsForHeightRange(ctx, transactionExecutedEvent, startHeight, endHeight) - if err != nil { - return 0, fmt.Errorf("failed to get block events: %w", err) - } - - if len(transactions) != len(blocks) { - return 0, fmt.Errorf("transactions and blocks have different length") - } - - // sort both, just in case - sort.Slice(blocks, func(i, j int) bool { - return blocks[i].Height < blocks[j].Height - }) - sort.Slice(transactions, func(i, j int) bool { - return transactions[i].Height < transactions[j].Height - }) - - for i := range transactions { - if transactions[i].Height != blocks[i].Height { - return 0, fmt.Errorf("transactions and blocks have different height") - } - - // append the transaction events to the block events - blocks[i].Events = append(blocks[i].Events, transactions[i].Events...) - - evmEvents := models.NewSingleBlockEvents(blocks[i]) - if evmEvents.Err != nil && errors.Is(evmEvents.Err, errs.ErrMissingBlock) { - evmEvents, err = r.accumulateBlockEvents( - ctx, - blocks[i], - blockExecutedEvent, - transactionExecutedEvent, - ) - if err != nil { - return 0, err - } - eventsChan <- evmEvents - // advance the height - fromCadenceHeight = evmEvents.Events.CadenceHeight() + 1 - break - } - eventsChan <- evmEvents - - // advance the height - fromCadenceHeight = evmEvents.Events.CadenceHeight() + 1 - } - - } - return fromCadenceHeight, nil -} - -// accumulateBlockEvents will keep fetching `EVM.TransactionExecuted` events -// until it finds their `EVM.BlockExecuted` event. -// At that point it will return the valid models.BlockEvents. -func (r *RPCBlockTrackingSubscriber) accumulateBlockEvents( - ctx context.Context, - block flow.BlockEvents, - blockExecutedEventType string, - txExecutedEventType string, -) (models.BlockEvents, error) { - evmEvents := models.NewSingleBlockEvents(block) - currentHeight := block.Height - transactionEvents := make([]flow.Event, 0) - - for evmEvents.Err != nil && errors.Is(evmEvents.Err, errs.ErrMissingBlock) { - blocks, err := r.client.GetEventsForHeightRange( - ctx, - blockExecutedEventType, - currentHeight, - currentHeight+maxRangeForGetEvents, - ) - if err != nil { - return models.BlockEvents{}, fmt.Errorf("failed to get block events: %w", err) - } - - transactions, err := r.client.GetEventsForHeightRange( - ctx, - txExecutedEventType, - currentHeight, - currentHeight+maxRangeForGetEvents, - ) - if err != nil { - return models.BlockEvents{}, fmt.Errorf("failed to get block events: %w", err) - } - - if len(transactions) != len(blocks) { - return models.BlockEvents{}, fmt.Errorf("transactions and blocks have different length") - } - - // sort both, just in case - sort.Slice(blocks, func(i, j int) bool { - return blocks[i].Height < blocks[j].Height - }) - sort.Slice(transactions, func(i, j int) bool { - return transactions[i].Height < transactions[j].Height - }) - - for i := range blocks { - if transactions[i].Height != blocks[i].Height { - return models.BlockEvents{}, fmt.Errorf("transactions and blocks have different height") - } - - // If no EVM.BlockExecuted event found, keep accumulating the incoming - // EVM.TransactionExecuted events, until we find the EVM.BlockExecuted - // event that includes them. - if len(blocks[i].Events) == 0 { - txEvents := transactions[i].Events - // Sort `EVM.TransactionExecuted` events - sort.Slice(txEvents, func(i, j int) bool { - if txEvents[i].TransactionIndex != txEvents[j].TransactionIndex { - return txEvents[i].TransactionIndex < txEvents[j].TransactionIndex - } - return txEvents[i].EventIndex < txEvents[j].EventIndex - }) - transactionEvents = append(transactionEvents, txEvents...) - } else { - blocks[i].Events = append(blocks[i].Events, transactionEvents...) - // We use `models.NewMultiBlockEvents`, as the `transactionEvents` - // are coming from different Flow blocks. - evmEvents = models.NewMultiBlockEvents(blocks[i]) - if evmEvents.Err == nil { - return evmEvents, nil - } - } - - currentHeight = blocks[i].Height + 1 - } - } - return evmEvents, nil -} - -// fetchMissingData is used as a backup mechanism for fetching EVM-related -// events, when the event streaming API returns an inconsistent response. -// An inconsistent response could be an EVM block that references EVM -// transactions which are not present in the response. It falls back -// to using grpc requests instead of streaming. -func (r *RPCBlockTrackingSubscriber) fetchMissingData( - ctx context.Context, - blockEvents flow.BlockEvents, -) models.BlockEvents { - // remove existing events - blockEvents.Events = nil - - for _, eventType := range blocksFilter(r.chain).EventTypes { - recoveredEvents, err := r.client.GetEventsForHeightRange( - ctx, - eventType, - blockEvents.Height, - blockEvents.Height, - ) - if err != nil { - return models.NewBlockEventsError(err) - } - - if len(recoveredEvents) != 1 { - return models.NewBlockEventsError( - fmt.Errorf( - "received %d but expected 1 event for height %d", - len(recoveredEvents), - blockEvents.Height, - ), - ) - } - - blockEvents.Events = append(blockEvents.Events, recoveredEvents[0].Events...) - } - - return models.NewSingleBlockEvents(blockEvents) -} - -// accumulateEventsMissingBlock will keep receiving transaction events until it can produce a valid -// EVM block event containing a block and transactions. At that point it will reset the recovery mode -// and return the valid block events. -func (r *RPCBlockTrackingSubscriber) accumulateEventsMissingBlock(events flow.BlockEvents) models.BlockEvents { - txEvents := events.Events - // Sort `EVM.TransactionExecuted` events - sort.Slice(txEvents, func(i, j int) bool { - if txEvents[i].TransactionIndex != txEvents[j].TransactionIndex { - return txEvents[i].TransactionIndex < txEvents[j].TransactionIndex - } - return txEvents[i].EventIndex < txEvents[j].EventIndex - }) - r.recoveredEvents = append(r.recoveredEvents, txEvents...) - events.Events = r.recoveredEvents - - // We use `models.NewMultiBlockEvents`, as the `transactionEvents` - // are coming from different Flow blocks. - recovered := models.NewMultiBlockEvents(events) - r.recovery = recovered.Err != nil - - if !r.recovery { - r.recoveredEvents = nil - } - - return recovered -} - -// recover tries to recover from an invalid data sent over the event stream. -// -// An invalid data can be a cause of corrupted index or network issue from the source, -// in which case we might miss one of the events (missing transaction), or it can be -// due to a failure from the system transaction which commits an EVM block, which results -// in missing EVM block event but present transactions. -func (r *RPCBlockTrackingSubscriber) recover( - ctx context.Context, - events flow.BlockEvents, - err error, -) models.BlockEvents { - r.logger.Warn().Err(err).Msgf( - "failed to parse EVM block events for Flow height: %d, entering recovery", - events.Height, - ) - - if errors.Is(err, errs.ErrMissingBlock) || r.recovery { - return r.accumulateEventsMissingBlock(events) - } - - if errors.Is(err, errs.ErrMissingTransactions) { - return r.fetchMissingData(ctx, events) - } - - return models.NewBlockEventsError(err) -} From 5e8f388212145367330b6f5b9e968ab0bb4bcab5 Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Fri, 24 Jan 2025 14:08:12 +0200 Subject: [PATCH 06/62] Optimize RPCBlockTrackingSubscriber to avoid fetch EVM tx events for empty EVM blocks --- .../ingestion/block_tracking_subscriber.go | 100 ++++++++++++------ 1 file changed, 66 insertions(+), 34 deletions(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index a7de72e74..9186533bf 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -10,7 +10,9 @@ import ( errs "github.com/onflow/flow-evm-gateway/models/errors" "github.com/onflow/flow-evm-gateway/services/requester" "github.com/onflow/flow-go-sdk" + "github.com/onflow/flow-go/fvm/evm/events" flowGo "github.com/onflow/flow-go/model/flow" + "github.com/onflow/go-ethereum/core/types" "github.com/rs/zerolog" ) @@ -151,40 +153,10 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 return } - var blockEvents flow.BlockEvents - for _, eventType := range blocksFilter(r.chain).EventTypes { - evts, err := r.client.GetEventsForHeightRange( - ctx, - eventType, - blockHeader.Height, - blockHeader.Height, - ) - if err != nil { - eventsChan <- models.NewBlockEventsError( - fmt.Errorf( - "failed to fetch EVM events for height: %d, with: %w", - blockHeader.Height, - err, - ), - ) - return - } - - if len(evts) != 1 { - eventsChan <- models.NewBlockEventsError( - fmt.Errorf( - "received unexpected number of EVM events for height: %d, got: %d, expected: 1", - blockHeader.Height, - len(evts), - ), - ) - return - } - blockEvent := evts[0] - blockEvents.BlockID = blockEvent.BlockID - blockEvents.BlockTimestamp = blockEvent.BlockTimestamp - blockEvents.Height = blockEvent.Height - blockEvents.Events = append(blockEvents.Events, blockEvent.Events...) + blockEvents, err := r.evmEventsForHeight(ctx, blockHeader.Height) + if err != nil { + eventsChan <- models.NewBlockEventsError(err) + return } evmEvents := models.NewSingleBlockEvents(blockEvents) @@ -243,3 +215,63 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 return eventsChan } + +func (r *RPCBlockTrackingSubscriber) evmEventsForHeight( + ctx context.Context, + height uint64, +) (flow.BlockEvents, error) { + eventTypes := blocksFilter(r.chain).EventTypes + evmBlockEvent := eventTypes[0] + + evts, err := r.client.GetEventsForHeightRange( + ctx, + evmBlockEvent, + height, + height, + ) + if err != nil { + return flow.BlockEvents{}, err + } + + if len(evts) != 1 && len(evts[0].Events) != 1 { + return flow.BlockEvents{}, fmt.Errorf( + "received unexpected number of EVM events for height: %d, got: %d, expected: 1", + height, + len(evts), + ) + } + + blockEvents := evts[0] + payload, err := events.DecodeBlockEventPayload(blockEvents.Events[0].Value) + if err != nil { + return flow.BlockEvents{}, err + } + + if payload.TransactionHashRoot == types.EmptyTxsHash { + return blockEvents, nil + } + + evmTxEvent := eventTypes[1] + evts, err = r.client.GetEventsForHeightRange( + ctx, + evmTxEvent, + height, + height, + ) + if err != nil { + return flow.BlockEvents{}, err + } + + if len(evts) != 1 && len(evts[0].Events) != 1 { + return flow.BlockEvents{}, fmt.Errorf( + "received unexpected number of EVM events for height: %d, got: %d, expected: 1", + height, + len(evts), + ) + } + txEvents := evts[0] + + blockEvents.Events = append(blockEvents.Events, txEvents.Events...) + + return blockEvents, nil +} From bfe61889f9d71293354569b3576e0839038a2cb7 Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Mon, 27 Jan 2025 11:42:51 +0200 Subject: [PATCH 07/62] Improve length checks for EVM related events --- services/ingestion/block_tracking_subscriber.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 9186533bf..e3fa32ad2 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -233,7 +233,10 @@ func (r *RPCBlockTrackingSubscriber) evmEventsForHeight( return flow.BlockEvents{}, err } - if len(evts) != 1 && len(evts[0].Events) != 1 { + // We are requesting the `EVM.BlockExecuted` events for a single Flow block, + // so we expect the length of `evts` to equal 1. + // The `EVM.BlockExecuted` event should be present for every Flow block. + if len(evts) != 1 || len(evts[0].Events) != 1 { return flow.BlockEvents{}, fmt.Errorf( "received unexpected number of EVM events for height: %d, got: %d, expected: 1", height, @@ -262,7 +265,9 @@ func (r *RPCBlockTrackingSubscriber) evmEventsForHeight( return flow.BlockEvents{}, err } - if len(evts) != 1 && len(evts[0].Events) != 1 { + // We are requesting the `EVM.TransactionExecuted` events for a single + // Flow block, so we expect the length of `evts` to equal 1. + if len(evts) != 1 { return flow.BlockEvents{}, fmt.Errorf( "received unexpected number of EVM events for height: %d, got: %d, expected: 1", height, From 037c23463b7471c60e0529a7d7da77c9b99239e6 Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Mon, 27 Jan 2025 11:51:56 +0200 Subject: [PATCH 08/62] Close events channel in RPCBlockTrackingSubscriber --- services/ingestion/block_tracking_subscriber.go | 1 + 1 file changed, 1 insertion(+) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index e3fa32ad2..9d712ba37 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -127,6 +127,7 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 err, ), ) + close(eventsChan) return eventsChan } lastReceivedHeight := height From 6afde4d1b3899eb557c6a8b757c04a3d5454361f Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Mon, 27 Jan 2025 13:05:04 +0200 Subject: [PATCH 09/62] Improve error handling to use the gRPC status code instead of strings --- services/ingestion/block_tracking_subscriber.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 9d712ba37..b08b8dfba 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -2,9 +2,7 @@ package ingestion import ( "context" - "errors" "fmt" - "strings" "github.com/onflow/flow-evm-gateway/models" errs "github.com/onflow/flow-evm-gateway/models/errors" @@ -14,6 +12,8 @@ import ( flowGo "github.com/onflow/flow-go/model/flow" "github.com/onflow/go-ethereum/core/types" "github.com/rs/zerolog" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) var _ EventSubscriber = &RPCBlockTrackingSubscriber{} @@ -189,8 +189,7 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 return } - if strings.Contains(errors.Unwrap(err).Error(), "DeadlineExceeded") || - strings.Contains(errors.Unwrap(err).Error(), "unexpected EOF") { + if status.Code(err) == codes.DeadlineExceeded || status.Code(err) == codes.Internal { blockHeadersChan, errChan, err = r.client.SubscribeBlockHeadersFromStartHeight( ctx, lastReceivedHeight+1, From ff927f7c6d78feb8f54ecf6c40eeeb8051bb7d60 Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Mon, 27 Jan 2025 13:10:39 +0200 Subject: [PATCH 10/62] Simplify constructor of RPCBlockTrackingSubscriber Co-authored-by: Peter Argue <89119817+peterargue@users.noreply.github.com> --- .../ingestion/block_tracking_subscriber.go | 22 ++++++------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index b08b8dfba..13c169d0b 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -35,22 +35,14 @@ func NewRPCBlockTrackingSubscriber( keyLock requester.KeyLock, startHeight uint64, ) *RPCBlockTrackingSubscriber { - eventSubscriber := NewRPCEventSubscriber( - logger, - client, - chainID, - keyLock, - startHeight, - ) - logger = logger.With().Str("component", "subscriber").Logger() - return &RPCBlockTrackingSubscriber{ - RPCEventSubscriber: eventSubscriber, - logger: logger, - client: client, - chain: chainID, - keyLock: keyLock, - height: startHeight, + RPCEventSubscriber: NewRPCEventSubscriber( + logger.With().Str("component", "subscriber").Logger(), + client, + chainID, + keyLock, + startHeight, + ) } } From 455526349ceb345e2d7bf3aef3d131ffaa78139e Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Mon, 27 Jan 2025 13:20:25 +0200 Subject: [PATCH 11/62] Remove redundant fields from RPCBlockTrackingSubscriber --- services/ingestion/block_tracking_subscriber.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 13c169d0b..0da7371c9 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -20,12 +20,6 @@ var _ EventSubscriber = &RPCBlockTrackingSubscriber{} type RPCBlockTrackingSubscriber struct { *RPCEventSubscriber - - logger zerolog.Logger - client *requester.CrossSporkClient - chain flowGo.ChainID - keyLock requester.KeyLock - height uint64 } func NewRPCBlockTrackingSubscriber( @@ -42,7 +36,7 @@ func NewRPCBlockTrackingSubscriber( chainID, keyLock, startHeight, - ) + ), } } From 34dbde58be0875f54d63f7751be53efeebcec583 Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Mon, 27 Jan 2025 13:41:15 +0200 Subject: [PATCH 12/62] Make us of GetEventsForBlockIDs method instead of GetEventsForHeightRange --- .../ingestion/block_tracking_subscriber.go | 20 +++++++++---------- services/requester/cross-spork_client.go | 12 +++++++++++ 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 0da7371c9..12fa7c77b 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -140,7 +140,7 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 return } - blockEvents, err := r.evmEventsForHeight(ctx, blockHeader.Height) + blockEvents, err := r.evmEventsForBlockHeader(ctx, blockHeader) if err != nil { eventsChan <- models.NewBlockEventsError(err) return @@ -202,18 +202,17 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 return eventsChan } -func (r *RPCBlockTrackingSubscriber) evmEventsForHeight( +func (r *RPCBlockTrackingSubscriber) evmEventsForBlockHeader( ctx context.Context, - height uint64, + blockHeader flow.BlockHeader, ) (flow.BlockEvents, error) { eventTypes := blocksFilter(r.chain).EventTypes evmBlockEvent := eventTypes[0] - evts, err := r.client.GetEventsForHeightRange( + evts, err := r.client.GetEventsForBlockHeader( ctx, evmBlockEvent, - height, - height, + blockHeader, ) if err != nil { return flow.BlockEvents{}, err @@ -225,7 +224,7 @@ func (r *RPCBlockTrackingSubscriber) evmEventsForHeight( if len(evts) != 1 || len(evts[0].Events) != 1 { return flow.BlockEvents{}, fmt.Errorf( "received unexpected number of EVM events for height: %d, got: %d, expected: 1", - height, + blockHeader.Height, len(evts), ) } @@ -241,11 +240,10 @@ func (r *RPCBlockTrackingSubscriber) evmEventsForHeight( } evmTxEvent := eventTypes[1] - evts, err = r.client.GetEventsForHeightRange( + evts, err = r.client.GetEventsForBlockHeader( ctx, evmTxEvent, - height, - height, + blockHeader, ) if err != nil { return flow.BlockEvents{}, err @@ -256,7 +254,7 @@ func (r *RPCBlockTrackingSubscriber) evmEventsForHeight( if len(evts) != 1 { return flow.BlockEvents{}, fmt.Errorf( "received unexpected number of EVM events for height: %d, got: %d, expected: 1", - height, + blockHeader.Height, len(evts), ) } diff --git a/services/requester/cross-spork_client.go b/services/requester/cross-spork_client.go index 955f3475c..a659a2d58 100644 --- a/services/requester/cross-spork_client.go +++ b/services/requester/cross-spork_client.go @@ -250,6 +250,18 @@ func (c *CrossSporkClient) GetEventsForHeightRange( return client.GetEventsForHeightRange(ctx, eventType, startHeight, endHeight) } +func (c *CrossSporkClient) GetEventsForBlockHeader( + ctx context.Context, + eventType string, + blockHeader flow.BlockHeader, +) ([]flow.BlockEvents, error) { + client, err := c.getClientForHeight(blockHeader.Height) + if err != nil { + return nil, err + } + return client.GetEventsForBlockIDs(ctx, eventType, []flow.Identifier{blockHeader.ID}) +} + func (c *CrossSporkClient) SubscribeBlockHeadersFromStartHeight( ctx context.Context, startHeight uint64, From bf4626c82504b69f0bcc2c9e24a159f95b5e4e37 Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Mon, 27 Jan 2025 13:46:08 +0200 Subject: [PATCH 13/62] Add description on RPCBlockTrackingSubscriber type Co-authored-by: Peter Argue <89119817+peterargue@users.noreply.github.com> --- services/ingestion/block_tracking_subscriber.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 12fa7c77b..71405a550 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -18,6 +18,19 @@ import ( var _ EventSubscriber = &RPCBlockTrackingSubscriber{} +// RPCBlockTrackingSubscriber subscribes to new EVM block events for unsealed finalized blocks. +// This is accomplished by following finalized blocks from the upstream Access node, and using the +// polling endpoint to fetch the events for each finalized block. +// +// IMPORTANT: Since data is downloaded and processed from unsealed blocks, it's possible for the +// data that was downloaded to be incorrect. This subscriber provides no handling or detection for +// cases where the received data differs from the data that was ultimately sealed. The operator must +// handle this manually. +// Since it's not reasonable to expect operators to do this manual tracking, this features should NOT +// be used outside of a limited Proof of Concept. Use at own risk. +// +// A future version of the RPCEventSubscriber will provide this detection and handling functionality +// at which point this subscriber will be removed. type RPCBlockTrackingSubscriber struct { *RPCEventSubscriber } From 1f084be5542acb74baf3cdb874e0cff500a0107b Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Mon, 27 Jan 2025 14:14:19 +0200 Subject: [PATCH 14/62] Refactor function for fetching EVM events on a given block header --- .../ingestion/block_tracking_subscriber.go | 66 ++++++++++--------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 71405a550..0a6359057 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -3,6 +3,7 @@ package ingestion import ( "context" "fmt" + "strings" "github.com/onflow/flow-evm-gateway/models" errs "github.com/onflow/flow-evm-gateway/models/errors" @@ -153,7 +154,7 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 return } - blockEvents, err := r.evmEventsForBlockHeader(ctx, blockHeader) + blockEvents, err := r.evmEventsForBlock(ctx, blockHeader) if err != nil { eventsChan <- models.NewBlockEventsError(err) return @@ -215,34 +216,18 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 return eventsChan } -func (r *RPCBlockTrackingSubscriber) evmEventsForBlockHeader( +func (r *RPCBlockTrackingSubscriber) evmEventsForBlock( ctx context.Context, blockHeader flow.BlockHeader, ) (flow.BlockEvents, error) { eventTypes := blocksFilter(r.chain).EventTypes - evmBlockEvent := eventTypes[0] - evts, err := r.client.GetEventsForBlockHeader( - ctx, - evmBlockEvent, - blockHeader, - ) + // evm Block events + blockEvents, err := r.getEventsByType(ctx, blockHeader, eventTypes[0]) if err != nil { return flow.BlockEvents{}, err } - // We are requesting the `EVM.BlockExecuted` events for a single Flow block, - // so we expect the length of `evts` to equal 1. - // The `EVM.BlockExecuted` event should be present for every Flow block. - if len(evts) != 1 || len(evts[0].Events) != 1 { - return flow.BlockEvents{}, fmt.Errorf( - "received unexpected number of EVM events for height: %d, got: %d, expected: 1", - blockHeader.Height, - len(evts), - ) - } - - blockEvents := evts[0] payload, err := events.DecodeBlockEventPayload(blockEvents.Events[0].Value) if err != nil { return flow.BlockEvents{}, err @@ -252,28 +237,49 @@ func (r *RPCBlockTrackingSubscriber) evmEventsForBlockHeader( return blockEvents, nil } - evmTxEvent := eventTypes[1] - evts, err = r.client.GetEventsForBlockHeader( + // evm TX events + txEvents, err := r.getEventsByType(ctx, blockHeader, eventTypes[1]) + if err != nil { + return flow.BlockEvents{}, err + } + + // combine block and tx events to be processed together + blockEvents.Events = append(blockEvents.Events, txEvents.Events...) + + return blockEvents, nil +} + +func (r *RPCBlockTrackingSubscriber) getEventsByType( + ctx context.Context, + blockHeader flow.BlockHeader, + eventType string, +) (flow.BlockEvents, error) { + evts, err := r.client.GetEventsForBlockHeader( ctx, - evmTxEvent, + eventType, blockHeader, ) if err != nil { return flow.BlockEvents{}, err } - // We are requesting the `EVM.TransactionExecuted` events for a single - // Flow block, so we expect the length of `evts` to equal 1. if len(evts) != 1 { + // this shouldn't happen and probably indicates a bug on the Access node. return flow.BlockEvents{}, fmt.Errorf( - "received unexpected number of EVM events for height: %d, got: %d, expected: 1", - blockHeader.Height, + "received unexpected number of block events: got: %d, expected: 1", len(evts), ) } - txEvents := evts[0] - blockEvents.Events = append(blockEvents.Events, txEvents.Events...) + // The `EVM.BlockExecuted` event should be present for every Flow block. + if strings.Contains(eventType, string(events.EventTypeBlockExecuted)) { + if len(evts[0].Events) != 1 { + return flow.BlockEvents{}, fmt.Errorf( + "received unexpected number of EVM events in block: got: %d, expected: 1", + len(evts[0].Events), + ) + } + } - return blockEvents, nil + return evts[0], nil } From a8329e4dc7bf4395dc412ef86a1de798630f058c Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Tue, 28 Jan 2025 10:48:29 -0800 Subject: [PATCH 15/62] Make PoC configurable --- bootstrap/bootstrap.go | 25 ++++++++++++++++++------- cmd/run/cmd.go | 5 +++++ config/config.go | 4 ++++ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/bootstrap/bootstrap.go b/bootstrap/bootstrap.go index af89179df..84bceb994 100644 --- a/bootstrap/bootstrap.go +++ b/bootstrap/bootstrap.go @@ -142,13 +142,24 @@ func (b *Bootstrap) StartEventIngestion(ctx context.Context) error { chainID := b.config.FlowNetworkID // create event subscriber - subscriber := ingestion.NewRPCBlockTrackingSubscriber( - b.logger, - b.client, - chainID, - b.keystore, - latestCadenceHeight, - ) + var subscriber ingestion.EventSubscriber + if b.config.ExperimentalSoftFinalityEnabled { + subscriber = ingestion.NewRPCEventSubscriber( + b.logger, + b.client, + chainID, + b.keystore, + latestCadenceHeight, + ) + } else { + subscriber = ingestion.NewRPCBlockTrackingSubscriber( + b.logger, + b.client, + chainID, + b.keystore, + latestCadenceHeight, + ) + } callTracerCollector, err := replayer.NewCallTracerCollector(b.logger) if err != nil { diff --git a/cmd/run/cmd.go b/cmd/run/cmd.go index 52aa19dc3..5f40301b8 100644 --- a/cmd/run/cmd.go +++ b/cmd/run/cmd.go @@ -222,6 +222,8 @@ func parseConfigFromFlags() error { return fmt.Errorf("unknown tx state validation: %s", txStateValidation) } + cfg.ExperimentalSoftFinalityEnabled = experimentalSoftFinalityEnabled + return nil } @@ -246,6 +248,8 @@ var ( initHeight, forceStartHeight uint64 + + experimentalSoftFinalityEnabled bool ) func init() { @@ -280,4 +284,5 @@ func init() { Cmd.Flags().StringVar(&cfg.ProfilerHost, "profiler-host", "localhost", "Host for the Profiler server") Cmd.Flags().IntVar(&cfg.ProfilerPort, "profiler-port", 6060, "Port for the Profiler server") Cmd.Flags().StringVar(&txStateValidation, "tx-state-validation", "tx-seal", "Sets the transaction validation mechanism. It can validate using the local state index, or wait for the outer Flow transaction to seal. Available values ('local-index' / 'tx-seal'), defaults to 'tx-seal'.") + Cmd.Flags().BoolVar(&experimentalSoftFinalityEnabled, "experimental-soft-finality-enabled", false, "Sets whether the gateway should use the experimental soft finality feature. WARNING: This may result in incorrect results being returned in certain circumstances. Use only if you know what you are doing.") } diff --git a/config/config.go b/config/config.go index 570258d20..da7051b2d 100644 --- a/config/config.go +++ b/config/config.go @@ -89,4 +89,8 @@ type Config struct { // TxStateValidation sets the transaction validation mechanism. It can validate // using the local state index, or wait for the outer Flow transaction to seal. TxStateValidation string + // ExperimentalSoftFinalityEnabled enables the experimental soft finality feature which syncs + // EVM block and transaction data from the upstream Access node before the block is sealed. + // CAUTION: This feature is experimental and may return incorrect data in certain circumstances. + ExperimentalSoftFinalityEnabled bool } From fa39603f070798a84d6e8657f00ae09c8ee98b91 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Tue, 28 Jan 2025 10:50:26 -0800 Subject: [PATCH 16/62] fix enabled conditional --- bootstrap/bootstrap.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bootstrap/bootstrap.go b/bootstrap/bootstrap.go index 84bceb994..bcff42f6e 100644 --- a/bootstrap/bootstrap.go +++ b/bootstrap/bootstrap.go @@ -144,7 +144,7 @@ func (b *Bootstrap) StartEventIngestion(ctx context.Context) error { // create event subscriber var subscriber ingestion.EventSubscriber if b.config.ExperimentalSoftFinalityEnabled { - subscriber = ingestion.NewRPCEventSubscriber( + subscriber = ingestion.NewRPCBlockTrackingSubscriber( b.logger, b.client, chainID, @@ -152,7 +152,7 @@ func (b *Bootstrap) StartEventIngestion(ctx context.Context) error { latestCadenceHeight, ) } else { - subscriber = ingestion.NewRPCBlockTrackingSubscriber( + subscriber = ingestion.NewRPCEventSubscriber( b.logger, b.client, chainID, From 823e965cda7f7c21e0948285e6ed698dfa40d528 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Wed, 29 Jan 2025 13:55:18 -0800 Subject: [PATCH 17/62] improve error reconnection handling --- .../ingestion/block_tracking_subscriber.go | 62 ++++++++++++------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 0a6359057..0e269486b 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "strings" + "time" "github.com/onflow/flow-evm-gateway/models" errs "github.com/onflow/flow-evm-gateway/models/errors" @@ -114,12 +115,21 @@ func (r *RPCBlockTrackingSubscriber) Subscribe(ctx context.Context) <-chan model func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint64) <-chan models.BlockEvents { eventsChan := make(chan models.BlockEvents) - blockHeadersChan, errChan, err := r.client.SubscribeBlockHeadersFromStartHeight( - ctx, - height, - flow.BlockStatusFinalized, - ) - if err != nil { + var blockHeadersChan <-chan flow.BlockHeader + var errChan <-chan error + + lastReceivedHeight := height + connect := func(height uint64) error { + var err error + blockHeadersChan, errChan, err = r.client.SubscribeBlockHeadersFromStartHeight( + ctx, + height, + flow.BlockStatusFinalized, + ) + return err + } + + if err := connect(lastReceivedHeight); err != nil { eventsChan <- models.NewBlockEventsError( fmt.Errorf( "failed to subscribe for finalized block headers on height: %d, with: %w", @@ -130,7 +140,6 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 close(eventsChan) return eventsChan } - lastReceivedHeight := height go func() { defer func() { @@ -145,6 +154,7 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 case blockHeader, ok := <-blockHeadersChan: if !ok { + // typically we receive an error in the errChan before the channels are closes var err error err = errs.ErrDisconnected if ctx.Err() != nil { @@ -180,6 +190,7 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 case err, ok := <-errChan: if !ok { + // typically we receive an error in the errChan before the channels are closes var err error err = errs.ErrDisconnected if ctx.Err() != nil { @@ -189,26 +200,33 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 return } - if status.Code(err) == codes.DeadlineExceeded || status.Code(err) == codes.Internal { - blockHeadersChan, errChan, err = r.client.SubscribeBlockHeadersFromStartHeight( - ctx, - lastReceivedHeight+1, - flow.BlockStatusFinalized, - ) - if err != nil { - eventsChan <- models.NewBlockEventsError( - fmt.Errorf( - "failed to subscribe for finalized block headers on height: %d, with: %w", - height, - err, - ), - ) + switch status.Code(err) { + case codes.NotFound: + // we can get not found when reconnecting after a disconnect/restart before the + // next block is finalized. just wait briefly and try again + select { + case <-ctx.Done(): return + case <-time.After(200 * time.Millisecond): } - } else { + case codes.DeadlineExceeded, codes.Internal: + // these are sometimes returned when the stream is disconnected by a middleware or the server + default: + // skip reconnect on all other errors eventsChan <- models.NewBlockEventsError(fmt.Errorf("%w: %w", errs.ErrDisconnected, err)) return } + + if err := connect(lastReceivedHeight + 1); err != nil { + eventsChan <- models.NewBlockEventsError( + fmt.Errorf( + "failed to resubscribe for finalized block headers on height: %d, with: %w", + lastReceivedHeight+1, + err, + ), + ) + return + } } } }() From 91b1ec08937541249f31e7ddbf330e67afdaf8b0 Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Thu, 30 Jan 2025 18:09:34 +0200 Subject: [PATCH 18/62] Remove redundant start-testnet & start-mainnet make recipes --- Makefile | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/Makefile b/Makefile index b3ff2fa32..ef0e054cd 100644 --- a/Makefile +++ b/Makefile @@ -227,36 +227,3 @@ endif docker run $(MODE) -p $(HOST_PORT):8545 -p $(HOST_METRICS_PORT):8080 $(MOUNT) "$(CONTAINER_REGISTRY)/flow-evm-gateway:$(IMAGE_TAG)" $(CMD_ARGS) -.PHONY: start-testnet -start-testnet: - rm -rf testnet-db-block-headers/ - rm -rf metrics/data/ - go run cmd/main.go run \ - --database-dir=testnet-db-block-headers \ - --access-node-grpc-host=access.devnet.nodes.onflow.org:9000 \ - --access-node-spork-hosts=access-001.devnet51.nodes.onflow.org:9000 \ - --flow-network-id=flow-testnet \ - --init-cadence-height=211176670 \ - --ws-enabled=true \ - --coinbase=FACF71692421039876a5BB4F10EF7A439D8ef61E \ - --coa-address=0x62631c28c9fc5a91 \ - --coa-key=2892fba444f1d5787739708874e3b01160671924610411ac787ac1379d420f49 \ - --gas-price=100 \ - --log-level=info - -.PHONY: start-mainnet -start-mainnet: - rm -rf mainnet-db-block-headers/ - rm -rf metrics/data/ - go run cmd/main.go run \ - --database-dir=mainnet-db-block-headers \ - --access-node-grpc-host=access.mainnet.nodes.onflow.org:9000 \ - --access-node-spork-hosts=access-001.mainnet25.nodes.onflow.org:9000 \ - --flow-network-id=flow-mainnet \ - --init-cadence-height=85981135 \ - --ws-enabled=true \ - --coinbase=FACF71692421039876a5BB4F10EF7A439D8ef61E \ - --coa-address=0xf1ab99c82dee3526 \ - --coa-key=2892fba444f1d5787739708874e3b01160671924610411ac787ac1379d420f49 \ - --gas-price=100 \ - --log-level=info From 1e977a9a9c5c002116ec3342b85b05dc0b7955a7 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Mon, 3 Feb 2025 10:27:57 -0800 Subject: [PATCH 19/62] retry getting events on NotFound and ResourceExhausted --- .../ingestion/block_tracking_subscriber.go | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 0e269486b..9d336b731 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -204,11 +204,7 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 case codes.NotFound: // we can get not found when reconnecting after a disconnect/restart before the // next block is finalized. just wait briefly and try again - select { - case <-ctx.Done(): - return - case <-time.After(200 * time.Millisecond): - } + time.Sleep(200 * time.Millisecond) case codes.DeadlineExceeded, codes.Internal: // these are sometimes returned when the stream is disconnected by a middleware or the server default: @@ -272,13 +268,26 @@ func (r *RPCBlockTrackingSubscriber) getEventsByType( blockHeader flow.BlockHeader, eventType string, ) (flow.BlockEvents, error) { - evts, err := r.client.GetEventsForBlockHeader( - ctx, - eventType, - blockHeader, - ) - if err != nil { - return flow.BlockEvents{}, err + var evts []flow.BlockEvents + var err error + + // retry until we get the block from an execution node that has the events + for { + evts, err = r.client.GetEventsForBlockHeader( + ctx, + eventType, + blockHeader, + ) + if err != nil { + // retry after a short pause + if status.Code(err) == codes.NotFound || status.Code(err) == codes.ResourceExhausted { + time.Sleep(200 * time.Millisecond) + continue + } + + return flow.BlockEvents{}, err + } + break } if len(evts) != 1 { From 23b4c8762a9f5476f2b18f1f35206a6777722657 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Fri, 14 Feb 2025 17:07:43 -0800 Subject: [PATCH 20/62] add system to verify soft finality events were eventually sealed --- bootstrap/bootstrap.go | 12 + .../ingestion/block_tracking_subscriber.go | 17 +- services/ingestion/sealing_verifier.go | 256 ++++++++++++++++++ storage/pebble/db.go | 23 ++ storage/pebble/events_hash.go | 65 +++++ storage/pebble/keys.go | 3 + 6 files changed, 373 insertions(+), 3 deletions(-) create mode 100644 services/ingestion/sealing_verifier.go create mode 100644 storage/pebble/events_hash.go diff --git a/bootstrap/bootstrap.go b/bootstrap/bootstrap.go index c0c7d0638..8e915544f 100644 --- a/bootstrap/bootstrap.go +++ b/bootstrap/bootstrap.go @@ -56,6 +56,7 @@ type Storages struct { Transactions storage.TransactionIndexer Receipts storage.ReceiptIndexer Traces storage.TraceIndexer + EventsHash *pebble.EventsHash } type Publishers struct { @@ -155,12 +156,21 @@ func (b *Bootstrap) StartEventIngestion(ctx context.Context) error { // create event subscriber var subscriber ingestion.EventSubscriber if b.config.ExperimentalSoftFinalityEnabled { + verifier := ingestion.NewSealingVerifier( + b.logger, + b.client, + chainID, + b.storages.EventsHash, + ) + go StartEngine(ctx, verifier, b.logger) + subscriber = ingestion.NewRPCBlockTrackingSubscriber( b.logger, b.client, chainID, b.keystore, nextCadenceHeight, + verifier, ) } else { subscriber = ingestion.NewRPCEventSubscriber( @@ -597,6 +607,7 @@ func setupStorage( blocks := pebble.NewBlocks(store, config.FlowNetworkID) storageAddress := evm.StorageAccountAddress(config.FlowNetworkID) registerStore := pebble.NewRegisterStorage(store, storageAddress) + eventsHash := pebble.NewEventsHash(store) batch := store.NewBatch() defer func() { @@ -676,6 +687,7 @@ func setupStorage( Transactions: pebble.NewTransactions(store), Receipts: pebble.NewReceipts(store), Traces: pebble.NewTraces(store), + EventsHash: eventsHash, }, nil } diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 9d336b731..084f70fbd 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -6,9 +6,6 @@ import ( "strings" "time" - "github.com/onflow/flow-evm-gateway/models" - errs "github.com/onflow/flow-evm-gateway/models/errors" - "github.com/onflow/flow-evm-gateway/services/requester" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go/fvm/evm/events" flowGo "github.com/onflow/flow-go/model/flow" @@ -16,6 +13,10 @@ import ( "github.com/rs/zerolog" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + + "github.com/onflow/flow-evm-gateway/models" + errs "github.com/onflow/flow-evm-gateway/models/errors" + "github.com/onflow/flow-evm-gateway/services/requester" ) var _ EventSubscriber = &RPCBlockTrackingSubscriber{} @@ -35,6 +36,8 @@ var _ EventSubscriber = &RPCBlockTrackingSubscriber{} // at which point this subscriber will be removed. type RPCBlockTrackingSubscriber struct { *RPCEventSubscriber + + verifier *SealingVerifier } func NewRPCBlockTrackingSubscriber( @@ -43,6 +46,7 @@ func NewRPCBlockTrackingSubscriber( chainID flowGo.ChainID, keyLock requester.KeyLock, startHeight uint64, + verifier *SealingVerifier, ) *RPCBlockTrackingSubscriber { return &RPCBlockTrackingSubscriber{ RPCEventSubscriber: NewRPCEventSubscriber( @@ -52,6 +56,7 @@ func NewRPCBlockTrackingSubscriber( keyLock, startHeight, ), + verifier: verifier, } } @@ -170,6 +175,12 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 return } + // submit the block events to the verifier for future sealing verification + if err := r.verifier.AddBlock(blockEvents); err != nil { + eventsChan <- models.NewBlockEventsError(err) + return + } + evmEvents := models.NewSingleBlockEvents(blockEvents) // if events contain an error, or we are in a recovery mode if evmEvents.Err != nil || r.recovery { diff --git a/services/ingestion/sealing_verifier.go b/services/ingestion/sealing_verifier.go new file mode 100644 index 000000000..73dc731ad --- /dev/null +++ b/services/ingestion/sealing_verifier.go @@ -0,0 +1,256 @@ +package ingestion + +import ( + "context" + "fmt" + "sync" + "time" + + "github.com/onflow/flow-go-sdk" + "github.com/onflow/flow-go-sdk/access" + flowGo "github.com/onflow/flow-go/model/flow" + "github.com/rs/zerolog" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "github.com/onflow/flow-evm-gateway/models" + errs "github.com/onflow/flow-evm-gateway/models/errors" + "github.com/onflow/flow-evm-gateway/services/requester" + "github.com/onflow/flow-evm-gateway/storage/pebble" +) + +var _ models.Engine = &SealingVerifier{} + +// SealingVerifier verifies that soft finality events received over the Access polling API match the +// actually sealed results from the event stream. +type SealingVerifier struct { + *models.EngineStatus + + logger zerolog.Logger + + client *requester.CrossSporkClient + chain flowGo.ChainID + + eventsHash *pebble.EventsHash + blocksToVerify map[uint64]flow.Identifier + + mu sync.Mutex +} + +// NewSealingVerifier creates a new sealing verifier. +func NewSealingVerifier( + logger zerolog.Logger, + client *requester.CrossSporkClient, + chain flowGo.ChainID, + eventsHash *pebble.EventsHash, +) *SealingVerifier { + return &SealingVerifier{ + EngineStatus: models.NewEngineStatus(), + logger: logger, + client: client, + chain: chain, + eventsHash: eventsHash, + } +} + +// Stop the engine. +func (v *SealingVerifier) Stop() { + v.MarkDone() + <-v.Stopped() +} + +// AddBlock adds a block to the sealing verifier for verification when the sealed data is received. +func (v *SealingVerifier) AddBlock(events flow.BlockEvents) error { + hash, err := CalculateHash(events) + if err != nil { + return fmt.Errorf("failed to calculate hash for block %d: %w", events.Height, err) + } + + if err := v.eventsHash.Store(events.Height, hash); err != nil { + return fmt.Errorf("failed to store events hash for block %d: %w", events.Height, err) + } + + v.mu.Lock() + defer v.mu.Unlock() + v.blocksToVerify[events.Height] = hash + + return nil +} + +// Run executes the sealing verifier. +// This method will block until the context is canceled or an error occurs. +func (v *SealingVerifier) Run(ctx context.Context) error { + defer v.MarkStopped() + + lastVerifiedHeight, err := v.eventsHash.ProcessedSealedHeight() + if err != nil { + return fmt.Errorf("failed to get processed sealed height: %w", err) + } + + var eventsChan <-chan flow.BlockEvents + var errChan <-chan error + + subscriptionCtx, cancel := context.WithCancel(ctx) + defer cancel() + + lastReceivedHeight := lastVerifiedHeight + 1 + connect := func(height uint64) error { + var err error + eventsChan, errChan, err = v.client.SubscribeEventsByBlockHeight( + subscriptionCtx, + height, + blocksFilter(v.chain), + access.WithHeartbeatInterval(1), + ) + return err + } + + if err := connect(lastReceivedHeight); err != nil { + return fmt.Errorf("failed to subscribe for finalized block events on height: %d, with: %w", lastReceivedHeight, err) + } + + v.MarkReady() + for { + select { + case <-ctx.Done(): + v.logger.Info().Msg("sealing verifier received done signal") + return nil + + case <-v.Done(): + v.logger.Info().Msg("sealing verifier received stop signal") + cancel() + return nil + + case blockEvents, ok := <-eventsChan: + if !ok { + if ctx.Err() != nil { + return nil + } + return fmt.Errorf("failed to receive block events: %w", err) + } + + if err := v.verifyBlock(blockEvents); err != nil { + v.logger.Fatal().Err(err). + Uint64("height", blockEvents.Height). + Str("block_id", blockEvents.BlockID.String()). + Msg("failed to verify block events") + return fmt.Errorf("failed to verify block events for %d: %w", blockEvents.Height, err) + } + + if err := v.eventsHash.SetProcessedSealedHeight(blockEvents.Height); err != nil { + return fmt.Errorf("failed to store processed sealed height: %w", err) + } + + case err, ok := <-errChan: + if !ok { + if ctx.Err() != nil { + return nil + } + return fmt.Errorf("failed to receive block events: %w", err) + } + + switch status.Code(err) { + case codes.NotFound: + // we can get not found when reconnecting after a disconnect/restart before the + // next block is finalized. just wait briefly and try again + time.Sleep(200 * time.Millisecond) + case codes.DeadlineExceeded, codes.Internal: + // these are sometimes returned when the stream is disconnected by a middleware or the server + default: + // skip reconnect on all other errors + return fmt.Errorf("%w: %w", errs.ErrDisconnected, err) + } + + if err := connect(lastReceivedHeight + 1); err != nil { + return fmt.Errorf("failed to resubscribe for finalized block headers on height: %d, with: %w", lastReceivedHeight+1, err) + } + } + } +} + +// getEventsHash returns the events hash for the given height +func (v *SealingVerifier) getEventsHash(height uint64) (flow.Identifier, error) { + v.mu.Lock() + defer v.mu.Unlock() + + if hash, ok := v.blocksToVerify[height]; ok { + return hash, nil + } + + hash, err := v.eventsHash.GetByHeight(height) + if err != nil { + return flow.Identifier{}, fmt.Errorf("failed to get events hash for block %d: %w", height, err) + } + + // note: don't cache it here since we will not revisit this height + + return hash, nil +} + +// verifyBlock verifies that the hash of the sealed events matches the hash of unsealed events stored +// for the same height. +func (v *SealingVerifier) verifyBlock(sealedEvents flow.BlockEvents) error { + unsealedHash, err := v.getEventsHash(sealedEvents.Height) + if err != nil { + return fmt.Errorf("no unsealed events found for height %d: %w", sealedEvents.Height, err) + } + + sealedHash, err := CalculateHash(sealedEvents) + if err != nil { + return fmt.Errorf("failed to calculate hash for sealed events: %w", err) + } + + v.mu.Lock() + defer v.mu.Unlock() + + // always delete since we will crash on error anyway + defer delete(v.blocksToVerify, sealedEvents.Height) + + if sealedHash != unsealedHash { + return fmt.Errorf("event hash mismatch: expected %s, got %s", sealedHash, unsealedHash) + } + + return nil +} + +// CalculateHash calculates the hash of the given block events object. +func CalculateHash(events flow.BlockEvents) (flow.Identifier, error) { + // convert to strip cadence payload objects + converted, err := convertFlowBlockEvents(events) + if err != nil { + return flow.Identifier{}, err + } + + hash := flowGo.MakeID(converted) + return flow.BytesToID(hash[:]), nil +} + +// convertFlowBlockEvents converts a flow.BlockEvents (flow-go-sdk) to a flowGo.BlockEvents (flow-go). +func convertFlowBlockEvents(events flow.BlockEvents) (flowGo.BlockEvents, error) { + blockID, err := flowGo.ByteSliceToId(events.BlockID.Bytes()) + if err != nil { + return flowGo.BlockEvents{}, fmt.Errorf("failed to convert block ID: %w", err) + } + + flowEvents := make([]flowGo.Event, len(events.Events)) + for i, e := range events.Events { + txID, err := flowGo.ByteSliceToId(e.TransactionID.Bytes()) + if err != nil { + return flowGo.BlockEvents{}, fmt.Errorf("failed to convert transaction ID %s: %w", e.TransactionID.Hex(), err) + } + flowEvents[i] = flowGo.Event{ + Type: flowGo.EventType(e.Type), + TransactionID: txID, + TransactionIndex: uint32(e.TransactionIndex), + EventIndex: uint32(e.EventIndex), + Payload: e.Payload, + } + } + + return flowGo.BlockEvents{ + BlockID: blockID, + BlockHeight: events.Height, + BlockTimestamp: events.BlockTimestamp, + Events: flowEvents, + }, nil +} diff --git a/storage/pebble/db.go b/storage/pebble/db.go index 5e3c0f89c..fa86c48ac 100644 --- a/storage/pebble/db.go +++ b/storage/pebble/db.go @@ -5,6 +5,8 @@ import ( "github.com/cockroachdb/pebble" "github.com/cockroachdb/pebble/bloom" + "github.com/onflow/flow-emulator/storage" + "github.com/rs/zerolog/log" ) // OpenDB opens a new pebble database at the provided directory. @@ -60,3 +62,24 @@ func OpenDB(dir string) (*pebble.DB, error) { } return db, nil } + +func WithBatch(store *Storage, f func(batch *pebble.Batch) error) error { + batch := store.NewBatch() + defer func(batch *pebble.Batch) { + err := batch.Close() + if err != nil { + log.Fatal().Err(err).Msg("failed to close batch") + } + }(batch) + + err := f(batch) + if err != nil { + return err + } + + if err := batch.Commit(pebble.Sync); err != nil { + return fmt.Errorf("failed to commit batch: %w", err) + } + + return nil +} diff --git a/storage/pebble/events_hash.go b/storage/pebble/events_hash.go new file mode 100644 index 000000000..37a3356c6 --- /dev/null +++ b/storage/pebble/events_hash.go @@ -0,0 +1,65 @@ +package pebble + +import ( + "encoding/binary" + "errors" + "fmt" + + pebbleDB "github.com/cockroachdb/pebble" + "github.com/onflow/flow-go-sdk" + + errs "github.com/onflow/flow-evm-gateway/models/errors" +) + +type EventsHash struct { + store *Storage +} + +func NewEventsHash(store *Storage) *EventsHash { + return &EventsHash{ + store: store, + } +} + +func (e *EventsHash) Store(height uint64, hash flow.Identifier) error { + return WithBatch(e.store, func(batch *pebbleDB.Batch) error { + if err := e.store.set(eventsHashKey, uint64Bytes(height), hash.Bytes(), batch); err != nil { + return fmt.Errorf( + "failed to store events hash for block %d, with: %w", + height, + err, + ) + } + return nil + }) +} + +func (e *EventsHash) GetByHeight(height uint64) (flow.Identifier, error) { + hash, err := e.store.get(eventsHashKey, uint64Bytes(height)) + if err != nil { + return flow.Identifier{}, fmt.Errorf("failed to get events hash for block %d, with: %w", height, err) + } + + return flow.BytesToID(hash), nil +} + +func (e *EventsHash) ProcessedSealedHeight() (uint64, error) { + val, err := e.store.get(sealedEventsHeightKey) + if err != nil { + if errors.Is(err, errs.ErrEntityNotFound) { + return 0, errs.ErrStorageNotInitialized + } + return 0, fmt.Errorf("failed to get latest processed sealed height: %w", err) + } + + return binary.BigEndian.Uint64(val), nil +} + +func (e *EventsHash) SetProcessedSealedHeight(height uint64) error { + return WithBatch(e.store, func(batch *pebbleDB.Batch) error { + if err := e.store.set(sealedEventsHeightKey, nil, uint64Bytes(height), batch); err != nil { + return fmt.Errorf("failed to store latest processed sealed height: %d, with: %w", height, err) + } + return nil + }) +} diff --git a/storage/pebble/keys.go b/storage/pebble/keys.go index aa46b61a3..36056de62 100644 --- a/storage/pebble/keys.go +++ b/storage/pebble/keys.go @@ -30,6 +30,9 @@ const ( // special keys latestEVMHeightKey = byte(100) latestCadenceHeightKey = byte(102) + + eventsHashKey = byte(150) + sealedEventsHeightKey = byte(151) ) // makePrefix makes a key used internally to store the values From d98d8c511284ba31808cef3a7e67481b88e903f0 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Tue, 18 Feb 2025 15:51:35 -0800 Subject: [PATCH 21/62] handle case when sealed stream is ahead --- bootstrap/bootstrap.go | 2 +- .../ingestion/block_tracking_subscriber.go | 9 + services/ingestion/sealing_verifier.go | 198 ++++++++++++------ storage/pebble/db.go | 1 - 4 files changed, 148 insertions(+), 62 deletions(-) diff --git a/bootstrap/bootstrap.go b/bootstrap/bootstrap.go index 8e915544f..bdbb1a745 100644 --- a/bootstrap/bootstrap.go +++ b/bootstrap/bootstrap.go @@ -161,8 +161,8 @@ func (b *Bootstrap) StartEventIngestion(ctx context.Context) error { b.client, chainID, b.storages.EventsHash, + nextCadenceHeight, ) - go StartEngine(ctx, verifier, b.logger) subscriber = ingestion.NewRPCBlockTrackingSubscriber( b.logger, diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 084f70fbd..a74f50cca 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -102,6 +102,15 @@ func (r *RPCBlockTrackingSubscriber) Subscribe(ctx context.Context) <-chan model Uint64("next-height", r.height). Msg("backfilling done, subscribe for live data") + // start the verifier after backfilling since backfilled data is already sealed + go func() { + r.verifier.SetStartHeight(r.height) + if err := r.verifier.Run(ctx); err != nil { + r.logger.Fatal().Err(err).Msg("failure running sealing verifier") + return + } + }() + // subscribe in the current spork, handling of context cancellation is done by the producer for ev := range r.subscribe(ctx, r.height) { eventsChan <- ev diff --git a/services/ingestion/sealing_verifier.go b/services/ingestion/sealing_verifier.go index 73dc731ad..806ae79d5 100644 --- a/services/ingestion/sealing_verifier.go +++ b/services/ingestion/sealing_verifier.go @@ -2,7 +2,9 @@ package ingestion import ( "context" + "errors" "fmt" + "sort" "sync" "time" @@ -27,12 +29,13 @@ type SealingVerifier struct { *models.EngineStatus logger zerolog.Logger - client *requester.CrossSporkClient chain flowGo.ChainID - eventsHash *pebble.EventsHash - blocksToVerify map[uint64]flow.Identifier + startHeight uint64 + eventsHash *pebble.EventsHash + unsealedBlocksToVerify map[uint64]flow.Identifier + sealedBlocksToVerify map[uint64]flow.Identifier mu sync.Mutex } @@ -43,13 +46,17 @@ func NewSealingVerifier( client *requester.CrossSporkClient, chain flowGo.ChainID, eventsHash *pebble.EventsHash, + startHeight uint64, ) *SealingVerifier { return &SealingVerifier{ - EngineStatus: models.NewEngineStatus(), - logger: logger, - client: client, - chain: chain, - eventsHash: eventsHash, + EngineStatus: models.NewEngineStatus(), + logger: logger.With().Str("component", "sealing_verifier").Logger(), + client: client, + chain: chain, + startHeight: startHeight, + eventsHash: eventsHash, + unsealedBlocksToVerify: make(map[uint64]flow.Identifier), + sealedBlocksToVerify: make(map[uint64]flow.Identifier), } } @@ -59,22 +66,15 @@ func (v *SealingVerifier) Stop() { <-v.Stopped() } +// SetStartHeight sets the start height for the sealing verifier. +// This is used to update the height when backfilling already sea +func (v *SealingVerifier) SetStartHeight(height uint64) { + v.startHeight = height +} + // AddBlock adds a block to the sealing verifier for verification when the sealed data is received. func (v *SealingVerifier) AddBlock(events flow.BlockEvents) error { - hash, err := CalculateHash(events) - if err != nil { - return fmt.Errorf("failed to calculate hash for block %d: %w", events.Height, err) - } - - if err := v.eventsHash.Store(events.Height, hash); err != nil { - return fmt.Errorf("failed to store events hash for block %d: %w", events.Height, err) - } - - v.mu.Lock() - defer v.mu.Unlock() - v.blocksToVerify[events.Height] = hash - - return nil + return v.onUnsealedEvents(events) } // Run executes the sealing verifier. @@ -84,7 +84,18 @@ func (v *SealingVerifier) Run(ctx context.Context) error { lastVerifiedHeight, err := v.eventsHash.ProcessedSealedHeight() if err != nil { - return fmt.Errorf("failed to get processed sealed height: %w", err) + if !errors.Is(err, errs.ErrStorageNotInitialized) { + return fmt.Errorf("failed to get processed sealed height: %w", err) + } + + // lastVerifiedHeight should be the block before the startHeight + // handle the case where startHeight is 0 like when running with the emulator + if lastVerifiedHeight = v.startHeight; lastVerifiedHeight > 0 { + lastVerifiedHeight = v.startHeight - 1 + } + if err := v.eventsHash.SetProcessedSealedHeight(lastVerifiedHeight); err != nil { + return fmt.Errorf("failed to initialize processed sealed height: %w", err) + } } var eventsChan <-chan flow.BlockEvents @@ -93,7 +104,7 @@ func (v *SealingVerifier) Run(ctx context.Context) error { subscriptionCtx, cancel := context.WithCancel(ctx) defer cancel() - lastReceivedHeight := lastVerifiedHeight + 1 + nextHeight := lastVerifiedHeight + 1 connect := func(height uint64) error { var err error eventsChan, errChan, err = v.client.SubscribeEventsByBlockHeight( @@ -105,40 +116,35 @@ func (v *SealingVerifier) Run(ctx context.Context) error { return err } - if err := connect(lastReceivedHeight); err != nil { - return fmt.Errorf("failed to subscribe for finalized block events on height: %d, with: %w", lastReceivedHeight, err) + v.logger.Info().Uint64("start_height", lastVerifiedHeight).Msg("starting verifier") + + if err := connect(nextHeight); err != nil { + return fmt.Errorf("failed to subscribe for finalized block events on height: %d, with: %w", nextHeight, err) } v.MarkReady() for { select { case <-ctx.Done(): - v.logger.Info().Msg("sealing verifier received done signal") + v.logger.Info().Msg("received done signal") return nil case <-v.Done(): - v.logger.Info().Msg("sealing verifier received stop signal") + v.logger.Info().Msg("received stop signal") cancel() return nil - case blockEvents, ok := <-eventsChan: + case sealedEvents, ok := <-eventsChan: if !ok { if ctx.Err() != nil { return nil } return fmt.Errorf("failed to receive block events: %w", err) } + nextHeight = sealedEvents.Height + 1 - if err := v.verifyBlock(blockEvents); err != nil { - v.logger.Fatal().Err(err). - Uint64("height", blockEvents.Height). - Str("block_id", blockEvents.BlockID.String()). - Msg("failed to verify block events") - return fmt.Errorf("failed to verify block events for %d: %w", blockEvents.Height, err) - } - - if err := v.eventsHash.SetProcessedSealedHeight(blockEvents.Height); err != nil { - return fmt.Errorf("failed to store processed sealed height: %w", err) + if err := v.onSealedEvents(sealedEvents); err != nil { + return fmt.Errorf("failed to process sealed events: %w", err) } case err, ok := <-errChan: @@ -161,55 +167,119 @@ func (v *SealingVerifier) Run(ctx context.Context) error { return fmt.Errorf("%w: %w", errs.ErrDisconnected, err) } - if err := connect(lastReceivedHeight + 1); err != nil { - return fmt.Errorf("failed to resubscribe for finalized block headers on height: %d, with: %w", lastReceivedHeight+1, err) + if err := connect(nextHeight); err != nil { + return fmt.Errorf("failed to resubscribe for finalized block headers on height: %d, with: %w", nextHeight, err) } } } } -// getEventsHash returns the events hash for the given height -func (v *SealingVerifier) getEventsHash(height uint64) (flow.Identifier, error) { +// onSealedEvents processes sealed events +// if unsealed events are found for the same height, the events are verified. +// otherwise, the sealed events are cached for future verification. +func (v *SealingVerifier) onSealedEvents(sealedEvents flow.BlockEvents) error { + if len(sealedEvents.Events) == 0 { + return nil // skip empty blocks + } + + sealedHash, err := CalculateHash(sealedEvents) + if err != nil { + return fmt.Errorf("failed to calculate hash for sealed events: %w", err) + } + v.mu.Lock() defer v.mu.Unlock() - if hash, ok := v.blocksToVerify[height]; ok { - return hash, nil + unsealedHash, err := v.getUnsealedEventsHash(sealedEvents.Height) + if err != nil { + if errors.Is(err, errs.ErrEntityNotFound) { + // we haven't processed the unsealed data for this block yet, cache the sealed hash + v.sealedBlocksToVerify[sealedEvents.Height] = sealedHash + return nil + } + return fmt.Errorf("no unsealed events found for height %d: %w", sealedEvents.Height, err) } - hash, err := v.eventsHash.GetByHeight(height) - if err != nil { - return flow.Identifier{}, fmt.Errorf("failed to get events hash for block %d: %w", height, err) + if err := v.verifyBlock(sealedEvents.Height, sealedHash, unsealedHash); err != nil { + v.logger.Fatal().Err(err). + Uint64("height", sealedEvents.Height). + Str("block_id", sealedEvents.BlockID.String()). + Msg("failed to verify block events") + return fmt.Errorf("failed to verify block events for %d: %w", sealedEvents.Height, err) } - // note: don't cache it here since we will not revisit this height + v.logger.Debug().Uint64("height", sealedEvents.Height).Msg("verified sealed height") - return hash, nil + return nil } -// verifyBlock verifies that the hash of the sealed events matches the hash of unsealed events stored -// for the same height. -func (v *SealingVerifier) verifyBlock(sealedEvents flow.BlockEvents) error { - unsealedHash, err := v.getEventsHash(sealedEvents.Height) +// onUnsealedEvents processes unsealed events. +// if sealed events are found for the same height, the events are verified. +// otherwise, the unsealed events are cached for future verification. +func (v *SealingVerifier) onUnsealedEvents(unsealedEvents flow.BlockEvents) error { + unsealedHash, err := CalculateHash(unsealedEvents) if err != nil { - return fmt.Errorf("no unsealed events found for height %d: %w", sealedEvents.Height, err) + return fmt.Errorf("failed to calculate hash for block %d: %w", unsealedEvents.Height, err) } - sealedHash, err := CalculateHash(sealedEvents) + v.mu.Lock() + defer v.mu.Unlock() + + // note: do this inside the lock to avoid a race with onSealedEvents + if err := v.eventsHash.Store(unsealedEvents.Height, unsealedHash); err != nil { + return fmt.Errorf("failed to store events hash for block %d: %w", unsealedEvents.Height, err) + } + + sealedHash, ok := v.sealedBlocksToVerify[unsealedEvents.Height] + if !ok { + v.unsealedBlocksToVerify[unsealedEvents.Height] = unsealedHash + return nil + } + + if err := v.verifyBlock(unsealedEvents.Height, sealedHash, unsealedHash); err != nil { + v.logger.Fatal().Err(err). + Uint64("height", unsealedEvents.Height). + Str("block_id", unsealedEvents.BlockID.String()). + Msg("failed to verify block events") + return fmt.Errorf("failed to verify block events for %d: %w", unsealedEvents.Height, err) + } + + v.logger.Debug().Uint64("height", unsealedEvents.Height).Msg("verified unsealed height") + + return nil +} + +// getUnsealedEventsHash returns the events hash for the given height without taking a lock +func (v *SealingVerifier) getUnsealedEventsHash(height uint64) (flow.Identifier, error) { + if hash, ok := v.unsealedBlocksToVerify[height]; ok { + return hash, nil + } + + hash, err := v.eventsHash.GetByHeight(height) if err != nil { - return fmt.Errorf("failed to calculate hash for sealed events: %w", err) + return flow.Identifier{}, fmt.Errorf("failed to get events hash for block %d: %w", height, err) } - v.mu.Lock() - defer v.mu.Unlock() + // note: don't cache it here since we will usually not revisit this height + return hash, nil +} + +// verifyBlock verifies that the hash of the sealed events matches the hash of unsealed events stored +// for the same height. +func (v *SealingVerifier) verifyBlock(height uint64, sealedHash, unsealedHash flow.Identifier) error { // always delete since we will crash on error anyway - defer delete(v.blocksToVerify, sealedEvents.Height) + defer delete(v.unsealedBlocksToVerify, height) + defer delete(v.sealedBlocksToVerify, height) if sealedHash != unsealedHash { return fmt.Errorf("event hash mismatch: expected %s, got %s", sealedHash, unsealedHash) } + if err := v.eventsHash.SetProcessedSealedHeight(height); err != nil { + return fmt.Errorf("failed to store processed sealed height: %w", err) + } + return nil } @@ -247,6 +317,14 @@ func convertFlowBlockEvents(events flow.BlockEvents) (flowGo.BlockEvents, error) } } + // need canonical order before hashing + sort.Slice(flowEvents, func(i, j int) bool { + if flowEvents[i].TransactionIndex != flowEvents[j].TransactionIndex { + return flowEvents[i].TransactionIndex < flowEvents[j].TransactionIndex + } + return flowEvents[i].EventIndex < flowEvents[j].EventIndex + }) + return flowGo.BlockEvents{ BlockID: blockID, BlockHeight: events.Height, diff --git a/storage/pebble/db.go b/storage/pebble/db.go index fa86c48ac..54707a25f 100644 --- a/storage/pebble/db.go +++ b/storage/pebble/db.go @@ -5,7 +5,6 @@ import ( "github.com/cockroachdb/pebble" "github.com/cockroachdb/pebble/bloom" - "github.com/onflow/flow-emulator/storage" "github.com/rs/zerolog/log" ) From 2f12447868a0b62f7e4b8251f029492968a9690d Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Fri, 21 Feb 2025 09:38:03 -0800 Subject: [PATCH 22/62] make verification configurable --- bootstrap/bootstrap.go | 17 +++++++----- cmd/run/cmd.go | 10 ++++--- config/config.go | 5 ++++ .../ingestion/block_tracking_subscriber.go | 26 +++++++++++-------- 4 files changed, 37 insertions(+), 21 deletions(-) diff --git a/bootstrap/bootstrap.go b/bootstrap/bootstrap.go index bdbb1a745..581d58631 100644 --- a/bootstrap/bootstrap.go +++ b/bootstrap/bootstrap.go @@ -156,13 +156,16 @@ func (b *Bootstrap) StartEventIngestion(ctx context.Context) error { // create event subscriber var subscriber ingestion.EventSubscriber if b.config.ExperimentalSoftFinalityEnabled { - verifier := ingestion.NewSealingVerifier( - b.logger, - b.client, - chainID, - b.storages.EventsHash, - nextCadenceHeight, - ) + var verifier *ingestion.SealingVerifier + if b.config.ExperimentalSealingVerificationEnabled { + verifier = ingestion.NewSealingVerifier( + b.logger, + b.client, + chainID, + b.storages.EventsHash, + nextCadenceHeight, + ) + } subscriber = ingestion.NewRPCBlockTrackingSubscriber( b.logger, diff --git a/cmd/run/cmd.go b/cmd/run/cmd.go index 5f40301b8..c4f78d14c 100644 --- a/cmd/run/cmd.go +++ b/cmd/run/cmd.go @@ -12,8 +12,6 @@ import ( "syscall" "time" - "github.com/onflow/flow-evm-gateway/bootstrap" - "github.com/onflow/flow-evm-gateway/config" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/crypto" flowGoKMS "github.com/onflow/flow-go-sdk/crypto/cloudkms" @@ -24,6 +22,9 @@ import ( "github.com/rs/zerolog" "github.com/rs/zerolog/log" "github.com/spf13/cobra" + + "github.com/onflow/flow-evm-gateway/bootstrap" + "github.com/onflow/flow-evm-gateway/config" ) var Cmd = &cobra.Command{ @@ -223,6 +224,7 @@ func parseConfigFromFlags() error { } cfg.ExperimentalSoftFinalityEnabled = experimentalSoftFinalityEnabled + cfg.ExperimentalSealingVerificationEnabled = experimentalSealingVerificationEnabled return nil } @@ -249,7 +251,8 @@ var ( initHeight, forceStartHeight uint64 - experimentalSoftFinalityEnabled bool + experimentalSoftFinalityEnabled, + experimentalSealingVerificationEnabled bool ) func init() { @@ -285,4 +288,5 @@ func init() { Cmd.Flags().IntVar(&cfg.ProfilerPort, "profiler-port", 6060, "Port for the Profiler server") Cmd.Flags().StringVar(&txStateValidation, "tx-state-validation", "tx-seal", "Sets the transaction validation mechanism. It can validate using the local state index, or wait for the outer Flow transaction to seal. Available values ('local-index' / 'tx-seal'), defaults to 'tx-seal'.") Cmd.Flags().BoolVar(&experimentalSoftFinalityEnabled, "experimental-soft-finality-enabled", false, "Sets whether the gateway should use the experimental soft finality feature. WARNING: This may result in incorrect results being returned in certain circumstances. Use only if you know what you are doing.") + Cmd.Flags().BoolVar(&experimentalSealingVerificationEnabled, "experimental-sealing-verification-enabled", true, "Sets whether the gateway should use the experimental soft finality sealing verification feature. WARNING: This may result in indexing halts if events do not match. Use only if you know what you are doing.") } diff --git a/config/config.go b/config/config.go index da7051b2d..171bc59fd 100644 --- a/config/config.go +++ b/config/config.go @@ -93,4 +93,9 @@ type Config struct { // EVM block and transaction data from the upstream Access node before the block is sealed. // CAUTION: This feature is experimental and may return incorrect data in certain circumstances. ExperimentalSoftFinalityEnabled bool + // ExperimentalSealingVerificationEnabled enables the experimental sealing verification feature + // which verifies the hash of the EVM events ingested by the requester engine match the hash + // of the events from the sealed block in the Flow network. + // CAUTION: This feature is experimental and will cause the node to halt if the events don't match. + ExperimentalSealingVerificationEnabled bool } diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index a74f50cca..9208cbcb5 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -103,13 +103,15 @@ func (r *RPCBlockTrackingSubscriber) Subscribe(ctx context.Context) <-chan model Msg("backfilling done, subscribe for live data") // start the verifier after backfilling since backfilled data is already sealed - go func() { - r.verifier.SetStartHeight(r.height) - if err := r.verifier.Run(ctx); err != nil { - r.logger.Fatal().Err(err).Msg("failure running sealing verifier") - return - } - }() + if r.verifier != nil { + go func() { + r.verifier.SetStartHeight(r.height) + if err := r.verifier.Run(ctx); err != nil { + r.logger.Fatal().Err(err).Msg("failure running sealing verifier") + return + } + }() + } // subscribe in the current spork, handling of context cancellation is done by the producer for ev := range r.subscribe(ctx, r.height) { @@ -184,10 +186,12 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 return } - // submit the block events to the verifier for future sealing verification - if err := r.verifier.AddBlock(blockEvents); err != nil { - eventsChan <- models.NewBlockEventsError(err) - return + if r.verifier != nil { + // submit the block events to the verifier for future sealing verification + if err := r.verifier.AddBlock(blockEvents); err != nil { + eventsChan <- models.NewBlockEventsError(err) + return + } } evmEvents := models.NewSingleBlockEvents(blockEvents) From a4766eb494b2f00231d64646afafcfedf9128069 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Fri, 21 Feb 2025 11:29:56 -0800 Subject: [PATCH 23/62] review feedback --- .../ingestion/block_tracking_subscriber.go | 2 +- services/ingestion/sealing_verifier.go | 30 ++++++++++++++----- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 9208cbcb5..077fe7ad8 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -188,7 +188,7 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 if r.verifier != nil { // submit the block events to the verifier for future sealing verification - if err := r.verifier.AddBlock(blockEvents); err != nil { + if err := r.verifier.AddFinalizedBlock(blockEvents); err != nil { eventsChan <- models.NewBlockEventsError(err) return } diff --git a/services/ingestion/sealing_verifier.go b/services/ingestion/sealing_verifier.go index 806ae79d5..3645820c2 100644 --- a/services/ingestion/sealing_verifier.go +++ b/services/ingestion/sealing_verifier.go @@ -21,7 +21,7 @@ import ( "github.com/onflow/flow-evm-gateway/storage/pebble" ) -var _ models.Engine = &SealingVerifier{} +var _ models.Engine = (*SealingVerifier)(nil) // SealingVerifier verifies that soft finality events received over the Access polling API match the // actually sealed results from the event stream. @@ -32,10 +32,18 @@ type SealingVerifier struct { client *requester.CrossSporkClient chain flowGo.ChainID - startHeight uint64 - eventsHash *pebble.EventsHash + startHeight uint64 + eventsHash *pebble.EventsHash + + // unsealedBlocksToVerify contains the events has for unsealed blocks by the ingestion engine + // Cache the unsealed data until the sealed data is available to verify. unsealedBlocksToVerify map[uint64]flow.Identifier - sealedBlocksToVerify map[uint64]flow.Identifier + + // sealedBlocksToVerify contains the events hash for sealed blocks return by the Access node + // Note: we also track sealed blocks since it's possible for the sealed data stream to get ahead + // of the unsealed data ingestion. In this case, we need to cache the sealed data until the unsealed + // data is available. + sealedBlocksToVerify map[uint64]flow.Identifier mu sync.Mutex } @@ -67,13 +75,14 @@ func (v *SealingVerifier) Stop() { } // SetStartHeight sets the start height for the sealing verifier. -// This is used to update the height when backfilling already sea +// This is used to update the height when backfilling to skip verification of already sealed blocks. func (v *SealingVerifier) SetStartHeight(height uint64) { v.startHeight = height } -// AddBlock adds a block to the sealing verifier for verification when the sealed data is received. -func (v *SealingVerifier) AddBlock(events flow.BlockEvents) error { +// AddFinalizedBlock adds events for an unsealed block to the sealing verifier for verification when +// the sealed data is received. +func (v *SealingVerifier) AddFinalizedBlock(events flow.BlockEvents) error { return v.onUnsealedEvents(events) } @@ -179,12 +188,17 @@ func (v *SealingVerifier) Run(ctx context.Context) error { // otherwise, the sealed events are cached for future verification. func (v *SealingVerifier) onSealedEvents(sealedEvents flow.BlockEvents) error { if len(sealedEvents.Events) == 0 { + v.mu.Lock() + defer v.mu.Unlock() + if _, ok := v.unsealedBlocksToVerify[sealedEvents.Height]; ok { + return fmt.Errorf("found unsealed events but no sealed events for height %d", sealedEvents.Height) + } return nil // skip empty blocks } sealedHash, err := CalculateHash(sealedEvents) if err != nil { - return fmt.Errorf("failed to calculate hash for sealed events: %w", err) + return fmt.Errorf("failed to calculate hash for sealed events for height %d: %w", sealedEvents.Height, err) } v.mu.Lock() From 219d7204d81df49e3e30b2d16513e08d1a9ab9cc Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Fri, 21 Feb 2025 14:29:13 -0800 Subject: [PATCH 24/62] handle verifier reconnects after AN reboot --- services/ingestion/sealing_verifier.go | 29 +++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/services/ingestion/sealing_verifier.go b/services/ingestion/sealing_verifier.go index 3645820c2..b28b40264 100644 --- a/services/ingestion/sealing_verifier.go +++ b/services/ingestion/sealing_verifier.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "sort" + "strings" "sync" "time" @@ -116,13 +117,27 @@ func (v *SealingVerifier) Run(ctx context.Context) error { nextHeight := lastVerifiedHeight + 1 connect := func(height uint64) error { var err error - eventsChan, errChan, err = v.client.SubscribeEventsByBlockHeight( - subscriptionCtx, - height, - blocksFilter(v.chain), - access.WithHeartbeatInterval(1), - ) - return err + for { + eventsChan, errChan, err = v.client.SubscribeEventsByBlockHeight( + subscriptionCtx, + height, + blocksFilter(v.chain), + access.WithHeartbeatInterval(1), + ) + + if err != nil { + // access node has not sealed the next height yet, wait and try again + // this typically happens when the AN reboots and the stream is reconnected before + // it has sealed the next block + if status.Code(err) == codes.InvalidArgument && strings.Contains(err.Error(), "higher than highest indexed height") { + time.Sleep(time.Second) + continue + } + return err + } + + return nil + } } v.logger.Info().Uint64("start_height", lastVerifiedHeight).Msg("starting verifier") From fc4ead52fbe9d616e66330c174ba967af08f86c5 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Wed, 5 Mar 2025 12:07:01 -0800 Subject: [PATCH 25/62] fix whitespace issue from resolving conflicts --- cmd/run/cmd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/run/cmd.go b/cmd/run/cmd.go index 279bf32f2..0f1ac8b96 100644 --- a/cmd/run/cmd.go +++ b/cmd/run/cmd.go @@ -289,6 +289,6 @@ func init() { Cmd.Flags().StringVar(&txStateValidation, "tx-state-validation", "tx-seal", "Sets the transaction validation mechanism. It can validate using the local state index, or wait for the outer Flow transaction to seal. Available values ('local-index' / 'tx-seal'), defaults to 'tx-seal'.") Cmd.Flags().Uint64Var(&cfg.TxRequestLimit, "tx-request-limit", 0, "Number of transaction submissions to allow per the specified interval.") Cmd.Flags().DurationVar(&cfg.TxRequestLimitDuration, "tx-request-limit-duration", time.Second*3, "Time interval upon which to enforce transaction submission rate limiting.") - Cmd.Flags().BoolVar(&experimentalSoftFinalityEnabled, "experimental-soft-finality-enabled", false, "Sets whether the gateway should use the experimental soft finality feature. WARNING: This may result in incorrect results being returned in certain circumstances. Use only if you know what you are doing.") + Cmd.Flags().BoolVar(&experimentalSoftFinalityEnabled, "experimental-soft-finality-enabled", false, "Sets whether the gateway should use the experimental soft finality feature. WARNING: This may result in incorrect results being returned in certain circumstances. Use only if you know what you are doing.") Cmd.Flags().BoolVar(&experimentalSealingVerificationEnabled, "experimental-sealing-verification-enabled", true, "Sets whether the gateway should use the experimental soft finality sealing verification feature. WARNING: This may result in indexing halts if events do not match. Use only if you know what you are doing.") } From 5d95d0767c0c403d9ab789f34b96f97e1d01fe78 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Wed, 5 Mar 2025 11:39:33 -0800 Subject: [PATCH 26/62] Check system tx if block is missing EVM block events --- go.mod | 4 +-- go.sum | 4 +++ .../ingestion/block_tracking_subscriber.go | 34 ++++++++++++++----- services/requester/cross-spork_client.go | 7 ++-- 4 files changed, 36 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index 71bee8074..4654b2c56 100644 --- a/go.mod +++ b/go.mod @@ -7,9 +7,9 @@ require ( github.com/goccy/go-json v0.10.2 github.com/hashicorp/go-multierror v1.1.1 github.com/onflow/atree v0.9.0 - github.com/onflow/cadence v1.3.1 + github.com/onflow/cadence v1.3.3 github.com/onflow/flow-go v0.38.1-0.20250218174738-2181389f9f7d - github.com/onflow/flow-go-sdk v1.3.1 + github.com/onflow/flow-go-sdk v1.3.4-0.20250305185710-21574a64879e github.com/onflow/go-ethereum v1.14.7 github.com/prometheus/client_golang v1.20.5 github.com/rs/cors v1.8.0 diff --git a/go.sum b/go.sum index 3055f70a3..657a13cf4 100644 --- a/go.sum +++ b/go.sum @@ -518,6 +518,8 @@ github.com/onflow/bridged-usdc/lib/go/contracts v1.0.0 h1:ofdfKH8KgY6qVFnlngTont github.com/onflow/bridged-usdc/lib/go/contracts v1.0.0/go.mod h1:K4/oaEhhnSuJ9q6fpq1w9WEWRGtkNskhmoyH8t+X9Mk= github.com/onflow/cadence v1.3.1 h1:bs9TFHQy8HHbwTtCtg5cLdyndWhmwq55RSwID1cb220= github.com/onflow/cadence v1.3.1/go.mod h1:6/47FljVAdl3/31tShI8JOJW0sXYZHK1PwXkE+yk0qA= +github.com/onflow/cadence v1.3.3 h1:h9uyhqfiiBahk0P7JHQ1XR5b42wOGRIn+fNRd3JppYs= +github.com/onflow/cadence v1.3.3/go.mod h1:6/47FljVAdl3/31tShI8JOJW0sXYZHK1PwXkE+yk0qA= github.com/onflow/crypto v0.25.2 h1:GjHunqVt+vPcdqhxxhAXiMIF3YiLX7gTuTR5O+VG2ns= github.com/onflow/crypto v0.25.2/go.mod h1:fY7eLqUdMKV8EGOw301unP8h7PvLVy8/6gVR++/g0BY= github.com/onflow/flow-core-contracts/lib/go/contracts v1.5.1-preview h1:W+QkNQcIbhtR+zXVROKq0bdDEnvzUfUrQrCmegmwzvc= @@ -532,6 +534,8 @@ github.com/onflow/flow-go v0.38.1-0.20250218174738-2181389f9f7d h1:XRefc4rcBjGDE github.com/onflow/flow-go v0.38.1-0.20250218174738-2181389f9f7d/go.mod h1:VS7MlNHZeDrGm9/jkuMCSvAQTLFXpzQD0BIMB8/QYB8= github.com/onflow/flow-go-sdk v1.3.1 h1:2YdTL/R1/DjMYYmyKgArTeQ93GKvLlfCeCpMVH7b8q4= github.com/onflow/flow-go-sdk v1.3.1/go.mod h1:0rMuCLShdX9F4pLBCPhlMGCFu8gu9SfiXT/Lc9qAi24= +github.com/onflow/flow-go-sdk v1.3.4-0.20250305185710-21574a64879e h1:hV13Xhkxxaeq+xfc0Kn6l9VB1dofEfQq8xpqGchp/24= +github.com/onflow/flow-go-sdk v1.3.4-0.20250305185710-21574a64879e/go.mod h1:tSLvYIac9DlmUEqKHSHbVRyv4mSB0va4AuiV3XB9ENc= github.com/onflow/flow-nft/lib/go/contracts v1.2.3 h1:4ju20g1xgDKWBT63rOj5f/Sa4Lc+naCSWT4p31x9yQk= github.com/onflow/flow-nft/lib/go/contracts v1.2.3/go.mod h1:eZ9VMMNfCq0ho6kV25xJn1kXeCfxnkhj3MwF3ed08gY= github.com/onflow/flow-nft/lib/go/templates v1.2.1 h1:SAALMZPDw9Eb9p5kSLnmnFxjyig1MLiT4JUlLp0/bSE= diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 077fe7ad8..5b23f9235 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -2,6 +2,7 @@ package ingestion import ( "context" + "errors" "fmt" "strings" "time" @@ -131,7 +132,7 @@ func (r *RPCBlockTrackingSubscriber) Subscribe(ctx context.Context) <-chan model func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint64) <-chan models.BlockEvents { eventsChan := make(chan models.BlockEvents) - var blockHeadersChan <-chan flow.BlockHeader + var blockHeadersChan <-chan *flow.BlockHeader var errChan <-chan error lastReceivedHeight := height @@ -256,7 +257,7 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 func (r *RPCBlockTrackingSubscriber) evmEventsForBlock( ctx context.Context, - blockHeader flow.BlockHeader, + blockHeader *flow.BlockHeader, ) (flow.BlockEvents, error) { eventTypes := blocksFilter(r.chain).EventTypes @@ -289,7 +290,7 @@ func (r *RPCBlockTrackingSubscriber) evmEventsForBlock( func (r *RPCBlockTrackingSubscriber) getEventsByType( ctx context.Context, - blockHeader flow.BlockHeader, + blockHeader *flow.BlockHeader, eventType string, ) (flow.BlockEvents, error) { var evts []flow.BlockEvents @@ -323,13 +324,30 @@ func (r *RPCBlockTrackingSubscriber) getEventsByType( } // The `EVM.BlockExecuted` event should be present for every Flow block. - if strings.Contains(eventType, string(events.EventTypeBlockExecuted)) { - if len(evts[0].Events) != 1 { - return flow.BlockEvents{}, fmt.Errorf( - "received unexpected number of EVM events in block: got: %d, expected: 1", - len(evts[0].Events), + if strings.Contains(eventType, string(events.EventTypeBlockExecuted)) && len(evts[0].Events) != 1 { + missingEventsErr := fmt.Errorf( + "received unexpected number of EVM events in block: got: %d, expected: 1", + len(evts[0].Events), + ) + + // EVM Blocks events are emitted from the system transaction. if the system transaction fails, + // there will be no EVM block events. + // Verify that the system transaction did fail, otherwise return an error + result, err := r.client.GetSystemTransactionResult(ctx, blockHeader.ID) + if err != nil { + return flow.BlockEvents{}, errors.Join( + missingEventsErr, + fmt.Errorf("failed to lookup system transaction result: %w", err), ) } + + // system transaction succeeded, return an error since this is an unexpected error case + if result.Error == nil { + return flow.BlockEvents{}, missingEventsErr + } + + // system transaction failed, there will not be any EVM block events + return evts[0], nil } return evts[0], nil diff --git a/services/requester/cross-spork_client.go b/services/requester/cross-spork_client.go index a659a2d58..6e8642bf9 100644 --- a/services/requester/cross-spork_client.go +++ b/services/requester/cross-spork_client.go @@ -6,7 +6,6 @@ import ( "github.com/hashicorp/go-multierror" "github.com/onflow/cadence" - errs "github.com/onflow/flow-evm-gateway/models/errors" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/access" "github.com/onflow/flow-go-sdk/access/grpc" @@ -14,6 +13,8 @@ import ( "github.com/rs/zerolog" "go.uber.org/ratelimit" "golang.org/x/exp/slices" + + errs "github.com/onflow/flow-evm-gateway/models/errors" ) type sporkClient struct { @@ -253,7 +254,7 @@ func (c *CrossSporkClient) GetEventsForHeightRange( func (c *CrossSporkClient) GetEventsForBlockHeader( ctx context.Context, eventType string, - blockHeader flow.BlockHeader, + blockHeader *flow.BlockHeader, ) ([]flow.BlockEvents, error) { client, err := c.getClientForHeight(blockHeader.Height) if err != nil { @@ -266,7 +267,7 @@ func (c *CrossSporkClient) SubscribeBlockHeadersFromStartHeight( ctx context.Context, startHeight uint64, blockStatus flow.BlockStatus, -) (<-chan flow.BlockHeader, <-chan error, error) { +) (<-chan *flow.BlockHeader, <-chan error, error) { client, err := c.getClientForHeight(startHeight) if err != nil { return nil, nil, err From 4b59bcb4fc40a6ced89574129856e867c1d5613e Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Wed, 5 Mar 2025 12:01:23 -0800 Subject: [PATCH 27/62] update from review feedback --- services/ingestion/block_tracking_subscriber.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 5b23f9235..af0a4f20d 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -322,12 +322,13 @@ func (r *RPCBlockTrackingSubscriber) getEventsByType( len(evts), ) } + event := evts[0] // The `EVM.BlockExecuted` event should be present for every Flow block. - if strings.Contains(eventType, string(events.EventTypeBlockExecuted)) && len(evts[0].Events) != 1 { + if strings.Contains(eventType, string(events.EventTypeBlockExecuted)) && len(event.Events) != 1 { missingEventsErr := fmt.Errorf( "received unexpected number of EVM events in block: got: %d, expected: 1", - len(evts[0].Events), + len(event.Events), ) // EVM Blocks events are emitted from the system transaction. if the system transaction fails, @@ -347,8 +348,8 @@ func (r *RPCBlockTrackingSubscriber) getEventsByType( } // system transaction failed, there will not be any EVM block events - return evts[0], nil + return event, nil } - return evts[0], nil + return event, nil } From d736faff77dd23a760fa8f1dfcb459863eb12db0 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Wed, 5 Mar 2025 12:09:50 -0800 Subject: [PATCH 28/62] tidy --- go.sum | 4 ---- 1 file changed, 4 deletions(-) diff --git a/go.sum b/go.sum index 657a13cf4..45d87ce44 100644 --- a/go.sum +++ b/go.sum @@ -516,8 +516,6 @@ github.com/onflow/atree v0.9.0 h1:M+Z/UPwzv0/Yy7ChI5T1ZIHD3YN1cs/hxGEs/HWhzaY= github.com/onflow/atree v0.9.0/go.mod h1:FT6udJF9Q7VQTu3wknDhFX+VV4D44ZGdqtTAE5iztck= github.com/onflow/bridged-usdc/lib/go/contracts v1.0.0 h1:ofdfKH8KgY6qVFnlngTontds/IBERANeWl0PBPCtPOA= github.com/onflow/bridged-usdc/lib/go/contracts v1.0.0/go.mod h1:K4/oaEhhnSuJ9q6fpq1w9WEWRGtkNskhmoyH8t+X9Mk= -github.com/onflow/cadence v1.3.1 h1:bs9TFHQy8HHbwTtCtg5cLdyndWhmwq55RSwID1cb220= -github.com/onflow/cadence v1.3.1/go.mod h1:6/47FljVAdl3/31tShI8JOJW0sXYZHK1PwXkE+yk0qA= github.com/onflow/cadence v1.3.3 h1:h9uyhqfiiBahk0P7JHQ1XR5b42wOGRIn+fNRd3JppYs= github.com/onflow/cadence v1.3.3/go.mod h1:6/47FljVAdl3/31tShI8JOJW0sXYZHK1PwXkE+yk0qA= github.com/onflow/crypto v0.25.2 h1:GjHunqVt+vPcdqhxxhAXiMIF3YiLX7gTuTR5O+VG2ns= @@ -532,8 +530,6 @@ github.com/onflow/flow-ft/lib/go/templates v1.0.1 h1:FDYKAiGowABtoMNusLuRCILIZDt github.com/onflow/flow-ft/lib/go/templates v1.0.1/go.mod h1:uQ8XFqmMK2jxyBSVrmyuwdWjTEb+6zGjRYotfDJ5pAE= github.com/onflow/flow-go v0.38.1-0.20250218174738-2181389f9f7d h1:XRefc4rcBjGDEqsj3OB6XjSjSeYwMtysl7jmaLYpg+s= github.com/onflow/flow-go v0.38.1-0.20250218174738-2181389f9f7d/go.mod h1:VS7MlNHZeDrGm9/jkuMCSvAQTLFXpzQD0BIMB8/QYB8= -github.com/onflow/flow-go-sdk v1.3.1 h1:2YdTL/R1/DjMYYmyKgArTeQ93GKvLlfCeCpMVH7b8q4= -github.com/onflow/flow-go-sdk v1.3.1/go.mod h1:0rMuCLShdX9F4pLBCPhlMGCFu8gu9SfiXT/Lc9qAi24= github.com/onflow/flow-go-sdk v1.3.4-0.20250305185710-21574a64879e h1:hV13Xhkxxaeq+xfc0Kn6l9VB1dofEfQq8xpqGchp/24= github.com/onflow/flow-go-sdk v1.3.4-0.20250305185710-21574a64879e/go.mod h1:tSLvYIac9DlmUEqKHSHbVRyv4mSB0va4AuiV3XB9ENc= github.com/onflow/flow-nft/lib/go/contracts v1.2.3 h1:4ju20g1xgDKWBT63rOj5f/Sa4Lc+naCSWT4p31x9yQk= From 70674b9353d2334ae6bb6f2f5ff691e5b359c7b9 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Wed, 5 Mar 2025 14:25:24 -0800 Subject: [PATCH 29/62] tidy tests --- Makefile | 1 - tests/go.mod | 4 ++-- tests/go.sum | 8 ++++---- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index c1060c1f8..5ca1c0888 100644 --- a/Makefile +++ b/Makefile @@ -78,7 +78,6 @@ e2e-test: .PHONY: check-tidy check-tidy: go mod tidy - git diff --exit-code cd tests go mod tidy git diff --exit-code diff --git a/tests/go.mod b/tests/go.mod index e6962b164..465f0c33f 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -4,12 +4,12 @@ go 1.23 require ( github.com/goccy/go-json v0.10.2 - github.com/onflow/cadence v1.3.1 + github.com/onflow/cadence v1.3.3 github.com/onflow/crypto v0.25.2 github.com/onflow/flow-emulator v1.2.1-0.20250219181005-4205d790a414 github.com/onflow/flow-evm-gateway v0.0.0-20240201154855-4d4d3d3f19c7 github.com/onflow/flow-go v0.38.1-0.20250218174738-2181389f9f7d - github.com/onflow/flow-go-sdk v1.3.1 + github.com/onflow/flow-go-sdk v1.3.4-0.20250305185710-21574a64879e github.com/onflow/go-ethereum v1.14.7 github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.10.0 diff --git a/tests/go.sum b/tests/go.sum index ae6d4890d..153650e1e 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -790,8 +790,8 @@ github.com/onflow/atree v0.9.0 h1:M+Z/UPwzv0/Yy7ChI5T1ZIHD3YN1cs/hxGEs/HWhzaY= github.com/onflow/atree v0.9.0/go.mod h1:FT6udJF9Q7VQTu3wknDhFX+VV4D44ZGdqtTAE5iztck= github.com/onflow/bridged-usdc/lib/go/contracts v1.0.0 h1:ofdfKH8KgY6qVFnlngTontds/IBERANeWl0PBPCtPOA= github.com/onflow/bridged-usdc/lib/go/contracts v1.0.0/go.mod h1:K4/oaEhhnSuJ9q6fpq1w9WEWRGtkNskhmoyH8t+X9Mk= -github.com/onflow/cadence v1.3.1 h1:bs9TFHQy8HHbwTtCtg5cLdyndWhmwq55RSwID1cb220= -github.com/onflow/cadence v1.3.1/go.mod h1:6/47FljVAdl3/31tShI8JOJW0sXYZHK1PwXkE+yk0qA= +github.com/onflow/cadence v1.3.3 h1:h9uyhqfiiBahk0P7JHQ1XR5b42wOGRIn+fNRd3JppYs= +github.com/onflow/cadence v1.3.3/go.mod h1:6/47FljVAdl3/31tShI8JOJW0sXYZHK1PwXkE+yk0qA= github.com/onflow/crypto v0.25.2 h1:GjHunqVt+vPcdqhxxhAXiMIF3YiLX7gTuTR5O+VG2ns= github.com/onflow/crypto v0.25.2/go.mod h1:fY7eLqUdMKV8EGOw301unP8h7PvLVy8/6gVR++/g0BY= github.com/onflow/flow-core-contracts/lib/go/contracts v1.5.1-preview h1:W+QkNQcIbhtR+zXVROKq0bdDEnvzUfUrQrCmegmwzvc= @@ -806,8 +806,8 @@ github.com/onflow/flow-ft/lib/go/templates v1.0.1 h1:FDYKAiGowABtoMNusLuRCILIZDt github.com/onflow/flow-ft/lib/go/templates v1.0.1/go.mod h1:uQ8XFqmMK2jxyBSVrmyuwdWjTEb+6zGjRYotfDJ5pAE= github.com/onflow/flow-go v0.38.1-0.20250218174738-2181389f9f7d h1:XRefc4rcBjGDEqsj3OB6XjSjSeYwMtysl7jmaLYpg+s= github.com/onflow/flow-go v0.38.1-0.20250218174738-2181389f9f7d/go.mod h1:VS7MlNHZeDrGm9/jkuMCSvAQTLFXpzQD0BIMB8/QYB8= -github.com/onflow/flow-go-sdk v1.3.1 h1:2YdTL/R1/DjMYYmyKgArTeQ93GKvLlfCeCpMVH7b8q4= -github.com/onflow/flow-go-sdk v1.3.1/go.mod h1:0rMuCLShdX9F4pLBCPhlMGCFu8gu9SfiXT/Lc9qAi24= +github.com/onflow/flow-go-sdk v1.3.4-0.20250305185710-21574a64879e h1:hV13Xhkxxaeq+xfc0Kn6l9VB1dofEfQq8xpqGchp/24= +github.com/onflow/flow-go-sdk v1.3.4-0.20250305185710-21574a64879e/go.mod h1:tSLvYIac9DlmUEqKHSHbVRyv4mSB0va4AuiV3XB9ENc= github.com/onflow/flow-nft/lib/go/contracts v1.2.3 h1:4ju20g1xgDKWBT63rOj5f/Sa4Lc+naCSWT4p31x9yQk= github.com/onflow/flow-nft/lib/go/contracts v1.2.3/go.mod h1:eZ9VMMNfCq0ho6kV25xJn1kXeCfxnkhj3MwF3ed08gY= github.com/onflow/flow-nft/lib/go/templates v1.2.1 h1:SAALMZPDw9Eb9p5kSLnmnFxjyig1MLiT4JUlLp0/bSE= From ace558d10ec4111ef9d13f9d155002b9877dee59 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Fri, 7 Mar 2025 13:22:09 -0800 Subject: [PATCH 30/62] Updates for new keystore --- services/ingestion/block_tracking_subscriber.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index af0a4f20d..1653d17e1 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -18,6 +18,7 @@ import ( "github.com/onflow/flow-evm-gateway/models" errs "github.com/onflow/flow-evm-gateway/models/errors" "github.com/onflow/flow-evm-gateway/services/requester" + "github.com/onflow/flow-evm-gateway/services/requester/keystore" ) var _ EventSubscriber = &RPCBlockTrackingSubscriber{} @@ -45,7 +46,7 @@ func NewRPCBlockTrackingSubscriber( logger zerolog.Logger, client *requester.CrossSporkClient, chainID flowGo.ChainID, - keyLock requester.KeyLock, + keyLock keystore.KeyLock, startHeight uint64, verifier *SealingVerifier, ) *RPCBlockTrackingSubscriber { @@ -206,9 +207,9 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 } for _, evt := range blockEvents.Events { - r.keyLock.UnlockKey(evt.TransactionID) + r.keyLock.NotifyTransaction(evt.TransactionID) } - r.keyLock.Notify(blockHeader.Height) + r.keyLock.NotifyBlock(blockHeader.Height) lastReceivedHeight = blockHeader.Height eventsChan <- evmEvents From d728f1433075fc759e04d59c53d3e7a0f1d254c5 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Fri, 7 Mar 2025 13:29:03 -0800 Subject: [PATCH 31/62] add block height to error --- services/ingestion/block_tracking_subscriber.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 1653d17e1..fc9ca008e 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -319,7 +319,8 @@ func (r *RPCBlockTrackingSubscriber) getEventsByType( if len(evts) != 1 { // this shouldn't happen and probably indicates a bug on the Access node. return flow.BlockEvents{}, fmt.Errorf( - "received unexpected number of block events: got: %d, expected: 1", + "received unexpected number of block events for cadence block %d: got: %d, expected: 1", + blockHeader.Height, len(evts), ) } From 62f691605f7cdb96ae3e3540d403c065c9470c35 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Fri, 7 Mar 2025 14:00:02 -0800 Subject: [PATCH 32/62] updates to handle system tx failure correctly --- .../ingestion/block_tracking_subscriber.go | 52 +++++++++++++------ 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index fc9ca008e..9f0b9d407 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -21,6 +21,8 @@ import ( "github.com/onflow/flow-evm-gateway/services/requester/keystore" ) +var ErrSystemTransactionFailed = errors.New("system transaction failed") + var _ EventSubscriber = &RPCBlockTrackingSubscriber{} // RPCBlockTrackingSubscriber subscribes to new EVM block events for unsealed finalized blocks. @@ -188,6 +190,12 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 return } + // this means that the system transaction failed AND there were no EVM transactions + // executed in the block. In this case, we can skip the block + if len(blockEvents.Events) == 0 { + continue + } + if r.verifier != nil { // submit the block events to the verifier for future sealing verification if err := r.verifier.AddFinalizedBlock(blockEvents); err != nil { @@ -264,23 +272,38 @@ func (r *RPCBlockTrackingSubscriber) evmEventsForBlock( // evm Block events blockEvents, err := r.getEventsByType(ctx, blockHeader, eventTypes[0]) - if err != nil { - return flow.BlockEvents{}, err - } - - payload, err := events.DecodeBlockEventPayload(blockEvents.Events[0].Value) - if err != nil { - return flow.BlockEvents{}, err - } + if err == nil { + payload, err := events.DecodeBlockEventPayload(blockEvents.Events[0].Value) + if err != nil { + return flow.BlockEvents{}, fmt.Errorf("failed to decode block event payload: %w", err) + } - if payload.TransactionHashRoot == types.EmptyTxsHash { - return blockEvents, nil + if payload.TransactionHashRoot == types.EmptyTxsHash { + return blockEvents, nil + } + } else if errors.Is(err, ErrSystemTransactionFailed) { + r.logger.Warn(). + Uint64("cadence_height", blockHeader.Height). + Str("cadence_block_id", blockHeader.ID.String()). + Msg("no EVM block events: system transaction failed") + + // continue to check for EVM Transaction events since there may still be tx executed events + // even if the system transaction failed + blockEvents = flow.BlockEvents{ + BlockID: blockHeader.ID, + Height: blockHeader.Height, + BlockTimestamp: blockHeader.Timestamp, + } + } else { + return flow.BlockEvents{}, fmt.Errorf("failed to get EVM block event for cadence block %d: %w", + blockHeader.Height, err) } // evm TX events txEvents, err := r.getEventsByType(ctx, blockHeader, eventTypes[1]) if err != nil { - return flow.BlockEvents{}, err + return flow.BlockEvents{}, fmt.Errorf("failed to get EVM transaction events for cadence block %d: %w", + blockHeader.Height, err) } // combine block and tx events to be processed together @@ -311,7 +334,7 @@ func (r *RPCBlockTrackingSubscriber) getEventsByType( continue } - return flow.BlockEvents{}, err + return flow.BlockEvents{}, fmt.Errorf("failed to get events from access node: %w", err) } break } @@ -319,8 +342,7 @@ func (r *RPCBlockTrackingSubscriber) getEventsByType( if len(evts) != 1 { // this shouldn't happen and probably indicates a bug on the Access node. return flow.BlockEvents{}, fmt.Errorf( - "received unexpected number of block events for cadence block %d: got: %d, expected: 1", - blockHeader.Height, + "received unexpected number of BlockEvents from access node: got: %d, expected: 1", len(evts), ) } @@ -350,7 +372,7 @@ func (r *RPCBlockTrackingSubscriber) getEventsByType( } // system transaction failed, there will not be any EVM block events - return event, nil + return flow.BlockEvents{}, ErrSystemTransactionFailed } return event, nil From a4a807fed94396a379d29e65aa2ad3cc9127cc18 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Fri, 7 Mar 2025 14:37:50 -0800 Subject: [PATCH 33/62] updates for verifying these blocks --- bootstrap/bootstrap.go | 12 +++++++++++- services/ingestion/block_tracking_subscriber.go | 16 +++++++++------- services/ingestion/sealing_verifier.go | 9 +-------- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/bootstrap/bootstrap.go b/bootstrap/bootstrap.go index 1dea2466d..9267efe8b 100644 --- a/bootstrap/bootstrap.go +++ b/bootstrap/bootstrap.go @@ -602,7 +602,17 @@ func setupStorage( if config.ForceStartCadenceHeight != 0 { logger.Warn().Uint64("height", config.ForceStartCadenceHeight).Msg("force setting starting Cadence height!!!") if err := blocks.SetLatestCadenceHeight(config.ForceStartCadenceHeight, batch); err != nil { - return nil, nil, err + return nil, nil, fmt.Errorf("failed to set latest cadence height: %w", err) + } + + verifiedHeight, err := eventsHash.ProcessedSealedHeight() + if err != nil && !errors.Is(err, errs.ErrStorageNotInitialized) { + return nil, nil, fmt.Errorf("failed to get latest verified sealed height: %w", err) + } + if verifiedHeight > config.ForceStartCadenceHeight { + if err := eventsHash.SetProcessedSealedHeight(config.ForceStartCadenceHeight); err != nil { + return nil, nil, fmt.Errorf("failed to set latest verified sealed height: %w", err) + } } } diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 9f0b9d407..8f215bd5e 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -109,7 +109,7 @@ func (r *RPCBlockTrackingSubscriber) Subscribe(ctx context.Context) <-chan model // start the verifier after backfilling since backfilled data is already sealed if r.verifier != nil { go func() { - r.verifier.SetStartHeight(r.height) + // r.verifier.SetStartHeight(r.height) if err := r.verifier.Run(ctx); err != nil { r.logger.Fatal().Err(err).Msg("failure running sealing verifier") return @@ -190,12 +190,6 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 return } - // this means that the system transaction failed AND there were no EVM transactions - // executed in the block. In this case, we can skip the block - if len(blockEvents.Events) == 0 { - continue - } - if r.verifier != nil { // submit the block events to the verifier for future sealing verification if err := r.verifier.AddFinalizedBlock(blockEvents); err != nil { @@ -204,6 +198,14 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 } } + // this means that the system transaction failed AND there were no EVM transactions + // executed in the block. In this case, we can skip the block + // Note: put this after the verify step, so we can verify that there were no EVM + // blocks in the sealed data as well + if len(blockEvents.Events) == 0 { + continue + } + evmEvents := models.NewSingleBlockEvents(blockEvents) // if events contain an error, or we are in a recovery mode if evmEvents.Err != nil || r.recovery { diff --git a/services/ingestion/sealing_verifier.go b/services/ingestion/sealing_verifier.go index b28b40264..78214d6e5 100644 --- a/services/ingestion/sealing_verifier.go +++ b/services/ingestion/sealing_verifier.go @@ -202,14 +202,7 @@ func (v *SealingVerifier) Run(ctx context.Context) error { // if unsealed events are found for the same height, the events are verified. // otherwise, the sealed events are cached for future verification. func (v *SealingVerifier) onSealedEvents(sealedEvents flow.BlockEvents) error { - if len(sealedEvents.Events) == 0 { - v.mu.Lock() - defer v.mu.Unlock() - if _, ok := v.unsealedBlocksToVerify[sealedEvents.Height]; ok { - return fmt.Errorf("found unsealed events but no sealed events for height %d", sealedEvents.Height) - } - return nil // skip empty blocks - } + // Note: there should be an unsealed event entry, even for blocks with no transactions sealedHash, err := CalculateHash(sealedEvents) if err != nil { From e10fbf7e590e99875821ed79a89fa0cda1495ec6 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Fri, 7 Mar 2025 14:48:23 -0800 Subject: [PATCH 34/62] add logging --- services/ingestion/sealing_verifier.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/services/ingestion/sealing_verifier.go b/services/ingestion/sealing_verifier.go index 78214d6e5..e696789b3 100644 --- a/services/ingestion/sealing_verifier.go +++ b/services/ingestion/sealing_verifier.go @@ -230,7 +230,10 @@ func (v *SealingVerifier) onSealedEvents(sealedEvents flow.BlockEvents) error { return fmt.Errorf("failed to verify block events for %d: %w", sealedEvents.Height, err) } - v.logger.Debug().Uint64("height", sealedEvents.Height).Msg("verified sealed height") + v.logger.Info(). + Uint64("height", sealedEvents.Height). + Int("num_events", len(sealedEvents.Events)). + Msg("verified sealed height") return nil } @@ -266,7 +269,10 @@ func (v *SealingVerifier) onUnsealedEvents(unsealedEvents flow.BlockEvents) erro return fmt.Errorf("failed to verify block events for %d: %w", unsealedEvents.Height, err) } - v.logger.Debug().Uint64("height", unsealedEvents.Height).Msg("verified unsealed height") + v.logger.Info(). + Uint64("height", unsealedEvents.Height). + Int("num_events", len(unsealedEvents.Events)). + Msg("verified unsealed height") return nil } From 8e04341b87b3e6967d6f8315ade4c618152da3ef Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Fri, 7 Mar 2025 15:24:34 -0800 Subject: [PATCH 35/62] make verifier wait for reexecuting data when force-start-height is used --- services/ingestion/sealing_verifier.go | 28 ++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/services/ingestion/sealing_verifier.go b/services/ingestion/sealing_verifier.go index e696789b3..4e7de7abc 100644 --- a/services/ingestion/sealing_verifier.go +++ b/services/ingestion/sealing_verifier.go @@ -13,6 +13,7 @@ import ( "github.com/onflow/flow-go-sdk/access" flowGo "github.com/onflow/flow-go/model/flow" "github.com/rs/zerolog" + "go.uber.org/atomic" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -46,6 +47,8 @@ type SealingVerifier struct { // data is available. sealedBlocksToVerify map[uint64]flow.Identifier + lastUnsealedHeight *atomic.Uint64 + mu sync.Mutex } @@ -66,6 +69,7 @@ func NewSealingVerifier( eventsHash: eventsHash, unsealedBlocksToVerify: make(map[uint64]flow.Identifier), sealedBlocksToVerify: make(map[uint64]flow.Identifier), + lastUnsealedHeight: atomic.NewUint64(startHeight), } } @@ -140,7 +144,7 @@ func (v *SealingVerifier) Run(ctx context.Context) error { } } - v.logger.Info().Uint64("start_height", lastVerifiedHeight).Msg("starting verifier") + v.logger.Info().Uint64("start_height", nextHeight).Msg("starting verifier") if err := connect(nextHeight); err != nil { return fmt.Errorf("failed to subscribe for finalized block events on height: %d, with: %w", nextHeight, err) @@ -213,12 +217,17 @@ func (v *SealingVerifier) onSealedEvents(sealedEvents flow.BlockEvents) error { defer v.mu.Unlock() unsealedHash, err := v.getUnsealedEventsHash(sealedEvents.Height) + + // cache the sealed hash if + // 1. we haven't processed the unsealed data for this block yet + // 2. we have the data, but the state was rolled back to a previous height. In this case, wait + // until we've reprocessed data for the height. + if errors.Is(err, errs.ErrEntityNotFound) || sealedEvents.Height > v.lastUnsealedHeight.Load() { + // we haven't processed the unsealed data for this block yet, cache the sealed hash + v.sealedBlocksToVerify[sealedEvents.Height] = sealedHash + return nil + } if err != nil { - if errors.Is(err, errs.ErrEntityNotFound) { - // we haven't processed the unsealed data for this block yet, cache the sealed hash - v.sealedBlocksToVerify[sealedEvents.Height] = sealedHash - return nil - } return fmt.Errorf("no unsealed events found for height %d: %w", sealedEvents.Height, err) } @@ -255,6 +264,13 @@ func (v *SealingVerifier) onUnsealedEvents(unsealedEvents flow.BlockEvents) erro return fmt.Errorf("failed to store events hash for block %d: %w", unsealedEvents.Height, err) } + // update the last unsealed height after successfully storing the hash + if unsealedEvents.Height > 0 && !v.lastUnsealedHeight.CompareAndSwap(unsealedEvents.Height-1, unsealedEvents.Height) { + // note: this conditional skips updating the lastUnsealedHeight if the height is 0. this is + // desired since it will be the last height when we process block 1. + return fmt.Errorf("received unsealed events out of order: expected %d, got %d", v.lastUnsealedHeight.Load(), unsealedEvents.Height) + } + sealedHash, ok := v.sealedBlocksToVerify[unsealedEvents.Height] if !ok { v.unsealedBlocksToVerify[unsealedEvents.Height] = unsealedHash From 1b20a6ba680312a68d49026b1de6e85088452321 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Fri, 7 Mar 2025 15:32:23 -0800 Subject: [PATCH 36/62] use correct unsealed start height --- services/ingestion/sealing_verifier.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/services/ingestion/sealing_verifier.go b/services/ingestion/sealing_verifier.go index 4e7de7abc..c4d88392c 100644 --- a/services/ingestion/sealing_verifier.go +++ b/services/ingestion/sealing_verifier.go @@ -60,6 +60,10 @@ func NewSealingVerifier( eventsHash *pebble.EventsHash, startHeight uint64, ) *SealingVerifier { + lastProcessedUnsealedHeight := startHeight + if lastProcessedUnsealedHeight > 0 { + lastProcessedUnsealedHeight-- + } return &SealingVerifier{ EngineStatus: models.NewEngineStatus(), logger: logger.With().Str("component", "sealing_verifier").Logger(), @@ -69,7 +73,7 @@ func NewSealingVerifier( eventsHash: eventsHash, unsealedBlocksToVerify: make(map[uint64]flow.Identifier), sealedBlocksToVerify: make(map[uint64]flow.Identifier), - lastUnsealedHeight: atomic.NewUint64(startHeight), + lastUnsealedHeight: atomic.NewUint64(lastProcessedUnsealedHeight), } } From 7226a6b95d54ac2121f9cf22a307c62a52291d81 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Fri, 7 Mar 2025 15:57:18 -0800 Subject: [PATCH 37/62] also check sealed heights --- services/ingestion/sealing_verifier.go | 32 ++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/services/ingestion/sealing_verifier.go b/services/ingestion/sealing_verifier.go index c4d88392c..c11536ff4 100644 --- a/services/ingestion/sealing_verifier.go +++ b/services/ingestion/sealing_verifier.go @@ -48,6 +48,7 @@ type SealingVerifier struct { sealedBlocksToVerify map[uint64]flow.Identifier lastUnsealedHeight *atomic.Uint64 + lastSealedHeight *atomic.Uint64 mu sync.Mutex } @@ -74,6 +75,7 @@ func NewSealingVerifier( unsealedBlocksToVerify: make(map[uint64]flow.Identifier), sealedBlocksToVerify: make(map[uint64]flow.Identifier), lastUnsealedHeight: atomic.NewUint64(lastProcessedUnsealedHeight), + lastSealedHeight: atomic.NewUint64(0), } } @@ -115,6 +117,7 @@ func (v *SealingVerifier) Run(ctx context.Context) error { return fmt.Errorf("failed to initialize processed sealed height: %w", err) } } + v.lastSealedHeight.Store(lastVerifiedHeight) var eventsChan <-chan flow.BlockEvents var errChan <-chan error @@ -148,7 +151,10 @@ func (v *SealingVerifier) Run(ctx context.Context) error { } } - v.logger.Info().Uint64("start_height", nextHeight).Msg("starting verifier") + v.logger.Info(). + Uint64("start_sealed_height", nextHeight). + Uint64("start_unsealed_height", v.lastUnsealedHeight.Load()). + Msg("starting verifier") if err := connect(nextHeight); err != nil { return fmt.Errorf("failed to subscribe for finalized block events on height: %d, with: %w", nextHeight, err) @@ -212,6 +218,13 @@ func (v *SealingVerifier) Run(ctx context.Context) error { func (v *SealingVerifier) onSealedEvents(sealedEvents flow.BlockEvents) error { // Note: there should be an unsealed event entry, even for blocks with no transactions + // update the last sealed height after successfully storing the hash + if sealedEvents.Height > 0 && !v.lastSealedHeight.CompareAndSwap(sealedEvents.Height-1, sealedEvents.Height) { + // note: this conditional skips updating the lastSealedHeight if the height is 0. this is + // desired since it will be the last height when we process block 1. + return fmt.Errorf("received sealed events out of order: expected %d, got %d", v.lastSealedHeight.Load()+1, sealedEvents.Height) + } + sealedHash, err := CalculateHash(sealedEvents) if err != nil { return fmt.Errorf("failed to calculate hash for sealed events for height %d: %w", sealedEvents.Height, err) @@ -229,6 +242,12 @@ func (v *SealingVerifier) onSealedEvents(sealedEvents flow.BlockEvents) error { if errors.Is(err, errs.ErrEntityNotFound) || sealedEvents.Height > v.lastUnsealedHeight.Load() { // we haven't processed the unsealed data for this block yet, cache the sealed hash v.sealedBlocksToVerify[sealedEvents.Height] = sealedHash + + v.logger.Info(). + Uint64("height", sealedEvents.Height). + Int("num_events", len(sealedEvents.Events)). + Msg("no unsealed data available for verification. caching sealed data") + return nil } if err != nil { @@ -272,11 +291,19 @@ func (v *SealingVerifier) onUnsealedEvents(unsealedEvents flow.BlockEvents) erro if unsealedEvents.Height > 0 && !v.lastUnsealedHeight.CompareAndSwap(unsealedEvents.Height-1, unsealedEvents.Height) { // note: this conditional skips updating the lastUnsealedHeight if the height is 0. this is // desired since it will be the last height when we process block 1. - return fmt.Errorf("received unsealed events out of order: expected %d, got %d", v.lastUnsealedHeight.Load(), unsealedEvents.Height) + return fmt.Errorf("received unsealed events out of order: expected %d, got %d", v.lastUnsealedHeight.Load()+1, unsealedEvents.Height) } + // loop though all cached sealed events and verify them + // this catches the case where + // for unsealedHeight := unsealedEvents.Height; unsealedHeight <= v.lastSealedHeight.Load(); unsealedHeight++ { sealedHash, ok := v.sealedBlocksToVerify[unsealedEvents.Height] if !ok { + v.logger.Info(). + Uint64("height", unsealedEvents.Height). + Int("num_events", len(unsealedEvents.Events)). + Msg("no sealed data available for verification. caching unsealed data") + v.unsealedBlocksToVerify[unsealedEvents.Height] = unsealedHash return nil } @@ -293,6 +320,7 @@ func (v *SealingVerifier) onUnsealedEvents(unsealedEvents flow.BlockEvents) erro Uint64("height", unsealedEvents.Height). Int("num_events", len(unsealedEvents.Events)). Msg("verified unsealed height") + // } return nil } From 05b38f2764272034c17869b05a5002363d247d34 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Fri, 7 Mar 2025 20:14:14 -0800 Subject: [PATCH 38/62] update to fixed version of sdk --- go.mod | 2 +- go.sum | 4 ++-- services/ingestion/sealing_verifier.go | 24 +++++++++++------------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/go.mod b/go.mod index 8847a8395..7caaf7c19 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/onflow/atree v0.9.0 github.com/onflow/cadence v1.3.3 github.com/onflow/flow-go v0.38.1-0.20250218174738-2181389f9f7d - github.com/onflow/flow-go-sdk v1.3.4-0.20250305185710-21574a64879e + github.com/onflow/flow-go-sdk v1.3.4-0.20250308010136-4653c344a477 github.com/onflow/go-ethereum v1.14.7 github.com/prometheus/client_golang v1.20.5 github.com/rs/cors v1.8.0 diff --git a/go.sum b/go.sum index 2376b814f..8c978e23c 100644 --- a/go.sum +++ b/go.sum @@ -583,8 +583,8 @@ github.com/onflow/flow-ft/lib/go/templates v1.0.1 h1:FDYKAiGowABtoMNusLuRCILIZDt github.com/onflow/flow-ft/lib/go/templates v1.0.1/go.mod h1:uQ8XFqmMK2jxyBSVrmyuwdWjTEb+6zGjRYotfDJ5pAE= github.com/onflow/flow-go v0.38.1-0.20250218174738-2181389f9f7d h1:XRefc4rcBjGDEqsj3OB6XjSjSeYwMtysl7jmaLYpg+s= github.com/onflow/flow-go v0.38.1-0.20250218174738-2181389f9f7d/go.mod h1:VS7MlNHZeDrGm9/jkuMCSvAQTLFXpzQD0BIMB8/QYB8= -github.com/onflow/flow-go-sdk v1.3.4-0.20250305185710-21574a64879e h1:hV13Xhkxxaeq+xfc0Kn6l9VB1dofEfQq8xpqGchp/24= -github.com/onflow/flow-go-sdk v1.3.4-0.20250305185710-21574a64879e/go.mod h1:tSLvYIac9DlmUEqKHSHbVRyv4mSB0va4AuiV3XB9ENc= +github.com/onflow/flow-go-sdk v1.3.4-0.20250308010136-4653c344a477 h1:Gf+GB4Dj2EFwj0bSuyveSMIoE19zPDufi/Jm1ck1IoA= +github.com/onflow/flow-go-sdk v1.3.4-0.20250308010136-4653c344a477/go.mod h1:tSLvYIac9DlmUEqKHSHbVRyv4mSB0va4AuiV3XB9ENc= github.com/onflow/flow-nft/lib/go/contracts v1.2.3 h1:4ju20g1xgDKWBT63rOj5f/Sa4Lc+naCSWT4p31x9yQk= github.com/onflow/flow-nft/lib/go/contracts v1.2.3/go.mod h1:eZ9VMMNfCq0ho6kV25xJn1kXeCfxnkhj3MwF3ed08gY= github.com/onflow/flow-nft/lib/go/templates v1.2.1 h1:SAALMZPDw9Eb9p5kSLnmnFxjyig1MLiT4JUlLp0/bSE= diff --git a/services/ingestion/sealing_verifier.go b/services/ingestion/sealing_verifier.go index c11536ff4..1a755fe18 100644 --- a/services/ingestion/sealing_verifier.go +++ b/services/ingestion/sealing_verifier.go @@ -125,7 +125,7 @@ func (v *SealingVerifier) Run(ctx context.Context) error { subscriptionCtx, cancel := context.WithCancel(ctx) defer cancel() - nextHeight := lastVerifiedHeight + 1 + reconnectHeight := lastVerifiedHeight + 1 connect := func(height uint64) error { var err error for { @@ -141,6 +141,7 @@ func (v *SealingVerifier) Run(ctx context.Context) error { // this typically happens when the AN reboots and the stream is reconnected before // it has sealed the next block if status.Code(err) == codes.InvalidArgument && strings.Contains(err.Error(), "higher than highest indexed height") { + v.logger.Info().Err(err).Uint64("height", height).Msg("waiting for start block to be sealed") time.Sleep(time.Second) continue } @@ -152,12 +153,12 @@ func (v *SealingVerifier) Run(ctx context.Context) error { } v.logger.Info(). - Uint64("start_sealed_height", nextHeight). - Uint64("start_unsealed_height", v.lastUnsealedHeight.Load()). + Uint64("start_sealed_height", v.lastSealedHeight.Load()+1). + Uint64("start_unsealed_height", v.lastUnsealedHeight.Load()+1). Msg("starting verifier") - if err := connect(nextHeight); err != nil { - return fmt.Errorf("failed to subscribe for finalized block events on height: %d, with: %w", nextHeight, err) + if err := connect(reconnectHeight); err != nil { + return fmt.Errorf("failed to subscribe for finalized block events on height: %d, with: %w", reconnectHeight, err) } v.MarkReady() @@ -179,12 +180,13 @@ func (v *SealingVerifier) Run(ctx context.Context) error { } return fmt.Errorf("failed to receive block events: %w", err) } - nextHeight = sealedEvents.Height + 1 if err := v.onSealedEvents(sealedEvents); err != nil { return fmt.Errorf("failed to process sealed events: %w", err) } + reconnectHeight = sealedEvents.Height + 1 + case err, ok := <-errChan: if !ok { if ctx.Err() != nil { @@ -205,8 +207,8 @@ func (v *SealingVerifier) Run(ctx context.Context) error { return fmt.Errorf("%w: %w", errs.ErrDisconnected, err) } - if err := connect(nextHeight); err != nil { - return fmt.Errorf("failed to resubscribe for finalized block headers on height: %d, with: %w", nextHeight, err) + if err := connect(reconnectHeight); err != nil { + return fmt.Errorf("failed to resubscribe for finalized block headers on height: %d, with: %w", reconnectHeight, err) } } } @@ -218,7 +220,7 @@ func (v *SealingVerifier) Run(ctx context.Context) error { func (v *SealingVerifier) onSealedEvents(sealedEvents flow.BlockEvents) error { // Note: there should be an unsealed event entry, even for blocks with no transactions - // update the last sealed height after successfully storing the hash + // ensure we have received sealed data for all blocks if sealedEvents.Height > 0 && !v.lastSealedHeight.CompareAndSwap(sealedEvents.Height-1, sealedEvents.Height) { // note: this conditional skips updating the lastSealedHeight if the height is 0. this is // desired since it will be the last height when we process block 1. @@ -294,9 +296,6 @@ func (v *SealingVerifier) onUnsealedEvents(unsealedEvents flow.BlockEvents) erro return fmt.Errorf("received unsealed events out of order: expected %d, got %d", v.lastUnsealedHeight.Load()+1, unsealedEvents.Height) } - // loop though all cached sealed events and verify them - // this catches the case where - // for unsealedHeight := unsealedEvents.Height; unsealedHeight <= v.lastSealedHeight.Load(); unsealedHeight++ { sealedHash, ok := v.sealedBlocksToVerify[unsealedEvents.Height] if !ok { v.logger.Info(). @@ -320,7 +319,6 @@ func (v *SealingVerifier) onUnsealedEvents(unsealedEvents flow.BlockEvents) erro Uint64("height", unsealedEvents.Height). Int("num_events", len(unsealedEvents.Events)). Msg("verified unsealed height") - // } return nil } From 7ea340abf53646e11fe1ced43007d486ef938026 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Fri, 7 Mar 2025 20:26:02 -0800 Subject: [PATCH 39/62] fix tidy check --- Makefile | 5 ++--- tests/go.mod | 2 +- tests/go.sum | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 5ca1c0888..a6ab71b98 100644 --- a/Makefile +++ b/Makefile @@ -77,9 +77,8 @@ e2e-test: .PHONY: check-tidy check-tidy: - go mod tidy - cd tests - go mod tidy + go mod tidy -v + cd tests; go mod tidy -v git diff --exit-code .PHONY: build diff --git a/tests/go.mod b/tests/go.mod index 465f0c33f..3aecd8023 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -9,7 +9,7 @@ require ( github.com/onflow/flow-emulator v1.2.1-0.20250219181005-4205d790a414 github.com/onflow/flow-evm-gateway v0.0.0-20240201154855-4d4d3d3f19c7 github.com/onflow/flow-go v0.38.1-0.20250218174738-2181389f9f7d - github.com/onflow/flow-go-sdk v1.3.4-0.20250305185710-21574a64879e + github.com/onflow/flow-go-sdk v1.3.4-0.20250308010136-4653c344a477 github.com/onflow/go-ethereum v1.14.7 github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.10.0 diff --git a/tests/go.sum b/tests/go.sum index 153650e1e..9b58acaf8 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -806,8 +806,8 @@ github.com/onflow/flow-ft/lib/go/templates v1.0.1 h1:FDYKAiGowABtoMNusLuRCILIZDt github.com/onflow/flow-ft/lib/go/templates v1.0.1/go.mod h1:uQ8XFqmMK2jxyBSVrmyuwdWjTEb+6zGjRYotfDJ5pAE= github.com/onflow/flow-go v0.38.1-0.20250218174738-2181389f9f7d h1:XRefc4rcBjGDEqsj3OB6XjSjSeYwMtysl7jmaLYpg+s= github.com/onflow/flow-go v0.38.1-0.20250218174738-2181389f9f7d/go.mod h1:VS7MlNHZeDrGm9/jkuMCSvAQTLFXpzQD0BIMB8/QYB8= -github.com/onflow/flow-go-sdk v1.3.4-0.20250305185710-21574a64879e h1:hV13Xhkxxaeq+xfc0Kn6l9VB1dofEfQq8xpqGchp/24= -github.com/onflow/flow-go-sdk v1.3.4-0.20250305185710-21574a64879e/go.mod h1:tSLvYIac9DlmUEqKHSHbVRyv4mSB0va4AuiV3XB9ENc= +github.com/onflow/flow-go-sdk v1.3.4-0.20250308010136-4653c344a477 h1:Gf+GB4Dj2EFwj0bSuyveSMIoE19zPDufi/Jm1ck1IoA= +github.com/onflow/flow-go-sdk v1.3.4-0.20250308010136-4653c344a477/go.mod h1:tSLvYIac9DlmUEqKHSHbVRyv4mSB0va4AuiV3XB9ENc= github.com/onflow/flow-nft/lib/go/contracts v1.2.3 h1:4ju20g1xgDKWBT63rOj5f/Sa4Lc+naCSWT4p31x9yQk= github.com/onflow/flow-nft/lib/go/contracts v1.2.3/go.mod h1:eZ9VMMNfCq0ho6kV25xJn1kXeCfxnkhj3MwF3ed08gY= github.com/onflow/flow-nft/lib/go/templates v1.2.1 h1:SAALMZPDw9Eb9p5kSLnmnFxjyig1MLiT4JUlLp0/bSE= From fd550719564ba7a47174270a19f5ea6d38a540a9 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Fri, 7 Mar 2025 20:31:08 -0800 Subject: [PATCH 40/62] reduce logging --- services/ingestion/sealing_verifier.go | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/services/ingestion/sealing_verifier.go b/services/ingestion/sealing_verifier.go index 1a755fe18..7311eb588 100644 --- a/services/ingestion/sealing_verifier.go +++ b/services/ingestion/sealing_verifier.go @@ -244,12 +244,6 @@ func (v *SealingVerifier) onSealedEvents(sealedEvents flow.BlockEvents) error { if errors.Is(err, errs.ErrEntityNotFound) || sealedEvents.Height > v.lastUnsealedHeight.Load() { // we haven't processed the unsealed data for this block yet, cache the sealed hash v.sealedBlocksToVerify[sealedEvents.Height] = sealedHash - - v.logger.Info(). - Uint64("height", sealedEvents.Height). - Int("num_events", len(sealedEvents.Events)). - Msg("no unsealed data available for verification. caching sealed data") - return nil } if err != nil { @@ -267,7 +261,7 @@ func (v *SealingVerifier) onSealedEvents(sealedEvents flow.BlockEvents) error { v.logger.Info(). Uint64("height", sealedEvents.Height). Int("num_events", len(sealedEvents.Events)). - Msg("verified sealed height") + Msg("verified height from sealed events") return nil } @@ -298,11 +292,6 @@ func (v *SealingVerifier) onUnsealedEvents(unsealedEvents flow.BlockEvents) erro sealedHash, ok := v.sealedBlocksToVerify[unsealedEvents.Height] if !ok { - v.logger.Info(). - Uint64("height", unsealedEvents.Height). - Int("num_events", len(unsealedEvents.Events)). - Msg("no sealed data available for verification. caching unsealed data") - v.unsealedBlocksToVerify[unsealedEvents.Height] = unsealedHash return nil } @@ -318,7 +307,7 @@ func (v *SealingVerifier) onUnsealedEvents(unsealedEvents flow.BlockEvents) erro v.logger.Info(). Uint64("height", unsealedEvents.Height). Int("num_events", len(unsealedEvents.Events)). - Msg("verified unsealed height") + Msg("verified height from unsealed events") return nil } From 1457b3ea28a804d640ee6ed3a9b6f284d1e9eaa6 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Wed, 12 Mar 2025 12:37:45 -0700 Subject: [PATCH 41/62] re-add verifier start block --- services/ingestion/block_tracking_subscriber.go | 2 +- services/ingestion/sealing_verifier.go | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 8f215bd5e..34024e859 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -109,7 +109,7 @@ func (r *RPCBlockTrackingSubscriber) Subscribe(ctx context.Context) <-chan model // start the verifier after backfilling since backfilled data is already sealed if r.verifier != nil { go func() { - // r.verifier.SetStartHeight(r.height) + r.verifier.SetStartHeight(r.height) if err := r.verifier.Run(ctx); err != nil { r.logger.Fatal().Err(err).Msg("failure running sealing verifier") return diff --git a/services/ingestion/sealing_verifier.go b/services/ingestion/sealing_verifier.go index 7311eb588..8c125af25 100644 --- a/services/ingestion/sealing_verifier.go +++ b/services/ingestion/sealing_verifier.go @@ -61,10 +61,12 @@ func NewSealingVerifier( eventsHash *pebble.EventsHash, startHeight uint64, ) *SealingVerifier { + // startHeight is the first height to verify, which is one block after the last processed height lastProcessedUnsealedHeight := startHeight if lastProcessedUnsealedHeight > 0 { lastProcessedUnsealedHeight-- } + return &SealingVerifier{ EngineStatus: models.NewEngineStatus(), logger: logger.With().Str("component", "sealing_verifier").Logger(), From 0071e4024560332d753b82bef265c559a7aa8eb5 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Wed, 12 Mar 2025 12:39:08 -0700 Subject: [PATCH 42/62] update to sdk v1.4.0 --- go.mod | 31 ++++++++++--------- go.sum | 68 ++++++++++++++++++++++------------------- tests/go.mod | 33 ++++++++++---------- tests/go.sum | 86 +++++++++++++++++++++++++++------------------------- 4 files changed, 113 insertions(+), 105 deletions(-) diff --git a/go.mod b/go.mod index 7caaf7c19..c47222cd3 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/onflow/atree v0.9.0 github.com/onflow/cadence v1.3.3 github.com/onflow/flow-go v0.38.1-0.20250218174738-2181389f9f7d - github.com/onflow/flow-go-sdk v1.3.4-0.20250308010136-4653c344a477 + github.com/onflow/flow-go-sdk v1.4.0 github.com/onflow/go-ethereum v1.14.7 github.com/prometheus/client_golang v1.20.5 github.com/rs/cors v1.8.0 @@ -23,11 +23,11 @@ require ( go.uber.org/ratelimit v0.3.1 golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 golang.org/x/sync v0.10.0 - google.golang.org/grpc v1.67.1 + google.golang.org/grpc v1.71.0 ) require ( - cloud.google.com/go/compute/metadata v0.5.0 // indirect + cloud.google.com/go/compute/metadata v0.6.0 // indirect cloud.google.com/go/iam v1.1.6 // indirect cloud.google.com/go/kms v1.15.7 // indirect github.com/DataDog/zstd v1.5.2 // indirect @@ -78,7 +78,7 @@ require ( github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/glog v1.2.2 // indirect + github.com/golang/glog v1.2.4 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect @@ -187,21 +187,22 @@ require ( github.com/x448/float16 v0.8.4 // indirect github.com/zeebo/blake3 v0.2.4 // indirect go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect - go.opentelemetry.io/otel v1.31.0 // indirect + go.opentelemetry.io/otel v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 // indirect - go.opentelemetry.io/otel/metric v1.31.0 // indirect - go.opentelemetry.io/otel/sdk v1.31.0 // indirect - go.opentelemetry.io/otel/trace v1.31.0 // indirect + go.opentelemetry.io/otel/metric v1.34.0 // indirect + go.opentelemetry.io/otel/sdk v1.34.0 // indirect + go.opentelemetry.io/otel/trace v1.34.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.31.0 // indirect - golang.org/x/net v0.33.0 // indirect - golang.org/x/oauth2 v0.24.0 // indirect - golang.org/x/sys v0.28.0 // indirect + golang.org/x/crypto v0.32.0 // indirect + golang.org/x/net v0.34.0 // indirect + golang.org/x/oauth2 v0.25.0 // indirect + golang.org/x/sys v0.29.0 // indirect golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect @@ -209,9 +210,9 @@ require ( google.golang.org/api v0.169.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect - google.golang.org/protobuf v1.36.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect + google.golang.org/protobuf v1.36.5 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.3.0 // indirect diff --git a/go.sum b/go.sum index 8c978e23c..d782c3b78 100644 --- a/go.sum +++ b/go.sum @@ -25,8 +25,8 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= -cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= +cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= +cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= @@ -257,8 +257,8 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.2 h1:1+mZ9upx1Dh6FmUTFR1naJ77miKiXgALjWOZ3NVFPmY= -github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc= +github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -583,8 +583,8 @@ github.com/onflow/flow-ft/lib/go/templates v1.0.1 h1:FDYKAiGowABtoMNusLuRCILIZDt github.com/onflow/flow-ft/lib/go/templates v1.0.1/go.mod h1:uQ8XFqmMK2jxyBSVrmyuwdWjTEb+6zGjRYotfDJ5pAE= github.com/onflow/flow-go v0.38.1-0.20250218174738-2181389f9f7d h1:XRefc4rcBjGDEqsj3OB6XjSjSeYwMtysl7jmaLYpg+s= github.com/onflow/flow-go v0.38.1-0.20250218174738-2181389f9f7d/go.mod h1:VS7MlNHZeDrGm9/jkuMCSvAQTLFXpzQD0BIMB8/QYB8= -github.com/onflow/flow-go-sdk v1.3.4-0.20250308010136-4653c344a477 h1:Gf+GB4Dj2EFwj0bSuyveSMIoE19zPDufi/Jm1ck1IoA= -github.com/onflow/flow-go-sdk v1.3.4-0.20250308010136-4653c344a477/go.mod h1:tSLvYIac9DlmUEqKHSHbVRyv4mSB0va4AuiV3XB9ENc= +github.com/onflow/flow-go-sdk v1.4.0 h1:7u8CzUBLPD5KbF2Str3CNywGe47DSPCiMDR26ZDDzTA= +github.com/onflow/flow-go-sdk v1.4.0/go.mod h1:xCo9l0V+anjXyg128waXdylStLT4SwmbKssmdHVT0Zc= github.com/onflow/flow-nft/lib/go/contracts v1.2.3 h1:4ju20g1xgDKWBT63rOj5f/Sa4Lc+naCSWT4p31x9yQk= github.com/onflow/flow-nft/lib/go/contracts v1.2.3/go.mod h1:eZ9VMMNfCq0ho6kV25xJn1kXeCfxnkhj3MwF3ed08gY= github.com/onflow/flow-nft/lib/go/templates v1.2.1 h1:SAALMZPDw9Eb9p5kSLnmnFxjyig1MLiT4JUlLp0/bSE= @@ -831,22 +831,26 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM= -go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= -go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= +go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= +go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 h1:K0XaT3DwHAcV4nKLzcQvwAgSyisUghWoY20I7huthMk= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0/go.mod h1:B5Ki776z/MBnVha1Nzwp5arlzBbE3+1jk+pGmaP5HME= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 h1:FFeLy03iVTXP6ffeN2iXrxfGsZGCjVx0/4KlizjyBwU= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0/go.mod h1:TMu73/k1CP8nBUpDLc71Wj/Kf7ZS9FK5b53VapRsP9o= -go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= -go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= -go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= -go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= -go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= -go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= +go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= +go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= +go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= +go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= +go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= +go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= +go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -883,8 +887,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -966,8 +970,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= -golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -977,8 +981,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= -golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= +golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1057,12 +1061,12 @@ 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.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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= -golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= -golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= +golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= +golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1210,10 +1214,10 @@ google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= -google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 h1:T6rh4haD3GVYsgEfWExoCZA2o2FmbNyKpTuAxbEFPTg= -google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:wp2WsuBYj6j8wUdo3ToZsdxxixbvQNAHqVJrTgi5E5M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= +google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 h1:GVIKPyP/kLIyVOgOnTwFOrvQaQUzOzGMCxgFUOEmm24= +google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422/go.mod h1:b6h1vNKhxaSoEI+5jc3PJUCustfli/mRab7295pY7rw= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1231,8 +1235,8 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= +google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1245,8 +1249,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.36.0 h1:mjIs9gYtt56AzC4ZaffQuh88TZurBGhIJMBZGSxNerQ= -google.golang.org/protobuf v1.36.0/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 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= diff --git a/tests/go.mod b/tests/go.mod index 3aecd8023..e735e09f4 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -9,14 +9,14 @@ require ( github.com/onflow/flow-emulator v1.2.1-0.20250219181005-4205d790a414 github.com/onflow/flow-evm-gateway v0.0.0-20240201154855-4d4d3d3f19c7 github.com/onflow/flow-go v0.38.1-0.20250218174738-2181389f9f7d - github.com/onflow/flow-go-sdk v1.3.4-0.20250308010136-4653c344a477 + github.com/onflow/flow-go-sdk v1.4.0 github.com/onflow/go-ethereum v1.14.7 github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.10.0 ) require ( - cloud.google.com/go/compute/metadata v0.5.0 // indirect + cloud.google.com/go/compute/metadata v0.6.0 // indirect cloud.google.com/go/iam v1.1.6 // indirect cloud.google.com/go/kms v1.15.7 // indirect github.com/DataDog/zstd v1.5.2 // indirect @@ -78,7 +78,7 @@ require ( github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/glog v1.2.2 // indirect + github.com/golang/glog v1.2.4 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect @@ -206,26 +206,27 @@ require ( github.com/x448/float16 v0.8.4 // indirect github.com/zeebo/blake3 v0.2.4 // indirect go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect - go.opentelemetry.io/otel v1.31.0 // indirect + go.opentelemetry.io/otel v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 // indirect - go.opentelemetry.io/otel/metric v1.31.0 // indirect - go.opentelemetry.io/otel/sdk v1.31.0 // indirect - go.opentelemetry.io/otel/trace v1.31.0 // indirect + go.opentelemetry.io/otel/metric v1.34.0 // indirect + go.opentelemetry.io/otel/sdk v1.34.0 // indirect + go.opentelemetry.io/otel/trace v1.34.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/ratelimit v0.3.1 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.31.0 // indirect + golang.org/x/crypto v0.32.0 // indirect golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 // indirect - golang.org/x/net v0.33.0 // indirect - golang.org/x/oauth2 v0.24.0 // indirect + golang.org/x/net v0.34.0 // indirect + golang.org/x/oauth2 v0.25.0 // indirect golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.28.0 // indirect - golang.org/x/term v0.27.0 // indirect + golang.org/x/sys v0.29.0 // indirect + golang.org/x/term v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect @@ -233,10 +234,10 @@ require ( google.golang.org/api v0.169.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect - google.golang.org/grpc v1.67.1 // indirect - google.golang.org/protobuf v1.36.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect + google.golang.org/grpc v1.71.0 // indirect + google.golang.org/protobuf v1.36.5 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools v2.2.0+incompatible // indirect diff --git a/tests/go.sum b/tests/go.sum index 9b58acaf8..16fad1cf1 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -25,8 +25,8 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= -cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= +cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= +cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= @@ -87,20 +87,20 @@ github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6l github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/aws/aws-sdk-go-v2 v1.27.0 h1:7bZWKoXhzI+mMR/HjdMx8ZCC5+6fY0lS5tr0bbgiLlo= -github.com/aws/aws-sdk-go-v2 v1.27.0/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= +github.com/aws/aws-sdk-go-v2 v1.30.4 h1:frhcagrVNrzmT95RJImMHgabt99vkXGslubDaDagTk8= +github.com/aws/aws-sdk-go-v2 v1.30.4/go.mod h1:CT+ZPWXbYrci8chcARI3OmI/qgd+f6WtuLOoaIA8PR0= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.5.1 h1:VGkV9KmhGqOQWnHyi4gLG98kE6OecT42fdrCGFWxJsc= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.5.1/go.mod h1:PLlnMiki//sGnCJiW+aVpvP/C8Kcm8mEj/IVm9+9qk4= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 h1:Ji0DY1xUsUr3I8cHps0G+XM3WWU16lP6yG8qu1GAZAs= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2/go.mod h1:5CsjAbs3NlGQyZNFACh+zztPDI7fU6eW9QsxjfnuBKg= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.9 h1:Wx0rlZoEJR7JwlSZcHnEa7CNjrSIyVxMFWGAaXy4fJY= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.9/go.mod h1:aVMHdE0aHO3v+f/iw01fmXV/5DbfQ3Bi9nN7nd9bE9Y= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 h1:KypMCbLPPHEmf9DgMGw51jMj77VfGPAN2Kv4cfhlfgI= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4/go.mod h1:Vz1JQXliGcQktFTN/LN6uGppAIRoLBR2bMvIMP0gOjc= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 h1:tJ5RnkHCiSH0jyd6gROjlJtNwov0eGYNz8s8nFcR0jQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18/go.mod h1:++NHzT+nAF7ZPrHPsA+ENvsXkOO8wEu+C6RXltAG4/c= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.7.0 h1:HWsM0YQWX76V6MOp07YuTYacm8k7h69ObJuw7Nck+og= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.7.0/go.mod h1:LKb3cKNQIMh+itGnEpKGcnL/6OIjPZqrtYah1w5f+3o= github.com/aws/aws-sdk-go-v2/service/s3 v1.15.0 h1:nPLfLPfglacc29Y949sDxpr3X/blaY40s3B85WT2yZU= github.com/aws/aws-sdk-go-v2/service/s3 v1.15.0/go.mod h1:Iv2aJVtVSm/D22rFoX99cLG4q4uB7tppuCsulGe98k4= -github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q= -github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= +github.com/aws/smithy-go v1.20.4 h1:2HK1zBdPgRbjFOHlfeQZfpC4r72MOb9bZkiFwggKO+4= +github.com/aws/smithy-go v1.20.4/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -374,8 +374,8 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.2 h1:1+mZ9upx1Dh6FmUTFR1naJ77miKiXgALjWOZ3NVFPmY= -github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc= +github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -581,8 +581,6 @@ github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZl 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/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= @@ -806,8 +804,8 @@ github.com/onflow/flow-ft/lib/go/templates v1.0.1 h1:FDYKAiGowABtoMNusLuRCILIZDt github.com/onflow/flow-ft/lib/go/templates v1.0.1/go.mod h1:uQ8XFqmMK2jxyBSVrmyuwdWjTEb+6zGjRYotfDJ5pAE= github.com/onflow/flow-go v0.38.1-0.20250218174738-2181389f9f7d h1:XRefc4rcBjGDEqsj3OB6XjSjSeYwMtysl7jmaLYpg+s= github.com/onflow/flow-go v0.38.1-0.20250218174738-2181389f9f7d/go.mod h1:VS7MlNHZeDrGm9/jkuMCSvAQTLFXpzQD0BIMB8/QYB8= -github.com/onflow/flow-go-sdk v1.3.4-0.20250308010136-4653c344a477 h1:Gf+GB4Dj2EFwj0bSuyveSMIoE19zPDufi/Jm1ck1IoA= -github.com/onflow/flow-go-sdk v1.3.4-0.20250308010136-4653c344a477/go.mod h1:tSLvYIac9DlmUEqKHSHbVRyv4mSB0va4AuiV3XB9ENc= +github.com/onflow/flow-go-sdk v1.4.0 h1:7u8CzUBLPD5KbF2Str3CNywGe47DSPCiMDR26ZDDzTA= +github.com/onflow/flow-go-sdk v1.4.0/go.mod h1:xCo9l0V+anjXyg128waXdylStLT4SwmbKssmdHVT0Zc= github.com/onflow/flow-nft/lib/go/contracts v1.2.3 h1:4ju20g1xgDKWBT63rOj5f/Sa4Lc+naCSWT4p31x9yQk= github.com/onflow/flow-nft/lib/go/contracts v1.2.3/go.mod h1:eZ9VMMNfCq0ho6kV25xJn1kXeCfxnkhj3MwF3ed08gY= github.com/onflow/flow-nft/lib/go/templates v1.2.1 h1:SAALMZPDw9Eb9p5kSLnmnFxjyig1MLiT4JUlLp0/bSE= @@ -1130,22 +1128,26 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM= -go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= -go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= +go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= +go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 h1:K0XaT3DwHAcV4nKLzcQvwAgSyisUghWoY20I7huthMk= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0/go.mod h1:B5Ki776z/MBnVha1Nzwp5arlzBbE3+1jk+pGmaP5HME= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 h1:FFeLy03iVTXP6ffeN2iXrxfGsZGCjVx0/4KlizjyBwU= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0/go.mod h1:TMu73/k1CP8nBUpDLc71Wj/Kf7ZS9FK5b53VapRsP9o= -go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= -go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= -go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= -go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= -go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= -go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= +go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= +go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= +go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= +go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= +go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= +go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= +go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1194,8 +1196,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1285,8 +1287,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= -golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1296,8 +1298,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= -golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= +golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1387,13 +1389,13 @@ 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.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= -golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= +golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= +golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1551,12 +1553,12 @@ google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= -google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 h1:T6rh4haD3GVYsgEfWExoCZA2o2FmbNyKpTuAxbEFPTg= -google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:wp2WsuBYj6j8wUdo3ToZsdxxixbvQNAHqVJrTgi5E5M= +google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 h1:GVIKPyP/kLIyVOgOnTwFOrvQaQUzOzGMCxgFUOEmm24= +google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422/go.mod h1:b6h1vNKhxaSoEI+5jc3PJUCustfli/mRab7295pY7rw= google.golang.org/genproto/googleapis/bytestream v0.0.0-20240304161311-37d4d3c04a78 h1:YqFWYZXim8bG9v68xU8WjTZmYKb5M5dMeSOWIp6jogI= google.golang.org/genproto/googleapis/bytestream v0.0.0-20240304161311-37d4d3c04a78/go.mod h1:vh/N7795ftP0AkN1w8XKqN4w1OdUKXW5Eummda+ofv8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1579,8 +1581,8 @@ google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= +google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1593,8 +1595,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.36.0 h1:mjIs9gYtt56AzC4ZaffQuh88TZurBGhIJMBZGSxNerQ= -google.golang.org/protobuf v1.36.0/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 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= From 1e2a0fda0dd68788600b3f77fa8ac5f61090387d Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Thu, 13 Mar 2025 13:45:31 -0700 Subject: [PATCH 43/62] fix crash when starting ahead of access node --- services/ingestion/engine.go | 4 ++-- services/ingestion/sealing_verifier.go | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/services/ingestion/engine.go b/services/ingestion/engine.go index 01e5ec892..9c130fe64 100644 --- a/services/ingestion/engine.go +++ b/services/ingestion/engine.go @@ -298,12 +298,12 @@ func (e *Engine) indexEvents(events *models.CadenceEvents, batch *pebbleDB.Batch txHash := tx.Hash() traceResult, err := traceCollector.Collect(txHash) if err != nil { - return err + return fmt.Errorf("failed to collect trace for transaction %s: %w", txHash, err) } err = e.traces.StoreTransaction(txHash, traceResult, batch) if err != nil { - return err + return fmt.Errorf("failed to store trace for transaction %s: %w", txHash, err) } } diff --git a/services/ingestion/sealing_verifier.go b/services/ingestion/sealing_verifier.go index 8c125af25..13284f926 100644 --- a/services/ingestion/sealing_verifier.go +++ b/services/ingestion/sealing_verifier.go @@ -142,7 +142,8 @@ func (v *SealingVerifier) Run(ctx context.Context) error { // access node has not sealed the next height yet, wait and try again // this typically happens when the AN reboots and the stream is reconnected before // it has sealed the next block - if status.Code(err) == codes.InvalidArgument && strings.Contains(err.Error(), "higher than highest indexed height") { + if strings.Contains(err.Error(), "could not get start height") && + strings.Contains(err.Error(), "higher than highest indexed height") { v.logger.Info().Err(err).Uint64("height", height).Msg("waiting for start block to be sealed") time.Sleep(time.Second) continue From f3a5b7fd811fdf1b62ae67a2577c4b5266d4b250 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Thu, 17 Apr 2025 12:09:36 -0700 Subject: [PATCH 44/62] Update eth_syncing to return false for currentBlock >= highestBlock --- api/api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/api.go b/api/api.go index 9afd32209..df46cf43c 100644 --- a/api/api.go +++ b/api/api.go @@ -149,7 +149,7 @@ func (b *BlockChainAPI) Syncing(ctx context.Context) (interface{}, error) { return handleError[any](err, b.logger, b.collector) } - if currentBlock == highestBlock { + if currentBlock >= highestBlock { return false, nil } From 3ec09b94602cace4e5c4982d9782ab1c158ac923 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Tue, 22 Apr 2025 06:06:24 -0700 Subject: [PATCH 45/62] Fix panic in debug_traceBlockByNumber when tracer is not set --- api/debug.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/debug.go b/api/debug.go index ca618c2f4..cc9d825fd 100644 --- a/api/debug.go +++ b/api/debug.go @@ -25,8 +25,8 @@ import ( "github.com/onflow/flow-evm-gateway/services/requester" "github.com/onflow/flow-evm-gateway/storage" "github.com/onflow/flow-evm-gateway/storage/pebble" - flowEVM "github.com/onflow/flow-go/fvm/evm" + flowEVM "github.com/onflow/flow-go/fvm/evm" offchain "github.com/onflow/flow-go/fvm/evm/offchain/storage" // this import is needed for side-effects, because the @@ -472,7 +472,7 @@ func isDefaultCallTracer(config *tracers.TraceConfig) bool { return false } - if *config.Tracer != replayer.TracerName { + if config.Tracer == nil || *config.Tracer != replayer.TracerName { return false } From 7b1c6f160788517d964d7fedc870fe25758b2706 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Mon, 5 May 2025 12:55:36 -0700 Subject: [PATCH 46/62] Add flag to disable enforcing the minimum gas price --- cmd/run/cmd.go | 2 +- config/config.go | 2 ++ services/requester/requester.go | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/run/cmd.go b/cmd/run/cmd.go index 0f1ac8b96..c3a8aa301 100644 --- a/cmd/run/cmd.go +++ b/cmd/run/cmd.go @@ -247,7 +247,6 @@ var ( cloudKMSKeyRingID, walletKey, txStateValidation string - initHeight, forceStartHeight uint64 @@ -267,6 +266,7 @@ func init() { Cmd.Flags().StringVar(&coinbase, "coinbase", "", "Coinbase address to use for fee collection") Cmd.Flags().Uint64Var(&initHeight, "init-cadence-height", 0, "Define the Cadence block height at which to start the indexing, if starting on a new network this flag should not be used.") Cmd.Flags().StringVar(&gas, "gas-price", "1", "Static gas price used for EVM transactions") + Cmd.Flags().BoolVar(&cfg.EnforceGasPrice, "enforce-gas-price", true, "Enable enforcing minimum gas price for EVM transactions. When true (default), transactions must specify a gas price greater than or equal to the configured gas price.") Cmd.Flags().StringVar(&coa, "coa-address", "", "Flow address that holds COA account used for submitting transactions") Cmd.Flags().StringVar(&key, "coa-key", "", "Private key value for the COA address used for submitting transactions") Cmd.Flags().StringVar(&keyAlg, "coa-key-alg", "ECDSA_P256", "Private key algorithm for the COA private key, only effective if coa-key/coa-key-file is present. Available values (ECDSA_P256 / ECDSA_secp256k1 / BLS_BLS12_381), defaults to ECDSA_P256.") diff --git a/config/config.go b/config/config.go index f26c40b85..ccfd7cdd1 100644 --- a/config/config.go +++ b/config/config.go @@ -58,6 +58,8 @@ type Config struct { COACloudKMSKey *flowGoKMS.Key // GasPrice is a fixed gas price that will be used when submitting transactions. GasPrice *big.Int + // EnforceGasPrice defines whether the minimum gas price should be enforced. + EnforceGasPrice bool // InitCadenceHeight is used for initializing the database on a local emulator or a live network. InitCadenceHeight uint64 // LogLevel defines how verbose the output log is diff --git a/services/requester/requester.go b/services/requester/requester.go index ddf56033b..5e325a438 100644 --- a/services/requester/requester.go +++ b/services/requester/requester.go @@ -230,7 +230,7 @@ func (e *EVM) SendRawTransaction(ctx context.Context, data []byte) (common.Hash, } } - if tx.GasPrice().Cmp(e.config.GasPrice) < 0 { + if tx.GasPrice().Cmp(e.config.GasPrice) < 0 && e.config.EnforceGasPrice { return common.Hash{}, errs.NewTxGasPriceTooLowError(e.config.GasPrice) } From b8c6187c7df5c3e59658ef7937c46b9a17f3fbfa Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Mon, 5 May 2025 12:58:25 -0700 Subject: [PATCH 47/62] add docs for flag to readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e2787279d..d1905acc7 100644 --- a/README.md +++ b/README.md @@ -233,6 +233,7 @@ The application can be configured using the following flags at runtime: | `coinbase` | `""` | Coinbase address to use for fee collection | | `init-cadence-height` | `0` | Cadence block height to start indexing; avoid using on a new network | | `gas-price` | `1` | Static gas price for EVM transactions | +| `enforce-gas-price` | `true` | Enable enforcing minimum gas price for EVM transactions. When true (default), transactions must specify a gas price greater than or equal to the configured gas price. | | `coa-address` | `""` | Flow address holding COA account for submitting transactions | | `coa-key` | `""` | Private key for the COA address used for transactions | | `coa-key-file` | `""` | Path to a JSON file of COA keys for key-rotation (exclusive with `coa-key` flag) | From f8a3eb1141f6f5c5b9f14a7f322ada5acd79ed92 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Mon, 5 May 2025 13:29:18 -0700 Subject: [PATCH 48/62] add EnforceGasPrice in testing configs --- tests/helpers.go | 1 + tests/integration_test.go | 53 +++++++++++++++++++++------------------ 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/tests/helpers.go b/tests/helpers.go index 422f0b0d4..dc8b3a9ee 100644 --- a/tests/helpers.go +++ b/tests/helpers.go @@ -165,6 +165,7 @@ func servicesSetup(t *testing.T) (emulator.Emulator, func()) { COAAddress: *coaAddress, COAKey: privateKey, GasPrice: new(big.Int).SetUint64(150), + EnforceGasPrice: true, LogLevel: zerolog.DebugLevel, LogWriter: testLogWriter(), RateLimit: 500, diff --git a/tests/integration_test.go b/tests/integration_test.go index ed866624d..6b3ef7af1 100644 --- a/tests/integration_test.go +++ b/tests/integration_test.go @@ -71,6 +71,7 @@ func Test_ConcurrentTransactionSubmissionWithTxSeal(t *testing.T) { COAAddress: *createdAddr, COAKey: privateKey, GasPrice: new(big.Int).SetUint64(0), + EnforceGasPrice: true, LogLevel: zerolog.DebugLevel, LogWriter: testLogWriter(), TxStateValidation: config.TxSealValidation, @@ -181,6 +182,7 @@ func Test_ConcurrentTransactionSubmissionWithLocalIndex(t *testing.T) { COAAddress: *createdAddr, COAKey: privateKey, GasPrice: new(big.Int).SetUint64(0), + EnforceGasPrice: true, LogLevel: zerolog.DebugLevel, LogWriter: testLogWriter(), TxStateValidation: config.LocalIndexValidation, @@ -275,18 +277,19 @@ func Test_EthClientTest(t *testing.T) { require.NoError(t, err) cfg := config.Config{ - DatabaseDir: t.TempDir(), - AccessNodeHost: grpcHost, - RPCPort: 8545, - RPCHost: "127.0.0.1", - FlowNetworkID: "flow-emulator", - EVMNetworkID: types.FlowEVMPreviewNetChainID, - Coinbase: eoaTestAccount, - COAAddress: *createdAddr, - COAKey: privateKey, - GasPrice: new(big.Int).SetUint64(150), - LogLevel: zerolog.DebugLevel, - LogWriter: testLogWriter(), + DatabaseDir: t.TempDir(), + AccessNodeHost: grpcHost, + RPCPort: 8545, + RPCHost: "127.0.0.1", + FlowNetworkID: "flow-emulator", + EVMNetworkID: types.FlowEVMPreviewNetChainID, + Coinbase: eoaTestAccount, + COAAddress: *createdAddr, + COAKey: privateKey, + GasPrice: new(big.Int).SetUint64(150), + EnforceGasPrice: true, + LogLevel: zerolog.DebugLevel, + LogWriter: testLogWriter(), } ready := make(chan struct{}) @@ -371,18 +374,19 @@ func Test_CloudKMSConcurrentTransactionSubmission(t *testing.T) { require.NoError(t, err) cfg := config.Config{ - DatabaseDir: t.TempDir(), - AccessNodeHost: grpcHost, - RPCPort: 8545, - RPCHost: "127.0.0.1", - FlowNetworkID: "flow-emulator", - EVMNetworkID: types.FlowEVMPreviewNetChainID, - Coinbase: eoaTestAccount, - COAAddress: *createdAddr, - COACloudKMSKey: &kmsKey, - GasPrice: new(big.Int).SetUint64(0), - LogLevel: zerolog.DebugLevel, - LogWriter: testLogWriter(), + DatabaseDir: t.TempDir(), + AccessNodeHost: grpcHost, + RPCPort: 8545, + RPCHost: "127.0.0.1", + FlowNetworkID: "flow-emulator", + EVMNetworkID: types.FlowEVMPreviewNetChainID, + Coinbase: eoaTestAccount, + COAAddress: *createdAddr, + COACloudKMSKey: &kmsKey, + GasPrice: new(big.Int).SetUint64(0), + EnforceGasPrice: true, + LogLevel: zerolog.DebugLevel, + LogWriter: testLogWriter(), } // todo change this test to use ingestion and emulator directly so we can completely remove @@ -486,6 +490,7 @@ func Test_ForceStartHeightIdempotency(t *testing.T) { COAAddress: *createdAddr, COAKey: privateKey, GasPrice: new(big.Int).SetUint64(0), + EnforceGasPrice: true, LogLevel: zerolog.DebugLevel, LogWriter: testLogWriter(), TxStateValidation: config.LocalIndexValidation, From b7e6803c938ee744292bfbd9933f8e4e6876e61f Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Thu, 8 May 2025 11:19:49 +0300 Subject: [PATCH 49/62] Bump flow-go-sdk version to v1.4.0 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 103d64327..b0b0d0d35 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/onflow/atree v0.10.0 github.com/onflow/cadence v1.3.4 github.com/onflow/flow-go v0.40.1 - github.com/onflow/flow-go-sdk v1.3.3 + github.com/onflow/flow-go-sdk v1.4.0 github.com/onflow/go-ethereum v1.14.7 github.com/prometheus/client_golang v1.20.5 github.com/rs/cors v1.8.0 diff --git a/go.sum b/go.sum index 6e55b17ed..808e4b278 100644 --- a/go.sum +++ b/go.sum @@ -580,8 +580,8 @@ github.com/onflow/flow-ft/lib/go/templates v1.0.1 h1:FDYKAiGowABtoMNusLuRCILIZDt github.com/onflow/flow-ft/lib/go/templates v1.0.1/go.mod h1:uQ8XFqmMK2jxyBSVrmyuwdWjTEb+6zGjRYotfDJ5pAE= github.com/onflow/flow-go v0.40.1 h1:2+Rejyu6D93ufRgmNCAes5QkPGOapdPlcFFpdSWPyeM= github.com/onflow/flow-go v0.40.1/go.mod h1:+QPdqmSYxvXN3oxtt1nS/oFlcDjOQGYhf0TvHQylbzg= -github.com/onflow/flow-go-sdk v1.3.3 h1:wj7llql3wesQYBePh3lEFI+jk3Df1sa13bRsL139JDo= -github.com/onflow/flow-go-sdk v1.3.3/go.mod h1:tSLvYIac9DlmUEqKHSHbVRyv4mSB0va4AuiV3XB9ENc= +github.com/onflow/flow-go-sdk v1.4.0 h1:7u8CzUBLPD5KbF2Str3CNywGe47DSPCiMDR26ZDDzTA= +github.com/onflow/flow-go-sdk v1.4.0/go.mod h1:xCo9l0V+anjXyg128waXdylStLT4SwmbKssmdHVT0Zc= github.com/onflow/flow-nft/lib/go/contracts v1.2.3 h1:4ju20g1xgDKWBT63rOj5f/Sa4Lc+naCSWT4p31x9yQk= github.com/onflow/flow-nft/lib/go/contracts v1.2.3/go.mod h1:eZ9VMMNfCq0ho6kV25xJn1kXeCfxnkhj3MwF3ed08gY= github.com/onflow/flow-nft/lib/go/templates v1.2.1 h1:SAALMZPDw9Eb9p5kSLnmnFxjyig1MLiT4JUlLp0/bSE= From 3400afc844dafab247e29938a6751aeb9728529e Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Thu, 8 May 2025 21:25:00 +0300 Subject: [PATCH 50/62] Create ValidationOptions for each tx submission --- services/requester/requester.go | 77 +++++++++++++++------------------ 1 file changed, 35 insertions(+), 42 deletions(-) diff --git a/services/requester/requester.go b/services/requester/requester.go index b11101bc1..a5282602b 100644 --- a/services/requester/requester.go +++ b/services/requester/requester.go @@ -109,11 +109,8 @@ type EVM struct { mux sync.Mutex keystore *keystore.KeyStore - head *types.Header - evmSigner types.Signer - validationOptions *txpool.ValidationOptions - collector metrics.Collector - rateLimiter limiter.Store + collector metrics.Collector + rateLimiter limiter.Store } func NewEVM( @@ -153,30 +150,6 @@ func NewEVM( } } - head := &types.Header{ - Number: big.NewInt(20_182_324), - Time: uint64(time.Now().Unix()), - GasLimit: blockGasLimit, - Difficulty: big.NewInt(0), - } - emulatorConfig := emulator.NewConfig( - emulator.WithChainID(config.EVMNetworkID), - emulator.WithBlockNumber(head.Number), - emulator.WithBlockTime(head.Time), - ) - evmSigner := emulator.GetSigner(emulatorConfig) - validationOptions := &txpool.ValidationOptions{ - Config: emulatorConfig.ChainConfig, - Accept: 0 | - 1< Date: Fri, 9 May 2025 16:52:10 +0300 Subject: [PATCH 51/62] Return authorization list for SetCodeTx type --- eth/types/types.go | 49 +++++++------ models/transaction.go | 5 ++ .../eth_eip_7702_contract_write_test.js | 73 ++++++++++++++++--- .../eth_eip_7702_sending_transactions_test.js | 68 ++++++++++++++--- 4 files changed, 149 insertions(+), 46 deletions(-) diff --git a/eth/types/types.go b/eth/types/types.go index 046b20412..414f371e9 100644 --- a/eth/types/types.go +++ b/eth/types/types.go @@ -274,28 +274,29 @@ type StorageResult struct { // Transaction represents a transaction that will serialize to the RPC representation of a transaction type Transaction struct { - BlockHash *common.Hash `json:"blockHash"` - BlockNumber *hexutil.Big `json:"blockNumber"` - From common.MixedcaseAddress `json:"from"` - Gas hexutil.Uint64 `json:"gas"` - GasPrice *hexutil.Big `json:"gasPrice"` - GasFeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"` - GasTipCap *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"` - MaxFeePerBlobGas *hexutil.Big `json:"maxFeePerBlobGas,omitempty"` - Hash common.Hash `json:"hash"` - Input hexutil.Bytes `json:"input"` - Nonce hexutil.Uint64 `json:"nonce"` - To *common.MixedcaseAddress `json:"to"` - TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` - Value *hexutil.Big `json:"value"` - Type hexutil.Uint64 `json:"type"` - Accesses *types.AccessList `json:"accessList,omitempty"` - ChainID *hexutil.Big `json:"chainId,omitempty"` - BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"` - V *hexutil.Big `json:"v"` - R *hexutil.Big `json:"r"` - S *hexutil.Big `json:"s"` - YParity *hexutil.Uint64 `json:"yParity,omitempty"` + BlockHash *common.Hash `json:"blockHash"` + BlockNumber *hexutil.Big `json:"blockNumber"` + From common.MixedcaseAddress `json:"from"` + Gas hexutil.Uint64 `json:"gas"` + GasPrice *hexutil.Big `json:"gasPrice"` + GasFeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"` + GasTipCap *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"` + MaxFeePerBlobGas *hexutil.Big `json:"maxFeePerBlobGas,omitempty"` + Hash common.Hash `json:"hash"` + Input hexutil.Bytes `json:"input"` + Nonce hexutil.Uint64 `json:"nonce"` + To *common.MixedcaseAddress `json:"to"` + TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` + Value *hexutil.Big `json:"value"` + Type hexutil.Uint64 `json:"type"` + Accesses *types.AccessList `json:"accessList,omitempty"` + ChainID *hexutil.Big `json:"chainId,omitempty"` + BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"` + AuthorizationList []types.SetCodeAuthorization `json:"authorizationList,omitempty"` + V *hexutil.Big `json:"v"` + R *hexutil.Big `json:"r"` + S *hexutil.Big `json:"s"` + YParity *hexutil.Uint64 `json:"yParity,omitempty"` size uint64 } @@ -381,6 +382,10 @@ func NewTransaction( result.BlobVersionedHashes = tx.BlobHashes() } + if tx.Type() > types.BlobTxType { + result.AuthorizationList = tx.SetCodeAuthorizations() + } + return result, nil } diff --git a/models/transaction.go b/models/transaction.go index 83a238666..a060313fc 100644 --- a/models/transaction.go +++ b/models/transaction.go @@ -49,6 +49,7 @@ type Transaction interface { BlobHashes() []common.Hash Size() uint64 AccessList() gethTypes.AccessList + SetCodeAuthorizations() []gethTypes.SetCodeAuthorization MarshalBinary() ([]byte, error) } @@ -140,6 +141,10 @@ func (dc DirectCall) AccessList() gethTypes.AccessList { return gethTypes.AccessList{} } +func (dc DirectCall) SetCodeAuthorizations() []gethTypes.SetCodeAuthorization { + return []gethTypes.SetCodeAuthorization{} +} + func (dc DirectCall) MarshalBinary() ([]byte, error) { return dc.DirectCall.Encode() } diff --git a/tests/web3js/eth_eip_7702_contract_write_test.js b/tests/web3js/eth_eip_7702_contract_write_test.js index f558ee83b..a81aca0ef 100644 --- a/tests/web3js/eth_eip_7702_contract_write_test.js +++ b/tests/web3js/eth_eip_7702_contract_write_test.js @@ -54,11 +54,31 @@ it('should perform contract writes with relay account', async () => { }) await new Promise((res) => setTimeout(() => res(), 1500)) - let transaction = await publicClient.getTransactionReceipt({ + + let transaction = await publicClient.getTransaction({ hash: hash }) + assert.equal(transaction.from, relay.address) + assert.equal(transaction.type, 'eip7702') + assert.equal(transaction.input, '0x8129fc1c') + assert.deepEqual( + transaction.authorizationList, + [ + { + address: '0x313af46a48eeb56d200fae0edb741628255d379f', + chainId: 646, + nonce: 1, + r: '0xa79ca044cfc5754e1fcd7e0007755dc1a98894f40a2a60436fd007fe3e0298d1', + s: '0x2897829f726104b4175474d2100d6b11d7a26498debb1917d24fae324e91275c', + yParity: 0 + } + ] + ) + + let txReceipt = await publicClient.getTransactionReceipt({ hash: hash }) - assert.equal(transaction.status, 'success') - assert.equal(transaction.type, 'eip7702') + assert.equal(txReceipt.from, relay.address) + assert.equal(txReceipt.status, 'success') + assert.equal(txReceipt.type, 'eip7702') hash = await walletClient.writeContract({ abi, @@ -67,11 +87,18 @@ it('should perform contract writes with relay account', async () => { }) await new Promise((res) => setTimeout(() => res(), 1500)) - transaction = await publicClient.getTransactionReceipt({ + + transaction = await publicClient.getTransaction({ hash: hash }) + assert.equal(transaction.from, relay.address) + assert.equal(transaction.type, 'eip1559') + assert.equal(transaction.input, '0x5c36b186') + + txReceipt = await publicClient.getTransactionReceipt({ hash: hash }) - assert.equal(transaction.status, 'success') - assert.equal(transaction.type, 'eip1559') + assert.equal(txReceipt.from, relay.address) + assert.equal(txReceipt.status, 'success') + assert.equal(txReceipt.type, 'eip1559') }) it('should perform contract writes with self-execution', async () => { @@ -90,11 +117,31 @@ it('should perform contract writes with self-execution', async () => { }) await new Promise((res) => setTimeout(() => res(), 1500)) - transaction = await publicClient.getTransactionReceipt({ + + let transaction = await publicClient.getTransaction({ hash: hash }) + assert.equal(transaction.from, relay.address) + assert.equal(transaction.type, 'eip7702') + assert.equal(transaction.input, '0x8129fc1c') + assert.deepEqual( + transaction.authorizationList, + [ + { + address: '0x313af46a48eeb56d200fae0edb741628255d379f', + chainId: 646, + nonce: 4, + r: '0xf4bc19cca28390f3628cfcda9076a8744b77cc87fa4f7745efa83b7a06cc3514', + s: '0x1d736fecc68ee92ab6fd805d91a3e3dbf27097d3578561402d7105eeeee00bb7', + yParity: 0 + } + ] + ) + + let txReceipt = await publicClient.getTransactionReceipt({ hash: hash }) - assert.equal(transaction.status, 'success') - assert.equal(transaction.type, 'eip7702') + assert.equal(txReceipt.from, relay.address) + assert.equal(txReceipt.status, 'success') + assert.equal(txReceipt.type, 'eip7702') hash = await walletClient.writeContract({ abi, @@ -103,9 +150,11 @@ it('should perform contract writes with self-execution', async () => { }) await new Promise((res) => setTimeout(() => res(), 1500)) - transaction = await publicClient.getTransactionReceipt({ + + txReceipt = await publicClient.getTransactionReceipt({ hash: hash }) - assert.equal(transaction.status, 'success') - assert.equal(transaction.type, 'eip1559') + assert.equal(txReceipt.from, relay.address) + assert.equal(txReceipt.status, 'success') + assert.equal(txReceipt.type, 'eip1559') }) diff --git a/tests/web3js/eth_eip_7702_sending_transactions_test.js b/tests/web3js/eth_eip_7702_sending_transactions_test.js index f3fa45b85..2d9e5b782 100644 --- a/tests/web3js/eth_eip_7702_sending_transactions_test.js +++ b/tests/web3js/eth_eip_7702_sending_transactions_test.js @@ -57,11 +57,31 @@ it('should send transactions with relay account', async () => { }) await new Promise((res) => setTimeout(() => res(), 1500)) - let transaction = await publicClient.getTransactionReceipt({ + + let transaction = await publicClient.getTransaction({ hash: hash }) + assert.equal(transaction.from, relay.address) + assert.equal(transaction.type, 'eip7702') + assert.equal(transaction.input, '0x8129fc1c') + assert.deepEqual( + transaction.authorizationList, + [ + { + address: '0x313af46a48eeb56d200fae0edb741628255d379f', + chainId: 646, + nonce: 1, + r: '0xa79ca044cfc5754e1fcd7e0007755dc1a98894f40a2a60436fd007fe3e0298d1', + s: '0x2897829f726104b4175474d2100d6b11d7a26498debb1917d24fae324e91275c', + yParity: 0 + } + ] + ) + + let txReceipt = await publicClient.getTransactionReceipt({ hash: hash }) - assert.equal(transaction.status, 'success') - assert.equal(transaction.type, 'eip7702') + assert.equal(txReceipt.from, relay.address) + assert.equal(txReceipt.status, 'success') + assert.equal(txReceipt.type, 'eip7702') hash = await walletClient.sendTransaction({ data: encodeFunctionData({ @@ -72,11 +92,13 @@ it('should send transactions with relay account', async () => { }) await new Promise((res) => setTimeout(() => res(), 1500)) - transaction = await publicClient.getTransactionReceipt({ + + txReceipt = await publicClient.getTransactionReceipt({ hash: hash }) - assert.equal(transaction.status, 'success') - assert.equal(transaction.type, 'eip1559') + assert.equal(txReceipt.from, relay.address) + assert.equal(txReceipt.status, 'success') + assert.equal(txReceipt.type, 'eip1559') }) it('should send self-executing transactions', async () => { @@ -97,11 +119,31 @@ it('should send self-executing transactions', async () => { }) await new Promise((res) => setTimeout(() => res(), 1500)) - let transaction = await publicClient.getTransactionReceipt({ + + let transaction = await publicClient.getTransaction({ hash: hash }) + assert.equal(transaction.from, relay.address) + assert.equal(transaction.type, 'eip7702') + assert.equal(transaction.input, '0x8129fc1c') + assert.deepEqual( + transaction.authorizationList, + [ + { + address: '0x313af46a48eeb56d200fae0edb741628255d379f', + chainId: 646, + nonce: 4, + r: '0xf4bc19cca28390f3628cfcda9076a8744b77cc87fa4f7745efa83b7a06cc3514', + s: '0x1d736fecc68ee92ab6fd805d91a3e3dbf27097d3578561402d7105eeeee00bb7', + yParity: 0 + } + ] + ) + + let txReceipt = await publicClient.getTransactionReceipt({ hash: hash }) - assert.equal(transaction.status, 'success') - assert.equal(transaction.type, 'eip7702') + assert.equal(txReceipt.from, relay.address) + assert.equal(txReceipt.status, 'success') + assert.equal(txReceipt.type, 'eip7702') hash = await walletClient.sendTransaction({ data: encodeFunctionData({ @@ -112,9 +154,11 @@ it('should send self-executing transactions', async () => { }) await new Promise((res) => setTimeout(() => res(), 1500)) - transaction = await publicClient.getTransactionReceipt({ + + txReceipt = await publicClient.getTransactionReceipt({ hash: hash }) - assert.equal(transaction.status, 'success') - assert.equal(transaction.type, 'eip1559') + assert.equal(txReceipt.from, relay.address) + assert.equal(txReceipt.status, 'success') + assert.equal(txReceipt.type, 'eip1559') }) From 4398ef5bcc3693f195cf69de2cd95c9b88768558 Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Mon, 12 May 2025 11:34:26 +0300 Subject: [PATCH 52/62] Add comments to describe the tx type checks in NewTransaction --- eth/types/types.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/eth/types/types.go b/eth/types/types.go index 414f371e9..42852d075 100644 --- a/eth/types/types.go +++ b/eth/types/types.go @@ -345,6 +345,7 @@ func NewTransaction( v, r, s := tx.RawSignatureValues() + // These are the common fields through all the transaction types result := &Transaction{ Type: hexutil.Uint64(tx.Type()), From: from, @@ -362,6 +363,29 @@ func NewTransaction( size: tx.Size(), } + // After the Pectra hard-fork, the full list of supported tx types is: + // LegacyTxType = 0x00 + // AccessListTxType = 0x01 + // DynamicFeeTxType = 0x02 + // BlobTxType = 0x03 + // SetCodeTxType = 0x04 + + // Each newly-added tx type, is backwards-compatible. + // It supports the fields of previous tx types and it + // introduces its own fields as well. By comparing + // with `if tx.Type() > SomeTxType`, we are + // able to save some duplicated lines of code, and + // incrementally apply the extra fields to their + // respective tx type. For example, when: + // `tx.Type()` is `DynamicFeeTxType`, the + // following conditions are true: + // `tx.Type() > LegacyTxType` + // `tx.Type() > AccessListTxType` + // but the rest are not. + // A `DynamicFeeTxType` supports the fields of + // `LegacyTxType` & `AccessListTxType`, but not + // the fields of `SetCodeTxType`. + if tx.Type() > types.LegacyTxType { al := tx.AccessList() yparity := hexutil.Uint64(v.Sign()) @@ -382,6 +406,8 @@ func NewTransaction( result.BlobVersionedHashes = tx.BlobHashes() } + // The `AuthorizationList` field became available with the introduction + // of https://eip7702.io/#specification, under the `SetCodeTxType` if tx.Type() > types.BlobTxType { result.AuthorizationList = tx.SetCodeAuthorizations() } From 644f35975c552c834c551c326ac6413d137ba977 Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Wed, 25 Jun 2025 16:39:36 +0300 Subject: [PATCH 53/62] Update to Cadence v1.6.2 & latest flow-go --- go.mod | 49 ++++++++-------- go.sum | 111 +++++++++++++++++------------------ tests/go.mod | 53 ++++++++--------- tests/go.sum | 148 ++++++++++++++++++++++++++++------------------- tests/helpers.go | 44 ++++++++------ 5 files changed, 219 insertions(+), 186 deletions(-) diff --git a/go.mod b/go.mod index 2f8b19c40..16eeb35ee 100644 --- a/go.mod +++ b/go.mod @@ -10,9 +10,9 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/holiman/uint256 v1.3.2 github.com/onflow/atree v0.10.0 - github.com/onflow/cadence v1.4.0 - github.com/onflow/flow-go v0.41.0-rc.2 - github.com/onflow/flow-go-sdk v1.5.0 + github.com/onflow/cadence v1.6.2 + github.com/onflow/flow-go v0.41.0-rc.1.0.20250618213905-cfbf84027792 + github.com/onflow/flow-go-sdk v1.6.1 github.com/onflow/go-ethereum v1.15.10 github.com/prometheus/client_golang v1.20.5 github.com/rs/cors v1.8.0 @@ -25,14 +25,18 @@ require ( go.uber.org/atomic v1.11.0 go.uber.org/ratelimit v0.3.1 golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 - golang.org/x/sync v0.13.0 + golang.org/x/sync v0.14.0 google.golang.org/grpc v1.72.0 ) require ( + cloud.google.com/go v0.120.0 // indirect + cloud.google.com/go/auth v0.16.1 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect cloud.google.com/go/compute/metadata v0.6.0 // indirect - cloud.google.com/go/iam v1.1.6 // indirect - cloud.google.com/go/kms v1.15.7 // indirect + cloud.google.com/go/iam v1.5.2 // indirect + cloud.google.com/go/kms v1.22.0 // indirect + cloud.google.com/go/longrunning v0.6.7 // indirect github.com/DataDog/zstd v1.5.2 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/SaveTheRbtz/mph v0.1.1-0.20240117162131-4166ec7869bc // indirect @@ -81,14 +85,13 @@ require ( github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v1.2.4 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect - github.com/google/s2a-go v0.1.7 // indirect + github.com/google/s2a-go v0.1.9 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect - github.com/googleapis/gax-go/v2 v2.12.2 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect + github.com/googleapis/gax-go/v2 v2.14.1 // indirect github.com/gorilla/websocket v1.5.3 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -186,38 +189,36 @@ require ( github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/turbolent/prettier v0.0.0-20220320183459-661cc755135d // indirect - github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect github.com/vmihailenco/msgpack/v4 v4.3.11 // indirect github.com/vmihailenco/tagparser v0.1.1 // indirect github.com/wlynxg/anet v0.0.5 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/zeebo/blake3 v0.2.4 // indirect - go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect - go.opentelemetry.io/otel v1.34.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect + go.opentelemetry.io/otel v1.35.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 // indirect - go.opentelemetry.io/otel/metric v1.34.0 // indirect - go.opentelemetry.io/otel/sdk v1.34.0 // indirect - go.opentelemetry.io/otel/trace v1.34.0 // indirect + go.opentelemetry.io/otel/metric v1.35.0 // indirect + go.opentelemetry.io/otel/sdk v1.35.0 // indirect + go.opentelemetry.io/otel/trace v1.35.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.37.0 // indirect golang.org/x/net v0.39.0 // indirect - golang.org/x/oauth2 v0.26.0 // indirect + golang.org/x/oauth2 v0.30.0 // indirect golang.org/x/sys v0.32.0 // indirect golang.org/x/text v0.24.0 // indirect - golang.org/x/time v0.9.0 // indirect + golang.org/x/time v0.11.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect gonum.org/v1/gonum v0.16.0 // indirect - google.golang.org/api v0.169.0 // indirect + google.golang.org/api v0.232.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a // indirect + google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250428153025-10db94c68c34 // indirect google.golang.org/protobuf v1.36.6 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 0ca20afb7..3e9bb1fa8 100644 --- a/go.sum +++ b/go.sum @@ -17,8 +17,12 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= -cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= +cloud.google.com/go v0.120.0 h1:wc6bgG9DHyKqF5/vQvX1CiZrtHnxJjBlKUyF9nP6meA= +cloud.google.com/go v0.120.0/go.mod h1:/beW32s8/pGRuj4IILWQNd4uuebeT4dkOhKmkfit64Q= +cloud.google.com/go/auth v0.16.1 h1:XrXauHMd30LhQYVRHLGvJiYeczweKQXZxsTbV9TiguU= +cloud.google.com/go/auth v0.16.1/go.mod h1:1howDHJ5IETh/LwYs3ZxvlkXF48aSqqJUM+5o02dNOI= +cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= +cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -29,10 +33,12 @@ cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4 cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= -cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= -cloud.google.com/go/kms v1.15.7 h1:7caV9K3yIxvlQPAcaFffhlT7d1qpxjB1wHBtjWa13SM= -cloud.google.com/go/kms v1.15.7/go.mod h1:ub54lbsa6tDkUwnu4W7Yt1aAIFLnspgh0kPGToDukeI= +cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8= +cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE= +cloud.google.com/go/kms v1.22.0 h1:dBRIj7+GDeeEvatJeTB19oYZNV0aj6wEqSIT/7gLqtk= +cloud.google.com/go/kms v1.22.0/go.mod h1:U7mf8Sva5jpOb4bxYZdtw/9zsbIjrklYwPcvMk34AL8= +cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE= +cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -252,8 +258,6 @@ github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -295,12 +299,11 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +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/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -324,18 +327,18 @@ github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8q github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= -github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= +github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= +github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 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/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= -github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= +github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4= +github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA= -github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= +github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q= +github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= @@ -549,8 +552,8 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onflow/atree v0.10.0 h1:LFYlRgb0fjs8vezBW/N/tzi+ijLMssjHwIwoV4RwYaA= github.com/onflow/atree v0.10.0/go.mod h1:aqnnE8Os77JiBIeC7UcbeM7N1V3Ys5XWH0CykeMpym0= -github.com/onflow/cadence v1.4.0 h1:78s0q76tf5iKEfGLCtw9+dJw0oyRbj6ycVompPOJz9k= -github.com/onflow/cadence v1.4.0/go.mod h1:MBHOSmj81EtNEGjvYK3UEaFMMrN6jo5wt9U7jvDVLUw= +github.com/onflow/cadence v1.6.2 h1:bzJmfAzEv+8dggmm3HwyH6PhsYLrXqfx6GcI+nPYJCU= +github.com/onflow/cadence v1.6.2/go.mod h1:MBHOSmj81EtNEGjvYK3UEaFMMrN6jo5wt9U7jvDVLUw= github.com/onflow/crypto v0.25.3 h1:XQ3HtLsw8h1+pBN+NQ1JYM9mS2mVXTyg55OldaAIF7U= github.com/onflow/crypto v0.25.3/go.mod h1:+1igaXiK6Tjm9wQOBD1EGwW7bYWMUGKtwKJ/2QL/OWs= github.com/onflow/flow-core-contracts/lib/go/contracts v1.6.1 h1:n2NTsVT4iH7snqW6nkP1PnxHmgEMCh3XZpbdSIqweO4= @@ -563,10 +566,10 @@ github.com/onflow/flow-ft/lib/go/contracts v1.0.1 h1:Ts5ob+CoCY2EjEd0W6vdLJ7hLL3 github.com/onflow/flow-ft/lib/go/contracts v1.0.1/go.mod h1:PwsL8fC81cjnUnTfmyL/HOIyHnyaw/JA474Wfj2tl6A= github.com/onflow/flow-ft/lib/go/templates v1.0.1 h1:FDYKAiGowABtoMNusLuRCILIZDtVqJ/5tYI4VkF5zfM= github.com/onflow/flow-ft/lib/go/templates v1.0.1/go.mod h1:uQ8XFqmMK2jxyBSVrmyuwdWjTEb+6zGjRYotfDJ5pAE= -github.com/onflow/flow-go v0.41.0-rc.2 h1:3IBwx8JzMvsEcsD97g4LjqC/ur/NEduEg25LY9U3GPY= -github.com/onflow/flow-go v0.41.0-rc.2/go.mod h1:7qgYhNQ3COT3USvk4goxAOfnvd/YNt28ddFGbheF1F4= -github.com/onflow/flow-go-sdk v1.5.0 h1:ZThmczgmeaSrKY47vh2m9klr8T+khtaLi2Ea1hscpV4= -github.com/onflow/flow-go-sdk v1.5.0/go.mod h1:fiNTgv1dMFb3T6P12QYMYDNWCoxkKQ/9McMppuCszng= +github.com/onflow/flow-go v0.41.0-rc.1.0.20250618213905-cfbf84027792 h1:/uQrnD16PMPqYiMTqYNRKnmxw83S0Ejd6zhLtXzixFY= +github.com/onflow/flow-go v0.41.0-rc.1.0.20250618213905-cfbf84027792/go.mod h1:vEpa6y5ef8QniyjpqXp0o1ohmTI3fYGwE7oGasivpa4= +github.com/onflow/flow-go-sdk v1.6.1 h1:Gf+4fV2rvKN8jyubtcQfuJPpbeHmhPWbUv8YvhWnUqg= +github.com/onflow/flow-go-sdk v1.6.1/go.mod h1:Ssf06IM5qZ2ctFe7NCBPQOxUashwm57N9AywghGyqfU= github.com/onflow/flow-nft/lib/go/contracts v1.2.4 h1:gWJgSSgIGo0qWOqr90+khQ69VoYF9vNlqzF+Yh6YYy4= github.com/onflow/flow-nft/lib/go/contracts v1.2.4/go.mod h1:eZ9VMMNfCq0ho6kV25xJn1kXeCfxnkhj3MwF3ed08gY= github.com/onflow/flow-nft/lib/go/templates v1.2.1 h1:SAALMZPDw9Eb9p5kSLnmnFxjyig1MLiT4JUlLp0/bSE= @@ -753,7 +756,6 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 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.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= @@ -778,8 +780,6 @@ github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGr github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= -github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack/v4 v4.3.11 h1:Q47CePddpNGNhk4GCnAx9DDtASi2rasatE0cd26cZoE= github.com/vmihailenco/msgpack/v4 v4.3.11/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY= @@ -810,28 +810,26 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM= -go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= -go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= +go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= +go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 h1:K0XaT3DwHAcV4nKLzcQvwAgSyisUghWoY20I7huthMk= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0/go.mod h1:B5Ki776z/MBnVha1Nzwp5arlzBbE3+1jk+pGmaP5HME= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 h1:FFeLy03iVTXP6ffeN2iXrxfGsZGCjVx0/4KlizjyBwU= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0/go.mod h1:TMu73/k1CP8nBUpDLc71Wj/Kf7ZS9FK5b53VapRsP9o= -go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= -go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= -go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= -go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= -go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= -go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= -go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= -go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= +go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= +go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= +go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= +go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= +go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o= +go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= +go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= +go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -947,7 +945,6 @@ golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -971,8 +968,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE= -golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -986,8 +983,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/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.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= -golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= +golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1084,8 +1081,8 @@ golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= -golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= +golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1169,8 +1166,8 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513 google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.169.0 h1:QwWPy71FgMWqJN/l6jVlFHUa29a7dcUy02I8o799nPY= -google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= +google.golang.org/api v0.232.0 h1:qGnmaIMf7KcuwHOlF3mERVzChloDYwRfOJOrHt8YC3I= +google.golang.org/api v0.232.0/go.mod h1:p9QCfBWZk1IJETUdbTKloR5ToFdKbYh2fkjsUL6vNoY= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1216,12 +1213,12 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= -google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= -google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a h1:nwKuGPlUAt+aR+pcrkfFRrTU1BVrSmYyYMxYbUIVHr0= -google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a/go.mod h1:3kWAYMk1I75K4vykHtKt2ycnOgpA6974V7bREqbsenU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a h1:51aaUVRocpvUOSQKM6Q7VuoaktNIaMCLuhZB6DKksq4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a/go.mod h1:uRxBH1mhmO8PGhU89cMcHaXKZqO+OfakD8QQO0oYwlQ= +google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb h1:ITgPrl429bc6+2ZraNSzMDk3I95nmQln2fuPstKwFDE= +google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:sAo5UzpjUwgFBCzupwhcLcxHVDK7vG5IqI30YnwX2eE= +google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 h1:vPV0tzlsK6EzEDHNNH5sa7Hs9bd7iXR7B1tSiPepkV0= +google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:pKLAc5OolXC3ViWGI62vvC0n10CpwAtRcTNCFwTKBEw= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250428153025-10db94c68c34 h1:h6p3mQqrmT1XkHVTfzLdNz1u7IhINeZkz67/xTbOuWs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250428153025-10db94c68c34/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= diff --git a/tests/go.mod b/tests/go.mod index c2cf90dc7..8e2868aa9 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -6,22 +6,26 @@ toolchain go1.23.8 require ( github.com/goccy/go-json v0.10.4 - github.com/onflow/cadence v1.4.0 + github.com/onflow/cadence v1.6.2 github.com/onflow/crypto v0.25.3 - github.com/onflow/flow-emulator v1.4.2-0.20250502072945-8c69ae3a424b + github.com/onflow/flow-emulator v1.5.2-0.20250620100838-4e2f7bc18c24 github.com/onflow/flow-evm-gateway v0.0.0-20240201154855-4d4d3d3f19c7 - github.com/onflow/flow-go v0.41.0-rc.2 - github.com/onflow/flow-go-sdk v1.5.0 + github.com/onflow/flow-go v0.41.0-rc.1.0.20250618213905-cfbf84027792 + github.com/onflow/flow-go-sdk v1.6.1 github.com/onflow/go-ethereum v1.15.10 github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.10.0 - golang.org/x/sync v0.13.0 + golang.org/x/sync v0.14.0 ) require ( + cloud.google.com/go v0.120.0 // indirect + cloud.google.com/go/auth v0.16.1 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect cloud.google.com/go/compute/metadata v0.6.0 // indirect - cloud.google.com/go/iam v1.1.6 // indirect - cloud.google.com/go/kms v1.15.7 // indirect + cloud.google.com/go/iam v1.5.2 // indirect + cloud.google.com/go/kms v1.22.0 // indirect + cloud.google.com/go/longrunning v0.6.7 // indirect github.com/DataDog/zstd v1.5.2 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/SaveTheRbtz/mph v0.1.1-0.20240117162131-4166ec7869bc // indirect @@ -81,16 +85,15 @@ require ( github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v1.2.4 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // 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.6.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/google/go-dap v0.11.0 // indirect github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect - github.com/google/s2a-go v0.1.7 // indirect + github.com/google/s2a-go v0.1.9 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect - github.com/googleapis/gax-go/v2 v2.12.2 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect + github.com/googleapis/gax-go/v2 v2.14.1 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/websocket v1.5.3 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect @@ -207,22 +210,20 @@ require ( github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/turbolent/prettier v0.0.0-20220320183459-661cc755135d // indirect - github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect github.com/vmihailenco/msgpack/v4 v4.3.11 // indirect github.com/vmihailenco/tagparser v0.1.1 // indirect github.com/wlynxg/anet v0.0.5 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/zeebo/blake3 v0.2.4 // indirect - go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect - go.opentelemetry.io/otel v1.34.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect + go.opentelemetry.io/otel v1.35.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 // indirect - go.opentelemetry.io/otel/metric v1.34.0 // indirect - go.opentelemetry.io/otel/sdk v1.34.0 // indirect - go.opentelemetry.io/otel/trace v1.34.0 // indirect + go.opentelemetry.io/otel/metric v1.35.0 // indirect + go.opentelemetry.io/otel/sdk v1.35.0 // indirect + go.opentelemetry.io/otel/trace v1.35.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect @@ -231,18 +232,18 @@ require ( golang.org/x/crypto v0.37.0 // indirect golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 // indirect golang.org/x/net v0.39.0 // indirect - golang.org/x/oauth2 v0.26.0 // indirect + golang.org/x/oauth2 v0.30.0 // indirect golang.org/x/sys v0.32.0 // indirect golang.org/x/term v0.31.0 // indirect golang.org/x/text v0.24.0 // indirect - golang.org/x/time v0.9.0 // indirect + golang.org/x/time v0.11.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect gonum.org/v1/gonum v0.16.0 // indirect - google.golang.org/api v0.169.0 // indirect + google.golang.org/api v0.232.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a // indirect + google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250428153025-10db94c68c34 // indirect google.golang.org/grpc v1.72.0 // indirect google.golang.org/protobuf v1.36.6 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/tests/go.sum b/tests/go.sum index a649a11dc..b1c042886 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -1,3 +1,5 @@ +cel.dev/expr v0.20.0 h1:OunBvVCfvpWlt4dN7zg3FM6TDkzOePe1+foGJ9AXeeI= +cel.dev/expr v0.20.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -17,8 +19,12 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= -cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= +cloud.google.com/go v0.120.0 h1:wc6bgG9DHyKqF5/vQvX1CiZrtHnxJjBlKUyF9nP6meA= +cloud.google.com/go v0.120.0/go.mod h1:/beW32s8/pGRuj4IILWQNd4uuebeT4dkOhKmkfit64Q= +cloud.google.com/go/auth v0.16.1 h1:XrXauHMd30LhQYVRHLGvJiYeczweKQXZxsTbV9TiguU= +cloud.google.com/go/auth v0.16.1/go.mod h1:1howDHJ5IETh/LwYs3ZxvlkXF48aSqqJUM+5o02dNOI= +cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= +cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -29,10 +35,14 @@ cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4 cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= -cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= -cloud.google.com/go/kms v1.15.7 h1:7caV9K3yIxvlQPAcaFffhlT7d1qpxjB1wHBtjWa13SM= -cloud.google.com/go/kms v1.15.7/go.mod h1:ub54lbsa6tDkUwnu4W7Yt1aAIFLnspgh0kPGToDukeI= +cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8= +cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE= +cloud.google.com/go/kms v1.22.0 h1:dBRIj7+GDeeEvatJeTB19oYZNV0aj6wEqSIT/7gLqtk= +cloud.google.com/go/kms v1.22.0/go.mod h1:U7mf8Sva5jpOb4bxYZdtw/9zsbIjrklYwPcvMk34AL8= +cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE= +cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY= +cloud.google.com/go/monitoring v1.24.0 h1:csSKiCJ+WVRgNkRzzz3BPoGjFhjPY23ZTcaenToJxMM= +cloud.google.com/go/monitoring v1.24.0/go.mod h1:Bd1PRK5bmQBQNnuGwHBfUamAV1ys9049oEPHnn4pcsc= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -43,13 +53,19 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg= -cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY= +cloud.google.com/go/storage v1.50.0 h1:3TbVkzTooBvnZsk7WaAQfOsNrdoM8QHusXA1cpk6QJs= +cloud.google.com/go/storage v1.50.0/go.mod h1:l7XeiD//vx5lfqE3RavfmU9yvk5Pp0Zhcv482poyafY= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.26.0 h1:f2Qw/Ehhimh5uO1fayV0QIW7DShEQqhtUfhYc+cBPlw= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.26.0/go.mod h1:2bIszWvQRlJVmJLiuLhukLImRjKPcYdzzsx6darK02A= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0 h1:5IT7xOdq17MtcdtL/vtl6mGfzhaq4m4vpollPRmlsBQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0/go.mod h1:ZV4VOm0/eHR06JLrXWe09068dHpr3TRpY9Uo7T+anuA= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0 h1:ig/FpDD2JofP/NExKQUbn7uOSZzJAQqogfqluZK4ed4= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= github.com/Jorropo/jsync v1.0.1 h1:6HgRolFZnsdfzRUj+ImB9og1JYOxQoReSywkHOGSaUU= github.com/Jorropo/jsync v1.0.1/go.mod h1:jCOZj3vrBCri3bSU3ErUYvevKlnbssrXeCivybS5ABQ= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= @@ -157,6 +173,8 @@ github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42 h1:Om6kYQYDUk5wWbT0t0q6pvyM49i9XZAv9dDrkDA7gjk= +github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= @@ -259,7 +277,12 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M= +github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A= +github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= +github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA= github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-ethereum v1.13.10 h1:Ppdil79nN+Vc+mXfge0AuUgmKWuVv4eMqzoIVSdqZek= @@ -307,6 +330,8 @@ github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3Bop github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E= +github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= @@ -377,8 +402,6 @@ github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -421,11 +444,10 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +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/go-dap v0.11.0 h1:SpAZJL41rOOvd85PuLCCLE1dteTQOyKNnn0H3DBHywo= github.com/google/go-dap v0.11.0/go.mod h1:HAeyoSd2WIfTfg+0GRXcFrb+RnojAtGNh+k+XTIxJDE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -450,19 +472,19 @@ github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8q github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= -github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= +github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= +github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 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/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= -github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= +github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4= +github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA= -github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= +github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q= +github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -782,26 +804,26 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onflow/atree v0.10.0 h1:LFYlRgb0fjs8vezBW/N/tzi+ijLMssjHwIwoV4RwYaA= github.com/onflow/atree v0.10.0/go.mod h1:aqnnE8Os77JiBIeC7UcbeM7N1V3Ys5XWH0CykeMpym0= -github.com/onflow/cadence v1.4.0 h1:78s0q76tf5iKEfGLCtw9+dJw0oyRbj6ycVompPOJz9k= -github.com/onflow/cadence v1.4.0/go.mod h1:MBHOSmj81EtNEGjvYK3UEaFMMrN6jo5wt9U7jvDVLUw= +github.com/onflow/cadence v1.6.2 h1:bzJmfAzEv+8dggmm3HwyH6PhsYLrXqfx6GcI+nPYJCU= +github.com/onflow/cadence v1.6.2/go.mod h1:MBHOSmj81EtNEGjvYK3UEaFMMrN6jo5wt9U7jvDVLUw= github.com/onflow/crypto v0.25.3 h1:XQ3HtLsw8h1+pBN+NQ1JYM9mS2mVXTyg55OldaAIF7U= github.com/onflow/crypto v0.25.3/go.mod h1:+1igaXiK6Tjm9wQOBD1EGwW7bYWMUGKtwKJ/2QL/OWs= github.com/onflow/flow-core-contracts/lib/go/contracts v1.6.1 h1:n2NTsVT4iH7snqW6nkP1PnxHmgEMCh3XZpbdSIqweO4= github.com/onflow/flow-core-contracts/lib/go/contracts v1.6.1/go.mod h1:3tMXL4npVbk/F1X6SqxZWelQn0pyGvMBVbUXsgvC6Is= github.com/onflow/flow-core-contracts/lib/go/templates v1.6.1 h1:Y0bDvS5fTOCrKr7QFl0by3qTq7MFnauVnHoxwW6nQzo= github.com/onflow/flow-core-contracts/lib/go/templates v1.6.1/go.mod h1:pN768Al/wLRlf3bwugv9TyxniqJxMu4sxnX9eQJam64= -github.com/onflow/flow-emulator v1.4.2-0.20250502072945-8c69ae3a424b h1:z7R5IwaGebAjli1oPQ77SRje8f0VVG9OxfkZDJIp5pU= -github.com/onflow/flow-emulator v1.4.2-0.20250502072945-8c69ae3a424b/go.mod h1:xqAWYYyL3ZO7aQT3DtZLTI0sq8TlV5zGjNmMkjcmL8c= +github.com/onflow/flow-emulator v1.5.2-0.20250620100838-4e2f7bc18c24 h1:iw4krYwJRuVmlIR95V5Izo2r6HURhbq9Hvz7+FQoG30= +github.com/onflow/flow-emulator v1.5.2-0.20250620100838-4e2f7bc18c24/go.mod h1:HkO7v/hRqmWPGhDkOx7xmOc2BB0XM+diASmpBdQoXN4= github.com/onflow/flow-evm-bridge v0.1.0 h1:7X2osvo4NnQgHj8aERUmbYtv9FateX8liotoLnPL9nM= github.com/onflow/flow-evm-bridge v0.1.0/go.mod h1:5UYwsnu6WcBNrwitGFxphCl5yq7fbWYGYuiCSTVF6pk= github.com/onflow/flow-ft/lib/go/contracts v1.0.1 h1:Ts5ob+CoCY2EjEd0W6vdLJ7hLL3SsEftzXG2JlmSe24= github.com/onflow/flow-ft/lib/go/contracts v1.0.1/go.mod h1:PwsL8fC81cjnUnTfmyL/HOIyHnyaw/JA474Wfj2tl6A= github.com/onflow/flow-ft/lib/go/templates v1.0.1 h1:FDYKAiGowABtoMNusLuRCILIZDtVqJ/5tYI4VkF5zfM= github.com/onflow/flow-ft/lib/go/templates v1.0.1/go.mod h1:uQ8XFqmMK2jxyBSVrmyuwdWjTEb+6zGjRYotfDJ5pAE= -github.com/onflow/flow-go v0.41.0-rc.2 h1:3IBwx8JzMvsEcsD97g4LjqC/ur/NEduEg25LY9U3GPY= -github.com/onflow/flow-go v0.41.0-rc.2/go.mod h1:7qgYhNQ3COT3USvk4goxAOfnvd/YNt28ddFGbheF1F4= -github.com/onflow/flow-go-sdk v1.5.0 h1:ZThmczgmeaSrKY47vh2m9klr8T+khtaLi2Ea1hscpV4= -github.com/onflow/flow-go-sdk v1.5.0/go.mod h1:fiNTgv1dMFb3T6P12QYMYDNWCoxkKQ/9McMppuCszng= +github.com/onflow/flow-go v0.41.0-rc.1.0.20250618213905-cfbf84027792 h1:/uQrnD16PMPqYiMTqYNRKnmxw83S0Ejd6zhLtXzixFY= +github.com/onflow/flow-go v0.41.0-rc.1.0.20250618213905-cfbf84027792/go.mod h1:vEpa6y5ef8QniyjpqXp0o1ohmTI3fYGwE7oGasivpa4= +github.com/onflow/flow-go-sdk v1.6.1 h1:Gf+4fV2rvKN8jyubtcQfuJPpbeHmhPWbUv8YvhWnUqg= +github.com/onflow/flow-go-sdk v1.6.1/go.mod h1:Ssf06IM5qZ2ctFe7NCBPQOxUashwm57N9AywghGyqfU= github.com/onflow/flow-nft/lib/go/contracts v1.2.4 h1:gWJgSSgIGo0qWOqr90+khQ69VoYF9vNlqzF+Yh6YYy4= github.com/onflow/flow-nft/lib/go/contracts v1.2.4/go.mod h1:eZ9VMMNfCq0ho6kV25xJn1kXeCfxnkhj3MwF3ed08gY= github.com/onflow/flow-nft/lib/go/templates v1.2.1 h1:SAALMZPDw9Eb9p5kSLnmnFxjyig1MLiT4JUlLp0/bSE= @@ -905,6 +927,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= 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= @@ -1035,6 +1059,8 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= +github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE= +github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= @@ -1051,7 +1077,6 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 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.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= @@ -1087,8 +1112,6 @@ github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= -github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= -github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack/v4 v4.3.11 h1:Q47CePddpNGNhk4GCnAx9DDtASi2rasatE0cd26cZoE= github.com/vmihailenco/msgpack/v4 v4.3.11/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY= @@ -1114,6 +1137,8 @@ github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= +github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM= +github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -1131,24 +1156,26 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM= -go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= -go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/contrib/detectors/gcp v1.34.0 h1:JRxssobiPg23otYU5SbWtQC//snGVIM3Tx6QRzlQBao= +go.opentelemetry.io/contrib/detectors/gcp v1.34.0/go.mod h1:cV4BMFcscUR/ckqLkbfQmF0PRsq8w/lMGzdbCSveBHo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= +go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= +go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 h1:K0XaT3DwHAcV4nKLzcQvwAgSyisUghWoY20I7huthMk= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0/go.mod h1:B5Ki776z/MBnVha1Nzwp5arlzBbE3+1jk+pGmaP5HME= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 h1:FFeLy03iVTXP6ffeN2iXrxfGsZGCjVx0/4KlizjyBwU= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0/go.mod h1:TMu73/k1CP8nBUpDLc71Wj/Kf7ZS9FK5b53VapRsP9o= -go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= -go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= -go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= -go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= -go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= -go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= -go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= -go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= +go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= +go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= +go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= +go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= +go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o= +go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= +go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= +go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1285,7 +1312,6 @@ golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -1309,8 +1335,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE= -golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1324,8 +1350,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/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.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= -golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= +golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1436,8 +1462,8 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= -golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= +golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1526,8 +1552,8 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513 google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.169.0 h1:QwWPy71FgMWqJN/l6jVlFHUa29a7dcUy02I8o799nPY= -google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= +google.golang.org/api v0.232.0 h1:qGnmaIMf7KcuwHOlF3mERVzChloDYwRfOJOrHt8YC3I= +google.golang.org/api v0.232.0/go.mod h1:p9QCfBWZk1IJETUdbTKloR5ToFdKbYh2fkjsUL6vNoY= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1577,14 +1603,14 @@ google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= -google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= -google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a h1:nwKuGPlUAt+aR+pcrkfFRrTU1BVrSmYyYMxYbUIVHr0= -google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a/go.mod h1:3kWAYMk1I75K4vykHtKt2ycnOgpA6974V7bREqbsenU= -google.golang.org/genproto/googleapis/bytestream v0.0.0-20240304161311-37d4d3c04a78 h1:YqFWYZXim8bG9v68xU8WjTZmYKb5M5dMeSOWIp6jogI= -google.golang.org/genproto/googleapis/bytestream v0.0.0-20240304161311-37d4d3c04a78/go.mod h1:vh/N7795ftP0AkN1w8XKqN4w1OdUKXW5Eummda+ofv8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a h1:51aaUVRocpvUOSQKM6Q7VuoaktNIaMCLuhZB6DKksq4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a/go.mod h1:uRxBH1mhmO8PGhU89cMcHaXKZqO+OfakD8QQO0oYwlQ= +google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb h1:ITgPrl429bc6+2ZraNSzMDk3I95nmQln2fuPstKwFDE= +google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:sAo5UzpjUwgFBCzupwhcLcxHVDK7vG5IqI30YnwX2eE= +google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 h1:vPV0tzlsK6EzEDHNNH5sa7Hs9bd7iXR7B1tSiPepkV0= +google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:pKLAc5OolXC3ViWGI62vvC0n10CpwAtRcTNCFwTKBEw= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20250428153025-10db94c68c34 h1:nfEb4Q4usCEhvyA4vmf47NmO3alop2ab5p5gupICWU4= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20250428153025-10db94c68c34/go.mod h1:h6yxum/C2qRb4txaZRLDHK8RyS0H/o2oEDeKY4onY/Y= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250428153025-10db94c68c34 h1:h6p3mQqrmT1XkHVTfzLdNz1u7IhINeZkz67/xTbOuWs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250428153025-10db94c68c34/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= diff --git a/tests/helpers.go b/tests/helpers.go index b0eb8ee74..23971ba63 100644 --- a/tests/helpers.go +++ b/tests/helpers.go @@ -92,6 +92,8 @@ func startEmulator(createTestAccounts bool) (*server.EmulatorServer, error) { Host: "localhost", TransactionExpiry: 10, TransactionMaxGasLimit: flow.DefaultMaxTransactionGasLimit, + SetupEVMEnabled: true, + SetupVMBridgeEnabled: false, }) go func() { @@ -231,35 +233,41 @@ func setupTestAccounts(emu emulator.Emulator) error { transaction(eoaAddress: [UInt8; 20]) { let fundVault: @FlowToken.Vault let auth: auth(Capabilities, Storage) &Account - + let coa: auth(EVM.Call) &EVM.CadenceOwnedAccount + prepare(signer: auth(Capabilities, Storage) &Account) { let vaultRef = signer.storage.borrow( from: /storage/flowTokenVault ) ?? panic("Could not borrow reference to the owner's Vault!") - + self.fundVault <- vaultRef.withdraw(amount: 10.0) as! @FlowToken.Vault self.auth = signer + + if !signer.storage.check<@EVM.CadenceOwnedAccount>(from: /storage/evm) { + signer.storage.save<@EVM.CadenceOwnedAccount>( + <- EVM.createCadenceOwnedAccount(), + to: /storage/evm + ) + } + + if !signer.capabilities.exists(/public/evm) { + let cap = signer.capabilities.storage.issue<&EVM.CadenceOwnedAccount>(/storage/evm) + signer.capabilities.publish(cap, at: /public/evm) + } + + self.coa = signer.storage.borrow(from: /storage/evm)! } - + execute { - let account <- EVM.createCadenceOwnedAccount() - account.deposit(from: <-self.fundVault) - + self.coa.deposit(from: <-self.fundVault) + let weiAmount: UInt = 5000000000000000000 // 5 Flow - let result = account.call( - to: EVM.EVMAddress(bytes: eoaAddress), - data: [], - gasLimit: 300000, + let result = self.coa.call( + to: EVM.EVMAddress(bytes: eoaAddress), + data: [], + gasLimit: 300000, value: EVM.Balance(attoflow: weiAmount) ) - - self.auth.storage.save<@EVM.CadenceOwnedAccount>( - <-account, - to: /storage/evm - ) - - let cap = self.auth.capabilities.storage.issue<&EVM.CadenceOwnedAccount>(/storage/evm) - self.auth.capabilities.publish(cap, at: /public/evm) } }` From 71e1ce861d7810c66985f5c02f8762fa76805324 Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Fri, 18 Jul 2025 16:52:07 +0300 Subject: [PATCH 54/62] Update RPCBlockTrackingSubscriber to use the new API for NotifyBlock --- services/ingestion/block_tracking_subscriber.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 34024e859..ee7417983 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -219,7 +219,12 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 for _, evt := range blockEvents.Events { r.keyLock.NotifyTransaction(evt.TransactionID) } - r.keyLock.NotifyBlock(blockHeader.Height) + r.keyLock.NotifyBlock( + flow.BlockHeader{ + ID: blockEvents.BlockID, + Height: blockEvents.Height, + }, + ) lastReceivedHeight = blockHeader.Height eventsChan <- evmEvents From cfa66565d0e78c2b3a8b3c9588f5fc7d2d49f727 Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Wed, 23 Jul 2025 13:44:32 +0300 Subject: [PATCH 55/62] Give blocks a chance to become sealed before calling NotifyBlock --- .../ingestion/block_tracking_subscriber.go | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index ee7417983..9c38aea6e 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -166,6 +166,8 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 close(eventsChan) }() + blockHeadersQueue := []flow.BlockHeader{} + for ctx.Err() == nil { select { case <-ctx.Done(): @@ -219,14 +221,24 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 for _, evt := range blockEvents.Events { r.keyLock.NotifyTransaction(evt.TransactionID) } - r.keyLock.NotifyBlock( - flow.BlockHeader{ - ID: blockEvents.BlockID, - Height: blockEvents.Height, - }, - ) lastReceivedHeight = blockHeader.Height + blockHeadersQueue = append(blockHeadersQueue, *blockHeader) + + // The current `blockHeader` has a status of `BlockStatusFinalized`, + // but calling `NotifyBlock` might fail if the AN has not actually + // finished syncing all collections. + // Hence, we keep a small queue of the incoming block headers, so + // that we can call `NotifyBlock` on block N-5, where N is the + // height of the current block header. This will give enough time + // for the block to be sealed. + if len(blockHeadersQueue) > 5 { + earliestBlockHeader := blockHeadersQueue[0] + r.keyLock.NotifyBlock(earliestBlockHeader) + + blockHeadersQueue = blockHeadersQueue[1:] + } + eventsChan <- evmEvents case err, ok := <-errChan: From 8b80fd0c5fe713e18d65cce437e92142abb93b75 Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Thu, 24 Jul 2025 15:27:29 +0300 Subject: [PATCH 56/62] Give blocks a better chance to become sealed before calling NotifyBlock --- services/ingestion/block_tracking_subscriber.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 9c38aea6e..5436da5c9 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -229,10 +229,10 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 // but calling `NotifyBlock` might fail if the AN has not actually // finished syncing all collections. // Hence, we keep a small queue of the incoming block headers, so - // that we can call `NotifyBlock` on block N-5, where N is the + // that we can call `NotifyBlock` on block N-15, where N is the // height of the current block header. This will give enough time // for the block to be sealed. - if len(blockHeadersQueue) > 5 { + if len(blockHeadersQueue) > 15 { earliestBlockHeader := blockHeadersQueue[0] r.keyLock.NotifyBlock(earliestBlockHeader) From f51de7222f1e2ad9982e015975d12f38e90e1994 Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Thu, 21 Aug 2025 12:21:58 +0300 Subject: [PATCH 57/62] Replace onflow/go-ethereum with ethereum/go-ethereum --- services/ingestion/block_tracking_subscriber.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 5436da5c9..27e95e150 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -7,10 +7,10 @@ import ( "strings" "time" + "github.com/ethereum/go-ethereum/core/types" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go/fvm/evm/events" flowGo "github.com/onflow/flow-go/model/flow" - "github.com/onflow/go-ethereum/core/types" "github.com/rs/zerolog" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" From 60caf94b3969b27c29d7cc5d7b1f87e7893549d0 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Mon, 20 Oct 2025 16:22:56 -0700 Subject: [PATCH 58/62] Handle missing evm block in spork root block --- .../ingestion/block_tracking_subscriber.go | 10 ++++ services/requester/cross-spork_client.go | 45 ++++++++++++++--- services/requester/cross-spork_client_test.go | 50 ++++++++++++++++--- services/testutils/mock_client.go | 3 +- 4 files changed, 91 insertions(+), 17 deletions(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 27e95e150..5bd583b5f 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -22,6 +22,7 @@ import ( ) var ErrSystemTransactionFailed = errors.New("system transaction failed") +var ErrSporkRootBlockHasNoEVMBlocks = errors.New("spork root block has no EVM blocks") var _ EventSubscriber = &RPCBlockTrackingSubscriber{} @@ -188,6 +189,10 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 blockEvents, err := r.evmEventsForBlock(ctx, blockHeader) if err != nil { + if errors.Is(err, ErrSporkRootBlockHasNoEVMBlocks) { + continue // no EVM blocks are expected in the spork root block + } + eventsChan <- models.NewBlockEventsError(err) return } @@ -369,6 +374,11 @@ func (r *RPCBlockTrackingSubscriber) getEventsByType( // The `EVM.BlockExecuted` event should be present for every Flow block. if strings.Contains(eventType, string(events.EventTypeBlockExecuted)) && len(event.Events) != 1 { + // The spork root block has no transactions, and therefore no EVM blocks. + if r.client.IsSporkRootBlockHeight(blockHeader.Height) { + return flow.BlockEvents{}, ErrSporkRootBlockHasNoEVMBlocks + } + missingEventsErr := fmt.Errorf( "received unexpected number of EVM events in block: got: %d, expected: 1", len(event.Events), diff --git a/services/requester/cross-spork_client.go b/services/requester/cross-spork_client.go index 6e8642bf9..d021150e5 100644 --- a/services/requester/cross-spork_client.go +++ b/services/requester/cross-spork_client.go @@ -61,6 +61,7 @@ func (s *sporkClients) add(logger zerolog.Logger, client access.Client) error { Msg("adding spork client") *s = append(*s, &sporkClient{ + // must use NodeRootBlockHeight here, since this is the first height available on the node. firstHeight: info.NodeRootBlockHeight, lastHeight: header.Height, client: client, @@ -108,9 +109,9 @@ func (s *sporkClients) continuous() bool { // Any API that supports cross-spork access must have a defined function // that shadows the original access Client function. type CrossSporkClient struct { - logger zerolog.Logger - sporkClients sporkClients - currentSporkFirstHeight uint64 + logger zerolog.Logger + sporkClients sporkClients + currentSporkRootHeight uint64 access.Client } @@ -122,6 +123,7 @@ func NewCrossSporkClient( logger zerolog.Logger, chainID flowGo.ChainID, ) (*CrossSporkClient, error) { + sporkRootBlockHeight := uint64(0) nodeRootBlockHeight := uint64(0) // Temp fix due to the fact that Emulator does not support the @@ -131,6 +133,19 @@ func NewCrossSporkClient( if err != nil { return nil, fmt.Errorf("failed to get node version info: %w", err) } + + if info.SporkRootBlockHeight != info.NodeRootBlockHeight { + logger.Warn(). + Uint64("spork-root-block-height", info.SporkRootBlockHeight). + Uint64("node-root-block-height", info.NodeRootBlockHeight). + Msg("spork root block height is not equal to node root block height. syncing may fail due to missing blocks.") + } + + // It's possible that the node's SporkRootBlockHeight != NodeRootBlockHeight if the node was + // bootstrapped with a block after the spork root block. In this case, using SporkRootBlockHeight + // for the checks in IsPastSpork and IsSporkRootBlockHeight is correct. However, there may be + // missing blocks in the gap between the roots. + sporkRootBlockHeight = info.SporkRootBlockHeight nodeRootBlockHeight = info.NodeRootBlockHeight } @@ -145,17 +160,31 @@ func NewCrossSporkClient( return nil, fmt.Errorf("provided past-spork clients don't create a continuous range of heights") } + // at this point, we've verified that the past spork clients form a continue range of heights. + // next, make sure the the last spork client forms a continuous range with the current spork + // client's node root block height. Note: this must be the NodeRootBlockHeight, not the + // SporkRootBlockHeight, since this is the first height available on the node. + if len(clients) > 0 && clients[len(clients)-1].lastHeight+1 != nodeRootBlockHeight { + return nil, fmt.Errorf("provided past-spork clients don't end at the spork root block height (%d != %d-1)", + clients[len(clients)-1].lastHeight, nodeRootBlockHeight) + } + return &CrossSporkClient{ - logger: logger, - currentSporkFirstHeight: nodeRootBlockHeight, - sporkClients: clients, - Client: currentSpork, + logger: logger, + currentSporkRootHeight: sporkRootBlockHeight, + sporkClients: clients, + Client: currentSpork, }, nil } // IsPastSpork will check if the provided height is contained in the previous sporks. func (c *CrossSporkClient) IsPastSpork(height uint64) bool { - return height < c.currentSporkFirstHeight + return height < c.currentSporkRootHeight +} + +// IsSporkRootBlockHeight will check if the provided height is the spork root block height. +func (c *CrossSporkClient) IsSporkRootBlockHeight(height uint64) bool { + return height == c.currentSporkRootHeight } // getClientForHeight returns the client for the given height that contains the height range. diff --git a/services/requester/cross-spork_client_test.go b/services/requester/cross-spork_client_test.go index 32c229301..800202e4a 100644 --- a/services/requester/cross-spork_client_test.go +++ b/services/requester/cross-spork_client_test.go @@ -73,14 +73,15 @@ func Test_CrossSporkClients(t *testing.T) { } func Test_CrossSpork(t *testing.T) { - t.Run("client", func(t *testing.T) { - past1Last := uint64(300) - past2Last := uint64(500) - currentLast := uint64(1000) - current := testutils.SetupClientForRange(501, currentLast) - past1 := testutils.SetupClientForRange(100, past1Last) - past2 := testutils.SetupClientForRange(301, past2Last) - + past1Last := uint64(300) + past2Last := uint64(500) + currentSporkRootHeight := uint64(501) + currentLast := uint64(1000) + past1 := testutils.SetupClientForRange(100, past1Last) + past2 := testutils.SetupClientForRange(301, past2Last) + current := testutils.SetupClientForRange(currentSporkRootHeight, currentLast) + + t.Run("clients form continuous range of heights", func(t *testing.T) { client, err := NewCrossSporkClient( current, []access.Client{past2, past1}, @@ -136,4 +137,37 @@ func Test_CrossSpork(t *testing.T) { require.ErrorContains(t, err, "invalid height not in available range: 10") }) + + t.Run("gap between current's spork root and node root heights", func(t *testing.T) { + current.GetNodeVersionInfoFunc = func(ctx context.Context) (*flow.NodeVersionInfo, error) { + return &flow.NodeVersionInfo{ + NodeRootBlockHeight: currentSporkRootHeight + 10, + SporkRootBlockHeight: currentSporkRootHeight, + }, nil + } + + client, err := NewCrossSporkClient( + current, + []access.Client{past2, past1}, + zerolog.Nop(), + flowGo.Previewnet, + ) + require.Error(t, err) + require.ErrorContains(t, err, "provided past-spork clients don't end at the spork root block height") + require.Nil(t, client) + }) + + t.Run("gap between past spork end height, and current spork root height", func(t *testing.T) { + currentWithGap := testutils.SetupClientForRange(currentSporkRootHeight+1, currentLast) + + client, err := NewCrossSporkClient( + currentWithGap, + []access.Client{past2, past1}, + zerolog.Nop(), + flowGo.Previewnet, + ) + require.Error(t, err) + require.ErrorContains(t, err, "provided past-spork clients don't end at the spork root block height") + require.Nil(t, client) + }) } diff --git a/services/testutils/mock_client.go b/services/testutils/mock_client.go index 2165b765d..56519c78a 100644 --- a/services/testutils/mock_client.go +++ b/services/testutils/mock_client.go @@ -97,7 +97,8 @@ func SetupClient(startHeight uint64, endHeight uint64) (*MockClient, chan flow.B }, GetNodeVersionInfoFunc: func(ctx context.Context) (*flow.NodeVersionInfo, error) { return &flow.NodeVersionInfo{ - NodeRootBlockHeight: startHeight, + NodeRootBlockHeight: startHeight, + SporkRootBlockHeight: startHeight, }, nil }, SubscribeEventsByBlockHeightFunc: func( From c754eb7295e11ad069adb2de8a67a9832325ba14 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Mon, 20 Oct 2025 16:38:02 -0700 Subject: [PATCH 59/62] verify events even for spork root block --- services/ingestion/block_tracking_subscriber.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 5bd583b5f..82f0dfa5a 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -188,11 +188,7 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 } blockEvents, err := r.evmEventsForBlock(ctx, blockHeader) - if err != nil { - if errors.Is(err, ErrSporkRootBlockHasNoEVMBlocks) { - continue // no EVM blocks are expected in the spork root block - } - + if err != nil && !errors.Is(err, ErrSporkRootBlockHasNoEVMBlocks) { eventsChan <- models.NewBlockEventsError(err) return } @@ -205,8 +201,10 @@ func (r *RPCBlockTrackingSubscriber) subscribe(ctx context.Context, height uint6 } } - // this means that the system transaction failed AND there were no EVM transactions - // executed in the block. In this case, we can skip the block + // this means that either: + // - the system transaction failed AND there were no EVM transactions + // - this was the spork root block which has no EVM blocks + // In either case, we can skip the block // Note: put this after the verify step, so we can verify that there were no EVM // blocks in the sealed data as well if len(blockEvents.Events) == 0 { From ec1385e4827dfc8e1a2dad86a4649ae3c6964965 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Tue, 21 Oct 2025 13:21:41 -0700 Subject: [PATCH 60/62] add support for backfilling past spork blocks in sealing verifier --- go.mod | 11 ++++ go.sum | 71 ++++++++++++++++++++ services/ingestion/sealing_verifier.go | 82 +++++++++++++++++++++++- services/requester/cross-spork_client.go | 5 ++ 4 files changed, 167 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index cbd1130cf..326a1acb5 100644 --- a/go.mod +++ b/go.mod @@ -61,12 +61,14 @@ require ( github.com/crate-crypto/go-eth-kzg v1.3.0 // indirect github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/dgraph-io/badger/v2 v2.2007.4 // indirect github.com/dgraph-io/ristretto v0.1.0 // indirect github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 // indirect github.com/dlclark/regexp2 v1.7.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/ef-ds/deque v1.0.4 // indirect @@ -80,6 +82,9 @@ require ( github.com/fxamacker/cbor/v2 v2.8.1-0.20250402194037-6f932b086829 // indirect github.com/fxamacker/circlehash v0.3.0 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect + github.com/go-kit/kit v0.12.0 // indirect + github.com/go-kit/log v0.2.1 // indirect + github.com/go-logfmt/logfmt v0.6.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 @@ -113,6 +118,7 @@ require ( github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect + github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jordanschalm/lockctx v0.0.0-20250412215529-226f85c10956 // indirect github.com/k0kubun/pp/v3 v3.5.0 // indirect github.com/kevinburke/go-bindata v3.24.0+incompatible // indirect @@ -130,6 +136,7 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect github.com/minio/sha256-simd v1.0.1 // indirect + github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect @@ -155,6 +162,7 @@ require ( github.com/onflow/flow/protobuf/go/flow v0.4.16 // indirect github.com/onflow/go-ethereum v1.13.4 // indirect github.com/onflow/sdks v0.6.0-preview.1 // indirect + github.com/onflow/wal v1.0.2 // indirect github.com/onsi/ginkgo v1.16.4 // indirect github.com/onsi/gomega v1.18.1 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect @@ -174,8 +182,10 @@ require ( github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.13.1 // indirect github.com/samber/lo v1.39.0 // indirect + github.com/schollz/progressbar/v3 v3.18.0 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/slok/go-http-metrics v0.12.0 // indirect + github.com/sony/gobreaker v0.5.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.10.0 // indirect github.com/spf13/cast v1.5.0 // indirect @@ -211,6 +221,7 @@ require ( golang.org/x/net v0.43.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect golang.org/x/sys v0.35.0 // indirect + golang.org/x/term v0.34.0 // indirect golang.org/x/text v0.28.0 // indirect golang.org/x/time v0.12.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect diff --git a/go.sum b/go.sum index 31ef9d0f5..44408a658 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= +cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -39,6 +41,8 @@ cloud.google.com/go/kms v1.22.0 h1:dBRIj7+GDeeEvatJeTB19oYZNV0aj6wEqSIT/7gLqtk= cloud.google.com/go/kms v1.22.0/go.mod h1:U7mf8Sva5jpOb4bxYZdtw/9zsbIjrklYwPcvMk34AL8= cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE= cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY= +cloud.google.com/go/monitoring v1.24.2 h1:5OTsoJ1dXYIiMiuL+sYscLc9BumrL3CarVLL7dd7lHM= +cloud.google.com/go/monitoring v1.24.2/go.mod h1:x7yzPWcgDRnPEv3sI+jJGBkwl5qINf+6qY4eq0I9B4U= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -49,11 +53,19 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.google.com/go/storage v1.50.0 h1:3TbVkzTooBvnZsk7WaAQfOsNrdoM8QHusXA1cpk6QJs= +cloud.google.com/go/storage v1.50.0/go.mod h1:l7XeiD//vx5lfqE3RavfmU9yvk5Pp0Zhcv482poyafY= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e h1:ZIWapoIRN1VqT8GR8jAwb1Ie9GyehWjVcGh32Y2MznE= github.com/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0 h1:UQUsRi8WTzhZntp5313l+CHIAT95ojUI2lpP/ExlZa4= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0/go.mod h1:Cz6ft6Dkn3Et6l2v2a9/RpN7epQ1GtDlO6lj8bEcOvw= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0 h1:5IT7xOdq17MtcdtL/vtl6mGfzhaq4m4vpollPRmlsBQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0/go.mod h1:ZV4VOm0/eHR06JLrXWe09068dHpr3TRpY9Uo7T+anuA= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0 h1:ig/FpDD2JofP/NExKQUbn7uOSZzJAQqogfqluZK4ed4= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= @@ -72,6 +84,20 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/aws/aws-sdk-go-v2 v1.39.1 h1:fWZhGAwVRK/fAN2tmt7ilH4PPAE11rDj7HytrmbZ2FE= +github.com/aws/aws-sdk-go-v2 v1.39.1/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.5.1 h1:VGkV9KmhGqOQWnHyi4gLG98kE6OecT42fdrCGFWxJsc= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.5.1/go.mod h1:PLlnMiki//sGnCJiW+aVpvP/C8Kcm8mEj/IVm9+9qk4= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 h1:oegbebPEMA/1Jny7kvwejowCaHz1FWZAQ94WXFNCyTM= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1/go.mod h1:kemo5Myr9ac0U9JfSjMo9yHLtw+pECEHsFtJ9tqCEI8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.7 h1:mLgc5QIgOy26qyh5bvW+nDoAppxgn3J2WV3m9ewq7+8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.7/go.mod h1:wXb/eQnqt8mDQIQTTmcw58B5mYGxzLGZGK8PWNFZ0BA= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.7.0 h1:HWsM0YQWX76V6MOp07YuTYacm8k7h69ObJuw7Nck+og= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.7.0/go.mod h1:LKb3cKNQIMh+itGnEpKGcnL/6OIjPZqrtYah1w5f+3o= +github.com/aws/aws-sdk-go-v2/service/s3 v1.15.0 h1:nPLfLPfglacc29Y949sDxpr3X/blaY40s3B85WT2yZU= +github.com/aws/aws-sdk-go-v2/service/s3 v1.15.0/go.mod h1:Iv2aJVtVSm/D22rFoX99cLG4q4uB7tppuCsulGe98k4= +github.com/aws/smithy-go v1.23.0 h1:8n6I3gXzWJB2DxBDnfxgBaSX6oe0d/t10qGz7OKqMCE= +github.com/aws/smithy-go v1.23.0/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -92,6 +118,8 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL 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/chengxilo/virtualterm v1.0.4 h1:Z6IpERbRVlfB8WkOmtbHiDbBANU7cimRIof7mk9/PwM= +github.com/chengxilo/virtualterm v1.0.4/go.mod h1:DyxxBZz/x1iqJjFxTFcr6/x+jSpqN0iwWCOK1q10rlY= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -102,6 +130,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 h1:aQ3y1lwWyqYPiWZThqv1aFbZMiM9vblcSArJRf2Irls= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/cockroachdb/crlib v0.0.0-20241015224233-894974b3ad94 h1:bvJv505UUfjzbaIPdNS4AEkHreDqQk6yuNpsdRHpwFA= github.com/cockroachdb/crlib v0.0.0-20241015224233-894974b3ad94/go.mod h1:Gq51ZeKaFCXk6QwuGM0w1dnaOqc/F5zKT2zA9D6Xeac= github.com/cockroachdb/datadriven v1.0.3-0.20240530155848-7682d40af056 h1:slXychO2uDM6hYRu4c0pD0udNI8uObfeKN6UInWViS8= @@ -191,7 +221,12 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M= +github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A= +github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= +github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= github.com/ethereum/c-kzg-4844/v2 v2.1.0 h1:gQropX9YFBhl3g4HYhwE70zq3IHFRgbbNPw0Shwzf5w= github.com/ethereum/c-kzg-4844/v2 v2.1.0/go.mod h1:TC48kOKjJKPbN7C++qIgt0TJzZ70QznYR7Ob+WXl57E= github.com/ethereum/go-ethereum v1.16.3 h1:nDoBSrmsrPbrDIVLTkDQCy1U9KdHN+F2PzvMbDoS42Q= @@ -218,6 +253,12 @@ github.com/fxamacker/circlehash v0.3.0 h1:XKdvTtIJV9t7DDUtsf0RIpC1OcxZtPbmgIH7ek github.com/fxamacker/circlehash v0.3.0/go.mod h1:3aq3OfVvsWtkWMb6A1owjOQFA+TLsD5FgJflnaQwtMM= github.com/fxamacker/golang-lru/v2 v2.0.0-20250716153046-22c8d17dc4ee h1:9RFHOj6xUdQRi1lz/BJXwi0IloXtv6Y2tp7rdSC7SQk= github.com/fxamacker/golang-lru/v2 v2.0.0-20250716153046-22c8d17dc4ee/go.mod h1:1FYBKLDzpfjjoWMTK1cIOxsTomg/n35DWNLu6FoYEb8= +github.com/gabriel-vasile/mimetype v1.4.6 h1:3+PzJTKLkvgjeTbts6msPJt4DixhT4YtFNf1gtGe3zc= +github.com/gabriel-vasile/mimetype v1.4.6/go.mod h1:JX1qVKqZd40hUPpAfiNTe0Sne7hdfKSbOqqmkq8GCXc= +github.com/gammazero/deque v1.0.0 h1:LTmimT8H7bXkkCy6gZX7zNLtkbz4NdS2z8LZuor3j34= +github.com/gammazero/deque v1.0.0/go.mod h1:iflpYvtGfM3U8S8j+sZEKIak3SAKYpA5/SQewgfXDKo= +github.com/gammazero/workerpool v1.1.3 h1:WixN4xzukFoN0XSeXF6puqEqFTl2mECI9S6W44HWy9Q= +github.com/gammazero/workerpool v1.1.3/go.mod h1:wPjyBLDbyKnUn2XwwyD3EEwo9dHutia9/fwNmSHWACc= github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9 h1:r5GgOLGbza2wVHRzK7aAj6lWZjfbAwiu/RDCVOKjRyM= @@ -230,6 +271,8 @@ github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3Bop github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI= +github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= @@ -248,7 +291,13 @@ github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiU 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-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn0+wvQ3bZ8b/AU4= +github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -409,6 +458,8 @@ github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCm github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs= github.com/ipfs/go-ipld-format v0.6.0 h1:VEJlA2kQ3LqFSIm5Vu6eIlSxD/Ze90xtc4Meten1F5U= github.com/ipfs/go-ipld-format v0.6.0/go.mod h1:g4QVMTn3marU3qXchwjpKPKgJv+zF+OlaKMyhJ4LHPg= +github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= +github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= @@ -455,14 +506,20 @@ github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+ github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4= github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= +github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.2.0 h1:EIZzjmeOE6c8Dav0sNv35vhZxATIXWZg6j/C08XmmDw= github.com/libp2p/go-flow-metrics v0.2.0/go.mod h1:st3qqfu8+pMfh+9Mzqb2GTiwrAGjIPszEjZmtksN8Jc= github.com/libp2p/go-libp2p v0.38.2 h1:9SZQDOCi82A25An4kx30lEtr6kGTxrtoaDkbs5xrK5k= github.com/libp2p/go-libp2p v0.38.2/go.mod h1:QWV4zGL3O9nXKdHirIC59DoRcZ446dfkjbOJ55NEWFo= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= +github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= +github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= github.com/libp2p/go-libp2p-pubsub v0.13.0 h1:RmFQ2XAy3zQtbt2iNPy7Tt0/3fwTnHpCQSSnmGnt1Ps= github.com/libp2p/go-libp2p-pubsub v0.13.0/go.mod h1:m0gpUOyrXKXdE7c8FNQ9/HLfWbxaEw7xku45w+PaqZo= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= @@ -601,6 +658,8 @@ github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= @@ -656,6 +715,8 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= 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= @@ -723,6 +784,8 @@ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs github.com/slok/go-http-metrics v0.12.0 h1:mAb7hrX4gB4ItU6NkFoKYdBslafg3o60/HbGBRsKaG8= github.com/slok/go-http-metrics v0.12.0/go.mod h1:Ee/mdT9BYvGrlGzlClkK05pP2hRHmVbRF9dtUVS8LNA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.5.0 h1:dRCvqm0P490vZPmy7ppEk2qCnCieBooFJ+YoXGYB+yg= +github.com/sony/gobreaker v0.5.0/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -746,6 +809,8 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= +github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE= +github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -804,6 +869,8 @@ github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= +github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM= +github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -815,6 +882,8 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/detectors/gcp v1.36.0 h1:F7q2tNlCaHY9nMKHR6XH9/qkp8FktLnIcy6jJNyOCQw= +go.opentelemetry.io/contrib/detectors/gcp v1.36.0/go.mod h1:IbBN8uAIIx734PTonTPxAxnjc2pQTxWNkwfstZ+6H2k= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= @@ -865,6 +934,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -1024,6 +1094,7 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/services/ingestion/sealing_verifier.go b/services/ingestion/sealing_verifier.go index 13284f926..694199bad 100644 --- a/services/ingestion/sealing_verifier.go +++ b/services/ingestion/sealing_verifier.go @@ -11,6 +11,7 @@ import ( "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/access" + "github.com/onflow/flow-go/engine/access/rpc/backend/events" flowGo "github.com/onflow/flow-go/model/flow" "github.com/rs/zerolog" "go.uber.org/atomic" @@ -120,6 +121,14 @@ func (v *SealingVerifier) Run(ctx context.Context) error { } } v.lastSealedHeight.Store(lastVerifiedHeight) + startHeight := v.lastSealedHeight.Load() + 1 + + if v.client.IsPastSpork(startHeight) { + if err := v.backfill(ctx, startHeight); err != nil { + return fmt.Errorf("failed to backfill: %w", err) + } + startHeight = v.lastSealedHeight.Load() + 1 + } var eventsChan <-chan flow.BlockEvents var errChan <-chan error @@ -127,7 +136,7 @@ func (v *SealingVerifier) Run(ctx context.Context) error { subscriptionCtx, cancel := context.WithCancel(ctx) defer cancel() - reconnectHeight := lastVerifiedHeight + 1 + reconnectHeight := startHeight connect := func(height uint64) error { var err error for { @@ -156,7 +165,7 @@ func (v *SealingVerifier) Run(ctx context.Context) error { } v.logger.Info(). - Uint64("start_sealed_height", v.lastSealedHeight.Load()+1). + Uint64("start_sealed_height", startHeight). Uint64("start_unsealed_height", v.lastUnsealedHeight.Load()+1). Msg("starting verifier") @@ -217,6 +226,75 @@ func (v *SealingVerifier) Run(ctx context.Context) error { } } +// backfill fetches EVM events for blocks before the current spork's root block, and adds them to the +// verifier's sealed events cache. +func (v *SealingVerifier) backfill(ctx context.Context, height uint64) error { + eventTypes := blocksFilter(v.chain).EventTypes + + sporkRootHeight := v.client.CurrentSporkRootHeight() + + v.logger.Info(). + Uint64("start_height", height). + Uint64("end_height", sporkRootHeight-1). + Msg("backfilling verifier") + + startHeight := height + for { + endHeight := startHeight + events.DefaultMaxHeightRange + if endHeight >= sporkRootHeight { + endHeight = sporkRootHeight - 1 + } + + // this will fail if the start and end heights are now in the same spork. The only way that + // could happen is if we skipped a spork. That's unlikely to happen, so not handling the case + // for now. + blockEvents, err := v.client.GetEventsForHeightRange(ctx, eventTypes[0], startHeight, endHeight) + if err != nil { + return fmt.Errorf("failed to get events for height range %d-%d: %w", startHeight, endHeight, err) + } + + txEvents, err := v.client.GetEventsForHeightRange(ctx, eventTypes[1], startHeight, endHeight) + if err != nil { + return fmt.Errorf("failed to get events for height range %d-%d: %w", startHeight, endHeight, err) + } + + // it's technically possible that the end height is modified by the Access node to match the + // sealed height. Since this is backfill mode, the AN is a historic AN so it is not sealing + // any new blocks. Therefore, both requests must have the same number of events. + if len(blockEvents) != len(txEvents) { + return fmt.Errorf("received unexpected number of events for height range %d-%d: %d != %d", startHeight, endHeight, len(blockEvents), len(txEvents)) + } + + var currentBlockTxEvents []flow.Event + for i, blockEvent := range blockEvents { + currentBlockTxEvents = append(currentBlockTxEvents, txEvents[i].Events...) + + // if the system transaction failed, there won't be an EVM block event, but there may + // be EVM transactions. Group all transactions into the next block. + if len(blockEvent.Events) != 1 { + v.logger.Warn(). + Uint64("height", blockEvent.Height). + Str("block_id", blockEvent.BlockID.String()). + Msg("missing evm block event. will accumulate transactions into the next block") + continue + } + + blockEvent.Events = append(blockEvent.Events, currentBlockTxEvents...) + if err := v.onSealedEvents(blockEvent); err != nil { + return fmt.Errorf("failed to verify block events for height %d: %w", blockEvent.Height, err) + } + + // transactions sucessessfully grouped with a block. reset the list + currentBlockTxEvents = nil + } + + startHeight = endHeight + 1 + if startHeight >= sporkRootHeight { + return nil + } + } +} + // onSealedEvents processes sealed events // if unsealed events are found for the same height, the events are verified. // otherwise, the sealed events are cached for future verification. diff --git a/services/requester/cross-spork_client.go b/services/requester/cross-spork_client.go index d021150e5..0e245dd02 100644 --- a/services/requester/cross-spork_client.go +++ b/services/requester/cross-spork_client.go @@ -187,6 +187,11 @@ func (c *CrossSporkClient) IsSporkRootBlockHeight(height uint64) bool { return height == c.currentSporkRootHeight } +// CurrentSporkRootHeight returns the spork root block height of the current spork. +func (c *CrossSporkClient) CurrentSporkRootHeight() uint64 { + return c.currentSporkRootHeight +} + // getClientForHeight returns the client for the given height that contains the height range. // // If the height is not contained in any of the past spork clients we return an error. From cb7f2108bb9521b828c7f72d474cab436c304f21 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Tue, 21 Oct 2025 14:09:57 -0700 Subject: [PATCH 61/62] verify backfilled blocks --- go.mod | 11 --- go.sum | 71 ------------------- models/events.go | 5 ++ .../ingestion/block_tracking_subscriber.go | 7 ++ services/ingestion/sealing_verifier.go | 3 +- 5 files changed, 13 insertions(+), 84 deletions(-) diff --git a/go.mod b/go.mod index 326a1acb5..cbd1130cf 100644 --- a/go.mod +++ b/go.mod @@ -61,14 +61,12 @@ require ( github.com/crate-crypto/go-eth-kzg v1.3.0 // indirect github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/dgraph-io/badger/v2 v2.2007.4 // indirect github.com/dgraph-io/ristretto v0.1.0 // indirect github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 // indirect github.com/dlclark/regexp2 v1.7.0 // indirect - github.com/docker/go-units v0.5.0 // indirect github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/ef-ds/deque v1.0.4 // indirect @@ -82,9 +80,6 @@ require ( github.com/fxamacker/cbor/v2 v2.8.1-0.20250402194037-6f932b086829 // indirect github.com/fxamacker/circlehash v0.3.0 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect - github.com/go-kit/kit v0.12.0 // indirect - github.com/go-kit/log v0.2.1 // indirect - github.com/go-logfmt/logfmt v0.6.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 @@ -118,7 +113,6 @@ require ( github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect - github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jordanschalm/lockctx v0.0.0-20250412215529-226f85c10956 // indirect github.com/k0kubun/pp/v3 v3.5.0 // indirect github.com/kevinburke/go-bindata v3.24.0+incompatible // indirect @@ -136,7 +130,6 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect github.com/minio/sha256-simd v1.0.1 // indirect - github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect @@ -162,7 +155,6 @@ require ( github.com/onflow/flow/protobuf/go/flow v0.4.16 // indirect github.com/onflow/go-ethereum v1.13.4 // indirect github.com/onflow/sdks v0.6.0-preview.1 // indirect - github.com/onflow/wal v1.0.2 // indirect github.com/onsi/ginkgo v1.16.4 // indirect github.com/onsi/gomega v1.18.1 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect @@ -182,10 +174,8 @@ require ( github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.13.1 // indirect github.com/samber/lo v1.39.0 // indirect - github.com/schollz/progressbar/v3 v3.18.0 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/slok/go-http-metrics v0.12.0 // indirect - github.com/sony/gobreaker v0.5.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.10.0 // indirect github.com/spf13/cast v1.5.0 // indirect @@ -221,7 +211,6 @@ require ( golang.org/x/net v0.43.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect golang.org/x/sys v0.35.0 // indirect - golang.org/x/term v0.34.0 // indirect golang.org/x/text v0.28.0 // indirect golang.org/x/time v0.12.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect diff --git a/go.sum b/go.sum index 44408a658..31ef9d0f5 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,3 @@ -cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= -cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -41,8 +39,6 @@ cloud.google.com/go/kms v1.22.0 h1:dBRIj7+GDeeEvatJeTB19oYZNV0aj6wEqSIT/7gLqtk= cloud.google.com/go/kms v1.22.0/go.mod h1:U7mf8Sva5jpOb4bxYZdtw/9zsbIjrklYwPcvMk34AL8= cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE= cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY= -cloud.google.com/go/monitoring v1.24.2 h1:5OTsoJ1dXYIiMiuL+sYscLc9BumrL3CarVLL7dd7lHM= -cloud.google.com/go/monitoring v1.24.2/go.mod h1:x7yzPWcgDRnPEv3sI+jJGBkwl5qINf+6qY4eq0I9B4U= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -53,19 +49,11 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -cloud.google.com/go/storage v1.50.0 h1:3TbVkzTooBvnZsk7WaAQfOsNrdoM8QHusXA1cpk6QJs= -cloud.google.com/go/storage v1.50.0/go.mod h1:l7XeiD//vx5lfqE3RavfmU9yvk5Pp0Zhcv482poyafY= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e h1:ZIWapoIRN1VqT8GR8jAwb1Ie9GyehWjVcGh32Y2MznE= github.com/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0 h1:UQUsRi8WTzhZntp5313l+CHIAT95ojUI2lpP/ExlZa4= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0/go.mod h1:Cz6ft6Dkn3Et6l2v2a9/RpN7epQ1GtDlO6lj8bEcOvw= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0 h1:5IT7xOdq17MtcdtL/vtl6mGfzhaq4m4vpollPRmlsBQ= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0/go.mod h1:ZV4VOm0/eHR06JLrXWe09068dHpr3TRpY9Uo7T+anuA= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0 h1:ig/FpDD2JofP/NExKQUbn7uOSZzJAQqogfqluZK4ed4= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= @@ -84,20 +72,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/aws/aws-sdk-go-v2 v1.39.1 h1:fWZhGAwVRK/fAN2tmt7ilH4PPAE11rDj7HytrmbZ2FE= -github.com/aws/aws-sdk-go-v2 v1.39.1/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.5.1 h1:VGkV9KmhGqOQWnHyi4gLG98kE6OecT42fdrCGFWxJsc= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.5.1/go.mod h1:PLlnMiki//sGnCJiW+aVpvP/C8Kcm8mEj/IVm9+9qk4= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 h1:oegbebPEMA/1Jny7kvwejowCaHz1FWZAQ94WXFNCyTM= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1/go.mod h1:kemo5Myr9ac0U9JfSjMo9yHLtw+pECEHsFtJ9tqCEI8= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.7 h1:mLgc5QIgOy26qyh5bvW+nDoAppxgn3J2WV3m9ewq7+8= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.7/go.mod h1:wXb/eQnqt8mDQIQTTmcw58B5mYGxzLGZGK8PWNFZ0BA= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.7.0 h1:HWsM0YQWX76V6MOp07YuTYacm8k7h69ObJuw7Nck+og= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.7.0/go.mod h1:LKb3cKNQIMh+itGnEpKGcnL/6OIjPZqrtYah1w5f+3o= -github.com/aws/aws-sdk-go-v2/service/s3 v1.15.0 h1:nPLfLPfglacc29Y949sDxpr3X/blaY40s3B85WT2yZU= -github.com/aws/aws-sdk-go-v2/service/s3 v1.15.0/go.mod h1:Iv2aJVtVSm/D22rFoX99cLG4q4uB7tppuCsulGe98k4= -github.com/aws/smithy-go v1.23.0 h1:8n6I3gXzWJB2DxBDnfxgBaSX6oe0d/t10qGz7OKqMCE= -github.com/aws/smithy-go v1.23.0/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -118,8 +92,6 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL 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/chengxilo/virtualterm v1.0.4 h1:Z6IpERbRVlfB8WkOmtbHiDbBANU7cimRIof7mk9/PwM= -github.com/chengxilo/virtualterm v1.0.4/go.mod h1:DyxxBZz/x1iqJjFxTFcr6/x+jSpqN0iwWCOK1q10rlY= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -130,8 +102,6 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 h1:aQ3y1lwWyqYPiWZThqv1aFbZMiM9vblcSArJRf2Irls= -github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/cockroachdb/crlib v0.0.0-20241015224233-894974b3ad94 h1:bvJv505UUfjzbaIPdNS4AEkHreDqQk6yuNpsdRHpwFA= github.com/cockroachdb/crlib v0.0.0-20241015224233-894974b3ad94/go.mod h1:Gq51ZeKaFCXk6QwuGM0w1dnaOqc/F5zKT2zA9D6Xeac= github.com/cockroachdb/datadriven v1.0.3-0.20240530155848-7682d40af056 h1:slXychO2uDM6hYRu4c0pD0udNI8uObfeKN6UInWViS8= @@ -221,12 +191,7 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M= -github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A= -github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= -github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= github.com/ethereum/c-kzg-4844/v2 v2.1.0 h1:gQropX9YFBhl3g4HYhwE70zq3IHFRgbbNPw0Shwzf5w= github.com/ethereum/c-kzg-4844/v2 v2.1.0/go.mod h1:TC48kOKjJKPbN7C++qIgt0TJzZ70QznYR7Ob+WXl57E= github.com/ethereum/go-ethereum v1.16.3 h1:nDoBSrmsrPbrDIVLTkDQCy1U9KdHN+F2PzvMbDoS42Q= @@ -253,12 +218,6 @@ github.com/fxamacker/circlehash v0.3.0 h1:XKdvTtIJV9t7DDUtsf0RIpC1OcxZtPbmgIH7ek github.com/fxamacker/circlehash v0.3.0/go.mod h1:3aq3OfVvsWtkWMb6A1owjOQFA+TLsD5FgJflnaQwtMM= github.com/fxamacker/golang-lru/v2 v2.0.0-20250716153046-22c8d17dc4ee h1:9RFHOj6xUdQRi1lz/BJXwi0IloXtv6Y2tp7rdSC7SQk= github.com/fxamacker/golang-lru/v2 v2.0.0-20250716153046-22c8d17dc4ee/go.mod h1:1FYBKLDzpfjjoWMTK1cIOxsTomg/n35DWNLu6FoYEb8= -github.com/gabriel-vasile/mimetype v1.4.6 h1:3+PzJTKLkvgjeTbts6msPJt4DixhT4YtFNf1gtGe3zc= -github.com/gabriel-vasile/mimetype v1.4.6/go.mod h1:JX1qVKqZd40hUPpAfiNTe0Sne7hdfKSbOqqmkq8GCXc= -github.com/gammazero/deque v1.0.0 h1:LTmimT8H7bXkkCy6gZX7zNLtkbz4NdS2z8LZuor3j34= -github.com/gammazero/deque v1.0.0/go.mod h1:iflpYvtGfM3U8S8j+sZEKIak3SAKYpA5/SQewgfXDKo= -github.com/gammazero/workerpool v1.1.3 h1:WixN4xzukFoN0XSeXF6puqEqFTl2mECI9S6W44HWy9Q= -github.com/gammazero/workerpool v1.1.3/go.mod h1:wPjyBLDbyKnUn2XwwyD3EEwo9dHutia9/fwNmSHWACc= github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9 h1:r5GgOLGbza2wVHRzK7aAj6lWZjfbAwiu/RDCVOKjRyM= @@ -271,8 +230,6 @@ github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3Bop github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI= -github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= @@ -291,13 +248,7 @@ github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiU 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-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= -github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= -github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= -github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= -github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn0+wvQ3bZ8b/AU4= -github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -458,8 +409,6 @@ github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCm github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs= github.com/ipfs/go-ipld-format v0.6.0 h1:VEJlA2kQ3LqFSIm5Vu6eIlSxD/Ze90xtc4Meten1F5U= github.com/ipfs/go-ipld-format v0.6.0/go.mod h1:g4QVMTn3marU3qXchwjpKPKgJv+zF+OlaKMyhJ4LHPg= -github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= -github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= @@ -506,20 +455,14 @@ github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+ github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4= github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= -github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= -github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= -github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= -github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.2.0 h1:EIZzjmeOE6c8Dav0sNv35vhZxATIXWZg6j/C08XmmDw= github.com/libp2p/go-flow-metrics v0.2.0/go.mod h1:st3qqfu8+pMfh+9Mzqb2GTiwrAGjIPszEjZmtksN8Jc= github.com/libp2p/go-libp2p v0.38.2 h1:9SZQDOCi82A25An4kx30lEtr6kGTxrtoaDkbs5xrK5k= github.com/libp2p/go-libp2p v0.38.2/go.mod h1:QWV4zGL3O9nXKdHirIC59DoRcZ446dfkjbOJ55NEWFo= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= -github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= -github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= github.com/libp2p/go-libp2p-pubsub v0.13.0 h1:RmFQ2XAy3zQtbt2iNPy7Tt0/3fwTnHpCQSSnmGnt1Ps= github.com/libp2p/go-libp2p-pubsub v0.13.0/go.mod h1:m0gpUOyrXKXdE7c8FNQ9/HLfWbxaEw7xku45w+PaqZo= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= @@ -658,8 +601,6 @@ github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= @@ -715,8 +656,6 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= -github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= -github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= 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= @@ -784,8 +723,6 @@ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs github.com/slok/go-http-metrics v0.12.0 h1:mAb7hrX4gB4ItU6NkFoKYdBslafg3o60/HbGBRsKaG8= github.com/slok/go-http-metrics v0.12.0/go.mod h1:Ee/mdT9BYvGrlGzlClkK05pP2hRHmVbRF9dtUVS8LNA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sony/gobreaker v0.5.0 h1:dRCvqm0P490vZPmy7ppEk2qCnCieBooFJ+YoXGYB+yg= -github.com/sony/gobreaker v0.5.0/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -809,8 +746,6 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= -github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE= -github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -869,8 +804,6 @@ github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= -github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM= -github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -882,8 +815,6 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/detectors/gcp v1.36.0 h1:F7q2tNlCaHY9nMKHR6XH9/qkp8FktLnIcy6jJNyOCQw= -go.opentelemetry.io/contrib/detectors/gcp v1.36.0/go.mod h1:IbBN8uAIIx734PTonTPxAxnjc2pQTxWNkwfstZ+6H2k= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= @@ -934,7 +865,6 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -1094,7 +1024,6 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/models/events.go b/models/events.go index 2d199f9f1..bc215eb97 100644 --- a/models/events.go +++ b/models/events.go @@ -152,6 +152,11 @@ func decodeCadenceEvents(events flow.BlockEvents) (*CadenceEvents, error) { return e, nil } +// BlockEvents returns the Flow block events. +func (c *CadenceEvents) BlockEvents() flow.BlockEvents { + return c.events +} + // Block evm block. If event doesn't contain EVM block the return value is nil. func (c *CadenceEvents) Block() *Block { return c.block diff --git a/services/ingestion/block_tracking_subscriber.go b/services/ingestion/block_tracking_subscriber.go index 82f0dfa5a..b5db04203 100644 --- a/services/ingestion/block_tracking_subscriber.go +++ b/services/ingestion/block_tracking_subscriber.go @@ -93,6 +93,13 @@ func (r *RPCBlockTrackingSubscriber) Subscribe(ctx context.Context) <-chan model return } + if r.verifier != nil { + if err := r.verifier.AddFinalizedBlock(ev.Events.BlockEvents()); err != nil { + r.logger.Fatal().Err(err).Msg("failed to add finalized block to sealing verifier") + return + } + } + // keep updating height, so after we are done back-filling // it will be at the first height in the current spork r.height = ev.Events.CadenceHeight() diff --git a/services/ingestion/sealing_verifier.go b/services/ingestion/sealing_verifier.go index 694199bad..9e4b21b40 100644 --- a/services/ingestion/sealing_verifier.go +++ b/services/ingestion/sealing_verifier.go @@ -11,7 +11,6 @@ import ( "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/access" - "github.com/onflow/flow-go/engine/access/rpc/backend/events" flowGo "github.com/onflow/flow-go/model/flow" "github.com/rs/zerolog" "go.uber.org/atomic" @@ -240,7 +239,7 @@ func (v *SealingVerifier) backfill(ctx context.Context, height uint64) error { startHeight := height for { - endHeight := startHeight + events.DefaultMaxHeightRange + endHeight := startHeight + maxRangeForGetEvents if endHeight >= sporkRootHeight { endHeight = sporkRootHeight - 1 } From 5e17b0be7f1809522b5570c826ef7f9a6af5950a Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Tue, 21 Oct 2025 15:27:01 -0700 Subject: [PATCH 62/62] delete stored hashes during force start height --- bootstrap/bootstrap.go | 5 ++++- storage/pebble/events_hash.go | 30 ++++++++++++++++++++++++++---- storage/pebble/storage.go | 6 ++++++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/bootstrap/bootstrap.go b/bootstrap/bootstrap.go index 84394f1fc..f8f246655 100644 --- a/bootstrap/bootstrap.go +++ b/bootstrap/bootstrap.go @@ -627,10 +627,13 @@ func setupStorage( return nil, nil, fmt.Errorf("failed to get latest verified sealed height: %w", err) } if verifiedHeight > config.ForceStartCadenceHeight { - if err := eventsHash.SetProcessedSealedHeight(config.ForceStartCadenceHeight); err != nil { + if err := eventsHash.BatchSetProcessedSealedHeight(config.ForceStartCadenceHeight, batch); err != nil { return nil, nil, fmt.Errorf("failed to set latest verified sealed height: %w", err) } } + if err := eventsHash.BatchRemoveAboveHeight(config.ForceStartCadenceHeight, batch); err != nil { + return nil, nil, fmt.Errorf("failed to reset events hash above height: %w", err) + } } // if database is not initialized require init height diff --git a/storage/pebble/events_hash.go b/storage/pebble/events_hash.go index 37a3356c6..b6e539970 100644 --- a/storage/pebble/events_hash.go +++ b/storage/pebble/events_hash.go @@ -43,6 +43,24 @@ func (e *EventsHash) GetByHeight(height uint64) (flow.Identifier, error) { return flow.BytesToID(hash), nil } +// RemoveAboveHeight removes all stored events hashes above the given height (exclusive). +func (e *EventsHash) BatchRemoveAboveHeight(height uint64, batch *pebbleDB.Batch) error { + for { + height++ // skip the current height + if _, err := e.GetByHeight(height); err != nil { + if errors.Is(err, errs.ErrEntityNotFound) { + // event hashes are inserted in order with no gaps, so we can stop at the first + // missing hash + return nil + } + return err + } + if err := e.store.delete(eventsHashKey, uint64Bytes(height), batch); err != nil { + return err + } + } +} + func (e *EventsHash) ProcessedSealedHeight() (uint64, error) { val, err := e.store.get(sealedEventsHeightKey) if err != nil { @@ -57,9 +75,13 @@ func (e *EventsHash) ProcessedSealedHeight() (uint64, error) { func (e *EventsHash) SetProcessedSealedHeight(height uint64) error { return WithBatch(e.store, func(batch *pebbleDB.Batch) error { - if err := e.store.set(sealedEventsHeightKey, nil, uint64Bytes(height), batch); err != nil { - return fmt.Errorf("failed to store latest processed sealed height: %d, with: %w", height, err) - } - return nil + return e.BatchSetProcessedSealedHeight(height, batch) }) } + +func (e *EventsHash) BatchSetProcessedSealedHeight(height uint64, batch *pebbleDB.Batch) error { + if err := e.store.set(sealedEventsHeightKey, nil, uint64Bytes(height), batch); err != nil { + return fmt.Errorf("failed to store latest processed sealed height: %d, with: %w", height, err) + } + return nil +} diff --git a/storage/pebble/storage.go b/storage/pebble/storage.go index 94c420cf1..d6e01965f 100644 --- a/storage/pebble/storage.go +++ b/storage/pebble/storage.go @@ -58,6 +58,12 @@ func (s *Storage) get(keyCode byte, key ...[]byte) ([]byte, error) { return cp, nil } +func (s *Storage) delete(keyCode byte, key []byte, batch *pebble.Batch) error { + prefixedKey := makePrefix(keyCode, key) + + return batch.Delete(prefixedKey, nil) +} + func (s *Storage) NewBatch() *pebble.Batch { return s.db.NewBatch() }