From d9ca60f3e47e69c6ab5105bbf14de0e6fea9e88d Mon Sep 17 00:00:00 2001 From: cawthorne Date: Tue, 24 Feb 2026 16:44:34 +0000 Subject: [PATCH 01/10] Aptos CRE tmp changes --- contracts/scripts/publish.sh | 3 ++- contracts/scripts/set_config.sh | 14 +++++++++++--- relayer/chainreader/chainreader.go | 20 ++++++++++++++++++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/contracts/scripts/publish.sh b/contracts/scripts/publish.sh index cee5caa35..ae9c37adb 100755 --- a/contracts/scripts/publish.sh +++ b/contracts/scripts/publish.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash set -euxo pipefail -PUBLISHER_PROFILE=default +# Use PUBLISHER_PROFILE from env for devnet/mainnet (e.g. PUBLISHER_PROFILE=devnet); default is default (local). +PUBLISHER_PROFILE=${PUBLISHER_PROFILE:-default} PUBLISHER_ADDR=0x$(aptos config show-profiles --profile=$PUBLISHER_PROFILE | grep 'account' | sed -n 's/.*"account": \"\(.*\)\".*/\1/p') # deploy platform forwarder diff --git a/contracts/scripts/set_config.sh b/contracts/scripts/set_config.sh index 5f1d3c85f..44a6a91fb 100755 --- a/contracts/scripts/set_config.sh +++ b/contracts/scripts/set_config.sh @@ -1,7 +1,15 @@ #!/usr/bin/env bash set -euxo pipefail -PLATFORM_FORWARDER_ADDR=$(cat platform/contract_address.txt) +# Use PLATFORM_FORWARDER_ADDR from env or from platform/contract_address.txt (after publish.sh). +# Use PUBLISHER_PROFILE from env for devnet (e.g. PUBLISHER_PROFILE=devnet). +PLATFORM_FORWARDER_ADDR=${PLATFORM_FORWARDER_ADDR:-$(cat platform/contract_address.txt)} +PUBLISHER_PROFILE=${PUBLISHER_PROFILE:-default} -# forwarder::set_config -aptos move run --function-id "$PLATFORM_FORWARDER_ADDR::forwarder::set_config" --assume-yes --args u32:1 u32:1 u8:1 "hex:[$ORACLE_PUBKEYS]" +if [ -z "$ORACLE_PUBKEYS" ]; then + echo "ORACLE_PUBKEYS is required (comma-separated quoted hex keys, e.g. \"0xabc\",\"0xdef\")" + exit 1 +fi + +# forwarder::set_config(don_id, config_version, f, oracles) +aptos move run --function-id "$PLATFORM_FORWARDER_ADDR::forwarder::set_config" --profile "$PUBLISHER_PROFILE" --assume-yes --args u32:1 u32:1 u8:1 "hex:[$ORACLE_PUBKEYS]" diff --git a/relayer/chainreader/chainreader.go b/relayer/chainreader/chainreader.go index eaedbee6a..eed74909d 100644 --- a/relayer/chainreader/chainreader.go +++ b/relayer/chainreader/chainreader.go @@ -327,6 +327,26 @@ func (a *aptosChainReader) GetLatestValue(ctx context.Context, readIdentifier st return codec.DecodeAptosJsonValue(transformedData, returnVal) } +// GetLatestValueWithHeadData returns the latest value and the current chain head (block height, timestamp). +// It calls GetLatestValue to fill returnVal, then fetches ledger info from the Aptos client to build the Head. +func (a *aptosChainReader) GetLatestValueWithHeadData(ctx context.Context, readIdentifier string, confidenceLevel primitives.ConfidenceLevel, params, returnVal any) (*types.Head, error) { + if err := a.GetLatestValue(ctx, readIdentifier, confidenceLevel, params, returnVal); err != nil { + return nil, err + } + nodeInfo, err := a.client.Info() + if err != nil { + return nil, fmt.Errorf("failed to get ledger info for head data: %w", err) + } + // LedgerTimestamp is in microseconds; Head.Timestamp is Unix seconds. + timestampSecs := nodeInfo.LedgerTimestamp() / 1000000 + head := &types.Head{ + Height: strconv.FormatUint(nodeInfo.BlockHeight(), 10), + Hash: nil, // Aptos NodeInfo does not expose block hash; view reads are at latest state + Timestamp: timestampSecs, + } + return head, nil +} + func (a *aptosChainReader) BatchGetLatestValues(ctx context.Context, request types.BatchGetLatestValuesRequest) (types.BatchGetLatestValuesResult, error) { result := make(types.BatchGetLatestValuesResult) From 5d90c38e7a0699ac2ae65491b065789912bd2ef8 Mon Sep 17 00:00:00 2001 From: cawthorne Date: Wed, 25 Feb 2026 23:52:07 +0000 Subject: [PATCH 02/10] Bump chainlink-common --- go.mod | 128 +++++++++++++++------------- go.sum | 265 ++++++++++++++++++++++++++++++--------------------------- 2 files changed, 207 insertions(+), 186 deletions(-) diff --git a/go.mod b/go.mod index 2da81b91a..e80100766 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/smartcontractkit/chainlink-aptos -go 1.24.1 +go 1.25.3 require ( github.com/aptos-labs/aptos-go-sdk v1.11.0 @@ -8,59 +8,60 @@ require ( github.com/ethereum/go-ethereum v1.16.8 github.com/go-viper/mapstructure/v2 v2.4.0 github.com/google/uuid v1.6.0 - github.com/hashicorp/go-plugin v1.6.3 + github.com/hashicorp/go-plugin v1.7.0 github.com/jmoiron/sqlx v1.4.0 github.com/jpillora/backoff v1.0.0 github.com/patrickmn/go-cache v2.1.0+incompatible - github.com/pelletier/go-toml/v2 v2.2.3 + github.com/pelletier/go-toml/v2 v2.2.4 github.com/prometheus/client_golang v1.22.0 github.com/shopspring/decimal v1.4.0 github.com/smacker/go-tree-sitter v0.0.0-20240827094217-dd81d9e9be82 - github.com/smartcontractkit/chainlink-common v0.7.1-0.20250519161208-80bc8b13c0e7 + github.com/smartcontractkit/chainlink-common v0.10.1-0.20260225231552-fd6482e9b481 + github.com/smartcontractkit/chainlink-common/pkg/values v0.0.0-20260225184310-053d0fd4e19a github.com/stretchr/testify v1.11.1 github.com/valyala/fastjson v1.6.4 - go.opentelemetry.io/otel v1.35.0 - go.opentelemetry.io/otel/metric v1.35.0 - go.opentelemetry.io/otel/trace v1.35.0 - go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.45.0 - golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 - golang.org/x/sync v0.18.0 - google.golang.org/protobuf v1.36.6 + go.opentelemetry.io/otel v1.39.0 + go.opentelemetry.io/otel/metric v1.39.0 + go.opentelemetry.io/otel/trace v1.39.0 + go.uber.org/zap v1.27.1 + golang.org/x/crypto v0.47.0 + golang.org/x/exp v0.0.0-20260112195511-716be5621a96 + golang.org/x/sync v0.19.0 + google.golang.org/protobuf v1.36.11 ) require ( filippo.io/edwards25519 v1.1.0 // indirect - github.com/Masterminds/semver/v3 v3.3.1 // indirect + github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 // indirect - github.com/XSAM/otelsql v0.29.0 // indirect - github.com/apache/arrow-go/v18 v18.0.0 // indirect + github.com/XSAM/otelsql v0.37.0 // indirect + github.com/apache/arrow-go/v18 v18.3.1 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/buger/jsonparser v1.1.1 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cenkalti/backoff/v5 v5.0.2 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/cloudevents/sdk-go/binding/format/protobuf/v2 v2.15.2 // indirect - github.com/cloudevents/sdk-go/v2 v2.16.0 // indirect + github.com/cloudevents/sdk-go/binding/format/protobuf/v2 v2.16.1 // indirect + github.com/cloudevents/sdk-go/v2 v2.16.1 // indirect github.com/coder/websocket v1.8.14 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect github.com/fatih/color v1.18.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.8 // indirect - github.com/go-json-experiment/json v0.0.0-20250213060926-925ba3f173fa // indirect - github.com/go-logr/logr v1.4.2 // indirect + github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 // indirect + github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.25.0 // indirect + github.com/go-playground/validator/v10 v10.26.0 // indirect github.com/goccy/go-json v0.10.5 // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/google/flatbuffers v24.3.25+incompatible // indirect + github.com/google/flatbuffers v25.2.10+incompatible // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect - github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/yamux v0.1.2 // indirect github.com/hasura/go-graphql-client v0.14.5 // indirect @@ -72,67 +73,72 @@ require ( github.com/jackc/pgio v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgproto3/v2 v2.3.3 // indirect - github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/pgtype v1.14.4 // indirect github.com/jackc/pgx/v4 v4.18.3 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.18.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.9 // indirect + github.com/klauspost/cpuid/v2 v2.2.10 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/lib/pq v1.10.9 // indirect github.com/mailru/easyjson v0.9.0 // indirect - github.com/marcboeker/go-duckdb v1.8.3 // indirect + github.com/marcboeker/go-duckdb v1.8.5 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect - github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/oklog/run v1.1.0 // indirect + github.com/oklog/run v1.2.0 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect github.com/pierrec/lz4/v4 v4.1.22 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.63.0 // indirect - github.com/prometheus/procfs v0.16.0 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.65.0 // indirect + github.com/prometheus/procfs v0.16.1 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/scylladb/go-reflectx v1.0.1 // indirect - github.com/smartcontractkit/freeport v0.1.0 // indirect + github.com/smartcontractkit/chain-selectors v1.0.89 // indirect + github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 // indirect + github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260217043601-5cc966896c4f // indirect + github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20251002192024-d2ad9222409b // indirect + github.com/smartcontractkit/chainlink-protos/node-platform v0.0.0-20260205130626-db2a2aab956b // indirect + github.com/smartcontractkit/freeport v0.1.3-0.20250716200817-cb5dfd0e369e // indirect github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect - github.com/smartcontractkit/libocr v0.0.0-20250220133800-f3b940c4f298 // indirect + github.com/smartcontractkit/libocr v0.0.0-20250912173940-f3ab0246e23d // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.10.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.10.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.35.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.10.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.34.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.34.0 // indirect - go.opentelemetry.io/otel/log v0.10.0 // indirect - go.opentelemetry.io/otel/sdk v1.35.0 // indirect - go.opentelemetry.io/otel/sdk/log v0.10.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect - go.opentelemetry.io/proto/otlp v1.5.0 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.36.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.36.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.36.0 // indirect + go.opentelemetry.io/otel/log v0.15.0 // indirect + go.opentelemetry.io/otel/sdk v1.39.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.15.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.39.0 // indirect + go.opentelemetry.io/proto/otlp v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/mod v0.29.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 // indirect - golang.org/x/text v0.31.0 // indirect - golang.org/x/tools v0.38.0 // indirect + golang.org/x/mod v0.32.0 // indirect + golang.org/x/net v0.49.0 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2 // indirect + golang.org/x/text v0.33.0 // indirect + golang.org/x/time v0.14.0 // indirect + golang.org/x/tools v0.41.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250219182151-9fdb1cabc7b2 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect - google.golang.org/grpc v1.71.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251029180050-ab9386a59fda // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda // indirect + google.golang.org/grpc v1.78.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index e7d66884c..81cdc6809 100644 --- a/go.sum +++ b/go.sum @@ -3,16 +3,16 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= -github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 h1:1zYrtlhrZ6/b6SAjLSfKzWtdgqK0U+HtH/VcBWh1BaU= github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6/go.mod h1:ioLG6R+5bUSO1oeGSDxOV3FADARuMoytZCSX6MEMQkI= -github.com/XSAM/otelsql v0.29.0 h1:pEw9YXXs8ZrGRYfDc0cmArIz9lci5b42gmP5+tA1Huc= -github.com/XSAM/otelsql v0.29.0/go.mod h1:d3/0xGIGC5RVEE+Ld7KotwaLy6zDeaF3fLJHOPpdN2w= +github.com/XSAM/otelsql v0.37.0 h1:ya5RNw028JW0eJW8Ma4AmoKxAYsJSGuNVbC7F1J457A= +github.com/XSAM/otelsql v0.37.0/go.mod h1:LHbCu49iU8p255nCn1oi04oX2UjSoRcUMiKEHo2a5qM= github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA= github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA= -github.com/apache/arrow-go/v18 v18.0.0 h1:1dBDaSbH3LtulTyOVYaBCHO3yVRwjV+TZaqn3g6V7ZM= -github.com/apache/arrow-go/v18 v18.0.0/go.mod h1:t6+cWRSmKgdQ6HsxisQjok+jBpKGhRDiqcf3p0p/F+A= +github.com/apache/arrow-go/v18 v18.3.1 h1:oYZT8FqONiK74JhlH3WKVv+2NKYoyZ7C2ioD4Dj3ixk= +github.com/apache/arrow-go/v18 v18.3.1/go.mod h1:12QBya5JZT6PnBihi5NJTzbACrDGXYkrgjujz3MRQXU= github.com/apache/thrift v0.21.0 h1:tdPmh/ptjE1IJnhbhrcl2++TauVjy242rkV/UzJChnE= github.com/apache/thrift v0.21.0/go.mod h1:W1H8aR/QRtYNvrPeFXBtobyRkd0/YVhTc6i07XIAgDw= github.com/aptos-labs/aptos-go-sdk v1.11.0 h1:vIL1hpjECUiu7zMl9Wz6VV8ttXsrDqKUj0HxoeaIER4= @@ -27,16 +27,16 @@ github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/ github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= +github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudevents/sdk-go/binding/format/protobuf/v2 v2.15.2 h1:FIvfKlS2mcuP0qYY6yzdIU9xdrRd/YMP0bNwFjXd0u8= -github.com/cloudevents/sdk-go/binding/format/protobuf/v2 v2.15.2/go.mod h1:POsdVp/08Mki0WD9QvvgRRpg9CQ6zhjfRrBoEY8JFS8= -github.com/cloudevents/sdk-go/v2 v2.16.0 h1:wnunjgiLQCfYlyo+E4+mFlZtAh7pKn7vT8MMD3lSwCg= -github.com/cloudevents/sdk-go/v2 v2.16.0/go.mod h1:5YWqklyhDSmGzBK/JENKKXdulbPq0JFf3c/KEnMLqgg= +github.com/cloudevents/sdk-go/binding/format/protobuf/v2 v2.16.1 h1:nLaJZcVAnaqch3K83AyzHfY2DmQM18/L7jvkmKSfkpI= +github.com/cloudevents/sdk-go/binding/format/protobuf/v2 v2.16.1/go.mod h1:6Q+F2puKpJ6zWv+R02BVnizJICf7++oRT5zwpZQAsbk= +github.com/cloudevents/sdk-go/v2 v2.16.1 h1:G91iUdqvl88BZ1GYYr9vScTj5zzXSyEuqbfE63gbu9Q= +github.com/cloudevents/sdk-go/v2 v2.16.1/go.mod h1:v/kVOaWjNfbvc6tkhhlkhvLapj8Aa8kvXiH5GiOHCKI= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= @@ -72,13 +72,13 @@ github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= -github.com/go-json-experiment/json v0.0.0-20250213060926-925ba3f173fa h1:Rpu6sKAzIeSWBkrFHD52g8yipagcPbY2Lmm70NL1Gzc= -github.com/go-json-experiment/json v0.0.0-20250213060926-925ba3f173fa/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M= +github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 h1:F8d1AJ6M9UQCavhwmO6ZsrYLfG8zVFWfEfMS2MXPkSY= +github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= @@ -87,8 +87,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= 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.25.0 h1:5Dh7cjvzR7BRZadnsVOzPhWsrwUr0nmsZJxEAnFLNO8= -github.com/go-playground/validator/v10 v10.25.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus= +github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k= +github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -117,8 +117,8 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/flatbuffers v24.3.25+incompatible h1:CX395cjN9Kke9mmalRoL3d81AtFUxJM+yDthflgJGkI= -github.com/google/flatbuffers v24.3.25+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q= +github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -136,18 +136,18 @@ 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/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpSQwGEnkcRpTqNOIR6bJbR0gAorgP9CSALpRcKoAA= github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0 h1:FbSCl+KggFl+Ocym490i/EyXF4lPgLoUtcSWquBM0Rs= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0/go.mod h1:qOchhhIlmRcqk/O9uCo/puJlyo07YINaIqdZfZG3Jkc= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 h1:sGm2vDRFUrQJO/Veii4h4zG2vvqG6uWNkBHSTqXOZk0= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2/go.mod h1:wd1YpapPLivG6nQgbf7ZkG1hhSOXDhhn4MLTknx2aAc= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-memdb v1.3.5 h1:b3taDMxCBCBVgyRrS1AZVHO14ubMYZB++QpNhBg+Nyo= github.com/hashicorp/go-memdb v1.3.5/go.mod h1:8IVKKBkVe+fxFgdFOYxzQQNjz+sWCyHCdIC/+5+Vy1Y= -github.com/hashicorp/go-plugin v1.6.3 h1:xgHB+ZUSYeuJi96WtxEjzi23uh7YQpznjGh0U0UUrwg= -github.com/hashicorp/go-plugin v1.6.3/go.mod h1:MRobyh+Wc/nYy1V4KAXUiYfzxoYhs7V1mlH1Z7iY2h0= +github.com/hashicorp/go-plugin v1.7.0 h1:YghfQH/0QmPNc/AZMTFE3ac8fipZyZECHdDPshfk+mA= +github.com/hashicorp/go-plugin v1.7.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8= @@ -190,8 +190,9 @@ github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwX github.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUOag= github.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= -github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= @@ -210,8 +211,8 @@ github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0f github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= -github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= +github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= +github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= @@ -223,8 +224,8 @@ github.com/klauspost/asmfmt v1.3.2 h1:4Ri7ox3EwapiOjCki+hw14RyKk201CN4rzyCJRFLpK github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= -github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= -github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= +github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= +github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -247,8 +248,8 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= -github.com/marcboeker/go-duckdb v1.8.3 h1:ZkYwiIZhbYsT6MmJsZ3UPTHrTZccDdM4ztoqSlEMXiQ= -github.com/marcboeker/go-duckdb v1.8.3/go.mod h1:C9bYRE1dPYb1hhfu/SSomm78B0FXmNgRvv6YBW/Hooc= +github.com/marcboeker/go-duckdb v1.8.5 h1:tkYp+TANippy0DaIOP5OEfBEwbUINqiFqgwMQ44jME0= +github.com/marcboeker/go-duckdb v1.8.5/go.mod h1:6mK7+WQE4P4u5AFLvVBmhFxY5fvhymFptghgJX6B+/8= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -268,8 +269,6 @@ github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 h1:AMFGa4R4MiIpsp github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 h1:+n/aFZefKZp7spd8DFdX7uMikMLXX4oubIzJF4kv/wI= github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= -github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 h1:BpfhmLKZf+SjVanKKhCgf3bg+511DmU9eDQTen7LLbY= -github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -279,12 +278,14 @@ github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= -github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= +github.com/oklog/run v1.2.0 h1:O8x3yXwah4A73hJdlrwo/2X6J62gE5qTMusH0dvz60E= +github.com/oklog/run v1.2.0/go.mod h1:mgDbKRSwPhJfesJ4PntqFUbKQRZ50NgmZTSPlFA0YFk= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= -github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= -github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -296,15 +297,15 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= -github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= -github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= -github.com/prometheus/procfs v0.16.0 h1:xh6oHhKwnOJKMYiYBDWmkHqQPyiY40sny36Cmx2bbsM= -github.com/prometheus/procfs v0.16.0/go.mod h1:8veyXUu3nGP7oaCxhX6yeaM5u4stL2FeMXnCqhDthZg= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE= +github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= +github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= +github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= @@ -321,14 +322,26 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/smacker/go-tree-sitter v0.0.0-20240827094217-dd81d9e9be82 h1:6C8qej6f1bStuePVkLSFxoU22XBS165D3klxlzRg8F4= github.com/smacker/go-tree-sitter v0.0.0-20240827094217-dd81d9e9be82/go.mod h1:xe4pgH49k4SsmkQq5OT8abwhWmnzkhpgnXeekbx2efw= -github.com/smartcontractkit/chainlink-common v0.7.1-0.20250519161208-80bc8b13c0e7 h1:yeDKMQSKJQwe5SdfPmbzjzgyZIeq1QlcR93K3e7tRCU= -github.com/smartcontractkit/chainlink-common v0.7.1-0.20250519161208-80bc8b13c0e7/go.mod h1:uNF6+noody47ZdmRwymDZAnQ7eKTXLzMKvl41LA63lo= -github.com/smartcontractkit/freeport v0.1.0 h1:3MZHeti5m+tSTBCq5R8rhawFHxrnQZYBZVL+xgS1sPo= -github.com/smartcontractkit/freeport v0.1.0/go.mod h1:T4zH9R8R8lVWKfU7tUvYz2o2jMv1OpGCdpY2j2QZXzU= +github.com/smartcontractkit/chain-selectors v1.0.89 h1:L9oWZGqQXWyTPnC6ODXgu3b0DFyLmJ9eHv+uJrE9IZY= +github.com/smartcontractkit/chain-selectors v1.0.89/go.mod h1:qy7whtgG5g+7z0jt0nRyii9bLND9m15NZTzuQPkMZ5w= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260225231552-fd6482e9b481 h1:eLjcUIHUTlJjXqez/Tn1lObUdwMnC6I+LPs9LKnsPBk= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260225231552-fd6482e9b481/go.mod h1:HXgSKzmZ/bhSx8nHU7hHW6dR+BHSXkdcpFv2T8qJcS8= +github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= +github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10/go.mod h1:oiDa54M0FwxevWwyAX773lwdWvFYYlYHHQV1LQ5HpWY= +github.com/smartcontractkit/chainlink-common/pkg/values v0.0.0-20260225184310-053d0fd4e19a h1:10aF65q+bq+8+z0NnAaJaJcUc0w+yU24JQ8sn47OTUI= +github.com/smartcontractkit/chainlink-common/pkg/values v0.0.0-20260225184310-053d0fd4e19a/go.mod h1:X+515dSSjIgr2C3urPuwJAOmyPsnGsV1Smoghbs0304= +github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260217043601-5cc966896c4f h1:MHlgzqiDPyDV397bZkzS9TtWXb3FR9Pb8FR9cP9h0As= +github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260217043601-5cc966896c4f/go.mod h1:Jqt53s27Tr0jDl8mdBXg1xhu6F8Fci8JOuq43tgHOM8= +github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20251002192024-d2ad9222409b h1:QuI6SmQFK/zyUlVWEf0GMkiUYBPY4lssn26nKSd/bOM= +github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20251002192024-d2ad9222409b/go.mod h1:qSTSwX3cBP3FKQwQacdjArqv0g6QnukjV4XuzO6UyoY= +github.com/smartcontractkit/chainlink-protos/node-platform v0.0.0-20260205130626-db2a2aab956b h1:36knUpKHHAZ86K4FGWXtx8i/EQftGdk2bqCoEu/Cha8= +github.com/smartcontractkit/chainlink-protos/node-platform v0.0.0-20260205130626-db2a2aab956b/go.mod h1:dkR2uYg9XYJuT1JASkPzWE51jjFkVb86P7a/yXe5/GM= +github.com/smartcontractkit/freeport v0.1.3-0.20250716200817-cb5dfd0e369e h1:Hv9Mww35LrufCdM9wtS9yVi/rEWGI1UnjHbcKKU0nVY= +github.com/smartcontractkit/freeport v0.1.3-0.20250716200817-cb5dfd0e369e/go.mod h1:T4zH9R8R8lVWKfU7tUvYz2o2jMv1OpGCdpY2j2QZXzU= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7/go.mod h1:FX7/bVdoep147QQhsOPkYsPEXhGZjeYx6lBSaSXtZOA= -github.com/smartcontractkit/libocr v0.0.0-20250220133800-f3b940c4f298 h1:PKiqnVOTChlH4a4ljJKL3OKGRgYfIpJS4YD1daAIKks= -github.com/smartcontractkit/libocr v0.0.0-20250220133800-f3b940c4f298/go.mod h1:Mb7+/LC4edz7HyHxX4QkE42pSuov4AV68+AxBXAap0o= +github.com/smartcontractkit/libocr v0.0.0-20250912173940-f3ab0246e23d h1:LokA9PoCNb8mm8mDT52c3RECPMRsGz1eCQORq+J3n74= +github.com/smartcontractkit/libocr v0.0.0-20250912173940-f3ab0246e23d/go.mod h1:Acy3BTBxou83ooMESLO90s8PKSu7RvLCzwSTbxxfOK0= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -364,46 +377,48 @@ github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -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.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4= -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/otlplog/otlploggrpc v0.10.0 h1:5dTKu4I5Dn4P2hxyW3l3jTaZx9ACgg0ECos1eAVrheY= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.10.0/go.mod h1:P5HcUI8obLrCCmM3sbVBohZFH34iszk/+CPWuakZWL8= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.10.0 h1:q/heq5Zh8xV1+7GoMGJpTxM2Lhq5+bFxB29tshuRuw0= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.10.0/go.mod h1:leO2CSTg0Y+LyvmR7Wm4pUxE8KAmaM2GCVx7O+RATLA= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.35.0 h1:QcFwRrZLc82r8wODjvyCbP7Ifp3UANaBSmhDSFjnqSc= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.35.0/go.mod h1:CXIWhUomyWBG/oY2/r/kLp6K/cmx9e/7DLpBuuGdLCA= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 h1:opwv08VbCZ8iecIWs+McMdHRcAXzjAeda3uG2kI/hcA= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0/go.mod h1:oOP3ABpW7vFHulLpE8aYtNBodrHhMTrvfxUXGvqm7Ac= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0fikVry1IsiUnXjf7QFvoNN3Xw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0/go.mod h1:u5BF1xyjstDowA1R5QAO9JHzqK+ublenEW/dyqTjBVk= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.10.0 h1:GKCEAZLEpEf78cUvudQdTg0aET2ObOZRB2HtXA0qPAI= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.10.0/go.mod h1:9/zqSWLCmHT/9Jo6fYeUDRRogOLL60ABLsHWS99lF8s= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.34.0 h1:czJDQwFrMbOr9Kk+BPo1y8WZIIFIK58SA1kykuVeiOU= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.34.0/go.mod h1:lT7bmsxOe58Tq+JIOkTQMCGXdu47oA+VJKLZHbaBKbs= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.34.0 h1:jBpDk4HAUsrnVO1FsfCfCOTEc/MkInJmvfCHYLFiT80= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.34.0/go.mod h1:H9LUIM1daaeZaz91vZcfeM0fejXPmgCYE8ZhzqfJuiU= -go.opentelemetry.io/otel/log v0.10.0 h1:1CXmspaRITvFcjA4kyVszuG4HjA61fPDxMb7q3BuyF0= -go.opentelemetry.io/otel/log v0.10.0/go.mod h1:PbVdm9bXKku/gL0oFfUF4wwsQsOPlpo4VEqjvxih+FM= -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/log v0.10.0 h1:lR4teQGWfeDVGoute6l0Ou+RpFqQ9vaPdrNJlST0bvw= -go.opentelemetry.io/otel/sdk/log v0.10.0/go.mod h1:A+V1UTWREhWAittaQEG4bYm4gAZa6xnvVu+xKrIRkzo= -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.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= -go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 h1:06ZeJRe5BnYXceSM9Vya83XXVaNGe3H1QqsvqRANQq8= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2/go.mod h1:DvPtKE63knkDVP88qpatBj81JxN+w1bqfVbsbCbj1WY= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 h1:tPLwQlXbJ8NSOfZc4OkgU5h2A38M4c9kfHSVc4PFQGs= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2/go.mod h1:QTnxBwT/1rBIgAG1goq6xMydfYOBKU6KTiYF4fp5zL8= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.36.0 h1:zwdo1gS2eH26Rg+CoqVQpEK1h8gvt5qyU5Kk5Bixvow= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.36.0/go.mod h1:rUKCPscaRWWcqGT6HnEmYrK+YNe5+Sw64xgQTOJ5b30= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.36.0 h1:gAU726w9J8fwr4qRDqu1GYMNNs4gXrU+Pv20/N1UpB4= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.36.0/go.mod h1:RboSDkp7N292rgu+T0MgVt2qgFGu6qa1RpZDOtpL76w= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 h1:dNzwXjZKpMpE2JhmO+9HsPl42NIXFIFSUSSs0fiqra0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0/go.mod h1:90PoxvaEB5n6AOdZvi+yWJQoE95U8Dhhw2bSyRqnTD0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0 h1:JgtbA0xkWHnTmYk7YusopJFX6uleBmAuZ8n05NEh8nQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0/go.mod h1:179AK5aar5R3eS9FucPy6rggvU0g52cvKId8pv4+v0c= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0 h1:nRVXXvf78e00EwY6Wp0YII8ww2JVWshZ20HfTlE11AM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0/go.mod h1:r49hO7CgrxY9Voaj3Xe8pANWtr0Oq916d0XAmOoCZAQ= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 h1:yEX3aC9KDgvYPhuKECHbOlr5GLwH6KTjLJ1sBSkkxkc= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0/go.mod h1:/GXR0tBmmkxDaCUGahvksvp66mx4yh5+cFXgSlhg0vQ= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 h1:rixTyDGXFxRy1xzhKrotaHy3/KXdPhlWARrCgK+eqUY= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.36.0 h1:G8Xec/SgZQricwWBJF/mHZc7A02YHedfFDENwJEdRA0= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.36.0/go.mod h1:PD57idA/AiFD5aqoxGxCvT/ILJPeHy3MjqU/NS7KogY= +go.opentelemetry.io/otel/log v0.15.0 h1:0VqVnc3MgyYd7QqNVIldC3dsLFKgazR6P3P3+ypkyDY= +go.opentelemetry.io/otel/log v0.15.0/go.mod h1:9c/G1zbyZfgu1HmQD7Qj84QMmwTp2QCQsZH1aeoWDE4= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/log v0.15.0 h1:WgMEHOUt5gjJE93yqfqJOkRflApNif84kxoHWS9VVHE= +go.opentelemetry.io/otel/sdk/log v0.15.0/go.mod h1:qDC/FlKQCXfH5hokGsNg9aUBGMJQsrUyeOiW5u+dKBQ= +go.opentelemetry.io/otel/sdk/log/logtest v0.13.0 h1:9yio6AFZ3QD9j9oqshV1Ibm9gPLlHNxurno5BreMtIA= +go.opentelemetry.io/otel/sdk/log/logtest v0.13.0/go.mod h1:QOGiAJHl+fob8Nu85ifXfuQYmJTFAvcrxL6w5/tu168= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= +go.opentelemetry.io/proto/otlp v1.6.0 h1:jQjP+AQyTf+Fe7OKj/MfkDrmK4MNVtw2NpXsf9fefDI= +go.opentelemetry.io/proto/otlp v1.6.0/go.mod h1:cicgGehlFuNdgZkcALOCh3VE6K/u2tAjzlRhDwmVpZc= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -419,8 +434,8 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= +go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -433,11 +448,11 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= +golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw= -golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM= +golang.org/x/exp v0.0.0-20260112195511-716be5621a96 h1:Z/6YuSHTLOHfNFdb8zVZomZr7cqNgTJvA8+Qz75D8gU= +golang.org/x/exp v0.0.0-20260112195511-716be5621a96/go.mod h1:nzimsREAkjBCIEFtHiYkrJyT+2uy9YZJB7H1k68CXZU= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -448,8 +463,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= -golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= +golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= +golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -465,8 +480,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -475,8 +490,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= 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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -505,10 +520,10 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 h1:LvzTn0GQhWuvKH/kVRS3R3bVAsdQWI7hvfLHGgh9+lU= -golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8/go.mod h1:Pi4ztBfryZoJEkyFTI5/Ocsu2jXyDr6iSdgJiYE/uwE= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2 h1:O1cMQHRfwNpDfDJerqRoE2oD+AFlyid87D40L/OkkJo= +golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2/go.mod h1:b7fPSJ0pKZ3ccUh8gnTONJxhn3c/PS6tyzQvyqw4iA8= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -525,10 +540,10 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= -golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= -golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= 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= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -545,8 +560,8 @@ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= -golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= +golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= +golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -555,25 +570,25 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= -gonum.org/v1/gonum v0.15.1 h1:FNy7N6OUZVUaWG9pTiD+jlhdQ3lMP+/LcTpJ6+a8sQ0= -gonum.org/v1/gonum v0.15.1/go.mod h1:eZTZuRFrzu5pcyjN5wJhcIhnUdNijYxX1T2IcrOGY0o= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= 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/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto/googleapis/api v0.0.0-20250219182151-9fdb1cabc7b2 h1:35ZFtrCgaAjF7AFAK0+lRSf+4AyYnWRbH7og13p7rZ4= -google.golang.org/genproto/googleapis/api v0.0.0-20250219182151-9fdb1cabc7b2/go.mod h1:W9ynFDP/shebLB1Hl/ESTOap2jHd6pmLXPNZC7SVDbA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 h1:e0AIkUUhxyBKh6ssZNrAMeqhA7RKUj42346d1y02i2g= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/genproto/googleapis/api v0.0.0-20251029180050-ab9386a59fda h1:+2XxjfsAu6vqFxwGBRcHiMaDCuZiqXGDUDVWVtrFAnE= +google.golang.org/genproto/googleapis/api v0.0.0-20251029180050-ab9386a59fda/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda h1:i/Q+bfisr7gq6feoJnS/DlpdwEL4ihp41fvRiM3Ork0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -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/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= +google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= 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= @@ -585,8 +600,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD 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.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= From 870ec5763f731ca99795c7ab50d965e180f0d2a4 Mon Sep 17 00:00:00 2001 From: cawthorne Date: Thu, 26 Feb 2026 00:09:59 +0000 Subject: [PATCH 03/10] Bump for Relayer updates --- cmd/chainlink-aptos/main.go | 12 +++++++----- go.mod | 4 ++-- go.sum | 8 ++++---- relayer/chain/chain.go | 10 ++++++++++ relayer/relay.go | 20 ++++++++++++++++++++ relayer/testutils/keystore.go | 5 +++++ relayer/write_target/write_target_test.go | 2 +- 7 files changed, 49 insertions(+), 12 deletions(-) diff --git a/cmd/chainlink-aptos/main.go b/cmd/chainlink-aptos/main.go index b6d635b41..45a2f0276 100644 --- a/cmd/chainlink-aptos/main.go +++ b/cmd/chainlink-aptos/main.go @@ -52,11 +52,13 @@ type pluginRelayer struct { ds sqlutil.DataSource } -// NewRelayer implements the Loopp factory method used by the Loopp server to instantiate a aptos relayer -// [github.com/smartcontractkit/chainlink-common/pkg/loop.PluginRelayer] -// loopKs must be an implementation that can construct a aptos keystore adapter +// NewRelayer implements the Loopp factory method used by the Loopp server to instantiate an aptos relayer +// [github.com/smartcontractkit/chainlink-common/pkg/loop.PluginRelayer]. +// ks must be an implementation that can construct an aptos keystore adapter // [github.com/smartcontractkit/chainlink-aptos/relayer/txm.NewKeystoreAdapter] -func (p *pluginRelayer) NewRelayer(ctx context.Context, rawConfig string, loopKs loop.Keystore, capRegistry core.CapabilitiesRegistry) (loop.Relayer, error) { +func (p *pluginRelayer) NewRelayer(ctx context.Context, rawConfig string, ks, csaKS core.Keystore, capRegistry core.CapabilitiesRegistry) (loop.Relayer, error) { + _ = csaKS + // Initialize the chain service cfg, err := config.NewDecodedTOMLConfig(rawConfig) if err != nil { @@ -64,7 +66,7 @@ func (p *pluginRelayer) NewRelayer(ctx context.Context, rawConfig string, loopKs } opts := chain.ChainOpts{ Logger: p.Logger, - KeyStore: loopKs, + KeyStore: ks, DS: p.ds, } chain, err := chain.NewChain(cfg, opts) diff --git a/go.mod b/go.mod index e80100766..6dd576d62 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/jpillora/backoff v1.0.0 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pelletier/go-toml/v2 v2.2.4 - github.com/prometheus/client_golang v1.22.0 + github.com/prometheus/client_golang v1.23.0 github.com/shopspring/decimal v1.4.0 github.com/smacker/go-tree-sitter v0.0.0-20240827094217-dd81d9e9be82 github.com/smartcontractkit/chainlink-common v0.10.1-0.20260225231552-fd6482e9b481 @@ -106,7 +106,7 @@ require ( github.com/smartcontractkit/chainlink-protos/node-platform v0.0.0-20260205130626-db2a2aab956b // indirect github.com/smartcontractkit/freeport v0.1.3-0.20250716200817-cb5dfd0e369e // indirect github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect - github.com/smartcontractkit/libocr v0.0.0-20250912173940-f3ab0246e23d // indirect + github.com/smartcontractkit/libocr v0.0.0-20251027221354-bdc84e1ed858 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/x448/float16 v0.8.4 // indirect diff --git a/go.sum b/go.sum index 81cdc6809..c891e3a89 100644 --- a/go.sum +++ b/go.sum @@ -294,8 +294,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= -github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= +github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc= +github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= @@ -340,8 +340,8 @@ github.com/smartcontractkit/freeport v0.1.3-0.20250716200817-cb5dfd0e369e h1:Hv9 github.com/smartcontractkit/freeport v0.1.3-0.20250716200817-cb5dfd0e369e/go.mod h1:T4zH9R8R8lVWKfU7tUvYz2o2jMv1OpGCdpY2j2QZXzU= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7/go.mod h1:FX7/bVdoep147QQhsOPkYsPEXhGZjeYx6lBSaSXtZOA= -github.com/smartcontractkit/libocr v0.0.0-20250912173940-f3ab0246e23d h1:LokA9PoCNb8mm8mDT52c3RECPMRsGz1eCQORq+J3n74= -github.com/smartcontractkit/libocr v0.0.0-20250912173940-f3ab0246e23d/go.mod h1:Acy3BTBxou83ooMESLO90s8PKSu7RvLCzwSTbxxfOK0= +github.com/smartcontractkit/libocr v0.0.0-20251027221354-bdc84e1ed858 h1:dz+lxAW+B+PUq32ODppSq5UKw06+EF6+EO6kk684bcQ= +github.com/smartcontractkit/libocr v0.0.0-20251027221354-bdc84e1ed858/go.mod h1:oJkBKVn8zoBQm7Feah9CiuEHyCqAhnp1LJBzrvloQtM= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/relayer/chain/chain.go b/relayer/chain/chain.go index 816f70bb5..1f1b5bd85 100644 --- a/relayer/chain/chain.go +++ b/relayer/chain/chain.go @@ -300,6 +300,16 @@ func (c *chain) LatestHead(ctx context.Context) (types.Head, error) { }, nil } +func (c *chain) GetChainInfo(ctx context.Context) (types.ChainInfo, error) { + ci := c.chainInfo() + return types.ChainInfo{ + FamilyName: ci.ChainFamilyName, + ChainID: ci.ChainID, + NetworkName: ci.NetworkName, + NetworkNameFull: ci.NetworkNameFull, + }, nil +} + // ChainService interface func (c *chain) GetChainStatus(ctx context.Context) (types.ChainStatus, error) { toml, err := c.cfg.TOMLString() diff --git a/relayer/relay.go b/relayer/relay.go index 119b90e1c..cc167a7e4 100644 --- a/relayer/relay.go +++ b/relayer/relay.go @@ -154,6 +154,10 @@ func (r *relayer) NewOCR3CapabilityProvider(ctx context.Context, rargs types.Rel return nil, errors.New("ocr3 capability provider is not supported for aptos") } +func (r *relayer) NewCCIPProvider(ctx context.Context, cargs types.CCIPProviderArgs) (types.CCIPProvider, error) { + return nil, errors.New("ccip provider is not supported for aptos") +} + func (r *relayer) NewCCIPCommitProvider(ctx context.Context, rargs types.RelayArgs, pargs types.PluginArgs) (types.CCIPCommitProvider, error) { return nil, errors.New("ccip.commit is not supported for aptos") } @@ -166,6 +170,18 @@ func (r *relayer) EVM() (types.EVMService, error) { return nil, errors.New("EVMService is not supported for aptos") } +func (r *relayer) TON() (types.TONService, error) { + return nil, errors.New("TONService is not supported for aptos") +} + +func (r *relayer) Solana() (types.SolanaService, error) { + return nil, errors.New("SolanaService is not supported for aptos") +} + +func (r *relayer) Aptos() (types.AptosService, error) { + return nil, errors.New("AptosService direct access is not supported for aptos relayer") +} + func (r *relayer) Replay(ctx context.Context, fromBlock string, args map[string]any) error { return errors.ErrUnsupported } @@ -179,6 +195,10 @@ func (r *relayer) LatestHead(ctx context.Context) (types.Head, error) { return r.chain.LatestHead(ctx) } +func (r *relayer) GetChainInfo(ctx context.Context) (types.ChainInfo, error) { + return r.chain.GetChainInfo(ctx) +} + func (r *relayer) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) (stats []types.NodeStatus, nextPageToken string, total int, err error) { return r.chain.ListNodeStatuses(ctx, pageSize, pageToken) } diff --git a/relayer/testutils/keystore.go b/relayer/testutils/keystore.go index be2489a70..fa7df0eee 100644 --- a/relayer/testutils/keystore.go +++ b/relayer/testutils/keystore.go @@ -3,6 +3,7 @@ package testutils import ( "context" "crypto/ed25519" + "errors" "fmt" "testing" @@ -49,3 +50,7 @@ func (tk *TestKeystore) Accounts(ctx context.Context) ([]string, error) { } return accounts, nil } + +func (tk *TestKeystore) Decrypt(ctx context.Context, account string, encrypted []byte) ([]byte, error) { + return nil, errors.ErrUnsupported +} diff --git a/relayer/write_target/write_target_test.go b/relayer/write_target/write_target_test.go index 2baddd7a8..b502ac945 100644 --- a/relayer/write_target/write_target_test.go +++ b/relayer/write_target/write_target_test.go @@ -16,7 +16,7 @@ import ( commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" - "github.com/smartcontractkit/chainlink-common/pkg/values" + "github.com/smartcontractkit/chainlink-protos/cre/go/values" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" From e2e63ef3f8874065235ffc3bd6137568c77c0878 Mon Sep 17 00:00:00 2001 From: cawthorne Date: Thu, 26 Feb 2026 00:41:20 +0000 Subject: [PATCH 04/10] Update Relayer for CRE Aptos --- relayer/relay.go | 246 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 245 insertions(+), 1 deletion(-) diff --git a/relayer/relay.go b/relayer/relay.go index cc167a7e4..28a5a9530 100644 --- a/relayer/relay.go +++ b/relayer/relay.go @@ -7,9 +7,12 @@ import ( "fmt" "math/big" + aptosdk "github.com/aptos-labs/aptos-go-sdk" + aptosapi "github.com/aptos-labs/aptos-go-sdk/api" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" + typeaptos "github.com/smartcontractkit/chainlink-common/pkg/types/chains/aptos" "github.com/smartcontractkit/chainlink-common/pkg/types/core" "github.com/smartcontractkit/chainlink-common/pkg/utils" @@ -179,7 +182,7 @@ func (r *relayer) Solana() (types.SolanaService, error) { } func (r *relayer) Aptos() (types.AptosService, error) { - return nil, errors.New("AptosService direct access is not supported for aptos relayer") + return r, nil } func (r *relayer) Replay(ctx context.Context, fromBlock string, args map[string]any) error { @@ -206,3 +209,244 @@ func (r *relayer) ListNodeStatuses(ctx context.Context, pageSize int32, pageToke func (r *relayer) Transact(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error { return r.chain.Transact(ctx, from, to, amount, balanceCheck) } + +func (r *relayer) AccountAPTBalance(ctx context.Context, req typeaptos.AccountAPTBalanceRequest) (*typeaptos.AccountAPTBalanceReply, error) { + client, err := r.chain.GetClient() + if err != nil { + return nil, fmt.Errorf("failed to get client: %w", err) + } + + balance, err := client.AccountAPTBalance(aptosdk.AccountAddress(req.Address)) + if err != nil { + return nil, err + } + + return &typeaptos.AccountAPTBalanceReply{Value: balance}, nil +} + +func (r *relayer) View(ctx context.Context, req typeaptos.ViewRequest) (*typeaptos.ViewReply, error) { + client, err := r.chain.GetClient() + if err != nil { + return nil, fmt.Errorf("failed to get client: %w", err) + } + + payload, err := toSDKViewPayload(req.Payload) + if err != nil { + return nil, err + } + + result, err := client.View(payload) + if err != nil { + return nil, err + } + + data, err := json.Marshal(result) + if err != nil { + return nil, fmt.Errorf("failed to marshal view response: %w", err) + } + + return &typeaptos.ViewReply{Data: data}, nil +} + +func (r *relayer) EventsByHandle(ctx context.Context, req typeaptos.EventsByHandleRequest) (*typeaptos.EventsByHandleReply, error) { + client, err := r.chain.GetClient() + if err != nil { + return nil, fmt.Errorf("failed to get client: %w", err) + } + + events, err := client.EventsByHandle(aptosdk.AccountAddress(req.Account), req.EventHandle, req.FieldName, req.Start, req.Limit) + if err != nil { + return nil, err + } + + out := &typeaptos.EventsByHandleReply{Events: make([]*typeaptos.Event, 0, len(events))} + for _, e := range events { + if e == nil { + continue + } + + ev := &typeaptos.Event{ + Version: e.Version, + Type: e.Type, + SequenceNumber: e.SequenceNumber, + } + if e.Guid != nil { + var addr typeaptos.AccountAddress + if e.Guid.AccountAddress != nil { + copy(addr[:], e.Guid.AccountAddress[:]) + } + ev.Guid = &typeaptos.GUID{ + CreationNumber: e.Guid.CreationNumber, + AccountAddress: addr, + } + } + if e.Data != nil { + data, marshalErr := json.Marshal(e.Data) + if marshalErr != nil { + return nil, fmt.Errorf("failed to marshal event data: %w", marshalErr) + } + ev.Data = data + } + out.Events = append(out.Events, ev) + } + + return out, nil +} + +func (r *relayer) TransactionByHash(ctx context.Context, req typeaptos.TransactionByHashRequest) (*typeaptos.TransactionByHashReply, error) { + client, err := r.chain.GetClient() + if err != nil { + return nil, fmt.Errorf("failed to get client: %w", err) + } + + tx, err := client.TransactionByHash(req.Hash) + if err != nil { + return nil, err + } + if tx == nil { + return &typeaptos.TransactionByHashReply{}, nil + } + + converted, err := convertSDKTransaction(tx) + if err != nil { + return nil, err + } + return &typeaptos.TransactionByHashReply{Transaction: converted}, nil +} + +func (r *relayer) SubmitTransaction(ctx context.Context, req typeaptos.SubmitTransactionRequest) (*typeaptos.SubmitTransactionReply, error) { + return nil, errors.New("submit transaction via AptosService is not supported by this relayer implementation") +} + +func (r *relayer) AccountTransactions(ctx context.Context, req typeaptos.AccountTransactionsRequest) (*typeaptos.AccountTransactionsReply, error) { + client, err := r.chain.GetClient() + if err != nil { + return nil, fmt.Errorf("failed to get client: %w", err) + } + + txs, err := client.AccountTransactions(aptosdk.AccountAddress(req.Address), req.Start, req.Limit) + if err != nil { + return nil, err + } + + out := &typeaptos.AccountTransactionsReply{Transactions: make([]*typeaptos.Transaction, 0, len(txs))} + for _, tx := range txs { + if tx == nil { + continue + } + asTxn := &aptosapi.Transaction{Type: tx.Type, Inner: tx.Inner} + converted, convErr := convertSDKTransaction(asTxn) + if convErr != nil { + return nil, convErr + } + out.Transactions = append(out.Transactions, converted) + } + + return out, nil +} + +func convertSDKTransaction(tx *aptosapi.Transaction) (*typeaptos.Transaction, error) { + if tx == nil { + return nil, nil + } + + var version *uint64 + if v := tx.Version(); v != nil { + vv := *v + version = &vv + } + + var success *bool + if s := tx.Success(); s != nil { + ss := *s + success = &ss + } + + data, err := json.Marshal(tx) + if err != nil { + return nil, fmt.Errorf("failed to marshal transaction: %w", err) + } + + return &typeaptos.Transaction{ + Type: typeaptos.TransactionVariant(tx.Type), + Hash: string(tx.Hash()), + Version: version, + Success: success, + Data: data, + }, nil +} + +func toSDKViewPayload(payload *typeaptos.ViewPayload) (*aptosdk.ViewPayload, error) { + if payload == nil { + return nil, fmt.Errorf("view payload is nil") + } + + argTypes := make([]aptosdk.TypeTag, 0, len(payload.ArgTypes)) + for _, t := range payload.ArgTypes { + converted, err := toSDKTypeTag(t) + if err != nil { + return nil, err + } + argTypes = append(argTypes, converted) + } + + return &aptosdk.ViewPayload{ + Module: aptosdk.ModuleId{ + Address: aptosdk.AccountAddress(payload.Module.Address), + Name: payload.Module.Name, + }, + Function: payload.Function, + ArgTypes: argTypes, + Args: payload.Args, + }, nil +} + +func toSDKTypeTag(tag typeaptos.TypeTag) (aptosdk.TypeTag, error) { + switch v := tag.Value.(type) { + case typeaptos.BoolTag: + return aptosdk.TypeTag{Value: &aptosdk.BoolTag{}}, nil + case typeaptos.U8Tag: + return aptosdk.TypeTag{Value: &aptosdk.U8Tag{}}, nil + case typeaptos.U16Tag: + return aptosdk.TypeTag{Value: &aptosdk.U16Tag{}}, nil + case typeaptos.U32Tag: + return aptosdk.TypeTag{Value: &aptosdk.U32Tag{}}, nil + case typeaptos.U64Tag: + return aptosdk.TypeTag{Value: &aptosdk.U64Tag{}}, nil + case typeaptos.U128Tag: + return aptosdk.TypeTag{Value: &aptosdk.U128Tag{}}, nil + case typeaptos.U256Tag: + return aptosdk.TypeTag{Value: &aptosdk.U256Tag{}}, nil + case typeaptos.AddressTag: + return aptosdk.TypeTag{Value: &aptosdk.AddressTag{}}, nil + case typeaptos.SignerTag: + return aptosdk.TypeTag{Value: &aptosdk.SignerTag{}}, nil + case typeaptos.VectorTag: + inner, err := toSDKTypeTag(v.ElementType) + if err != nil { + return aptosdk.TypeTag{}, err + } + return aptosdk.TypeTag{Value: &aptosdk.VectorTag{TypeParam: inner}}, nil + case typeaptos.StructTag: + typeParams := make([]aptosdk.TypeTag, 0, len(v.TypeParams)) + for _, p := range v.TypeParams { + inner, err := toSDKTypeTag(p) + if err != nil { + return aptosdk.TypeTag{}, err + } + typeParams = append(typeParams, inner) + } + return aptosdk.TypeTag{ + Value: &aptosdk.StructTag{ + Address: aptosdk.AccountAddress(v.Address), + Module: v.Module, + Name: v.Name, + TypeParams: typeParams, + }, + }, nil + case typeaptos.GenericTag: + return aptosdk.TypeTag{Value: &aptosdk.GenericTag{Num: uint64(v.Index)}}, nil + default: + return aptosdk.TypeTag{}, fmt.Errorf("unsupported aptos type tag: %T", tag.Value) + } +} From e5872d4f65c8809b67bfb94a3f4c058fb72717e7 Mon Sep 17 00:00:00 2001 From: cawthorne Date: Thu, 26 Feb 2026 01:43:29 +0000 Subject: [PATCH 05/10] Update Relayer for CRE Aptos 2 --- relayer/chain/chain.go | 7 ++ relayer/relay.go | 143 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 147 insertions(+), 3 deletions(-) diff --git a/relayer/chain/chain.go b/relayer/chain/chain.go index 1f1b5bd85..d96324436 100644 --- a/relayer/chain/chain.go +++ b/relayer/chain/chain.go @@ -35,6 +35,7 @@ type Chain interface { ID() string Config() *config.TOMLConfig DataSource() sqlutil.DataSource + KeyStore() loop.Keystore TxManager() *txm.AptosTxm LogPoller() *logpoller.AptosLogPoller @@ -77,6 +78,7 @@ type chain struct { cfg *config.TOMLConfig lggr logger.Logger ds sqlutil.DataSource + ks loop.Keystore // Sub-services txm *txm.AptosTxm @@ -117,6 +119,7 @@ func newChain(cfg *config.TOMLConfig, loopKs loop.Keystore, lggr logger.Logger, cfg: cfg, lggr: logger.Named(lggr, "Chain"), ds: ds, + ks: loopKs, } getClient := func() (aptos.AptosRpcClient, error) { @@ -169,6 +172,10 @@ func (c *chain) DataSource() sqlutil.DataSource { return c.ds } +func (c *chain) KeyStore() loop.Keystore { + return c.ks +} + func (c *chain) ChainID() string { return c.id } diff --git a/relayer/relay.go b/relayer/relay.go index 28a5a9530..433375e5a 100644 --- a/relayer/relay.go +++ b/relayer/relay.go @@ -2,6 +2,7 @@ package relayer import ( "context" + "crypto/ed25519" "encoding/json" "errors" "fmt" @@ -9,17 +10,20 @@ import ( aptosdk "github.com/aptos-labs/aptos-go-sdk" aptosapi "github.com/aptos-labs/aptos-go-sdk/api" + "github.com/aptos-labs/aptos-go-sdk/bcs" + aptoscrypto "github.com/aptos-labs/aptos-go-sdk/crypto" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" typeaptos "github.com/smartcontractkit/chainlink-common/pkg/types/chains/aptos" "github.com/smartcontractkit/chainlink-common/pkg/types/core" - "github.com/smartcontractkit/chainlink-common/pkg/utils" + commonutils "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink-aptos/relayer/chain" "github.com/smartcontractkit/chainlink-aptos/relayer/chainreader" crconfig "github.com/smartcontractkit/chainlink-aptos/relayer/chainreader/config" "github.com/smartcontractkit/chainlink-aptos/relayer/chainwriter" + rutils "github.com/smartcontractkit/chainlink-aptos/relayer/utils" write_target "github.com/smartcontractkit/chainlink-aptos/relayer/write_target/aptos" ) @@ -29,7 +33,7 @@ type relayer struct { chain chain.Chain lggr logger.Logger - starter utils.StartStopOnce + starter commonutils.StartStopOnce stopCh services.StopChan } @@ -315,7 +319,102 @@ func (r *relayer) TransactionByHash(ctx context.Context, req typeaptos.Transacti } func (r *relayer) SubmitTransaction(ctx context.Context, req typeaptos.SubmitTransactionRequest) (*typeaptos.SubmitTransactionReply, error) { - return nil, errors.New("submit transaction via AptosService is not supported by this relayer implementation") + cfg := r.chain.Config() + if cfg.Workflow == nil || cfg.Workflow.PublicKey == "" { + return nil, fmt.Errorf("workflow public key not configured") + } + + client, err := r.chain.GetClient() + if err != nil { + return nil, fmt.Errorf("failed to get client: %w", err) + } + + var payload aptosdk.TransactionPayload + if err := bcs.Deserialize(&payload, req.EncodedPayload); err != nil { + return nil, fmt.Errorf("failed to decode transaction payload: %w", err) + } + + publicKey, err := rutils.HexPublicKeyToEd25519PublicKey(cfg.Workflow.PublicKey) + if err != nil { + return nil, fmt.Errorf("invalid workflow public key: %w", err) + } + fromAddress := rutils.Ed25519PublicKeyToAddress(publicKey) + + accountInfo, err := client.Account(fromAddress) + if err != nil { + return nil, fmt.Errorf("failed to fetch account info: %w", err) + } + sequenceNumber, err := accountInfo.SequenceNumber() + if err != nil { + return nil, fmt.Errorf("failed to parse sequence number: %w", err) + } + + chainID, err := client.GetChainId() + if err != nil { + return nil, fmt.Errorf("failed to fetch chain id: %w", err) + } + + info, err := client.Info() + if err != nil { + return nil, fmt.Errorf("failed to fetch node info: %w", err) + } + ledgerTimestamp := info.LedgerTimestamp() + if ledgerTimestamp == 0 { + return nil, fmt.Errorf("ledger timestamp is zero") + } + + txCfg := cfg.TransactionManager + expiration := (ledgerTimestamp / 1_000_000) + txCfg.TxExpirationSecs + + var maxGasAmount uint64 + var gasUnitPrice uint64 + if req.GasConfig != nil { + maxGasAmount = req.GasConfig.MaxGasAmount + gasUnitPrice = req.GasConfig.GasUnitPrice + } else { + gasInfo, gasErr := client.EstimateGasPrice() + if gasErr != nil { + return nil, fmt.Errorf("failed to estimate gas price: %w", gasErr) + } + maxGasAmount = txCfg.DefaultMaxGasAmount + txCfg.GasLimitOverhead + gasUnitPrice = gasInfo.GasEstimate + } + + rawTx := aptosdk.RawTransaction{ + Sender: fromAddress, + SequenceNumber: sequenceNumber, + Payload: payload, + MaxGasAmount: maxGasAmount, + GasUnitPrice: gasUnitPrice, + ExpirationTimestampSeconds: expiration, + ChainId: chainID, + } + + signedTx, signature, err := signRawTransaction(ctx, r.chain.KeyStore(), cfg.Workflow.PublicKey, publicKey, &rawTx) + if err != nil { + return nil, err + } + + submitResponse, err := client.SubmitTransaction(signedTx) + if err != nil { + return nil, err + } + if submitResponse == nil || submitResponse.Hash == "" { + return nil, fmt.Errorf("submit transaction returned empty hash") + } + + return &typeaptos.SubmitTransactionReply{ + PendingTransaction: &typeaptos.PendingTransaction{ + Hash: submitResponse.Hash, + Sender: typeaptos.AccountAddress(fromAddress), + SequenceNumber: sequenceNumber, + MaxGasAmount: maxGasAmount, + GasUnitPrice: gasUnitPrice, + ExpirationTimestampSecs: expiration, + Payload: req.EncodedPayload, + Signature: signature, + }, + }, nil } func (r *relayer) AccountTransactions(ctx context.Context, req typeaptos.AccountTransactionsRequest) (*typeaptos.AccountTransactionsReply, error) { @@ -450,3 +549,41 @@ func toSDKTypeTag(tag typeaptos.TypeTag) (aptosdk.TypeTag, error) { return aptosdk.TypeTag{}, fmt.Errorf("unsupported aptos type tag: %T", tag.Value) } } + +func signRawTransaction( + ctx context.Context, + ks core.Keystore, + publicKeyHex string, + publicKey ed25519.PublicKey, + rawTx *aptosdk.RawTransaction, +) (*aptosdk.SignedTransaction, []byte, error) { + signingMessage, err := rawTx.SigningMessage() + if err != nil { + return nil, nil, fmt.Errorf("failed to create signing message: %w", err) + } + + signature, err := ks.Sign(ctx, publicKeyHex, signingMessage) + if err != nil { + return nil, nil, fmt.Errorf("failed to sign message: %w", err) + } + + edSig := aptoscrypto.Ed25519Signature{} + if err := edSig.FromBytes(signature); err != nil { + return nil, nil, fmt.Errorf("failed to decode ed25519 signature: %w", err) + } + + authenticator := &aptoscrypto.AccountAuthenticator{ + Variant: aptoscrypto.AccountAuthenticatorEd25519, + Auth: &aptoscrypto.Ed25519Authenticator{ + PubKey: &aptoscrypto.Ed25519PublicKey{Inner: publicKey}, + Sig: &edSig, + }, + } + + signedTx, err := rawTx.SignedTransactionWithAuthenticator(authenticator) + if err != nil { + return nil, nil, fmt.Errorf("failed to build signed transaction: %w", err) + } + + return signedTx, signature, nil +} From 743cd5042c8cea37a924c87df7ef595dd4302a37 Mon Sep 17 00:00:00 2001 From: cawthorne Date: Thu, 26 Feb 2026 18:59:37 +0000 Subject: [PATCH 06/10] Add LedgerVersion to Relayer --- relayer/relay.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/relayer/relay.go b/relayer/relay.go index 433375e5a..858a71d5e 100644 --- a/relayer/relay.go +++ b/relayer/relay.go @@ -239,7 +239,12 @@ func (r *relayer) View(ctx context.Context, req typeaptos.ViewRequest) (*typeapt return nil, err } - result, err := client.View(payload) + var result []any + if req.LedgerVersion != nil { + result, err = client.View(payload, *req.LedgerVersion) + } else { + result, err = client.View(payload) + } if err != nil { return nil, err } From 71c8c69c998f5638838a2704a728d754c6e38a0d Mon Sep 17 00:00:00 2001 From: cawthorne Date: Thu, 26 Feb 2026 19:17:13 +0000 Subject: [PATCH 07/10] relayer/aptos: implement AptosService.LedgerVersion via node Info() --- relayer/relay.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/relayer/relay.go b/relayer/relay.go index 858a71d5e..f98cf8913 100644 --- a/relayer/relay.go +++ b/relayer/relay.go @@ -228,6 +228,20 @@ func (r *relayer) AccountAPTBalance(ctx context.Context, req typeaptos.AccountAP return &typeaptos.AccountAPTBalanceReply{Value: balance}, nil } +func (r *relayer) LedgerVersion(ctx context.Context) (uint64, error) { + client, err := r.chain.GetClient() + if err != nil { + return 0, fmt.Errorf("failed to get client: %w", err) + } + + info, err := client.Info() + if err != nil { + return 0, fmt.Errorf("failed to fetch node info: %w", err) + } + + return info.LedgerVersion(), nil +} + func (r *relayer) View(ctx context.Context, req typeaptos.ViewRequest) (*typeaptos.ViewReply, error) { client, err := r.chain.GetClient() if err != nil { From a80554bdc774929841dd19ec57971d9573b73c22 Mon Sep 17 00:00:00 2001 From: cawthorne Date: Thu, 26 Feb 2026 20:10:05 +0000 Subject: [PATCH 08/10] bump chainlink-common + chainlink-protos --- go.mod | 5 ++--- go.sum | 6 ++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 6dd576d62..5f022cec9 100644 --- a/go.mod +++ b/go.mod @@ -16,8 +16,8 @@ require ( github.com/prometheus/client_golang v1.23.0 github.com/shopspring/decimal v1.4.0 github.com/smacker/go-tree-sitter v0.0.0-20240827094217-dd81d9e9be82 - github.com/smartcontractkit/chainlink-common v0.10.1-0.20260225231552-fd6482e9b481 - github.com/smartcontractkit/chainlink-common/pkg/values v0.0.0-20260225184310-053d0fd4e19a + github.com/smartcontractkit/chainlink-common v0.10.1-0.20260226191628-ecce52da56c9 + github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260217043601-5cc966896c4f github.com/stretchr/testify v1.11.1 github.com/valyala/fastjson v1.6.4 go.opentelemetry.io/otel v1.39.0 @@ -101,7 +101,6 @@ require ( github.com/scylladb/go-reflectx v1.0.1 // indirect github.com/smartcontractkit/chain-selectors v1.0.89 // indirect github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 // indirect - github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260217043601-5cc966896c4f // indirect github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20251002192024-d2ad9222409b // indirect github.com/smartcontractkit/chainlink-protos/node-platform v0.0.0-20260205130626-db2a2aab956b // indirect github.com/smartcontractkit/freeport v0.1.3-0.20250716200817-cb5dfd0e369e // indirect diff --git a/go.sum b/go.sum index c891e3a89..ea0daae80 100644 --- a/go.sum +++ b/go.sum @@ -324,12 +324,10 @@ github.com/smacker/go-tree-sitter v0.0.0-20240827094217-dd81d9e9be82 h1:6C8qej6f github.com/smacker/go-tree-sitter v0.0.0-20240827094217-dd81d9e9be82/go.mod h1:xe4pgH49k4SsmkQq5OT8abwhWmnzkhpgnXeekbx2efw= github.com/smartcontractkit/chain-selectors v1.0.89 h1:L9oWZGqQXWyTPnC6ODXgu3b0DFyLmJ9eHv+uJrE9IZY= github.com/smartcontractkit/chain-selectors v1.0.89/go.mod h1:qy7whtgG5g+7z0jt0nRyii9bLND9m15NZTzuQPkMZ5w= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260225231552-fd6482e9b481 h1:eLjcUIHUTlJjXqez/Tn1lObUdwMnC6I+LPs9LKnsPBk= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260225231552-fd6482e9b481/go.mod h1:HXgSKzmZ/bhSx8nHU7hHW6dR+BHSXkdcpFv2T8qJcS8= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260226191628-ecce52da56c9 h1:9rcOyYENSbzKzRFn1jeemsxMgUjrL0tfGo/SW3oN3bs= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260226191628-ecce52da56c9/go.mod h1:HXgSKzmZ/bhSx8nHU7hHW6dR+BHSXkdcpFv2T8qJcS8= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10/go.mod h1:oiDa54M0FwxevWwyAX773lwdWvFYYlYHHQV1LQ5HpWY= -github.com/smartcontractkit/chainlink-common/pkg/values v0.0.0-20260225184310-053d0fd4e19a h1:10aF65q+bq+8+z0NnAaJaJcUc0w+yU24JQ8sn47OTUI= -github.com/smartcontractkit/chainlink-common/pkg/values v0.0.0-20260225184310-053d0fd4e19a/go.mod h1:X+515dSSjIgr2C3urPuwJAOmyPsnGsV1Smoghbs0304= github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260217043601-5cc966896c4f h1:MHlgzqiDPyDV397bZkzS9TtWXb3FR9Pb8FR9cP9h0As= github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260217043601-5cc966896c4f/go.mod h1:Jqt53s27Tr0jDl8mdBXg1xhu6F8Fci8JOuq43tgHOM8= github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20251002192024-d2ad9222409b h1:QuI6SmQFK/zyUlVWEf0GMkiUYBPY4lssn26nKSd/bOM= From 7d4f6db595a56347307782b29ad362e4fe0f6227 Mon Sep 17 00:00:00 2001 From: cawthorne Date: Thu, 26 Feb 2026 22:27:55 +0000 Subject: [PATCH 09/10] Manage Sequence numbers based on onchain sequence number --- relayer/relay.go | 199 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 153 insertions(+), 46 deletions(-) diff --git a/relayer/relay.go b/relayer/relay.go index f98cf8913..5396c4fe8 100644 --- a/relayer/relay.go +++ b/relayer/relay.go @@ -7,6 +7,9 @@ import ( "errors" "fmt" "math/big" + "strings" + "sync" + "time" aptosdk "github.com/aptos-labs/aptos-go-sdk" aptosapi "github.com/aptos-labs/aptos-go-sdk/api" @@ -35,6 +38,9 @@ type relayer struct { starter commonutils.StartStopOnce stopCh services.StopChan + + sequenceMu sync.Mutex + nextSequence map[string]uint64 } func NewRelayer(lggr logger.Logger, chain chain.Chain, capRegistry core.CapabilitiesRegistry) (*relayer, error) { @@ -53,9 +59,10 @@ func NewRelayer(lggr logger.Logger, chain chain.Chain, capRegistry core.Capabili } return &relayer{ - chain: chain, - lggr: lggr, - stopCh: make(chan struct{}), + chain: chain, + lggr: lggr, + stopCh: make(chan struct{}), + nextSequence: make(map[string]uint64), }, nil } @@ -359,32 +366,6 @@ func (r *relayer) SubmitTransaction(ctx context.Context, req typeaptos.SubmitTra } fromAddress := rutils.Ed25519PublicKeyToAddress(publicKey) - accountInfo, err := client.Account(fromAddress) - if err != nil { - return nil, fmt.Errorf("failed to fetch account info: %w", err) - } - sequenceNumber, err := accountInfo.SequenceNumber() - if err != nil { - return nil, fmt.Errorf("failed to parse sequence number: %w", err) - } - - chainID, err := client.GetChainId() - if err != nil { - return nil, fmt.Errorf("failed to fetch chain id: %w", err) - } - - info, err := client.Info() - if err != nil { - return nil, fmt.Errorf("failed to fetch node info: %w", err) - } - ledgerTimestamp := info.LedgerTimestamp() - if ledgerTimestamp == 0 { - return nil, fmt.Errorf("ledger timestamp is zero") - } - - txCfg := cfg.TransactionManager - expiration := (ledgerTimestamp / 1_000_000) + txCfg.TxExpirationSecs - var maxGasAmount uint64 var gasUnitPrice uint64 if req.GasConfig != nil { @@ -395,26 +376,20 @@ func (r *relayer) SubmitTransaction(ctx context.Context, req typeaptos.SubmitTra if gasErr != nil { return nil, fmt.Errorf("failed to estimate gas price: %w", gasErr) } - maxGasAmount = txCfg.DefaultMaxGasAmount + txCfg.GasLimitOverhead + maxGasAmount = cfg.TransactionManager.DefaultMaxGasAmount + cfg.TransactionManager.GasLimitOverhead gasUnitPrice = gasInfo.GasEstimate } - rawTx := aptosdk.RawTransaction{ - Sender: fromAddress, - SequenceNumber: sequenceNumber, - Payload: payload, - MaxGasAmount: maxGasAmount, - GasUnitPrice: gasUnitPrice, - ExpirationTimestampSeconds: expiration, - ChainId: chainID, - } - - signedTx, signature, err := signRawTransaction(ctx, r.chain.KeyStore(), cfg.Workflow.PublicKey, publicKey, &rawTx) - if err != nil { - return nil, err - } - - submitResponse, err := client.SubmitTransaction(signedTx) + submitResponse, sequenceNumber, expiration, signature, err := r.submitTransactionWithManagedSequence( + ctx, + client, + cfg.Workflow.PublicKey, + publicKey, + fromAddress, + payload, + maxGasAmount, + gasUnitPrice, + ) if err != nil { return nil, err } @@ -436,6 +411,138 @@ func (r *relayer) SubmitTransaction(ctx context.Context, req typeaptos.SubmitTra }, nil } +func (r *relayer) submitTransactionWithManagedSequence( + ctx context.Context, + client aptosdk.AptosRpcClient, + publicKeyHex string, + publicKey ed25519.PublicKey, + fromAddress aptosdk.AccountAddress, + payload aptosdk.TransactionPayload, + maxGasAmount uint64, + gasUnitPrice uint64, +) (*aptosapi.SubmitTransactionResponse, uint64, uint64, []byte, error) { + r.sequenceMu.Lock() + defer r.sequenceMu.Unlock() + + addressKey := fromAddress.String() + txCfg := r.chain.Config().TransactionManager + maxAttempts := int(txCfg.MaxSubmitRetryAttempts) + if maxAttempts < 1 { + maxAttempts = 1 + } + + lastErr := error(nil) + for attempt := 1; attempt <= maxAttempts; attempt++ { + chainID, err := client.GetChainId() + if err != nil { + return nil, 0, 0, nil, fmt.Errorf("failed to fetch chain id: %w", err) + } + + info, err := client.Info() + if err != nil { + return nil, 0, 0, nil, fmt.Errorf("failed to fetch node info: %w", err) + } + ledgerTimestamp := info.LedgerTimestamp() + if ledgerTimestamp == 0 { + return nil, 0, 0, nil, fmt.Errorf("ledger timestamp is zero") + } + expiration := (ledgerTimestamp / 1_000_000) + txCfg.TxExpirationSecs + + onchainSequence, err := r.fetchSequenceNumber(client, fromAddress) + if err != nil { + return nil, 0, 0, nil, err + } + sequenceNumber := onchainSequence + if cached, ok := r.nextSequence[addressKey]; ok && cached > sequenceNumber { + sequenceNumber = cached + } + + rawTx := aptosdk.RawTransaction{ + Sender: fromAddress, + SequenceNumber: sequenceNumber, + Payload: payload, + MaxGasAmount: maxGasAmount, + GasUnitPrice: gasUnitPrice, + ExpirationTimestampSeconds: expiration, + ChainId: chainID, + } + + signedTx, signature, err := signRawTransaction(ctx, r.chain.KeyStore(), publicKeyHex, publicKey, &rawTx) + if err != nil { + return nil, 0, 0, nil, err + } + + submitResponse, err := client.SubmitTransaction(signedTx) + if err == nil { + r.nextSequence[addressKey] = sequenceNumber + 1 + return submitResponse, sequenceNumber, expiration, signature, nil + } + + lastErr = err + kind := classifySequenceError(err) + if kind == sequenceErrorUnknown || attempt == maxAttempts { + delete(r.nextSequence, addressKey) + break + } + + switch kind { + case sequenceErrorTooOld, sequenceErrorInvalidUpdate: + // Another transaction likely already consumed this sequence in the mempool. + r.nextSequence[addressKey] = sequenceNumber + 1 + case sequenceErrorTooNew: + // Our local cursor got ahead of what the network can currently accept. + // Drop cache and rehydrate from onchain sequence on next attempt. + delete(r.nextSequence, addressKey) + } + + if txCfg.SubmitDelayDuration > 0 { + time.Sleep(time.Duration(txCfg.SubmitDelayDuration) * time.Second) + } + } + + return nil, 0, 0, nil, lastErr +} + +func (r *relayer) fetchSequenceNumber(client aptosdk.AptosRpcClient, fromAddress aptosdk.AccountAddress) (uint64, error) { + accountInfo, err := client.Account(fromAddress) + if err != nil { + return 0, fmt.Errorf("failed to fetch account info: %w", err) + } + sequenceNumber, err := accountInfo.SequenceNumber() + if err != nil { + return 0, fmt.Errorf("failed to parse sequence number: %w", err) + } + return sequenceNumber, nil +} + +type sequenceErrorKind int + +const ( + sequenceErrorUnknown sequenceErrorKind = iota + sequenceErrorTooOld + sequenceErrorTooNew + sequenceErrorInvalidUpdate +) + +func classifySequenceError(err error) sequenceErrorKind { + var httpErr *aptosdk.HttpError + if !errors.As(err, &httpErr) { + return sequenceErrorUnknown + } + + body := strings.ToUpper(string(httpErr.Body)) + if strings.Contains(body, "SEQUENCE_NUMBER_TOO_OLD") { + return sequenceErrorTooOld + } + if strings.Contains(body, "SEQUENCE_NUMBER_TOO_NEW") { + return sequenceErrorTooNew + } + if strings.Contains(body, "INVALID_TRANSACTION_UPDATE") || strings.Contains(body, "TRANSACTION ALREADY IN MEMPOOL WITH A DIFFERENT PAYLOAD") { + return sequenceErrorInvalidUpdate + } + return sequenceErrorUnknown +} + func (r *relayer) AccountTransactions(ctx context.Context, req typeaptos.AccountTransactionsRequest) (*typeaptos.AccountTransactionsReply, error) { client, err := r.chain.GetClient() if err != nil { From e59e9b1ad93fc5eef2d70d04b4053aa30730fbc7 Mon Sep 17 00:00:00 2001 From: cawthorne Date: Thu, 26 Feb 2026 22:37:44 +0000 Subject: [PATCH 10/10] aptos: route SubmitTransaction through txm and fix mempool sequence collisions --- relayer/relay.go | 218 ++++------------------------------ relayer/txm/tx.go | 18 ++- relayer/txm/txm.go | 196 ++++++++++++++++++++++++++---- relayer/txm/txm_error_test.go | 4 +- relayer/txm/txstore.go | 11 ++ 5 files changed, 224 insertions(+), 223 deletions(-) diff --git a/relayer/relay.go b/relayer/relay.go index 5396c4fe8..bfc06989f 100644 --- a/relayer/relay.go +++ b/relayer/relay.go @@ -2,19 +2,15 @@ package relayer import ( "context" - "crypto/ed25519" "encoding/json" "errors" "fmt" "math/big" - "strings" - "sync" - "time" aptosdk "github.com/aptos-labs/aptos-go-sdk" aptosapi "github.com/aptos-labs/aptos-go-sdk/api" "github.com/aptos-labs/aptos-go-sdk/bcs" - aptoscrypto "github.com/aptos-labs/aptos-go-sdk/crypto" + "github.com/google/uuid" "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" @@ -38,9 +34,6 @@ type relayer struct { starter commonutils.StartStopOnce stopCh services.StopChan - - sequenceMu sync.Mutex - nextSequence map[string]uint64 } func NewRelayer(lggr logger.Logger, chain chain.Chain, capRegistry core.CapabilitiesRegistry) (*relayer, error) { @@ -59,10 +52,9 @@ func NewRelayer(lggr logger.Logger, chain chain.Chain, capRegistry core.Capabili } return &relayer{ - chain: chain, - lggr: lggr, - stopCh: make(chan struct{}), - nextSequence: make(map[string]uint64), + chain: chain, + lggr: lggr, + stopCh: make(chan struct{}), }, nil } @@ -380,169 +372,43 @@ func (r *relayer) SubmitTransaction(ctx context.Context, req typeaptos.SubmitTra gasUnitPrice = gasInfo.GasEstimate } - submitResponse, sequenceNumber, expiration, signature, err := r.submitTransactionWithManagedSequence( + txID, err := uuid.NewUUID() + if err != nil { + return nil, err + } + submittedTx, err := r.chain.TxManager().SubmitPayload( ctx, - client, - cfg.Workflow.PublicKey, - publicKey, + txID.String(), + nil, fromAddress, + publicKey, payload, maxGasAmount, gasUnitPrice, ) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to submit transaction via txm: %w", err) } - if submitResponse == nil || submitResponse.Hash == "" { + if submittedTx == nil || submittedTx.Hash == "" { return nil, fmt.Errorf("submit transaction returned empty hash") } + sender := typeaptos.AccountAddress(submittedTx.Sender) + return &typeaptos.SubmitTransactionReply{ PendingTransaction: &typeaptos.PendingTransaction{ - Hash: submitResponse.Hash, - Sender: typeaptos.AccountAddress(fromAddress), - SequenceNumber: sequenceNumber, - MaxGasAmount: maxGasAmount, - GasUnitPrice: gasUnitPrice, - ExpirationTimestampSecs: expiration, + Hash: submittedTx.Hash, + Sender: sender, + SequenceNumber: submittedTx.Nonce, + MaxGasAmount: submittedTx.MaxGasAmount, + GasUnitPrice: submittedTx.GasUnitPrice, + ExpirationTimestampSecs: submittedTx.ExpirationTimestampSecs, Payload: req.EncodedPayload, - Signature: signature, + Signature: submittedTx.Signature, }, }, nil } -func (r *relayer) submitTransactionWithManagedSequence( - ctx context.Context, - client aptosdk.AptosRpcClient, - publicKeyHex string, - publicKey ed25519.PublicKey, - fromAddress aptosdk.AccountAddress, - payload aptosdk.TransactionPayload, - maxGasAmount uint64, - gasUnitPrice uint64, -) (*aptosapi.SubmitTransactionResponse, uint64, uint64, []byte, error) { - r.sequenceMu.Lock() - defer r.sequenceMu.Unlock() - - addressKey := fromAddress.String() - txCfg := r.chain.Config().TransactionManager - maxAttempts := int(txCfg.MaxSubmitRetryAttempts) - if maxAttempts < 1 { - maxAttempts = 1 - } - - lastErr := error(nil) - for attempt := 1; attempt <= maxAttempts; attempt++ { - chainID, err := client.GetChainId() - if err != nil { - return nil, 0, 0, nil, fmt.Errorf("failed to fetch chain id: %w", err) - } - - info, err := client.Info() - if err != nil { - return nil, 0, 0, nil, fmt.Errorf("failed to fetch node info: %w", err) - } - ledgerTimestamp := info.LedgerTimestamp() - if ledgerTimestamp == 0 { - return nil, 0, 0, nil, fmt.Errorf("ledger timestamp is zero") - } - expiration := (ledgerTimestamp / 1_000_000) + txCfg.TxExpirationSecs - - onchainSequence, err := r.fetchSequenceNumber(client, fromAddress) - if err != nil { - return nil, 0, 0, nil, err - } - sequenceNumber := onchainSequence - if cached, ok := r.nextSequence[addressKey]; ok && cached > sequenceNumber { - sequenceNumber = cached - } - - rawTx := aptosdk.RawTransaction{ - Sender: fromAddress, - SequenceNumber: sequenceNumber, - Payload: payload, - MaxGasAmount: maxGasAmount, - GasUnitPrice: gasUnitPrice, - ExpirationTimestampSeconds: expiration, - ChainId: chainID, - } - - signedTx, signature, err := signRawTransaction(ctx, r.chain.KeyStore(), publicKeyHex, publicKey, &rawTx) - if err != nil { - return nil, 0, 0, nil, err - } - - submitResponse, err := client.SubmitTransaction(signedTx) - if err == nil { - r.nextSequence[addressKey] = sequenceNumber + 1 - return submitResponse, sequenceNumber, expiration, signature, nil - } - - lastErr = err - kind := classifySequenceError(err) - if kind == sequenceErrorUnknown || attempt == maxAttempts { - delete(r.nextSequence, addressKey) - break - } - - switch kind { - case sequenceErrorTooOld, sequenceErrorInvalidUpdate: - // Another transaction likely already consumed this sequence in the mempool. - r.nextSequence[addressKey] = sequenceNumber + 1 - case sequenceErrorTooNew: - // Our local cursor got ahead of what the network can currently accept. - // Drop cache and rehydrate from onchain sequence on next attempt. - delete(r.nextSequence, addressKey) - } - - if txCfg.SubmitDelayDuration > 0 { - time.Sleep(time.Duration(txCfg.SubmitDelayDuration) * time.Second) - } - } - - return nil, 0, 0, nil, lastErr -} - -func (r *relayer) fetchSequenceNumber(client aptosdk.AptosRpcClient, fromAddress aptosdk.AccountAddress) (uint64, error) { - accountInfo, err := client.Account(fromAddress) - if err != nil { - return 0, fmt.Errorf("failed to fetch account info: %w", err) - } - sequenceNumber, err := accountInfo.SequenceNumber() - if err != nil { - return 0, fmt.Errorf("failed to parse sequence number: %w", err) - } - return sequenceNumber, nil -} - -type sequenceErrorKind int - -const ( - sequenceErrorUnknown sequenceErrorKind = iota - sequenceErrorTooOld - sequenceErrorTooNew - sequenceErrorInvalidUpdate -) - -func classifySequenceError(err error) sequenceErrorKind { - var httpErr *aptosdk.HttpError - if !errors.As(err, &httpErr) { - return sequenceErrorUnknown - } - - body := strings.ToUpper(string(httpErr.Body)) - if strings.Contains(body, "SEQUENCE_NUMBER_TOO_OLD") { - return sequenceErrorTooOld - } - if strings.Contains(body, "SEQUENCE_NUMBER_TOO_NEW") { - return sequenceErrorTooNew - } - if strings.Contains(body, "INVALID_TRANSACTION_UPDATE") || strings.Contains(body, "TRANSACTION ALREADY IN MEMPOOL WITH A DIFFERENT PAYLOAD") { - return sequenceErrorInvalidUpdate - } - return sequenceErrorUnknown -} - func (r *relayer) AccountTransactions(ctx context.Context, req typeaptos.AccountTransactionsRequest) (*typeaptos.AccountTransactionsReply, error) { client, err := r.chain.GetClient() if err != nil { @@ -675,41 +541,3 @@ func toSDKTypeTag(tag typeaptos.TypeTag) (aptosdk.TypeTag, error) { return aptosdk.TypeTag{}, fmt.Errorf("unsupported aptos type tag: %T", tag.Value) } } - -func signRawTransaction( - ctx context.Context, - ks core.Keystore, - publicKeyHex string, - publicKey ed25519.PublicKey, - rawTx *aptosdk.RawTransaction, -) (*aptosdk.SignedTransaction, []byte, error) { - signingMessage, err := rawTx.SigningMessage() - if err != nil { - return nil, nil, fmt.Errorf("failed to create signing message: %w", err) - } - - signature, err := ks.Sign(ctx, publicKeyHex, signingMessage) - if err != nil { - return nil, nil, fmt.Errorf("failed to sign message: %w", err) - } - - edSig := aptoscrypto.Ed25519Signature{} - if err := edSig.FromBytes(signature); err != nil { - return nil, nil, fmt.Errorf("failed to decode ed25519 signature: %w", err) - } - - authenticator := &aptoscrypto.AccountAuthenticator{ - Variant: aptoscrypto.AccountAuthenticatorEd25519, - Auth: &aptoscrypto.Ed25519Authenticator{ - PubKey: &aptoscrypto.Ed25519PublicKey{Inner: publicKey}, - Sig: &edSig, - }, - } - - signedTx, err := rawTx.SignedTransactionWithAuthenticator(authenticator) - if err != nil { - return nil, nil, fmt.Errorf("failed to build signed transaction: %w", err) - } - - return signedTx, signature, nil -} diff --git a/relayer/txm/tx.go b/relayer/txm/tx.go index a3128dc2e..2ce13a7d1 100644 --- a/relayer/txm/tx.go +++ b/relayer/txm/tx.go @@ -20,8 +20,18 @@ type AptosTx struct { FunctionName string TypeTags []aptos.TypeTag BcsValues [][]byte - Attempt uint64 - Status commontypes.TransactionStatus - Simulate bool - Fee *big.Int // Transaction fee in octas (1e-8 APT) + // Payload, when set, is used directly instead of reconstructing an EntryFunction from ModuleName/FunctionName/Args. + Payload *aptos.TransactionPayload + GasUnitPriceOverride *uint64 + Attempt uint64 + Status commontypes.TransactionStatus + Simulate bool + Fee *big.Int // Transaction fee in octas (1e-8 APT) + + LastSubmittedHash string + LastSubmittedNonce uint64 + LastSubmittedExpirationTimestampSecs uint64 + LastSubmittedMaxGasAmount uint64 + LastSubmittedGasUnitPrice uint64 + LastSubmittedSignature []byte } diff --git a/relayer/txm/txm.go b/relayer/txm/txm.go index fe8e18aff..1b5696297 100644 --- a/relayer/txm/txm.go +++ b/relayer/txm/txm.go @@ -45,6 +45,16 @@ type AptosTxm struct { client aptos.AptosRpcClient } +type SubmittedTransaction struct { + Hash string + Nonce uint64 + ExpirationTimestampSecs uint64 + MaxGasAmount uint64 + GasUnitPrice uint64 + Signature []byte + Sender aptos.AccountAddress +} + // TODO: Config input is not validated for sanity func New(lgr logger.Logger, keystore loop.Keystore, config Config, getClient func() (aptos.AptosRpcClient, error)) (*AptosTxm, error) { client, err := getClient() @@ -226,6 +236,85 @@ func (a *AptosTxm) Enqueue(transactionID string, txMetadata *commontypes.TxMeta, return nil } +// SubmitPayload submits a pre-encoded Aptos payload via TXM synchronously and +// returns the first submitted tx details (hash/nonce/gas/signature) when +// accepted into mempool. +func (a *AptosTxm) SubmitPayload( + ctx context.Context, + transactionID string, + txMetadata *commontypes.TxMeta, + fromAddress aptos.AccountAddress, + publicKey ed25519.PublicKey, + payload aptos.TransactionPayload, + maxGasAmount uint64, + gasUnitPrice uint64, +) (*SubmittedTransaction, error) { + if transactionID == "" { + transactionID = uuid.New().String() + } + + if err := ctx.Err(); err != nil { + return nil, err + } + + currentTimestamp := getTimestampSecs() + tx := &AptosTx{ + ID: transactionID, + Metadata: txMetadata, + Timestamp: currentTimestamp, + FromAddress: fromAddress, + PublicKey: publicKey, + Payload: &payload, + Status: commontypes.Pending, + Simulate: false, + } + if maxGasAmount > 0 { + if tx.Metadata == nil { + tx.Metadata = &commontypes.TxMeta{} + } + tx.Metadata.GasLimit = new(big.Int).SetUint64(maxGasAmount) + } + if gasUnitPrice > 0 { + price := gasUnitPrice + tx.GasUnitPriceOverride = &price + } + + a.transactionsLock.Lock() + _, transactionExists := a.transactions[transactionID] + if transactionExists { + a.transactionsLock.Unlock() + return nil, errors.New("transaction already exists") + } + + if (currentTimestamp - a.transactionsLastPruneTime) > a.config.PruneIntervalSecs { + for txID, existingTx := range a.transactions { + if existingTx.Status != commontypes.Finalized && existingTx.Status != commontypes.Failed && existingTx.Status != commontypes.Fatal { + continue + } + if (currentTimestamp - existingTx.Timestamp) < a.config.PruneTxExpirationSecs { + continue + } + delete(a.transactions, txID) + } + a.transactionsLastPruneTime = currentTimestamp + } + + a.transactions[transactionID] = tx + a.transactionsLock.Unlock() + + a.signAndBroadcast(tx) + + status, err := a.GetStatus(transactionID) + if err != nil { + return nil, err + } + if status != commontypes.Unconfirmed && status != commontypes.Finalized { + return nil, fmt.Errorf("transaction not accepted by txm, status=%d", status) + } + + return a.GetSubmittedTransaction(transactionID) +} + func (a *AptosTxm) GetStatus(transactionID string) (commontypes.TransactionStatus, error) { if transactionID == "" { return commontypes.Unknown, errors.New("nil tx id") @@ -264,6 +353,34 @@ func (a *AptosTxm) GetTransactionFee(ctx context.Context, transactionID string) return tx.Fee, nil } +func (a *AptosTxm) GetSubmittedTransaction(transactionID string) (*SubmittedTransaction, error) { + if transactionID == "" { + return nil, errors.New("nil tx id") + } + + a.transactionsLock.RLock() + defer a.transactionsLock.RUnlock() + + tx, ok := a.transactions[transactionID] + if !ok { + return nil, errors.New("no such tx") + } + if tx.LastSubmittedHash == "" { + return nil, errors.New("transaction has not been submitted yet") + } + + sig := append([]byte(nil), tx.LastSubmittedSignature...) + return &SubmittedTransaction{ + Hash: tx.LastSubmittedHash, + Nonce: tx.LastSubmittedNonce, + ExpirationTimestampSecs: tx.LastSubmittedExpirationTimestampSecs, + MaxGasAmount: tx.LastSubmittedMaxGasAmount, + GasUnitPrice: tx.LastSubmittedGasUnitPrice, + Signature: sig, + Sender: tx.FromAddress, + }, nil +} + func (a *AptosTxm) broadcastLoop() { defer a.done.Done() @@ -327,16 +444,21 @@ func (a *AptosTxm) createRawTx(client aptos.AptosRpcClient, tx *AptosTx, nonce u expirationTimestampSecs := ledgerTimestampSecs + a.config.TxExpirationSecs - payload := aptos.TransactionPayload{ - Payload: &aptos.EntryFunction{ - Module: aptos.ModuleId{ - Address: tx.ContractAddress, - Name: tx.ModuleName, + payload := aptos.TransactionPayload{} + if tx.Payload != nil { + payload = *tx.Payload + } else { + payload = aptos.TransactionPayload{ + Payload: &aptos.EntryFunction{ + Module: aptos.ModuleId{ + Address: tx.ContractAddress, + Name: tx.ModuleName, + }, + Function: tx.FunctionName, + ArgTypes: tx.TypeTags, + Args: tx.BcsValues, }, - Function: tx.FunctionName, - ArgTypes: tx.TypeTags, - Args: tx.BcsValues, - }, + } } rawTx := &aptos.RawTransaction{ @@ -377,6 +499,10 @@ func (a *AptosTxm) createRawTx(client aptos.AptosRpcClient, tx *AptosTx, nonce u } } + if tx.GasUnitPriceOverride != nil && *tx.GasUnitPriceOverride > 0 { + rawTx.GasUnitPrice = *tx.GasUnitPriceOverride + } + if rawTx.GasUnitPrice == 0 { // If simulate was disabled or failed, populate the gas unit price. gasInfo, err := client.EstimateGasPrice() @@ -411,21 +537,21 @@ func (a *AptosTxm) createRawTx(client aptos.AptosRpcClient, tx *AptosTx, nonce u return rawTx, nil } -func (a *AptosTxm) createSignedTx(client aptos.AptosRpcClient, rawTx *aptos.RawTransaction, publicKey ed25519.PublicKey, fromAddress aptos.AccountAddress) (*aptos.SignedTransaction, error) { +func (a *AptosTxm) createSignedTx(client aptos.AptosRpcClient, rawTx *aptos.RawTransaction, publicKey ed25519.PublicKey, fromAddress aptos.AccountAddress) (*aptos.SignedTransaction, []byte, error) { signingMessage, err := rawTx.SigningMessage() if err != nil { - return nil, fmt.Errorf("failed to create signing message: %w", err) + return nil, nil, fmt.Errorf("failed to create signing message: %w", err) } signature, err := a.keystore.Sign(context.Background(), fmt.Sprintf("%064x", publicKey), signingMessage) if err != nil { - return nil, fmt.Errorf("failed to sign message for address %s: %w", fromAddress, err) + return nil, nil, fmt.Errorf("failed to sign message for address %s: %w", fromAddress, err) } sig := aptoscrypto.Ed25519Signature{} err = sig.FromBytes(signature) if err != nil { - return nil, fmt.Errorf("failed to deserialize signature: %w", err) + return nil, nil, fmt.Errorf("failed to deserialize signature: %w", err) } authenticator := &aptoscrypto.Ed25519Authenticator{ @@ -438,10 +564,10 @@ func (a *AptosTxm) createSignedTx(client aptos.AptosRpcClient, rawTx *aptos.RawT Auth: authenticator, }) if err != nil { - return nil, fmt.Errorf("failed to sign tx: %w", err) + return nil, nil, fmt.Errorf("failed to sign tx: %w", err) } - return signedTx, nil + return signedTx, signature, nil } func (a *AptosTxm) updateTransactionStatus(tx *AptosTx, status commontypes.TransactionStatus) { @@ -450,6 +576,17 @@ func (a *AptosTxm) updateTransactionStatus(tx *AptosTx, status commontypes.Trans tx.Status = status } +func (a *AptosTxm) updateTransactionSubmittedState(tx *AptosTx, hash string, nonce uint64, expirationTimestampSecs uint64, maxGasAmount uint64, gasUnitPrice uint64, signature []byte) { + a.transactionsLock.Lock() + defer a.transactionsLock.Unlock() + tx.LastSubmittedHash = hash + tx.LastSubmittedNonce = nonce + tx.LastSubmittedExpirationTimestampSecs = expirationTimestampSecs + tx.LastSubmittedMaxGasAmount = maxGasAmount + tx.LastSubmittedGasUnitPrice = gasUnitPrice + tx.LastSubmittedSignature = append([]byte(nil), signature...) +} + func (a *AptosTxm) updateTransactionFee(tx *AptosTx, fee *big.Int) { a.transactionsLock.Lock() defer a.transactionsLock.Unlock() @@ -482,11 +619,16 @@ func (a *AptosTxm) signAndBroadcast(tx *AptosTx) { } newTxStore, err := a.accountStore.CreateTxStore(tx.FromAddress.String(), sequenceNumber) if err != nil { - ctxLogger.Errorw("failed to create tx store", "fromAddress", tx.FromAddress.String(), "error", err) - a.updateTransactionStatus(tx, commontypes.Failed) - return + // Another concurrent submission may have created the store first. + txStore = a.accountStore.GetTxStore(tx.FromAddress.String()) + if txStore == nil { + ctxLogger.Errorw("failed to create tx store", "fromAddress", tx.FromAddress.String(), "error", err) + a.updateTransactionStatus(tx, commontypes.Failed) + return + } + } else { + txStore = newTxStore } - txStore = newTxStore } currentAttempt := a.getTransactionAttempt(tx) @@ -508,7 +650,7 @@ func (a *AptosTxm) signAndBroadcast(tx *AptosTx) { return } - signedTx, err := a.createSignedTx(client, rawTx, tx.PublicKey, tx.FromAddress) + signedTx, signature, err := a.createSignedTx(client, rawTx, tx.PublicKey, tx.FromAddress) if err != nil { ctxLogger.Errorw("failed to create signed tx", "error", err) a.updateTransactionStatus(tx, commontypes.Failed) @@ -526,6 +668,7 @@ func (a *AptosTxm) signAndBroadcast(tx *AptosTx) { // tx included in the Mempool currentAttempt := a.getTransactionAttempt(tx) ctxLogger.Debugw("submit tx successful", "attempt", currentAttempt, "submitResponse", submitResponse) + a.updateTransactionSubmittedState(tx, submitResponse.Hash, nonce, rawTx.ExpirationTimestampSeconds, rawTx.MaxGasAmount, rawTx.GasUnitPrice, signature) err = txStore.AddUnconfirmed(nonce, submitResponse.Hash, rawTx.ExpirationTimestampSeconds, tx) if err != nil { @@ -552,11 +695,20 @@ func (a *AptosTxm) signAndBroadcast(tx *AptosTx) { ctxLogger.Errorw("failed to submit signed tx, retrying..", "error", httpError) time.Sleep(time.Duration(a.config.SubmitDelayDuration) * time.Second) - httpErrorBody := string(httpError.Body) - if strings.Contains(httpErrorBody, "SEQUENCE_NUMBER_TOO_OLD") || strings.Contains(httpErrorBody, "SEQUENCE_NUMBER_TOO_NEW") { + httpErrorBody := strings.ToUpper(string(httpError.Body)) + isTooOld := strings.Contains(httpErrorBody, "SEQUENCE_NUMBER_TOO_OLD") + isTooNew := strings.Contains(httpErrorBody, "SEQUENCE_NUMBER_TOO_NEW") + isInvalidUpdate := strings.Contains(httpErrorBody, "INVALID_TRANSACTION_UPDATE") || strings.Contains(httpErrorBody, "TRANSACTION ALREADY IN MEMPOOL WITH A DIFFERENT PAYLOAD") + + if isTooOld || isTooNew { // Try to resync the nonce before the next attempt. _ = a.resyncNonce(client, tx) } + if isTooOld || isInvalidUpdate { + // Mempool accepted a tx with this nonce, but onchain sequence may not + // be updated yet. Move local nonce cursor forward. + txStore.AdvanceNextNonce(nonce + 1) + } } } diff --git a/relayer/txm/txm_error_test.go b/relayer/txm/txm_error_test.go index 04ade5c00..295585fae 100644 --- a/relayer/txm/txm_error_test.go +++ b/relayer/txm/txm_error_test.go @@ -137,7 +137,7 @@ func runErrorsTest(t *testing.T, logger logger.Logger, config Config, rpcURL str require.NoError(t, err) rawTx.SequenceNumber = sequenceNumber - 1 - signedTx, err := txm.createSignedTx(rlClient, rawTx, selectedTx.PublicKey, selectedTx.FromAddress) + signedTx, _, err := txm.createSignedTx(rlClient, rawTx, selectedTx.PublicKey, selectedTx.FromAddress) require.NoError(t, err) _, err = client.SubmitTransaction(signedTx) @@ -147,7 +147,7 @@ func runErrorsTest(t *testing.T, logger logger.Logger, config Config, rpcURL str // Test with expired transaction rawTx.SequenceNumber = sequenceNumber rawTx.ExpirationTimestampSeconds = rawTx.ExpirationTimestampSeconds - txm.config.TxExpirationSecs - 3600 // 1 hour ago - signedTx, err = txm.createSignedTx(rlClient, rawTx, selectedTx.PublicKey, selectedTx.FromAddress) + signedTx, _, err = txm.createSignedTx(rlClient, rawTx, selectedTx.PublicKey, selectedTx.FromAddress) require.NoError(t, err) _, err = client.SubmitTransaction(signedTx) diff --git a/relayer/txm/txstore.go b/relayer/txm/txstore.go index db7717561..ce73e51ef 100644 --- a/relayer/txm/txstore.go +++ b/relayer/txm/txstore.go @@ -86,6 +86,17 @@ func (s *TxStore) GetNextNonce() uint64 { return nextNonce } +// AdvanceNextNonce moves the tx store cursor forward to at least minNextNonce. +// This is used for mempool-only sequence collisions where onchain nonce has not +// moved yet but the previous nonce is already occupied by another in-flight tx. +func (s *TxStore) AdvanceNextNonce(minNextNonce uint64) { + s.lock.Lock() + defer s.lock.Unlock() + if s.nextNonce < minNextNonce { + s.nextNonce = minNextNonce + } +} + func (s *TxStore) AddUnconfirmed(nonce uint64, hash string, expirationTimestampSecs uint64, tx *AptosTx) error { s.lock.Lock() defer s.lock.Unlock()