diff --git a/core/capabilities/integration_tests/keystone/contracts_setup.go b/core/capabilities/integration_tests/keystone/contracts_setup.go index 8193d2b13ce..2b70324a120 100644 --- a/core/capabilities/integration_tests/keystone/contracts_setup.go +++ b/core/capabilities/integration_tests/keystone/contracts_setup.go @@ -22,6 +22,7 @@ func SetupForwarderContract(t *testing.T, reportCreator *framework.DON, signers = append(signers, common.HexToAddress(p.Signer)) } + t.Logf("Setting config for forwarder: %s with reportCreator: %d and signers: %v and version: %d and f: %d", addr.String(), reportCreator.GetID(), signers, reportCreator.GetConfigVersion(), reportCreator.GetF()) _, err = fwd.SetConfig(backend.TransactionOpts(), reportCreator.GetID(), reportCreator.GetConfigVersion(), reportCreator.GetF(), signers) require.NoError(t, err) backend.Commit() @@ -40,6 +41,7 @@ func SetupConsumerContract(t *testing.T, backend *framework.EthBlockchain, ownerAddr := common.HexToAddress(workflowOwner) + t.Logf("Setting config for consumer: %s with forwarder: %s and owner: %s and workflow name: %s", addr.String(), forwarderAddress.String(), ownerAddr.String(), workflowName) _, err = consumer.SetConfig(backend.TransactionOpts(), []common.Address{forwarderAddress}, []common.Address{ownerAddr}, [][10]byte{nameBytes}) require.NoError(t, err) diff --git a/core/chainlink.Dockerfile b/core/chainlink.Dockerfile index b92a8f741e4..e6c0ec451ec 100644 --- a/core/chainlink.Dockerfile +++ b/core/chainlink.Dockerfile @@ -11,6 +11,10 @@ COPY GNUmakefile package.json ./ COPY tools/bin/ldflags ./tools/bin/ ADD go.mod go.sum ./ + +COPY ./plugins/scripts/setup_git_auth.sh /tmp/ +RUN --mount=type=secret,id=GIT_AUTH_TOKEN /tmp/setup_git_auth.sh + RUN --mount=type=cache,target=/go/pkg/mod \ go mod download COPY . . @@ -33,10 +37,10 @@ RUN --mount=type=secret,id=GIT_AUTH_TOKEN \ GOBIN=/go/bin make install-loopinstall && \ GOBIN=/gobins CL_LOOPINSTALL_OUTPUT_DIR=${CL_LOOPINSTALL_OUTPUT_DIR} make install-plugins-local install-plugins-public && \ if [ "${CL_INSTALL_PRIVATE_PLUGINS}" = "true" ]; then \ - GOBIN=/gobins CL_LOOPINSTALL_OUTPUT_DIR=${CL_LOOPINSTALL_OUTPUT_DIR} make install-plugins-private; \ + GOBIN=/gobins CL_LOOPINSTALL_OUTPUT_DIR=${CL_LOOPINSTALL_OUTPUT_DIR} make install-plugins-private; \ fi && \ if [ "${CL_INSTALL_TESTING_PLUGINS}" = "true" ]; then \ - GOBIN=/gobins CL_LOOPINSTALL_OUTPUT_DIR=${CL_LOOPINSTALL_OUTPUT_DIR} make install-plugins-testing; \ + GOBIN=/gobins CL_LOOPINSTALL_OUTPUT_DIR=${CL_LOOPINSTALL_OUTPUT_DIR} make install-plugins-testing; \ fi # Copy any shared libraries. @@ -50,10 +54,10 @@ RUN --mount=type=cache,target=/go/pkg/mod \ RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=/root/.cache/go-build \ if [ "$GO_COVER_FLAG" = "true" ]; then \ - GOBIN=/gobins make install-chainlink-cover; \ - else \ - GOBIN=/gobins make install-chainlink; \ - fi + GOBIN=/gobins make install-chainlink-cover; \ + else \ + GOBIN=/gobins make install-chainlink; \ + fi ## # Final Image @@ -66,9 +70,9 @@ RUN apt-get update && apt-get install -y ca-certificates gnupg lsb-release curl # Install Postgres for CLI tools, needed specifically for DB backups RUN curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \ - && echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" |tee /etc/apt/sources.list.d/pgdg.list \ - && apt-get update && apt-get install -y postgresql-client-16 \ - && rm -rf /var/lib/apt/lists/* + && echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" |tee /etc/apt/sources.list.d/pgdg.list \ + && apt-get update && apt-get install -y postgresql-client-16 \ + && rm -rf /var/lib/apt/lists/* RUN if [ ${CHAINLINK_USER} != root ]; then useradd --uid 14933 --create-home ${CHAINLINK_USER}; fi USER ${CHAINLINK_USER} diff --git a/core/config/env/env.go b/core/config/env/env.go index 56bc2af45d4..e94968c3b23 100644 --- a/core/config/env/env.go +++ b/core/config/env/env.go @@ -24,15 +24,16 @@ var ( // LOOPP commands and vars var ( - MedianPlugin = NewPlugin("median") - MercuryPlugin = NewPlugin("mercury") - AptosPlugin = NewPlugin("aptos") - EVMPlugin = NewPlugin("evm") - CosmosPlugin = NewPlugin("cosmos") - SolanaPlugin = NewPlugin("solana") - StarknetPlugin = NewPlugin("starknet") - TronPlugin = NewPlugin("tron") - TONPlugin = NewPlugin("ton") + MedianPlugin = NewPlugin("median") + MercuryPlugin = NewPlugin("mercury") + AptosPlugin = NewPlugin("aptos") + EVMPlugin = NewPlugin("evm") + CosmosPlugin = NewPlugin("cosmos") + SolanaPlugin = NewPlugin("solana") + StarknetPlugin = NewPlugin("starknet") + TronPlugin = NewPlugin("tron") + TONPlugin = NewPlugin("ton") + SecureMintPlugin = NewPlugin("securemint") // PrometheusDiscoveryHostName is the externally accessible hostname // published by the node in the `/discovery` endpoint. Generally, it is expected to match // the public hostname of node. diff --git a/core/scripts/cre/environment/configs/workflow-don.toml b/core/scripts/cre/environment/configs/workflow-don.toml index f86af42a85c..a14ae5a2f4c 100755 --- a/core/scripts/cre/environment/configs/workflow-don.toml +++ b/core/scripts/cre/environment/configs/workflow-don.toml @@ -2,7 +2,7 @@ [[blockchains]] type = "anvil" chain_id = "1337" - docker_cmd_params = ["-b", "5"] + docker_cmd_params = ["-b", "2"] [[blockchains]] type = "anvil" @@ -74,7 +74,7 @@ JSONConsole = true [Telemetry] - Enabled = true + Enabled = false Endpoint = 'host.docker.internal:4317' ChipIngressEndpoint = 'chip-ingress:50051' InsecureConnection = true @@ -99,7 +99,7 @@ JSONConsole = true [Telemetry] - Enabled = true + Enabled = false Endpoint = 'host.docker.internal:4317' ChipIngressEndpoint = 'chip-ingress:50051' InsecureConnection = true @@ -124,7 +124,7 @@ JSONConsole = true [Telemetry] - Enabled = true + Enabled = false Endpoint = 'host.docker.internal:4317' ChipIngressEndpoint = 'chip-ingress:50051' InsecureConnection = true @@ -149,7 +149,7 @@ JSONConsole = true [Telemetry] - Enabled = true + Enabled = false Endpoint = 'host.docker.internal:4317' ChipIngressEndpoint = 'chip-ingress:50051' InsecureConnection = true @@ -174,7 +174,7 @@ JSONConsole = true [Telemetry] - Enabled = true + Enabled = false Endpoint = 'host.docker.internal:4317' ChipIngressEndpoint = 'chip-ingress:50051' InsecureConnection = true diff --git a/core/scripts/go.mod b/core/scripts/go.mod index ba9419f421b..2216cbefa06 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -152,8 +152,8 @@ require ( github.com/buger/goterm v1.0.4 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/bytecodealliance/wasmtime-go/v28 v28.0.0 // indirect - github.com/bytedance/sonic v1.12.3 // indirect - github.com/bytedance/sonic/loader v0.2.0 // indirect + github.com/bytedance/sonic v1.13.3 // indirect + github.com/bytedance/sonic/loader v0.2.4 // indirect github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.70.2 // indirect github.com/cdk8s-team/cdk8s-plus-go/cdk8splus30/v2 v2.4.8 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect @@ -163,8 +163,7 @@ require ( github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240821051457-da69c6d9617a // 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/cloudwego/base64x v0.1.4 // indirect - github.com/cloudwego/iasm v0.2.0 // indirect + github.com/cloudwego/base64x v0.1.5 // indirect github.com/cockroachdb/errors v1.11.3 // indirect github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect @@ -250,7 +249,7 @@ require ( github.com/gin-contrib/expvar v0.0.1 // indirect github.com/gin-contrib/sessions v0.0.5 // indirect github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect + github.com/gin-contrib/sse v1.1.0 // indirect github.com/gin-gonic/gin v1.10.1 // indirect github.com/gkampitakis/ciinfo v0.3.2 // indirect github.com/gkampitakis/go-diff v1.3.2 // indirect @@ -354,7 +353,7 @@ require ( github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect github.com/klauspost/compress v1.18.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.10 // indirect + github.com/klauspost/cpuid/v2 v2.2.11 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect @@ -518,7 +517,7 @@ require ( github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/tyler-smith/go-bip39 v1.1.0 // indirect - github.com/ugorji/go/codec v1.2.12 // indirect + github.com/ugorji/go/codec v1.3.0 // indirect github.com/ulule/limiter/v3 v3.11.2 // indirect github.com/unrolled/secure v1.13.0 // indirect github.com/urfave/cli/v2 v2.27.6 // indirect @@ -532,7 +531,7 @@ require ( github.com/xhit/go-str2duration/v2 v2.1.0 // indirect github.com/xlab/treeprint v1.2.0 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect - github.com/xssnick/tonutils-go v1.13.0 // indirect + github.com/xssnick/tonutils-go v1.14.0 // indirect github.com/yuin/goldmark v1.7.12 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/zclconf/go-cty v1.16.0 // indirect @@ -545,7 +544,7 @@ require ( go.etcd.io/bbolt v1.4.0 // indirect go.mongodb.org/mongo-driver v1.17.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 // indirect + go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.62.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect @@ -559,7 +558,7 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.35.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.35.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0 // indirect go.opentelemetry.io/otel/log v0.13.0 // indirect go.opentelemetry.io/otel/metric v1.37.0 // indirect go.opentelemetry.io/otel/sdk v1.37.0 // indirect @@ -572,7 +571,7 @@ require ( go.uber.org/mock v0.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/ratelimit v0.3.1 // indirect - golang.org/x/arch v0.11.0 // indirect + golang.org/x/arch v0.18.0 // indirect golang.org/x/crypto v0.40.0 // indirect golang.org/x/exp v0.0.0-20250711185948-6ae5c78190dc // indirect golang.org/x/lint v0.0.0-20241112194109-818c5a804067 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 05f0c5dfeba..01264fc5e99 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -281,11 +281,11 @@ github.com/bxcodec/faker v2.0.1+incompatible h1:P0KUpUw5w6WJXwrPfv35oc91i4d8nf40 github.com/bxcodec/faker v2.0.1+incompatible/go.mod h1:BNzfpVdTwnFJ6GtfYTcQu6l6rHShT+veBxNCnjCx5XM= github.com/bytecodealliance/wasmtime-go/v28 v28.0.0 h1:aBU8cexP2rPZ0Qz488kvn2NXvWZHL2aG1/+n7Iv+xGc= github.com/bytecodealliance/wasmtime-go/v28 v28.0.0/go.mod h1:4OCU0xAW9ycwtX4nMF4zxwgJBJ5/0eMfJiHB0wAmkV4= -github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU= -github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= +github.com/bytedance/sonic v1.13.3 h1:MS8gmaH16Gtirygw7jV91pDCN33NyMrPbN7qiYhEsF0= +github.com/bytedance/sonic v1.13.3/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= -github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= -github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= +github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.70.2 h1:6khni3TG7XJsyXgg5gdbY/IZCiBnpAi8XVZZUBizGUc= github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.70.2/go.mod h1:JFGcyqRE2qXgHsBw27/L0D1uEJtLhUm2Vqx4dFOHSzA= github.com/cdk8s-team/cdk8s-plus-go/cdk8splus30/v2 v2.4.8 h1:vtT/G9hb1fstaeS52wcSYDKmZY0qExoroP5lhiFQe8U= @@ -317,9 +317,8 @@ github.com/cloudevents/sdk-go/v2 v2.16.1 h1:G91iUdqvl88BZ1GYYr9vScTj5zzXSyEuqbfE github.com/cloudevents/sdk-go/v2 v2.16.1/go.mod h1:v/kVOaWjNfbvc6tkhhlkhvLapj8Aa8kvXiH5GiOHCKI= github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 h1:lkAMpLVBDaj17e85keuznYcH5rqI438v41pKcBl4ZxQ= github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= -github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= -github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= -github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= +github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -605,8 +604,9 @@ github.com/gin-contrib/sessions v0.0.5/go.mod h1:vYAuaUPqie3WUSsft6HUlCjlwwoJQs9 github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4 h1:Z9J0PVIt1PuibOShaOw1jH8hUYz+Ak8NLsR/GI0Hv5I= github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4/go.mod h1:CEPcgZiz8998l9E8fDm16h8UfHRL7b+5oG0j/0koeVw= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= +github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ= @@ -1082,8 +1082,8 @@ github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zt github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -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/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU= +github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= 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= @@ -1720,8 +1720,8 @@ github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3C github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= -github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= +github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= github.com/ulule/limiter/v3 v3.11.2 h1:P4yOrxoEMJbOTfRJR2OzjL90oflzYPPmWg+dvwN2tHA= github.com/ulule/limiter/v3 v3.11.2/go.mod h1:QG5GnFOCV+k7lrL5Y8kgEeeflPH3+Cviqlqa8SVSQxI= github.com/umbracle/ethgo v0.1.3 h1:s8D7Rmphnt71zuqrgsGTMS5gTNbueGO1zKLh7qsFzTM= @@ -1760,8 +1760,8 @@ github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= -github.com/xssnick/tonutils-go v1.13.0 h1:LV2JzB+CuuWaLQiYNolK+YI3NRQOpS0W+T+N+ctF6VQ= -github.com/xssnick/tonutils-go v1.13.0/go.mod h1:EDe/9D/HZpAenbR+WPMQHICOF0BZWAe01TU5+Vpg08k= +github.com/xssnick/tonutils-go v1.14.0 h1:9+WXLKleINMWTSBN/uRJuE3d2BRYtxDh55hCG5PYCBE= +github.com/xssnick/tonutils-go v1.14.0/go.mod h1:68xwWjpoGGqiTbLJ0gT63sKu1Z1moCnDLLzA+DKanIg= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1814,16 +1814,16 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 h1:1f31+6grJmV3X4lxcEvUy13i5/kfDw1nJZwhd8mA4tg= -go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0/go.mod h1:1P/02zM3OwkX9uki+Wmxw3a5GVb6KUXRsa7m7bOC9Fg= +go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.62.0 h1:fZNpsQuTwFFSGC96aJexNOBrCD7PjD9Tm/HyHtXhmnk= +go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.62.0/go.mod h1:+NFxPSeYg0SoiRUO4k0ceJYMCY9FiRbYFmByUpm7GJY= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0 h1:0tY123n7CdWMem7MOVdKOt0YfshufLCwfE5Bob+hQuM= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0/go.mod h1:CosX/aS4eHnG9D7nESYpV753l4j9q5j3SL/PUYd2lR8= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= -go.opentelemetry.io/contrib/propagators/b3 v1.24.0 h1:n4xwCdTx3pZqZs2CjS/CUZAs03y3dZcGhC/FepKtEUY= -go.opentelemetry.io/contrib/propagators/b3 v1.24.0/go.mod h1:k5wRxKRU2uXx2F8uNJ4TaonuEO/V7/5xoz7kdsDACT8= +go.opentelemetry.io/contrib/propagators/b3 v1.37.0 h1:0aGKdIuVhy5l4GClAjl72ntkZJhijf2wg1S7b5oLoYA= +go.opentelemetry.io/contrib/propagators/b3 v1.37.0/go.mod h1:nhyrxEJEOQdwR15zXrCKI6+cJK60PXAkJ/jRyfhr2mg= go.opentelemetry.io/otel v1.6.3/go.mod h1:7BgNga5fNlF/iZjG06hM3yofffp0ofKCDwSXx1GC4dI= go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= @@ -1845,8 +1845,8 @@ go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 h1:yEX3aC9KDgvYPhuKE go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0/go.mod h1:/GXR0tBmmkxDaCUGahvksvp66mx4yh5+cFXgSlhg0vQ= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.35.0 h1:PB3Zrjs1sG1GBX51SXyTSoOTqcDglmsk7nT6tkKPb/k= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.35.0/go.mod h1:U2R3XyVPzn0WX7wOIypPuptulsMcPDPs/oiSVOMVnHY= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.35.0 h1:T0Ec2E+3YZf5bgTNQVet8iTDW7oIk03tXHq+wkwIDnE= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.35.0/go.mod h1:30v2gqH+vYGJsesLWFov8u47EpYTcIQcBjKpI6pJThg= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0 h1:SNhVp/9q4Go/XHBkQ1/d5u9P/U+L1yaGPoi0x+mStaI= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0/go.mod h1:tx8OOlGH6R4kLV67YaYO44GFXloEjGPZuMjEkaaqIp4= go.opentelemetry.io/otel/log v0.13.0 h1:yoxRoIZcohB6Xf0lNv9QIyCzQvrtGZklVbdCoyb7dls= go.opentelemetry.io/otel/log v0.13.0/go.mod h1:INKfG4k1O9CL25BaM1qLe0zIedOpvlS5Z7XgSbmN83E= go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= @@ -1895,8 +1895,8 @@ go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/arch v0.11.0 h1:KXV8WWKCXm6tRpLirl2szsO5j/oOODwZf4hATmGVNs4= -golang.org/x/arch v0.11.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.18.0 h1:WN9poc33zL4AzGxqf8VtpKUnGvMi8O9lhNyBMF/85qc= +golang.org/x/arch v0.18.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 2b1888ac4f4..96beddf0b11 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -1114,6 +1114,32 @@ func newCREServices( globalLogger.Debug("External registry not configured, skipping registry syncer and starting with an empty registry") opts.CapabilitiesRegistry.SetLocalRegistry(&capabilities.TestMetadataRegistry{}) } + + // TODO(gg): remove + // // enable hack unless it's specifically disabled on the environment (e.g. for tests) + // secureMintTransmitterHackDisabled, ok := os.LookupEnv("SECURE_TRANSMITTER_HACK_DISABLED") + // if !ok || secureMintTransmitterHackDisabled != "true" { + // globalLogger.Infow("HACK: initializing Secure Mint transmitter for sending mock secure mint trigger events") + // transmitterConfig := securemint.TransmitterConfig{ + // Logger: globalLogger, + // CapabilitiesRegistry: opts.CapabilitiesRegistry, + // DonID: 1, + // TriggerCapabilityName: "securemint-trigger", + // TriggerCapabilityVersion: "1.0.0", + // TriggerTickerMinResolutionMs: 1000, + // TriggerSendChannelBufferSize: 1000, + // } + // transmitter, err := transmitterConfig.NewTransmitter("securemint-transmitter") + // if err != nil { + // globalLogger.Errorw("could not create Secure Mint transmitter, skipping", "error", err) + // } else { + // srvcs = append(srvcs, transmitter) + // globalLogger.Infow("HACK: successfully created Secure Mint transmitter") + // } + // } else { + // globalLogger.Infow("HACK: Secure Mint transmitter hack disabled, skipping") + // } + return &CREServices{ workflowRateLimiter: workflowRateLimiter, workflowLimits: workflowLimits, diff --git a/core/services/job/orm.go b/core/services/job/orm.go index 6b50e6dfb0f..f2888a7e8ba 100644 --- a/core/services/job/orm.go +++ b/core/services/job/orm.go @@ -167,7 +167,7 @@ func (o *orm) AssertBridgesExist(ctx context.Context, p pipeline.Pipeline) error return nil } -// CreateJob creates the job, and it's associated spec record. +// CreateJob creates the job, and its associated spec record. // Expects an unmarshalled job spec as the jb argument i.e. output from ValidatedXX. // Scans all persisted records back into jb func (o *orm) CreateJob(ctx context.Context, jb *Job) error { @@ -647,7 +647,7 @@ func (o *orm) insertGatewaySpec(ctx context.Context, spec *GatewaySpec) (specID // ValidateKeyStoreMatch confirms that the key has a valid match in the keystore func ValidateKeyStoreMatch(ctx context.Context, spec *OCR2OracleSpec, keyStore keystore.Master, key string) (err error) { switch spec.PluginType { - case types.Mercury, types.LLO: + case types.Mercury, types.LLO, types.SecureMint: _, err = keyStore.CSA().Get(key) if err != nil { err = errors.Errorf("no CSA key matching: %q", key) diff --git a/core/services/ocr3/securemint/README.md b/core/services/ocr3/securemint/README.md new file mode 100644 index 00000000000..b89c7bb30c0 --- /dev/null +++ b/core/services/ocr3/securemint/README.md @@ -0,0 +1,121 @@ +# SecureMint Plugin + +## Overview + +The SecureMint plugin is a plugin that allows for secure minting of tokens. + +## Validation + +Validating whether the SecureMint plugin is working as expected is done by running the integration test. + +The test is located in the `core/services/ocr3/securemint` directory. + +### Prerequisites: +```bash +docker run --name cl-postgres -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=dbname -p 5432:5432 -d postgres +make setup-testdb +``` + +### Run test: +```bash + time SECURE_TRANSMITTER_HACK_DISABLED=true CL_DATABASE_URL=postgresql://chainlink_dev:insecurepassword@localhost:5432/chainlink_development_test?sslmode=disable go test -timeout 2m -run ^TestIntegration_SecureMint_happy_path$ github.com/smartcontractkit/chainlink/v2/core/services/ocr3/securemint -v 2>&1 | tee all.log | awk '/DEBUG|INFO|WARN|ERROR/ { print > "node_logs.log"; next }; { print > "other.log" }; tail all.log' +``` + +### If you change any dependencies: +```bash +go mod tidy && go mod vendor +modvendor -copy="**/*.a **/*.h" -v +``` + +(the `modvendor` step might not be necessary, but for me it was (see also https://github.com/marcboeker/go-duckdb/issues/174#issuecomment-1979097864)) + +### Logs + +* other.log: Contains all non-node output from the test run, this can be used to quickly see test failures +* node_logs.log: Contains all logs from the nodes started up in the test run, this can be used to see the full output of the test run +* all.log: Contains the complete output of the test run, this can be used to see test failures within the context of the node logs + + +### Debug test with VSCode: + +Create a launch.json file in the .vscode directory with the following content: + +```json +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug Secure Mint Integration Test", + "type": "go", + "request": "launch", + "mode": "test", + "program": "${workspaceFolder}/core/services/ocr3/securemint/integrationtest", + "args": [ + "-test.run", + "^TestIntegration_SecureMint_happy_path$", + "-test.v", + "-test.timeout", + "2m", + "2>&1", + "|", + "tee", + "all.log", + "|", + "awk '/DEBUG|INFO|WARN|ERROR/ { print > 'node_logs.log'; next }; { print > 'other.log' }'", + ], + "env": { + "ENV": "test", + "CL_DATABASE_URL": "postgresql://chainlink_dev:insecurepassword@localhost:5432/chainlink_development_test?sslmode=disable", + } + } + ] +} +``` + +Then run the test by Cmd+P: "Start Debugging". + +## Hacks + + +### XXX_SingletonTransmitter + +This is a hack to allow the `TestIntegration_SecureMint_happy_path` integration test to assess whether secure mint reports are being transmitted as a trigger to a Workflow. + +It gives the integration test access to the SecureMint transmitter, which is used to assert on the number of transmissions. + + +### SECURE_TRANSMITTER_HACK_DISABLED + +This is a hack to allow testing the Secure Mint plugin in the local CRE dev environment. + +It makes sure that the secure mint workflow trigger (in `securemint/transmitter.go`) generates stub reports on a regular cadence. + +It is enabled by default, but can be disabled by setting the `SECURE_TRANSMITTER_HACK_DISABLED` environment variable to `true`. + + +## Secure Mint Workflow + +The Secure Mint plugin's reports are triggers for a CRE Workflow. + +The secure mint workflow, and specifically the securemint aggregator (see `chainlink-common/pkg/capabilities/consensus/ocr3/datafeeds/securemint_aggregator.go`) are tested in `core/capabilities/integration_tests/keystone/securemint_workflow_test.go`. + +You can run it as follows: +```bash +time SECURE_TRANSMITTER_HACK_DISABLED=true CL_DATABASE_URL=postgresql://chainlink_dev:insecurepassword@localhost:5432/chainlink_development_test?sslmode=disable go test -timeout 2m -run ^Test_runSecureMintWorkflow$ github.com/smartcontractkit/chainlink/v2/core/capabilities/integration_tests/keystone -v 2>&1 | tee all.log | awk '/DEBUG|INFO|WARN|ERROR/ { print > "node_logs.log"; next }; { print > "other.log" }'; tail all.log +``` + +### Layers of abstraction in sending a Workflow trigger + +When sending a Workflow trigger, the SecureMint report is wrapped in a number of layers of abstraction. + +``` +Top +=== +- transmitter wraps in: capabilities.TriggerResponse{Event: capabilities.TriggerEvent, Err} +- transmitter wraps in: capabilities.TriggerEvent{TriggerType: 0, ID: "securemint-trigger", Outputs: values.Map, Payload: nil} +- transmitter wraps in: values.Map{"sigs": signatures, "configDigest": cfgDigest, "seqNr": seqNr, "report": } +- libocr wraps in: ocr3types.ReportWithInfo{Report: json-marshaled PorReport, Info: chainSelector} +- plugin creates: por.PorReport{ConfigDigest, SeqNr, Block, Mintable} +=== +Bottom +``` \ No newline at end of file diff --git a/core/services/ocr3/securemint/config/config.go b/core/services/ocr3/securemint/config/config.go new file mode 100644 index 00000000000..faa7c80467a --- /dev/null +++ b/core/services/ocr3/securemint/config/config.go @@ -0,0 +1,57 @@ +package config + +import ( + "encoding/json" + + "github.com/pkg/errors" +) + +// SecureMintConfig holds secure mint specific configuration +type SecureMintConfig struct { + Token string `json:"token"` + Reserves string `json:"reserves"` + ChainSelectors []string `json:"chainSelectors"` + + // Trigger capability configuration + TriggerCapabilityName string `json:"triggerCapabilityName"` + TriggerCapabilityVersion string `json:"triggerCapabilityVersion"` + TriggerTickerMinResolutionMs int `json:"triggerTickerMinResolutionMs"` + TriggerSendChannelBufferSize int `json:"triggerSendChannelBufferSize"` +} + +// SecureMintTriggerConfig holds configuration for secure mint trigger subscribers +type SecureMintTriggerConfig struct { + // The interval in milliseconds after which a new trigger event is generated. + MaxFrequencyMs uint64 `json:"maxFrequencyMs" yaml:"maxFrequencyMs" mapstructure:"maxFrequencyMs"` +} + +// Parse parses the secure mint configuration from JSON bytes +func Parse(configBytes []byte) (*SecureMintConfig, error) { + if len(configBytes) == 0 { + return nil, errors.New("secure mint config cannot be empty") + } + + var config SecureMintConfig + if err := json.Unmarshal(configBytes, &config); err != nil { + return nil, errors.Wrap(err, "failed to unmarshal SecureMintConfig") + } + + return &config, nil +} + +// Validate validates the secure mint plugin-specific config. +func (cfg *SecureMintConfig) Validate() error { + if cfg == nil { + return errors.New("secure mint plugin config cannot be nil") + } + + if cfg.Token == "" { + return errors.New("token cannot be empty") + } + + if cfg.Reserves == "" { + return errors.New("reserves cannot be empty") + } + + return nil +} diff --git a/core/services/ocr3/securemint/config/config_test.go b/core/services/ocr3/securemint/config/config_test.go new file mode 100644 index 00000000000..7f238fdd812 --- /dev/null +++ b/core/services/ocr3/securemint/config/config_test.go @@ -0,0 +1,129 @@ +package config + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_Validate(t *testing.T) { + tests := []struct { + name string + cfg *SecureMintConfig + err bool + }{ + { + name: "valid config", + cfg: &SecureMintConfig{ + Token: "eth", + Reserves: "platform", + }, + err: false, + }, + { + name: "nil config", + cfg: nil, + err: true, + }, + { + name: "invalid token", + cfg: &SecureMintConfig{ + Token: "", + Reserves: "platform", + }, + err: true, + }, + { + name: "invalid reserves", + cfg: &SecureMintConfig{ + Token: "eth", + Reserves: "", + }, + err: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.cfg.Validate() + if tt.err { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestParseSecureMintConfig(t *testing.T) { + tests := []struct { + name string + configJSON string + expectedToken string + expectedReserves string + expectedChainSelectors []string + expectError bool + }{ + { + name: "empty config is invalid", + configJSON: "", + expectError: true, + }, + { + name: "custom values", + configJSON: `{"token": "btc", "reserves": "custom", "chainSelectors": ["8953668971247136127", "729797994450396300"]}`, + expectedToken: "btc", + expectedReserves: "custom", + expectedChainSelectors: []string{"8953668971247136127", "729797994450396300"}, + expectError: false, + }, + { + name: "partial config uses empty string", + configJSON: `{"token": "link", "chainSelectors": ["8953668971247136127", "729797994450396300"]}`, + expectedToken: "link", + expectedReserves: "", + expectedChainSelectors: []string{"8953668971247136127", "729797994450396300"}, + expectError: false, + }, + { + name: "partial config uses empty string 2", + configJSON: `{"reserves": "custom", "chainSelectors": ["8953668971247136127", "729797994450396300"]}`, + expectedToken: "", + expectedReserves: "custom", + expectedChainSelectors: []string{"8953668971247136127", "729797994450396300"}, + expectError: false, + }, + { + name: "partial config uses empty slice", + configJSON: `{"token": "btc", "reserves": "custom"}`, + expectedToken: "btc", + expectedReserves: "custom", + expectedChainSelectors: nil, + expectError: false, + }, + { + name: "invalid JSON", + configJSON: `{"token": "btc", "reserves":}`, + expectedToken: "", + expectedReserves: "", + expectError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + config, err := Parse([]byte(tt.configJSON)) + + if tt.expectError { + require.Error(t, err) + return + } + + require.NoError(t, err) + require.NotNil(t, config) + require.Equal(t, tt.expectedToken, config.Token) + require.Equal(t, tt.expectedReserves, config.Reserves) + require.Equal(t, tt.expectedChainSelectors, config.ChainSelectors) + }) + } +} diff --git a/core/services/ocr3/securemint/ea/ea.go b/core/services/ocr3/securemint/ea/ea.go new file mode 100644 index 00000000000..dcd7349c7bd --- /dev/null +++ b/core/services/ocr3/securemint/ea/ea.go @@ -0,0 +1,184 @@ +package ea + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "math/big" + "strconv" + "time" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + sm_config "github.com/smartcontractkit/chainlink/v2/core/services/ocr3/securemint/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" + "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" + "github.com/smartcontractkit/por_mock_ocr3plugin/por" +) + +// externalAdapter implements por.ExternalAdapter +var _ por.ExternalAdapter = &externalAdapter{} + +type externalAdapter struct { + config *sm_config.SecureMintConfig + chainSelectors []uint64 // use parsed chain selectors from config + runner pipeline.Runner + job job.Job + spec pipeline.Spec + saver ocrcommon.Saver + lggr logger.Logger +} + +func NewExternalAdapter(config *sm_config.SecureMintConfig, runner pipeline.Runner, job job.Job, spec pipeline.Spec, saver ocrcommon.Saver, lggr logger.Logger) (*externalAdapter, error) { + chainSelectors := make([]uint64, 0, len(config.ChainSelectors)) + for _, chainSelector := range config.ChainSelectors { + chainSelectorUint64, err := strconv.ParseUint(chainSelector, 10, 64) + if err != nil { + return nil, fmt.Errorf("failed to parse chain selector: %s", chainSelector) + } + chainSelectors = append(chainSelectors, chainSelectorUint64) + } + + return &externalAdapter{config: config, chainSelectors: chainSelectors, runner: runner, job: job, spec: spec, saver: saver, lggr: lggr}, nil +} + +// GetPayload retrieves the payload for the given blocks by executing a pipeline run. +func (ea *externalAdapter) GetPayload(ctx context.Context, blocks por.Blocks) (por.ExternalAdapterPayload, error) { + ea.lggr.Debugf("GetPayload called with blocks parameter: %v", blocks) + + // Create the request for the external adapter + req := Request{ + Token: ea.config.Token, + Reserves: ea.config.Reserves, + } + + // coalesce blocks with config.ChainSelectors + coalescedBlocks := make(map[uint64]uint64) + for _, chainSelector := range ea.chainSelectors { + coalescedBlocks[chainSelector] = uint64(blocks[por.ChainSelector(chainSelector)]) + } + + // add coalesced blocks to request + for chainSelector, blockNumber := range coalescedBlocks { + req.SupplyChains = append(req.SupplyChains, strconv.FormatUint(chainSelector, 10)) + req.SupplyChainBlocks = append(req.SupplyChainBlocks, blockNumber) + } + + // Serialize EA request to JSON + reqJSON, err := json.Marshal(req) + if err != nil { + return por.ExternalAdapterPayload{}, fmt.Errorf("failed to marshal ea request: %w (request: %#v)", err, req) + } + + ea.lggr.Debugf("GetPayload serialized ea request to JSON: %v", string(reqJSON)) + + // Execute the request + vars := map[string]any{ + "jb": map[string]any{ + "databaseID": ea.job.ID, + "externalJobID": ea.job.ExternalJobID, + "name": ea.job.Name.ValueOrZero(), + }, + "action": "get_payload", + "ea_request": req, + } + + run, trrs, err := ea.runner.ExecuteRun(ctx, ea.spec, pipeline.NewVarsFrom(vars)) + if err != nil { + return por.ExternalAdapterPayload{}, fmt.Errorf("failed to execute GetPayload: %w", err) + } + + ea.saver.Save(run) + + // Parse and return results + for _, trr := range trrs { + if !trr.IsTerminal() { + continue + } + + resultMap, ok := trr.Result.Value.(map[string]any) + if !ok { + return por.ExternalAdapterPayload{}, fmt.Errorf("unexpected result type for GetPayload: %T", trr.Result.Value) + } + + payload, err := ea.convertMapToPayload(resultMap) + if err != nil { + return por.ExternalAdapterPayload{}, fmt.Errorf("failed to convert EA response map to payload: %w, map: %#v", err, resultMap) + } + + ea.lggr.Debugw("GetPayload result", "payload", payload) + if len(blocks) == 0 { + ea.lggr.Debugw("Plugin does not know about any chains or blocks yet, not returning any mintables") + // set Mintables to empty map - plugin will error out if it's not empty when it hasn't requested any mintables yet + // TODO(gg): we should probably update the plugin to handle this case + payload.Mintables = make(por.Mintables) + } + ea.lggr.Debugw("GetPayload returning", "payload", payload) + + return payload, nil + } + + return por.ExternalAdapterPayload{}, errors.New("no terminal result for GetPayload") +} + +// convertMapToPayload converts a map[string]any response to por.ExternalAdapterPayload +func (ea *externalAdapter) convertMapToPayload(resultMap map[string]any) (por.ExternalAdapterPayload, error) { + // Marshal and unmarshal to convert to Response struct + b, err := json.Marshal(resultMap) + if err != nil { + return por.ExternalAdapterPayload{}, fmt.Errorf("failed to marshal EA payload map: %w", err) + } + + ea.lggr.Debugf("EA response: %s", string(b)) + + var eaResponse Response + if err := json.Unmarshal(b, &eaResponse); err != nil { + return por.ExternalAdapterPayload{}, fmt.Errorf("failed to unmarshal EA response: %w", err) + } + + // Create the payload + payload := por.ExternalAdapterPayload{ + Mintables: make(por.Mintables), + LatestBlocks: make(por.Blocks), + } + + // Convert mintables + for chainSelector, mintable := range eaResponse.Mintables { + chainSelectorUint64, err := strconv.ParseUint(chainSelector, 10, 64) + if err != nil { + return por.ExternalAdapterPayload{}, fmt.Errorf("failed to parse chain selector: %s", chainSelector) + } + + mintableAmount, ok := new(big.Int).SetString(mintable.Mintable, 10) + if !ok { + return por.ExternalAdapterPayload{}, fmt.Errorf("failed to parse mintable amount: %s", mintable.Mintable) + } + + payload.Mintables[por.ChainSelector(chainSelectorUint64)] = por.BlockMintablePair{ + Block: por.BlockNumber(mintable.Block), + Mintable: mintableAmount, + } + } + + // Convert reserve info + reserveAmount, ok := new(big.Int).SetString(eaResponse.ReserveInfo.ReserveAmount, 10) + if !ok { + return por.ExternalAdapterPayload{}, fmt.Errorf("failed to parse reserve amount: %s", eaResponse.ReserveInfo.ReserveAmount) + } + payload.ReserveInfo = por.ReserveInfo{ + ReserveAmount: reserveAmount, + Timestamp: time.UnixMilli(eaResponse.ReserveInfo.Timestamp), + } + + // Convert latest blocks + for chainSelector, block := range eaResponse.LatestBlocks { + chainSelectorUint64, err := strconv.ParseUint(chainSelector, 10, 64) + if err != nil { + return por.ExternalAdapterPayload{}, fmt.Errorf("failed to parse chain selector: %s", chainSelector) + } + payload.LatestBlocks[por.ChainSelector(chainSelectorUint64)] = por.BlockNumber(block) + } + + return payload, nil +} diff --git a/core/services/ocr3/securemint/ea/ea_test.go b/core/services/ocr3/securemint/ea/ea_test.go new file mode 100644 index 00000000000..05c29c53ade --- /dev/null +++ b/core/services/ocr3/securemint/ea/ea_test.go @@ -0,0 +1,118 @@ +package ea + +import ( + "context" + "encoding/json" + "math/big" + "testing" + "time" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + sm_config "github.com/smartcontractkit/chainlink/v2/core/services/ocr3/securemint/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" + "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" + "github.com/smartcontractkit/chainlink/v2/core/services/pipeline/mocks" + "github.com/smartcontractkit/por_mock_ocr3plugin/por" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" +) + +func Test_GetPayload(t *testing.T) { + + // Setup test context, logger, and other dependencies + ctx := testutils.Context(t) + lggr := logger.NullLogger + runner := mocks.NewRunner(t) + saver := ocrcommon.NewResultRunSaver( + runner, + lggr, + 1000, + 100, + ) + + config := &sm_config.SecureMintConfig{ + Token: "eth", + Reserves: "platform", + ChainSelectors: []uint64{5009297550715157269}, + } + job := job.Job{} + spec := pipeline.Spec{} + executedRun := &pipeline.Run{} + + ea := NewExternalAdapter(config, runner, job, spec, saver, lggr) + + results := pipeline.TaskRunResults{ + { + Task: &pipeline.AnyTask{}, + Result: pipeline.Result{ + Value: map[string]any{ // outer `data` field is already stripped off in the parse step of the pipeline + "mintables": map[string]any{ + "5009297550715157269": map[string]any{ + "mintable": "10", + "block": 8, + }, + }, + "reserveInfo": map[string]any{ + "reserveAmount": "10332550000000000000000", + "timestamp": 1749483841486, + }, + "latestBlocks": map[string]any{ + "5009297550715157269": 23, + }, + }, + Error: nil, + }, + }, + } + + // Capture the 'ea_request' parameter from the pipeline run + var eaRequest any + runner.EXPECT().ExecuteRun(mock.Anything, mock.Anything, mock.Anything).Return(executedRun, results, nil).Run(func(_ context.Context, _ pipeline.Spec, vars pipeline.Vars) { + var err error + eaRequest, err = vars.Get("ea_request") + require.NoError(t, err) + }) + + payload, err := ea.GetPayload(ctx, por.Blocks{1234567890: 1234567890, 5009297550715157269: 10}) + require.NoError(t, err, "GetPayload should not return an error") + + // Validate the 'ea_request' parameter serialized to json + eaRequestJSON, err := json.Marshal(eaRequest) + require.NoError(t, err, "Failed to marshal ea_request to JSON") + assert.JSONEq(t, + `{ + "reserves": "platform", + "supplyChains": [ + "5009297550715157269" + ], + "supplyChainBlocks": [ + 10 + ], + "token": "eth" + }`, + string(eaRequestJSON), + ) + + // Validate the resulting payload + amount, ok := big.NewInt(10).SetString("10332550000000000000000", 10) + require.True(t, ok, "Failed to parse reserve amount from string") + expectedPayload := por.ExternalAdapterPayload{ + Mintables: por.Mintables{ + 5009297550715157269: { + Block: 8, + Mintable: big.NewInt(10), + }, + }, + ReserveInfo: por.ReserveInfo{ + ReserveAmount: amount, + Timestamp: time.UnixMilli(1749483841486), + }, + LatestBlocks: por.Blocks{ + 5009297550715157269: 23, + }, + } + assert.Equal(t, expectedPayload, payload) +} diff --git a/core/services/ocr3/securemint/ea/types.go b/core/services/ocr3/securemint/ea/types.go new file mode 100644 index 00000000000..aaa93e8a76d --- /dev/null +++ b/core/services/ocr3/securemint/ea/types.go @@ -0,0 +1,57 @@ +package ea + +// Request represents the request structure sent to the secure mint external adapter. +// Example (sent in the 'data' field): +// +// { +// "data": { +// "token": "eth", +// "reserves": "platform", +// "supplyChains": [ +// "5009297550715157269" +// ], +// "supplyChainBlocks": [ +// 0 +// ] +// } +// } +type Request struct { + Token string `json:"token"` + Reserves string `json:"reserves"` + SupplyChains []string `json:"supplyChains,omitempty"` + SupplyChainBlocks []uint64 `json:"supplyChainBlocks,omitempty"` +} + +// Response represents the response structure from the secure mint external adapter. +// Example: +// +// { +// "mintables": { +// "5009297550715157269": { +// "mintable": "5", +// "block": 22667990 +// } +// }, +// "reserveInfo": { +// "reserveAmount": "10332550000000000000000", +// "timestamp": 1749483841486 +// }, +// "latestBlocks": { +// "5009297550715157269": 22667990 +// } +// } +type Response struct { + Mintables map[string]MintableInfo `json:"mintables"` + ReserveInfo ReserveInfo `json:"reserveInfo"` + LatestBlocks map[string]uint64 `json:"latestBlocks"` +} + +type MintableInfo struct { + Mintable string `json:"mintable"` + Block uint64 `json:"block"` +} + +type ReserveInfo struct { + ReserveAmount string `json:"reserveAmount"` + Timestamp int64 `json:"timestamp"` +} diff --git a/core/services/ocr3/securemint/integrationtest/helpers_test.go b/core/services/ocr3/securemint/integrationtest/helpers_test.go new file mode 100644 index 00000000000..ace5a21f0eb --- /dev/null +++ b/core/services/ocr3/securemint/integrationtest/helpers_test.go @@ -0,0 +1,354 @@ +package integrationtest + +import ( + "crypto/ed25519" + "encoding/json" + "fmt" + "io" + "math/big" + "net/http" + "net/http/httptest" + "net/url" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + "go.uber.org/zap/zaptest/observer" + + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + evmtypes "github.com/smartcontractkit/chainlink-evm/pkg/types" + "github.com/smartcontractkit/chainlink/v2/core/bridges" + "github.com/smartcontractkit/chainlink/v2/core/config/toml" + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/keystest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/csakey" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" + sm_ea "github.com/smartcontractkit/chainlink/v2/core/services/ocr3/securemint/ea" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" + "github.com/smartcontractkit/chainlink/v2/core/store/models" + "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" + "github.com/smartcontractkit/wsrpc/credentials" +) + +type node struct { + app chainlink.Application + clientPubKey credentials.StaticSizedPublicKey + keyBundle ocr2key.KeyBundle + observedLogs *observer.ObservedLogs +} + +func (node *node) addBootstrapJob(t *testing.T, spec string) *job.Job { + job, err := ocrbootstrap.ValidatedBootstrapSpecToml(spec) + require.NoError(t, err) + err = node.app.AddJobV2(testutils.Context(t), &job) + require.NoError(t, err) + return &job +} + +func setupNode( + t *testing.T, + port int, + dbName string, + backend evmtypes.Backend, + csaKey csakey.KeyV2, + f func(*chainlink.Config), +) (app chainlink.Application, peerID string, clientPubKey credentials.StaticSizedPublicKey, ocr2kb ocr2key.KeyBundle, observedLogs *observer.ObservedLogs) { + k := big.NewInt(int64(port)) // keys unique to port + p2pKey := p2pkey.MustNewV2XXXTestingOnly(k) + rdr := keystest.NewRandReaderFromSeed(int64(port)) + ocr2kb = ocr2key.MustNewInsecure(rdr, chaintype.EVM) + + p2paddresses := []string{fmt.Sprintf("127.0.0.1:%d", port)} + + config, _ := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, _ *chainlink.Secrets) { + // set finality depth to 1 so we don't have to wait for multiple blocks + c.EVM[0].FinalityDepth = ptr[uint32](1) + + // [JobPipeline] + c.JobPipeline.MaxSuccessfulRuns = ptr(uint64(1000)) + c.JobPipeline.VerboseLogging = ptr(true) + + // [Feature] + c.Feature.UICSAKeys = ptr(true) + c.Feature.LogPoller = ptr(true) + c.Feature.FeedsManager = ptr(false) + + // [OCR] + c.OCR.Enabled = ptr(false) + + // [OCR2] + c.OCR2.Enabled = ptr(true) + c.OCR2.ContractPollInterval = commonconfig.MustNewDuration(500 * time.Millisecond) + + // [P2P] + c.P2P.PeerID = ptr(p2pKey.PeerID()) + c.P2P.TraceLogging = ptr(true) + + // [P2P.V2] + c.P2P.V2.Enabled = ptr(true) + c.P2P.V2.AnnounceAddresses = &p2paddresses + c.P2P.V2.ListenAddresses = &p2paddresses + c.P2P.V2.DeltaDial = commonconfig.MustNewDuration(500 * time.Millisecond) + c.P2P.V2.DeltaReconcile = commonconfig.MustNewDuration(5 * time.Second) + + // [Log] + c.Log.Level = ptr(toml.LogLevel(zapcore.DebugLevel)) // generally speaking we want debug level for logs unless overridden + + // [EVM.Transactions] + for _, evmCfg := range c.EVM { + evmCfg.Transactions.Enabled = ptr(false) // don't need txmgr + } + + // Optional overrides + if f != nil { + f(c) + } + }) + + lggr, observedLogs := logger.TestLoggerObserved(t, config.Log().Level()) + + app = cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, backend, p2pKey, ocr2kb, csaKey, lggr.Named(dbName)) + err := app.Start(testutils.Context(t)) + require.NoError(t, err) + + t.Cleanup(func() { + assert.NoError(t, app.Stop()) + }) + + return app, p2pKey.PeerID().Raw(), csaKey.StaticSizedPublicKey(), ocr2kb, observedLogs +} + +func ptr[T any](t T) *T { return &t } + +func createSecureMintBootstrapJob(t *testing.T, bootstrapNode node, configuratorAddress common.Address, chainID, fromBlock string) *job.Job { + return bootstrapNode.addBootstrapJob(t, fmt.Sprintf(` + type = "bootstrap" + relay = "evm" + schemaVersion = 1 + name = "bootstrap-secure-mint" + contractID = "%s" + contractConfigTrackerPollInterval = "1s" + contractConfigConfirmations = 1 + + [relayConfig] + chainID = %s + fromBlock = %s + providerType = "securemint" + lloDonID = 1 + lloConfigMode = "bluegreen"`, // Using lloConfigMode 'bluegreen' since otherwise LLO config poller won't work + configuratorAddress.Hex(), + chainID, + fromBlock), + ) +} + +func addSecureMintOCRJobs( + t *testing.T, + nodes []node, + configuratorAddress common.Address, +) (jobIDs map[int]int32) { + // node idx => job id + jobIDs = make(map[int]int32) + + // Create one bridge and one SM Feed OCR job on each node + for i, node := range nodes { + name := "securemint-ea" + + bmBridge := createSecureMintBridge(t, name, i, node.app.BridgeORM()) + t.Logf("Created secure mint bridge %s on node %d", bmBridge, i) + + jobID := addSecureMintJob( + t, + node, + configuratorAddress, + bmBridge, + ) + jobIDs[i] = jobID + t.Logf("Added secure mint job with id %d on node %d", jobID, i) + } + return jobIDs +} + +func addSecureMintJob( + t *testing.T, + node node, + configuratorAddress common.Address, + bridgeName string, +) (id int32) { + + spec := getSecureMintJobSpec(t, configuratorAddress.Hex(), node.keyBundle.ID(), node.clientPubKey[:], bridgeName) + + c := node.app.GetConfig() + job, err := validate.ValidatedOracleSpecToml(testutils.Context(t), c.OCR2(), c.Insecure(), spec, nil) + require.NoError(t, err) + + err = node.app.AddJobV2(testutils.Context(t), &job) + require.NoError(t, err) + t.Logf("Added secure mint job spec %s", job.ExternalJobID) + + return job.ID +} + +func getSecureMintJobSpec(t *testing.T, ocrContractAddress, keyBundleID string, publicKey ed25519.PublicKey, bridgeName string) string { + + t.Logf("Using transmitter address %x for job", publicKey) + + return fmt.Sprintf(` + type = "offchainreporting2" + relay = "evm" + schemaVersion = 1 + pluginType = "securemint" + name = "secure mint spec" + contractID = "%s" + ocrKeyBundleID = "%s" + transmitterID = "%x" + contractConfigConfirmations = 1 + contractConfigTrackerPollInterval = "1s" + observationSource = """ + // data source 1 + ds1 [type=bridge name="%s" requestData=<{ "data": $(ea_request) }>]; + ds1_parse [type=jsonparse path="data"]; + + ds1 -> ds1_parse -> answer1; + + answer1 [type=any index=0]; + """ + + allowNoBootstrappers = false + + [relayConfig] + chainID = 1337 + fromBlock = 1 + providerType = "securemint" + lloDonID = 1 + lloConfigMode = "bluegreen" + + [pluginConfig] + maxChains = 5 + token = "btc" + reserves = "custom" + chainSelectors = ["8953668971247136127", "729797994450396300"] + `, // Using lloConfigMode 'bluegreen' since otherwise LLO config poller won't work + ocrContractAddress, // contract address + keyBundleID, // ocr key bundle id + publicKey, // transmitter id + bridgeName) // bridge name +} + +// Based on https://chainlink-core.slack.com/archives/C090PQH50M6/p1749483857095389?thread_ts=1749482941.061609&cid=C090PQH50M6 +func createSecureMintBridge(t *testing.T, name string, i int, borm bridges.ORM) (bridgeName string) { + ctx := testutils.Context(t) + + initialResponse := sm_ea.Response{ + Mintables: map[string]sm_ea.MintableInfo{}, + LatestBlocks: map[string]uint64{ + "8953668971247136127": 5, // "bitcoin-testnet-rootstock" + "729797994450396300": 5, // "telos-evm-testnet" + }, + ReserveInfo: sm_ea.ReserveInfo{ + ReserveAmount: "1000", + Timestamp: time.Now().UnixMilli(), + }, + } + jsonInitialResp, err := json.Marshal(initialResponse) + require.NoError(t, err) + + fullResponse := sm_ea.Response{ + Mintables: map[string]sm_ea.MintableInfo{ + "8953668971247136127": { // "bitcoin-testnet-rootstock" + Block: uint64(5), + Mintable: "10", + }, + "729797994450396300": { // "telos-evm-testnet" + Block: uint64(5), + Mintable: "25", + }, + }, + LatestBlocks: map[string]uint64{ + "8953668971247136127": 8, // "bitcoin-testnet-rootstock" + "729797994450396300": 7, // "telos-evm-testnet" + }, + ReserveInfo: sm_ea.ReserveInfo{ + ReserveAmount: "500", + Timestamp: time.Now().UnixMilli(), + }, + } + jsonFullResponse, err := json.Marshal(fullResponse) + require.NoError(t, err) + + //nolint:testifylint // allow require.NoError in the http server + bridge := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { + body, err := io.ReadAll(req.Body) + defer req.Body.Close() + require.NoError(t, err) + t.Logf("Received request for secure mint bridge %s on node %d: path %s, request body %s", name, i, req.URL.String(), string(body)) + + // Parse the request body into a map to extract the 'data' field + var requestMap map[string]any + err = json.Unmarshal(body, &requestMap) + require.NoError(t, err, "Failed to parse request body as map for bridge %s on node %d", name, i) + + dataField, exists := requestMap["data"] + require.True(t, exists, "Request body should contain 'data' field for bridge %s on node %d", name, i) + + // Marshal the data field back to JSON and parse as ea.Request + dataBytes, err := json.Marshal(dataField) + require.NoError(t, err, "Failed to marshal data field for bridge %s on node %d", name, i) + var eaRequest sm_ea.Request + err = json.Unmarshal(dataBytes, &eaRequest) + require.NoError(t, err, "Failed to parse request body as ea.Request for bridge %s on node %d", name, i) + + // Validate the parsed ea.Request + assert.Equal(t, "btc", eaRequest.Token, "Token should be 'eth'") + assert.Equal(t, "custom", eaRequest.Reserves, "Reserves should be 'platform'") + + // Return initial EA response if empty request (first round) + if len(eaRequest.SupplyChains) == 0 && len(eaRequest.SupplyChainBlocks) == 0 { + t.Logf("Received empty supply chains for secure mint bridge %s on node %d, returning initial response", name, i) + res.WriteHeader(http.StatusOK) + _, err = res.Write(fmt.Appendf(nil, `{"data": %s}`, string(jsonInitialResp))) + require.NoError(t, err) + return + } + + // Validate non-empty request + assert.Contains(t, eaRequest.SupplyChains, "8953668971247136127", "Supply chains should contain bitcoin-testnet-rootstock") + assert.Contains(t, eaRequest.SupplyChains, "729797994450396300", "Supply chains should contain telos-evm-testnet") + assert.Len(t, eaRequest.SupplyChains, 2, "Should have exactly 2 supply chains") + + assert.Len(t, eaRequest.SupplyChainBlocks, 2, "Should have exactly 2 supply chain blocks") + assert.GreaterOrEqual(t, eaRequest.SupplyChainBlocks[0], uint64(0), "Supply chain block should be at least 0") + assert.GreaterOrEqual(t, eaRequest.SupplyChainBlocks[1], uint64(0), "Supply chain block should be at least 0") + + // Return full EA response with mintable amounts + res.WriteHeader(http.StatusOK) + resp := fmt.Sprintf(`{"data": %s}`, string(jsonFullResponse)) + t.Logf("Responding from secure mint bridge %s on node %d with: %s", name, i, resp) + _, err = res.Write([]byte(resp)) + require.NoError(t, err) + })) + t.Cleanup(func() { + t.Logf("Closing secure mint bridge %s on node %d with url %s", name, i, bridge.URL) + bridge.Close() + }) + t.Logf("Created secure mint bridge %s on node %d with URL %s", name, i, bridge.URL) + + u, _ := url.Parse(bridge.URL) + bridgeName = fmt.Sprintf("bridge-%s-%d", name, i) + require.NoError(t, borm.CreateBridgeType(ctx, &bridges.BridgeType{ + Name: bridges.BridgeName(bridgeName), + URL: models.WebURL(*u), + })) + + return bridgeName +} diff --git a/core/services/ocr3/securemint/integrationtest/integration_test.go b/core/services/ocr3/securemint/integrationtest/integration_test.go new file mode 100644 index 00000000000..eee29ef1e13 --- /dev/null +++ b/core/services/ocr3/securemint/integrationtest/integration_test.go @@ -0,0 +1,409 @@ +package integrationtest + +import ( + "crypto/ed25519" + "encoding/hex" + "encoding/json" + "fmt" + "math/big" + "strings" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + gethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/onsi/gomega" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/atomic" + + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" + "github.com/smartcontractkit/chainlink-common/pkg/values" + datastreamsllo "github.com/smartcontractkit/chainlink-data-streams/llo" + "github.com/smartcontractkit/chainlink-evm/gethwrappers/data-feeds/generated/data_feeds_cache" + "github.com/smartcontractkit/chainlink-evm/gethwrappers/llo-feeds/generated/configurator" + "github.com/smartcontractkit/chainlink-evm/pkg/assets" + evmtestutils "github.com/smartcontractkit/chainlink-evm/pkg/testutils" + evmtypes "github.com/smartcontractkit/chainlink-evm/pkg/types" + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/csakey" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr3/securemint" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/llo" + "github.com/smartcontractkit/freeport" + "github.com/smartcontractkit/libocr/commontypes" + "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" + ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/por_mock_ocr3plugin/por" +) + +var ( + fNodes = uint8(1) + nNodes = 4 // number of nodes (not including bootstrap) +) + +// TestIntegration_SecureMint_happy_path tests runs a small DON which runs the secure mint plugin +// and verifies that it can successfully create reports. +// +// Inspired by: +// * core/internal/features/ocr2/features_ocr2_test.go +// * core/services/ocr2/plugins/ocr2keeper/integration_21_test.go +func TestIntegration_SecureMint_happy_path(t *testing.T) { + const salt = 100 + + clientCSAKeys := make([]csakey.KeyV2, nNodes) + clientPubKeys := make([]ed25519.PublicKey, nNodes) + for i := range nNodes { + k := big.NewInt(int64(salt + i)) + key := csakey.MustNewV2XXXTestingOnly(k) + clientCSAKeys[i] = key + clientPubKeys[i] = key.PublicKey + } + + steve, backend := setupBlockchain(t) + fromBlock, err := backend.Client().BlockNumber(testutils.Context(t)) + require.NoError(t, err) + t.Logf("Starting from block: %d", fromBlock) + + // Setup bootstrap + bootstrapCSAKey := csakey.MustNewV2XXXTestingOnly(big.NewInt(salt - 1)) + bootstrapNodePort := freeport.GetOne(t) + appBootstrap, bootstrapPeerID, _, bootstrapKb, _ := setupNode(t, bootstrapNodePort, "bootstrap_securemint", backend, bootstrapCSAKey, nil) + bootstrapNode := node{app: appBootstrap, keyBundle: bootstrapKb} + + p2pV2Bootstrappers := []commontypes.BootstrapperLocator{ + // Supply the bootstrap IP and port as a V2 peer address + {PeerID: bootstrapPeerID, Addrs: []string{fmt.Sprintf("127.0.0.1:%d", bootstrapNodePort)}}, + } + + // Setup oracle nodes + oracles, nodes := setupNodes(t, nNodes, backend, clientCSAKeys, func(c *chainlink.Config) { + // inform node about bootstrap node + c.P2P.V2.DefaultBootstrappers = &p2pV2Bootstrappers + }) + + allowedSenders := make([]common.Address, len(nodes)) + for i, node := range nodes { + keys, err := node.app.GetKeyStore().Eth().EnabledKeysForChain(testutils.Context(t), testutils.SimulatedChainID) + require.NoError(t, err) + allowedSenders[i] = keys[0].Address // assuming the first key is the transmitter + } + + _, configuratorAddress := setSecureMintOnchainConfigUsingOCR3Configurator(t, steve, backend, nodes, oracles) + + t.Logf("Creating bootstrap job with configurator address: %s", configuratorAddress.Hex()) + bootstrapJob := createSecureMintBootstrapJob(t, bootstrapNode, configuratorAddress, testutils.SimulatedChainID.String(), fmt.Sprintf("%d", fromBlock)) + t.Logf("Created bootstrap job: %s with id %d", bootstrapJob.Name.ValueOrZero(), bootstrapJob.ID) + + jobIDs := addSecureMintOCRJobs(t, nodes, configuratorAddress) + + t.Logf("jobIDs: %v", jobIDs) + validateJobsRunningSuccessfully(t, nodes, jobIDs) + +} + +func setupBlockchain(t *testing.T) ( + *bind.TransactOpts, + evmtypes.Backend, +) { + steve := evmtestutils.MustNewSimTransactor(t) // config contract deployer and owner + genesisData := gethtypes.GenesisAlloc{steve.From: {Balance: assets.Ether(1000).ToInt()}} + backend := cltest.NewSimulatedBackend(t, genesisData, ethconfig.Defaults.Miner.GasCeil) + backend.Commit() + backend.Commit() // ensure starting block number at least 1 + + return steve, backend +} + +func setupNodes(t *testing.T, nNodes int, backend evmtypes.Backend, clientCSAKeys []csakey.KeyV2, f func(*chainlink.Config)) (oracles []confighelper.OracleIdentityExtra, nodes []node) { + ports := freeport.GetN(t, nNodes) + for i := range nNodes { + app, peerID, transmitter, kb, observedLogs := setupNode(t, ports[i], fmt.Sprintf("oracle_securemint_%d", i), backend, clientCSAKeys[i], f) + + nodes = append(nodes, node{ + app: app, + clientPubKey: transmitter, + keyBundle: kb, + observedLogs: observedLogs, + }) + offchainPublicKey, err := hex.DecodeString(strings.TrimPrefix(kb.OnChainPublicKey(), "0x")) + require.NoError(t, err) + oracles = append(oracles, confighelper.OracleIdentityExtra{ + OracleIdentity: confighelper.OracleIdentity{ + OnchainPublicKey: offchainPublicKey, + TransmitAccount: ocr2types.Account(hex.EncodeToString(transmitter[:])), + OffchainPublicKey: kb.OffchainPublicKey(), + PeerID: peerID, + }, + ConfigEncryptionPublicKey: kb.ConfigEncryptionPublicKey(), + }) + } + return +} + +func validateJobsRunningSuccessfully(t *testing.T, nodes []node, jobIDs map[int]int32) { + + // 0. Add ourselves as a subscriber to the secure mint trigger capability + transmissions := atomic.NewInt32(0) + transmitter := securemint.XXX_SingletonTransmitter.Load().(capabilities.TriggerCapability) + triggerConfig, err := values.NewMap(map[string]any{ + "workflowID": "securemint-workflow", + "maxFrequencyMs": 1000, + }) + require.NoError(t, err) + registerCh, err := transmitter.RegisterTrigger(testutils.Context(t), capabilities.TriggerRegistrationRequest{ + TriggerID: "securemint-trigger", + Metadata: capabilities.RequestMetadata{ + WorkflowID: "securemint-workflow", + }, + Config: triggerConfig, + }) + require.NoError(t, err) + go func() { + for resp := range registerCh { + t.Logf("Received trigger response: %+v", resp) + outputs, err := resp.Event.Outputs.Unwrap() + require.NoError(t, err) + t.Logf("Received trigger response outputs: %+v", outputs) + transmissions.Inc() + } + }() + + // 1. Assert no job spec errors + for i, node := range nodes { + jobs, _, err := node.app.JobORM().FindJobs(testutils.Context(t), 0, 1000) + require.NoErrorf(t, err, "assert error finding jobs for node %d", i) + t.Logf("%d jobs found for node %d", len(jobs), i) + for _, j := range jobs { + t.Logf("job %d on node %d oracle spec: %#v", j.ID, i, j.OCR2OracleSpec) + t.Logf("job %d on node %d pipeline spec: %#v", j.ID, i, j.PipelineSpec) + } + // No spec errors + for _, j := range jobs { + ignore := 0 + for _, jse := range j.JobSpecErrors { + // Non-fatal timing related error, ignore for testing. + if strings.Contains(jse.Description, "leader's phase conflicts tGrace timeout") { + ignore++ + } else { + t.Errorf("assert error: job spec error on node %d: %v", i, jse) + } + } + require.Lenf(t, j.JobSpecErrors, ignore, "assert error: job spec errors on node %d", i) + } + } + + t.Logf("No job spec errors identified for any node") + + runs, err := nodes[0].app.PipelineORM().GetAllRuns(testutils.Context(t)) + require.NoError(t, err, "assert error getting all runs") + t.Logf("Found %d runs", len(runs)) + for _, run := range runs { + t.Logf("Run ID: %d, Job ID: %d, Status: %s", run.ID, run.JobID, run.Status()) + } + + // 2. Assert that all the Secure Mint jobs get a run with valid values eventually + var wg sync.WaitGroup + for i, node := range nodes { + wg.Add(1) + go func() { + defer wg.Done() + + pr := cltest.WaitForPipelineComplete(t, i, jobIDs[i], 1, 0, node.app.JobORM(), 30*time.Second, 1*time.Second) + outputs, err := pr[0].Outputs.MarshalJSON() + if !assert.NoError(t, err) { + t.Logf("assert error marshalling outputs for job %d: %v", jobIDs[i], err) + return + } + t.Logf("Pipeline itself is %+v", pr[0]) + t.Logf("Pipeline run outputs are %s", string(outputs)) + }() + } + t.Logf("waiting for pipeline runs to complete") + wg.Wait() + t.Logf("All pipeline runs completed successfully") + + // 3. Check that transmissions work + expectedNumTransmissions := int32(4) + gomega.NewWithT(t).Eventually(func() bool { + numTransmissions := transmissions.Load() + t.Logf("Number of (stub) report transmissions: %d", numTransmissions) + return numTransmissions >= expectedNumTransmissions + }, 30*time.Second, 1*time.Second).Should( + gomega.BeTrue(), + fmt.Sprintf("expected at least %d reports transmitted, but got less", expectedNumTransmissions), + ) +} + +func setSecureMintOnchainConfigUsingOCR3Configurator(t *testing.T, steve *bind.TransactOpts, backend evmtypes.Backend, nodes []node, oracles []confighelper.OracleIdentityExtra) (*configurator.Configurator, common.Address) { + + // 1. Deploy configurator contract + configuratorAddress, _, configurator, err := configurator.DeployConfigurator(steve, backend.Client()) + require.NoError(t, err) + backend.Commit() + + // Ensure we have finality depth worth of blocks to start. + for range 5 { + backend.Commit() + } + t.Logf("Deployed OCR3Configurator contract at: %s", configuratorAddress.Hex()) + + // 2. Get the oracle config + smPluginConfig := por.PorOffchainConfig{MaxChains: 5} + smPluginConfigBytes, err := smPluginConfig.Serialize() + require.NoError(t, err) + + // using the data streams llo codec for the validation about version and predecessor config digest in the Configurator contract: https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/llo-feeds/v0.5.0/configuration/Configurator.sol#L116-L124 + onchainConfig, err := (&datastreamsllo.EVMOnchainConfigCodec{}).Encode(datastreamsllo.OnchainConfig{ + Version: 1, + PredecessorConfigDigest: nil, + }) + require.NoError(t, err) + + signers, _, f, outOnchainConfig, offchainConfigVersion, offchainConfig, err := ocr3confighelper.ContractSetConfigArgsForTests( + 2*time.Second, // deltaProgress, + 20*time.Second, // deltaResend, + 400*time.Millisecond, // deltaInitial, + 500*time.Millisecond, // deltaRound, + 250*time.Millisecond, // deltaGrace, + 300*time.Millisecond, // deltaCertifiedCommitRequest, + 1*time.Minute, // deltaStage, + 100, // rMax, + []int{len(oracles)}, // s, + oracles, // oracles, + smPluginConfigBytes, // reportingPluginConfig, + nil, // maxDurationInitialization, + 250*time.Millisecond, // maxDurationQuery, + 1*time.Second, // maxDurationObservation, + 1*time.Second, // maxDurationShouldAcceptAttestedReport, + 1*time.Second, // maxDurationShouldTransmitAcceptedReport, + int(fNodes), // f, + onchainConfig, // onchainConfig (binary blob containing configuration passed through to the ReportingPlugin and also available to the contract. Unlike ReportingPluginConfig which is only available offchain.) + ) + require.NoError(t, err) + + // 3. Set config on the contract + signerKeys := make([][]byte, len(signers)) + for i, signer := range signers { + signerKeys[i] = signer + } + + // use csa keys as transmitters, similar to LLO + transmitters := make([][32]byte, nNodes) + for i := range nNodes { + transmitters[i] = nodes[i].clientPubKey + } + t.Logf("transmitters: %v", transmitters) + + configID := [32]byte{} + copy(configID[:], common.FromHex("0x0000000000000000000000000000000000000000000000000000000000000001")) + + _, err = configurator.SetProductionConfig(steve, configID, signerKeys, transmitters, f, outOnchainConfig, offchainConfigVersion, offchainConfig) + if err != nil { + t.Logf("Error: %s", err) + errString, err := rPCErrorFromError(err) + require.NoError(t, err) + t.Fatalf("Failed to configure contract: %s %s", errString, err) + } + + // make sure config is finalized + for range 5 { + backend.Commit() + } + + var topic common.Hash + topic = llo.ProductionConfigSet + + logs, err := backend.Client().FilterLogs(testutils.Context(t), ethereum.FilterQuery{Addresses: []common.Address{configuratorAddress}, Topics: [][]common.Hash{[]common.Hash{topic, configID}}}) + require.NoError(t, err) + require.GreaterOrEqual(t, len(logs), 1) + cfg, err := llo.DecodeProductionConfigSetLog(logs[len(logs)-1].Data) + require.NoError(t, err) + + t.Logf("Configurator config digest: 0x%x", cfg.ConfigDigest) + + return configurator, configuratorAddress +} + +func rPCErrorFromError(txError error) (string, error) { + errBytes, err := json.Marshal(txError) + if err != nil { + return "", err + } + var callErr struct { + Code int + Data string `json:"data"` + Message string `json:"message"` + } + err = json.Unmarshal(errBytes, &callErr) + if err != nil { + return "", err + } + // If the error data is blank + if len(callErr.Data) == 0 { + return callErr.Data, nil + } + // Some nodes prepend "Reverted " and we also remove the 0x + trimmed := strings.TrimPrefix(callErr.Data, "Reverted ")[2:] + data, err := hex.DecodeString(trimmed) + if err != nil { + return "", err + } + revert, err := abi.UnpackRevert(data) + // If we can't decode the revert reason, return the raw data + if err != nil { + return callErr.Data, nil + } + return revert, nil +} + +// Not used yet, in scope for chain writing +func setupDataFeedsCacheContract(t *testing.T, steve *bind.TransactOpts, backend evmtypes.Backend, allowedSenders []common.Address, workflowOwner, workflowName string) ( + common.Address, *data_feeds_cache.DataFeedsCache) { + + addr, _, dataFeedsCache, err := data_feeds_cache.DeployDataFeedsCache(steve, backend.Client()) + require.NoError(t, err) + backend.Commit() + + var nameBytes [10]byte + copy(nameBytes[:], workflowName) + + ownerAddr := common.HexToAddress(workflowOwner) + + _, err = dataFeedsCache.SetFeedAdmin(steve, ownerAddr, true) + require.NoError(t, err) + + backend.Commit() + + metadatas := make([]data_feeds_cache.DataFeedsCacheWorkflowMetadata, len(allowedSenders)) + for i, sender := range allowedSenders { + metadatas[i] = + data_feeds_cache.DataFeedsCacheWorkflowMetadata{ + AllowedSender: sender, + AllowedWorkflowOwner: ownerAddr, + AllowedWorkflowName: nameBytes, + } + } + + feedIDBytes := [16]byte{} + copy(feedIDBytes[:], common.FromHex("0xA1B2C3D4E5F600010203040506070809")) + + _, err = dataFeedsCache.SetDecimalFeedConfigs(steve, [][16]byte{feedIDBytes}, []string{"securemint"}, metadatas) + if err != nil { + errString, err := rPCErrorFromError(err) + require.NoError(t, err) + + t.Fatalf("Failed to configure contract: %s", errString) + } + + backend.Commit() + + return addr, dataFeedsCache +} diff --git a/core/services/ocr3/securemint/keyringadapter/README.md b/core/services/ocr3/securemint/keyringadapter/README.md new file mode 100644 index 00000000000..9406fc70954 --- /dev/null +++ b/core/services/ocr3/securemint/keyringadapter/README.md @@ -0,0 +1,111 @@ +# PoR OCR3 OnchainKeyring Adapter + +This file contains an adapter implementation that enables the use of existing OCR2 OnchainKeyring implementations with the OCR3 PoR (Proof of Reserve) plugin. + +## Overview + +The `OnchainKeyringAdapter` wraps an existing `types.OnchainKeyring` (OCR2) and adapts it to implement `ocr3types.OnchainKeyring[ChainSelector]` (OCR3) specifically for the PoR system. + +## Key Features + +- **Interface Adaptation**: Converts between OCR2 and OCR3 keyring interfaces +- **Parameter Conversion**: Automatically converts OCR3 parameters (config digest, sequence number, report with info) to OCR2 ReportContext format +- **Backward Compatibility**: Allows reuse of existing OCR2 keyring implementations +- **Type Safety**: Strongly typed for PoR ChainSelector + +## Usage Example + +```go +package main + +import ( + "github.com/smartcontractkit/por_mock_ocr3plugin/por" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" +) + +func main() { + // Create an OCR2 keyring (example using EVM keyring) + ocr2Bundle, err := ocr2key.New(chaintype.EVM) + if err != nil { + panic(err) + } + + // Wrap the OCR2 keyring with the PoR adapter + porKeyring := por.NewOnchainKeyringAdapter(ocr2Bundle) + + // Now you can use porKeyring as an ocr3types.OnchainKeyring[por.ChainSelector] + // for the PoR OCR3 plugin + + // Example usage in OCR3 context: + configDigest := types.ConfigDigest([32]byte{1, 2, 3}) + seqNr := uint64(42) + reportWithInfo := ocr3types.ReportWithInfo[por.ChainSelector]{ + Report: []byte("example-report"), + Info: por.ChainSelector(1234), + } + + signature, err := porKeyring.Sign(configDigest, seqNr, reportWithInfo) + if err != nil { + panic(err) + } + + isValid := porKeyring.Verify( + porKeyring.PublicKey(), + configDigest, + seqNr, + reportWithInfo, + signature, + ) + + println("Signature valid:", isValid) +} +``` + +## Implementation Details + +### Interface Mapping + +The adapter maps OCR3 interface methods to OCR2 interface methods as follows: + +| OCR3 Method | OCR2 Method | Conversion | +|-------------|-------------|------------| +| `PublicKey()` | `PublicKey()` | Direct passthrough | +| `Sign(ConfigDigest, uint64, ReportWithInfo[ChainSelector])` | `Sign(ReportContext, Report)` | Converts parameters to ReportContext | +| `Verify(OnchainPublicKey, ConfigDigest, uint64, ReportWithInfo[ChainSelector], []byte)` | `Verify(OnchainPublicKey, ReportContext, Report, []byte)` | Converts parameters to ReportContext | +| `MaxSignatureLength()` | `MaxSignatureLength()` | Direct passthrough | + +### Parameter Conversion + +OCR3 parameters are converted to OCR2 ReportContext as follows: + +```go +reportContext := types.ReportContext{ + ReportTimestamp: types.ReportTimestamp{ + ConfigDigest: configDigest, // From OCR3 parameter + Epoch: uint32(seqNr), // OCR3 sequence number as epoch + Round: 0, // Fixed to 0 (OCR3 doesn't use rounds) + }, + ExtraHash: [32]byte{}, // Empty hash +} +``` + +## Benefits + +1. **Reusability**: Existing OCR2 keyrings can be used with OCR3 PoR without modification +2. **Simplicity**: Single adapter handles all necessary conversions +3. **Type Safety**: Generic implementation ensures compile-time type checking +4. **Testing**: Comprehensive test suite ensures correct parameter conversion + +## Related Files + +- `onchain_keyring_adapter.go` - Main adapter implementation +- `onchain_keyring_adapter_test.go` - Comprehensive test suite +- `types.go` - PoR-specific type definitions including ChainSelector +- `external_adapter_interface.go` - Original external adapter interface + +## See Also + +- Reference implementations in `/core/services/ocrcommon/adapters.go` +- OCR2 keyring implementations in `/core/services/keystore/keys/ocr2key/` +- OCR3 types in `libocr/offchainreporting2plus/ocr3types/` diff --git a/core/services/ocr3/securemint/keyringadapter/example_usage.go b/core/services/ocr3/securemint/keyringadapter/example_usage.go new file mode 100644 index 00000000000..528ca938e63 --- /dev/null +++ b/core/services/ocr3/securemint/keyringadapter/example_usage.go @@ -0,0 +1,92 @@ +package keyringadapter + +import ( + "fmt" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/por_mock_ocr3plugin/por" +) + +// ExampleUsage demonstrates how to use the OnchainKeyringAdapter +// to wrap an existing OCR2 keyring for use with OCR3 PoR plugin. +func ExampleUsage() { + // This is a simplified example showing the adapter usage pattern. + // In real usage, you would obtain the OCR2 keyring from your keystore. + + // Step 1: Get an existing OCR2 OnchainKeyring + // This could be from your keystore, e.g.: + // ocr2Bundle, err := ocr2key.New(chaintype.EVM) + // if err != nil { ... } + // ocr2Keyring := ocr2Bundle + + // For this example, we'll use a mock keyring + mockOCR2Keyring := &mockExampleKeyring{ + publicKey: types.OnchainPublicKey("example-public-key"), + maxSigLen: 65, // typical for ECDSA signatures + } + + // Step 2: Wrap the OCR2 keyring with the PoR adapter + porKeyring := NewSecureMintOCR3OnchainKeyringAdapter(mockOCR2Keyring) + + // Step 3: Use the adapter as an OCR3 OnchainKeyring for PoR + configDigest := types.ConfigDigest([32]byte{1, 2, 3, 4, 5}) // example digest + seqNr := uint64(42) + chainSelector := por.ChainSelector(1234) // example chain selector + + reportWithInfo := ocr3types.ReportWithInfo[por.ChainSelector]{ + Report: []byte("example-por-report"), + Info: chainSelector, + } + + // Sign a report + signature, err := porKeyring.Sign(configDigest, seqNr, reportWithInfo) + if err != nil { + fmt.Printf("Error signing report: %v\n", err) + return + } + + // Verify the signature + isValid := porKeyring.Verify( + porKeyring.PublicKey(), + configDigest, + seqNr, + reportWithInfo, + signature, + ) + + fmt.Printf("Report signed successfully\n") + fmt.Printf("Signature length: %d bytes\n", len(signature)) + fmt.Printf("Max signature length: %d bytes\n", porKeyring.MaxSignatureLength()) + fmt.Printf("Signature valid: %t\n", isValid) + fmt.Printf("Public key: %x\n", porKeyring.PublicKey()) +} + +// mockExampleKeyring is a simple mock implementation for demonstration purposes +type mockExampleKeyring struct { + publicKey types.OnchainPublicKey + maxSigLen int +} + +func (m *mockExampleKeyring) PublicKey() types.OnchainPublicKey { + return m.publicKey +} + +func (m *mockExampleKeyring) Sign(ctx types.ReportContext, report types.Report) ([]byte, error) { + // In a real implementation, this would use cryptographic signing + return []byte("example-signature"), nil +} + +func (m *mockExampleKeyring) Verify( + pubKey types.OnchainPublicKey, + ctx types.ReportContext, + report types.Report, + signature []byte, +) bool { + // In a real implementation, this would verify the cryptographic signature + return true +} + +func (m *mockExampleKeyring) MaxSignatureLength() int { + return m.maxSigLen +} diff --git a/core/services/ocr3/securemint/keyringadapter/onchain_keyring_adapter.go b/core/services/ocr3/securemint/keyringadapter/onchain_keyring_adapter.go new file mode 100644 index 00000000000..071ee025c3d --- /dev/null +++ b/core/services/ocr3/securemint/keyringadapter/onchain_keyring_adapter.go @@ -0,0 +1,81 @@ +package keyringadapter + +import ( + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/por_mock_ocr3plugin/por" +) + +// SecureMintOCR3OnchainKeyringAdapter adapts an OCR2 OnchainKeyring to implement ocr3types.OnchainKeyring[ChainSelector] +// This adapter enables the use of existing OCR2 keyrings with the OCR3 PoR plugin. +// Copied and adapted from core/services/ocrcommon/adapters.go +// Ideally we use ocrcommon.OCR3OnchainKeyringMultiChainAdapter instead? Problem is that that one is not typed, it assumes []byte as the Report type, while we use por.ChainSelector. +type SecureMintOCR3OnchainKeyringAdapter struct { + ocr2Keyring types.OnchainKeyring +} + +// Ensure OnchainKeyringAdapter implements the OCR3 OnchainKeyring interface for PoR ChainSelector +var _ ocr3types.OnchainKeyring[por.ChainSelector] = &SecureMintOCR3OnchainKeyringAdapter{} + +// NewSecureMintOCR3OnchainKeyringAdapter creates a new adapter that wraps an OCR2 OnchainKeyring +// to implement the OCR3 OnchainKeyring interface for PoR ChainSelector. +func NewSecureMintOCR3OnchainKeyringAdapter(keyring types.OnchainKeyring) *SecureMintOCR3OnchainKeyringAdapter { + return &SecureMintOCR3OnchainKeyringAdapter{ + ocr2Keyring: keyring, + } +} + +// PublicKey returns the public key of the underlying OCR2 keyring. +func (adapter *SecureMintOCR3OnchainKeyringAdapter) PublicKey() types.OnchainPublicKey { + return adapter.ocr2Keyring.PublicKey() +} + +// Sign creates a signature over the given report using the OCR2 keyring. +// It converts the OCR3 parameters (config digest, sequence number, and report with info) +// into the OCR2 ReportContext format expected by the underlying keyring. +func (adapter *SecureMintOCR3OnchainKeyringAdapter) Sign( + configDigest types.ConfigDigest, + seqNr uint64, + reportWithInfo ocr3types.ReportWithInfo[por.ChainSelector], +) (signature []byte, err error) { + // Convert OCR3 parameters to OCR2 ReportContext + // Note: seqNr is converted to uint32 for Epoch field, which may truncate for very large values + reportContext := types.ReportContext{ + ReportTimestamp: types.ReportTimestamp{ + ConfigDigest: configDigest, + Epoch: uint32(seqNr), //nolint:gosec // Intentional conversion, matches OCR protocol + Round: 0, // OCR3 doesn't use rounds in the same way as OCR2 + }, + ExtraHash: [32]byte{}, // Initialize with empty hash + } + + return adapter.ocr2Keyring.Sign(reportContext, reportWithInfo.Report) +} + +// Verify verifies a signature over the given report using the OCR2 keyring. +// It converts the OCR3 parameters into the OCR2 ReportContext format for verification. +func (adapter *SecureMintOCR3OnchainKeyringAdapter) Verify( + publicKey types.OnchainPublicKey, + configDigest types.ConfigDigest, + seqNr uint64, + reportWithInfo ocr3types.ReportWithInfo[por.ChainSelector], + signature []byte, +) bool { + // Convert OCR3 parameters to OCR2 ReportContext + // Note: seqNr is converted to uint32 for Epoch field, which may truncate for very large values + reportContext := types.ReportContext{ + ReportTimestamp: types.ReportTimestamp{ + ConfigDigest: configDigest, + Epoch: uint32(seqNr), //nolint:gosec // Intentional conversion, matches OCR protocol + Round: 0, // OCR3 doesn't use rounds in the same way as OCR2 + }, + ExtraHash: [32]byte{}, // Initialize with empty hash + } + + return adapter.ocr2Keyring.Verify(publicKey, reportContext, reportWithInfo.Report, signature) +} + +// MaxSignatureLength returns the maximum signature length from the underlying OCR2 keyring. +func (adapter *SecureMintOCR3OnchainKeyringAdapter) MaxSignatureLength() int { + return adapter.ocr2Keyring.MaxSignatureLength() +} diff --git a/core/services/ocr3/securemint/keyringadapter/onchain_keyring_adapter_test.go b/core/services/ocr3/securemint/keyringadapter/onchain_keyring_adapter_test.go new file mode 100644 index 00000000000..b7d65088382 --- /dev/null +++ b/core/services/ocr3/securemint/keyringadapter/onchain_keyring_adapter_test.go @@ -0,0 +1,178 @@ +package keyringadapter + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/por_mock_ocr3plugin/por" +) + +// mockOCR2OnchainKeyring is a mock implementation of types.OnchainKeyring for testing +type mockOCR2OnchainKeyring struct { + publicKey types.OnchainPublicKey + maxSignatureLength int + signFunc func(types.ReportContext, types.Report) ([]byte, error) + verifyFunc func(types.OnchainPublicKey, types.ReportContext, types.Report, []byte) bool +} + +func (m *mockOCR2OnchainKeyring) PublicKey() types.OnchainPublicKey { + return m.publicKey +} + +func (m *mockOCR2OnchainKeyring) Sign(ctx types.ReportContext, report types.Report) ([]byte, error) { + if m.signFunc != nil { + return m.signFunc(ctx, report) + } + return []byte("mock-signature"), nil +} + +func (m *mockOCR2OnchainKeyring) Verify( + pubKey types.OnchainPublicKey, + ctx types.ReportContext, + report types.Report, + signature []byte, +) bool { + if m.verifyFunc != nil { + return m.verifyFunc(pubKey, ctx, report, signature) + } + return true +} + +func (m *mockOCR2OnchainKeyring) MaxSignatureLength() int { + return m.maxSignatureLength +} + +func TestPorOnchainKeyringAdapter(t *testing.T) { + // Setup test data + testPublicKey := types.OnchainPublicKey("test-public-key") + testConfigDigest := types.ConfigDigest([32]byte{1, 2, 3, 4, 5}) + testSeqNr := uint64(42) + testReport := types.Report([]byte("test-report")) + testChainSelector := por.ChainSelector(1234) + testSignature := []byte("test-signature") + testMaxSigLen := 65 + + reportWithInfo := ocr3types.ReportWithInfo[por.ChainSelector]{ + Report: testReport, + Info: testChainSelector, + } + + t.Run("adapter implements the correct interface", func(t *testing.T) { + mockKeyring := &mockOCR2OnchainKeyring{ + publicKey: testPublicKey, + maxSignatureLength: testMaxSigLen, + } + + adapter := NewSecureMintOCR3OnchainKeyringAdapter(mockKeyring) + + // Verify that the adapter implements the OCR3 OnchainKeyring interface + var _ ocr3types.OnchainKeyring[por.ChainSelector] = adapter + }) + + t.Run("PublicKey returns the underlying keyring's public key", func(t *testing.T) { + mockKeyring := &mockOCR2OnchainKeyring{ + publicKey: testPublicKey, + maxSignatureLength: testMaxSigLen, + } + + adapter := NewSecureMintOCR3OnchainKeyringAdapter(mockKeyring) + assert.Equal(t, testPublicKey, adapter.PublicKey()) + }) + + t.Run("MaxSignatureLength returns the underlying keyring's max signature length", func(t *testing.T) { + mockKeyring := &mockOCR2OnchainKeyring{ + publicKey: testPublicKey, + maxSignatureLength: testMaxSigLen, + } + + adapter := NewSecureMintOCR3OnchainKeyringAdapter(mockKeyring) + assert.Equal(t, testMaxSigLen, adapter.MaxSignatureLength()) + }) + + t.Run("Sign correctly converts OCR3 parameters to OCR2 format", func(t *testing.T) { + var capturedReportContext types.ReportContext + var capturedReport types.Report + + mockKeyring := &mockOCR2OnchainKeyring{ + publicKey: testPublicKey, + maxSignatureLength: testMaxSigLen, + signFunc: func(ctx types.ReportContext, report types.Report) ([]byte, error) { + capturedReportContext = ctx + capturedReport = report + return testSignature, nil + }, + } + + adapter := NewSecureMintOCR3OnchainKeyringAdapter(mockKeyring) + signature, err := adapter.Sign(testConfigDigest, testSeqNr, reportWithInfo) + + require.NoError(t, err) + assert.Equal(t, testSignature, signature) + + // Verify the conversion from OCR3 to OCR2 format + assert.Equal(t, testConfigDigest, capturedReportContext.ReportTimestamp.ConfigDigest) + assert.Equal(t, uint32(testSeqNr), capturedReportContext.ReportTimestamp.Epoch) + assert.Equal(t, uint8(0), capturedReportContext.ReportTimestamp.Round) + assert.Equal(t, [32]byte{}, capturedReportContext.ExtraHash) + assert.Equal(t, testReport, capturedReport) + }) + + t.Run("Verify correctly converts OCR3 parameters to OCR2 format", func(t *testing.T) { + var capturedPublicKey types.OnchainPublicKey + var capturedReportContext types.ReportContext + var capturedReport types.Report + var capturedSignature []byte + + mockKeyring := &mockOCR2OnchainKeyring{ + publicKey: testPublicKey, + maxSignatureLength: testMaxSigLen, + verifyFunc: func( + pubKey types.OnchainPublicKey, + ctx types.ReportContext, + report types.Report, + signature []byte, + ) bool { + capturedPublicKey = pubKey + capturedReportContext = ctx + capturedReport = report + capturedSignature = signature + return true + }, + } + + adapter := NewSecureMintOCR3OnchainKeyringAdapter(mockKeyring) + result := adapter.Verify(testPublicKey, testConfigDigest, testSeqNr, reportWithInfo, testSignature) + + assert.True(t, result) + + // Verify the conversion from OCR3 to OCR2 format + assert.Equal(t, testPublicKey, capturedPublicKey) + assert.Equal(t, testConfigDigest, capturedReportContext.ReportTimestamp.ConfigDigest) + assert.Equal(t, uint32(testSeqNr), capturedReportContext.ReportTimestamp.Epoch) + assert.Equal(t, uint8(0), capturedReportContext.ReportTimestamp.Round) + assert.Equal(t, [32]byte{}, capturedReportContext.ExtraHash) + assert.Equal(t, testReport, capturedReport) + assert.Equal(t, testSignature, capturedSignature) + }) + + t.Run("Sign and Verify work together", func(t *testing.T) { + mockKeyring := &mockOCR2OnchainKeyring{ + publicKey: testPublicKey, + maxSignatureLength: testMaxSigLen, + } + + adapter := NewSecureMintOCR3OnchainKeyringAdapter(mockKeyring) + + // Sign a report + signature, err := adapter.Sign(testConfigDigest, testSeqNr, reportWithInfo) + require.NoError(t, err) + + // Verify the signature + isValid := adapter.Verify(testPublicKey, testConfigDigest, testSeqNr, reportWithInfo, signature) + assert.True(t, isValid) + }) +} diff --git a/core/services/ocr3/securemint/services.go b/core/services/ocr3/securemint/services.go new file mode 100644 index 00000000000..138ddb257a6 --- /dev/null +++ b/core/services/ocr3/securemint/services.go @@ -0,0 +1,194 @@ +package securemint + +import ( + "context" + "errors" + "fmt" + "sync/atomic" + + "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink-common/pkg/types" + coretypes "github.com/smartcontractkit/chainlink-common/pkg/types/core" + "github.com/smartcontractkit/chainlink/v2/core/config/env" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr3/promwrapper" + sm_plugin_config "github.com/smartcontractkit/chainlink/v2/core/services/ocr3/securemint/config" + sm_ea "github.com/smartcontractkit/chainlink/v2/core/services/ocr3/securemint/ea" + "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" + "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" + evm_types "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" + "github.com/smartcontractkit/chainlink/v2/plugins" + libocr "github.com/smartcontractkit/libocr/offchainreporting2plus" + "github.com/smartcontractkit/por_mock_ocr3plugin/por" + sm_plugin "github.com/smartcontractkit/por_mock_ocr3plugin/por" +) + +var _ JobConfig = (*smJobConfig)(nil) + +type JobConfig interface { + JobPipelineMaxSuccessfulRuns() uint64 + JobPipelineResultWriteQueueDepth() uint64 + plugins.RegistrarConfig +} + +// concrete implementation of JobConfig +type smJobConfig struct { + jobPipelineMaxSuccessfulRuns uint64 + jobPipelineResultWriteQueueDepth uint64 + plugins.RegistrarConfig +} + +func NewJobConfig(jobPipelineMaxSuccessfulRuns uint64, jobPipelineResultWriteQueueDepth uint64, pluginProcessCfg plugins.RegistrarConfig) JobConfig { + return &smJobConfig{ + jobPipelineMaxSuccessfulRuns: jobPipelineMaxSuccessfulRuns, + jobPipelineResultWriteQueueDepth: jobPipelineResultWriteQueueDepth, + RegistrarConfig: pluginProcessCfg, + } +} + +func (m *smJobConfig) JobPipelineMaxSuccessfulRuns() uint64 { + return m.jobPipelineMaxSuccessfulRuns +} + +func (m *smJobConfig) JobPipelineResultWriteQueueDepth() uint64 { + return m.jobPipelineResultWriteQueueDepth +} + +// TODO(gg): this is a hack to allow the integration tests to access the transmitter to assert on the number of transmissions +var XXX_SingletonTransmitter atomic.Value // capabilities.TriggerCapability + +// NewSecureMintServices creates all securemint plugin specific services. +func NewSecureMintServices(ctx context.Context, + jb job.Job, + isNewlyCreatedJob bool, + relayer loop.Relayer, + pipelineRunner pipeline.Runner, + lggr logger.Logger, + argsNoPlugin libocr.OCR3OracleArgs[por.ChainSelector], + cfg JobConfig, + capabilitiesRegistry coretypes.CapabilitiesRegistry, +) (srvs []job.ServiceCtx, err error) { + // Parse and validate the secure mint plugin configuration + secureMintPluginConfig, err := sm_plugin_config.Parse(jb.OCR2OracleSpec.PluginConfig.Bytes()) + if err != nil { + return nil, fmt.Errorf("failed to parse secure mint plugin config: %w", err) + } + + if err = secureMintPluginConfig.Validate(); err != nil { + return nil, fmt.Errorf("invalid secure mint plugin config: %#v, %w", secureMintPluginConfig, err) + } + + spec := jb.OCR2OracleSpec + + // Get relay config to extract don ID + relayConfig, err := evm_types.NewRelayOpts(types.RelayArgs{ + ExternalJobID: jb.ExternalJobID, + JobID: jb.ID, + ContractID: spec.ContractID, + New: isNewlyCreatedJob, + RelayConfig: spec.RelayConfig.Bytes(), + ProviderType: string(spec.PluginType), + }).RelayConfig() + if err != nil { + return nil, fmt.Errorf("failed to get relay config: %w", err) + } + + // Create result run saver for pipeline execution + runSaver := ocrcommon.NewResultRunSaver( + pipelineRunner, + lggr, + cfg.JobPipelineMaxSuccessfulRuns(), + cfg.JobPipelineResultWriteQueueDepth(), + ) + + configProvider, err := relayer.NewConfigProvider(ctx, types.RelayArgs{ + ExternalJobID: jb.ExternalJobID, + JobID: jb.ID, + OracleSpecID: *jb.OCR2OracleSpecID, + ContractID: spec.ContractID, + New: isNewlyCreatedJob, + RelayConfig: spec.RelayConfig.Bytes(), + ProviderType: string(spec.PluginType), + }) + if err != nil { + return nil, fmt.Errorf("failed to create config provider: %w", err) + } + srvs = append(srvs, configProvider) + + argsNoPlugin.ContractConfigTracker = configProvider.ContractConfigTracker() + argsNoPlugin.OffchainConfigDigester = configProvider.OffchainConfigDigester() + + // Create the new secure mint transmitter with trigger capabilities + transmitterConfig := TransmitterConfig{ + Logger: lggr, + CapabilitiesRegistry: capabilitiesRegistry, + DonID: relayConfig.LLODONID, + TriggerCapabilityName: secureMintPluginConfig.TriggerCapabilityName, + TriggerCapabilityVersion: secureMintPluginConfig.TriggerCapabilityVersion, + TriggerTickerMinResolutionMs: secureMintPluginConfig.TriggerTickerMinResolutionMs, + TriggerSendChannelBufferSize: secureMintPluginConfig.TriggerSendChannelBufferSize, + } + + transmitter, err := transmitterConfig.NewTransmitter(spec.TransmitterID.String) + if err != nil { + return nil, fmt.Errorf("failed to create secure mint transmitter: %w", err) + } + argsNoPlugin.ContractTransmitter = transmitter + XXX_SingletonTransmitter.Store(transmitter) + srvs = append(srvs, transmitter) + + abort := func() { + if cerr := services.MultiCloser(srvs).Close(); cerr != nil { + lggr.Errorw("Error closing services", "err", cerr) + } + } + + // Create the reporting plugin factory + if cmdName := env.SecureMintPlugin.Cmd.Get(); cmdName != "" { + abort() + return nil, errors.New("LOOPP for securemint plugin not implemented yet") + } + + ea, err := sm_ea.NewExternalAdapter(secureMintPluginConfig, pipelineRunner, jb, *jb.PipelineSpec, runSaver, lggr) + if err != nil { + return nil, fmt.Errorf("failed to create secure mint external adapter: %w", err) + } + + // Create the original SecureMint plugin factory + smPluginFactory := &sm_plugin.PorReportingPluginFactory{ + Logger: argsNoPlugin.Logger, + ExternalAdapter: ea, + ContractReader: newStubContractReader(argsNoPlugin.ContractConfigTracker), // since we don't write to chain yet, we mock the contract reader which returns the most recent config digest from the config contract + ReportMarshaler: sm_plugin.NewMockReportMarshaler(), + } + + // Get relay ID for chain identification + rid, err := spec.RelayID() + if err != nil { + return nil, fmt.Errorf("failed to get relay ID: %w", err) + } + + // Wrap the factory with prometheus metrics monitoring + argsNoPlugin.ReportingPluginFactory = promwrapper.NewReportingPluginFactory( + smPluginFactory, + lggr, + "evm", + rid.ChainID, + "secure-mint", + ) + + // Create the oracle + var oracle libocr.Oracle + oracle, err = libocr.NewOracle(argsNoPlugin) + if err != nil { + abort() + return nil, fmt.Errorf("failed to create oracle: %w", err) + } + + // Assemble all services + srvs = append(srvs, runSaver, job.NewServiceAdapter(oracle)) + + return srvs, nil +} diff --git a/core/services/ocr3/securemint/stub_contractreader.go b/core/services/ocr3/securemint/stub_contractreader.go new file mode 100644 index 00000000000..f358aea41b5 --- /dev/null +++ b/core/services/ocr3/securemint/stub_contractreader.go @@ -0,0 +1,38 @@ +package securemint + +import ( + "context" + "fmt" + "time" + + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/por_mock_ocr3plugin/por" + sm_plugin "github.com/smartcontractkit/por_mock_ocr3plugin/por" +) + +var _ sm_plugin.ContractReader = &stubContractReader{} + +// stubContractReader is a mock implementation of the ContractReader interface. +// It retrieves the latest config digest from the config contract and then uses that to return mocked report details. +type stubContractReader struct { + contractConfigTracker ocrtypes.ContractConfigTracker +} + +func newStubContractReader(contractConfigTracker ocrtypes.ContractConfigTracker) *stubContractReader { + return &stubContractReader{ + contractConfigTracker: contractConfigTracker, + } +} + +func (m *stubContractReader) GetLatestTransmittedReportDetails(ctx context.Context, _ por.ChainSelector) (sm_plugin.TransmittedReportDetails, error) { + _, configDigest, err := m.contractConfigTracker.LatestConfigDetails(ctx) + if err != nil { + return sm_plugin.TransmittedReportDetails{}, fmt.Errorf("failed to get config digest: %w", err) + } + + return sm_plugin.TransmittedReportDetails{ + ConfigDigest: [32]byte(configDigest), + SeqNr: 1, // Mock sequence number + LatestTimestamp: time.Now(), // Mock timestamp + }, nil +} diff --git a/core/services/ocr3/securemint/transmitter.go b/core/services/ocr3/securemint/transmitter.go new file mode 100644 index 00000000000..1535e47c487 --- /dev/null +++ b/core/services/ocr3/securemint/transmitter.go @@ -0,0 +1,239 @@ +package securemint + +import ( + "context" + "fmt" + "sync" + + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/services" + coretypes "github.com/smartcontractkit/chainlink-common/pkg/types/core" + "github.com/smartcontractkit/chainlink-common/pkg/values" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr3/securemint/config" + "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/por_mock_ocr3plugin/por" +) + +const ( + defaultCapabilityName = "securemint-trigger" + defaultCapabilityVersion = "1.0.0" + defaultTickerResolutionMs = 1000 + defaultSendChannelBufferSize = 1000 +) + +type Transmitter interface { + ocr3types.ContractTransmitter[por.ChainSelector] + services.Service +} + +type TransmitterConfig struct { + Logger logger.Logger `json:"-"` + CapabilitiesRegistry coretypes.CapabilitiesRegistry `json:"-"` + DonID uint32 `json:"-"` + + TriggerCapabilityName string `json:"triggerCapabilityName"` + TriggerCapabilityVersion string `json:"triggerCapabilityVersion"` + TriggerTickerMinResolutionMs int `json:"triggerTickerMinResolutionMs"` + TriggerSendChannelBufferSize int `json:"triggerSendChannelBufferSize"` +} + +var _ Transmitter = &transmitter{} +var _ capabilities.TriggerCapability = &transmitter{} + +type transmitter struct { + services.Service + eng *services.Engine + capabilities.CapabilityInfo + + config TransmitterConfig + fromAccount ocr2types.Account + registry coretypes.CapabilitiesRegistry + + subscribers map[string]*subscriber + mu sync.Mutex +} + +type subscriber struct { + ch chan<- capabilities.TriggerResponse + workflowID string + config config.SecureMintTriggerConfig +} + +func (c TransmitterConfig) NewTransmitter(transmitterID string) (*transmitter, error) { + return c.newTransmitter(c.Logger, transmitterID) +} + +func (c TransmitterConfig) newTransmitter(lggr logger.Logger, transmitterID string) (*transmitter, error) { + lggr.Infow("Initializing SecureMintTransmitter", "triggerCapabilityName", c.TriggerCapabilityName, "triggerCapabilityVersion", c.TriggerCapabilityVersion) + t := &transmitter{ + config: c, + fromAccount: ocr2types.Account(transmitterID), + registry: c.CapabilitiesRegistry, + subscribers: make(map[string]*subscriber), + } + if t.config.TriggerCapabilityName == "" { + t.config.TriggerCapabilityName = defaultCapabilityName + } + if t.config.TriggerCapabilityVersion == "" { + t.config.TriggerCapabilityVersion = defaultCapabilityVersion + } + if t.config.TriggerTickerMinResolutionMs == 0 { + t.config.TriggerTickerMinResolutionMs = defaultTickerResolutionMs + } + if t.config.TriggerSendChannelBufferSize == 0 { + t.config.TriggerSendChannelBufferSize = defaultSendChannelBufferSize + } + + capInfo, err := capabilities.NewCapabilityInfo( + // TODO(CAPPL-645): add labels + t.config.TriggerCapabilityName+"@"+t.config.TriggerCapabilityVersion, + capabilities.CapabilityTypeTrigger, + "Secure Mint Trigger", + ) + if err != nil { + return nil, err + } + t.CapabilityInfo = capInfo + + t.Service, t.eng = services.Config{ + Name: "SecureMintTransmitter", + Start: t.start, + Close: t.close, + }.NewServiceEngine(lggr) + + t.eng.Infow("SecureMintTransmitter initialized", "triggerCapabilityName", t.config.TriggerCapabilityName, "triggerCapabilityVersion", t.config.TriggerCapabilityVersion) + return t, nil +} + +func (t *transmitter) start(ctx context.Context) error { + t.eng.Infow("Starting SecureMintTransmitter", "triggerCapabilityName", t.config.TriggerCapabilityName, "triggerCapabilityVersion", t.config.TriggerCapabilityVersion) + err := t.registry.Add(ctx, t) + if err != nil { + return fmt.Errorf("failed to add transmitter to registry: %w", err) + } + t.eng.Infow("SecureMintTransmitter registered", "triggerCapabilityInfo", t.CapabilityInfo) + return nil +} + +func (t *transmitter) close() error { + t.eng.Infow("Closing SecureMintTransmitter", "triggerCapabilityName", t.config.TriggerCapabilityName, "triggerCapabilityVersion", t.config.TriggerCapabilityVersion) + return t.registry.Remove(context.Background(), t.CapabilityInfo.ID) +} + +func (t *transmitter) FromAccount(context.Context) (ocr2types.Account, error) { + t.eng.Debugw("FromAccount", "fromAccount", t.fromAccount) + return t.fromAccount, nil +} + +func (t *transmitter) Transmit( + ctx context.Context, + cd ocr2types.ConfigDigest, + seqNr uint64, + report ocr3types.ReportWithInfo[por.ChainSelector], + sigs []types.AttributedOnchainSignature, +) error { + t.eng.Debugw("Transmit called", "cd", cd, "seqNr", seqNr, "report", report, "sigs", sigs) + // Process the secure mint report and convert it to a trigger event + capSigs := make([]capabilities.OCRAttributedOnchainSignature, len(sigs)) + for i, sig := range sigs { + capSigs[i] = capabilities.OCRAttributedOnchainSignature{ + Signer: uint32(sig.Signer), + Signature: sig.Signature, + } + } + + // TODO(gg): should we use commoncap.OCRTriggerEvent instead? Probably better to enforce field names + outputs, err := values.NewMap(map[string]any{ + "report": report, + "sigs": capSigs, + "seqNr": seqNr, + "configDigest": cd, + }) + if err != nil { + return fmt.Errorf("failed to create outputs map: %w", err) + } + ev := &capabilities.TriggerEvent{ + TriggerType: t.CapabilityInfo.ID, // TODO(gg): is this correct? type != ID I would assume + ID: "securemint-trigger", // TODO(gg): probably we should use a more unique ID + Outputs: outputs, + } + return t.processNewEvent(ctx, ev) +} + +func (t *transmitter) processNewEvent(ctx context.Context, event *capabilities.TriggerEvent) error { + t.mu.Lock() + defer t.mu.Unlock() + + capResponse := capabilities.TriggerResponse{ + Event: *event, + } + + t.eng.Debugw("ProcessReport pushing event", "eventID", event.ID) + nIncludedSubscribers := 0 + for _, sub := range t.subscribers { + // include this subscriber (no frequency limiting as requested) + select { + case sub.ch <- capResponse: + case <-ctx.Done(): + t.eng.Error("context done, dropping event") + return ctx.Err() + default: + // drop event if channel is full - processNewEvent() should be non-blocking + t.eng.Errorw("subscriber channel full, dropping event", "eventID", event.ID, "workflowID", sub.workflowID) + } + nIncludedSubscribers++ + } + t.eng.Debugw("ProcessReport done", "eventID", event.ID, "nIncludedSubscribers", nIncludedSubscribers) + return nil +} + +func (t *transmitter) RegisterTrigger(ctx context.Context, req capabilities.TriggerRegistrationRequest) (<-chan capabilities.TriggerResponse, error) { + t.eng.Debugw("RegisterTrigger", "triggerID", req.TriggerID, "metadata", req.Metadata) + t.mu.Lock() + defer t.mu.Unlock() + + config, err := validateConfig(req.Config, &t.config) + if err != nil { + return nil, fmt.Errorf("invalid config: %w", err) + } + if _, ok := t.subscribers[req.TriggerID]; ok { + return nil, fmt.Errorf("triggerId %s already registered", t.ID) + } + + ch := make(chan capabilities.TriggerResponse, defaultSendChannelBufferSize) + t.subscribers[req.TriggerID] = + &subscriber{ + ch: ch, + workflowID: req.Metadata.WorkflowID, + config: *config, + } + return ch, nil +} + +func validateConfig(registerConfig *values.Map, capabilityConfig *TransmitterConfig) (*config.SecureMintTriggerConfig, error) { + cfg := &config.SecureMintTriggerConfig{} + if err := registerConfig.UnwrapTo(cfg); err != nil { + return nil, err + } + if int64(cfg.MaxFrequencyMs)%int64(capabilityConfig.TriggerTickerMinResolutionMs) != 0 { //nolint:gosec // disable G115 + return nil, fmt.Errorf("MaxFrequencyMs must be a multiple of %d", capabilityConfig.TriggerTickerMinResolutionMs) + } + return cfg, nil +} + +func (t *transmitter) UnregisterTrigger(ctx context.Context, req capabilities.TriggerRegistrationRequest) error { + t.eng.Debugw("UnregisterTrigger", "triggerID", req.TriggerID) + t.mu.Lock() + defer t.mu.Unlock() + + subscriber, ok := t.subscribers[req.TriggerID] + if !ok { + return fmt.Errorf("triggerId %s not registered", t.ID) + } + close(subscriber.ch) + delete(t.subscribers, req.TriggerID) + return nil +} diff --git a/core/services/ocr3/securemint/transmitter_test.go b/core/services/ocr3/securemint/transmitter_test.go new file mode 100644 index 00000000000..d0851b2332b --- /dev/null +++ b/core/services/ocr3/securemint/transmitter_test.go @@ -0,0 +1,161 @@ +package securemint + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/values" +) + +func TestTransmitter_NewTransmitter(t *testing.T) { + lggr := logger.Test(t) + + // Create a mock capabilities registry + mockRegistry := &mockCapabilitiesRegistry{} + + config := TransmitterConfig{ + Logger: lggr, + CapabilitiesRegistry: mockRegistry, + DonID: 1, + TriggerCapabilityName: "test-trigger", + TriggerCapabilityVersion: "1.0.0", + TriggerTickerMinResolutionMs: 1000, + TriggerSendChannelBufferSize: 1000, + } + + transmitter, err := config.NewTransmitter("test-transmitter") + require.NoError(t, err) + require.NotNil(t, transmitter) + + // Verify it implements the required interfaces + assert.Implements(t, (*Transmitter)(nil), transmitter) + assert.Implements(t, (*capabilities.TriggerCapability)(nil), transmitter) + + // Test service lifecycle + err = transmitter.Start(context.Background()) + require.NoError(t, err) + + err = transmitter.Close() + require.NoError(t, err) +} + +func TestTransmitter_RegisterTrigger(t *testing.T) { + lggr := logger.Test(t) + mockRegistry := &mockCapabilitiesRegistry{} + + config := TransmitterConfig{ + Logger: lggr, + CapabilitiesRegistry: mockRegistry, + DonID: 1, + TriggerCapabilityName: "test-trigger", + TriggerCapabilityVersion: "1.0.0", + TriggerTickerMinResolutionMs: 1000, + TriggerSendChannelBufferSize: 1000, + } + + transmitter, err := config.NewTransmitter("test-transmitter") + require.NoError(t, err) + + err = transmitter.Start(context.Background()) + require.NoError(t, err) + defer transmitter.Close() + + // Create trigger config as values.Map + triggerConfig, err := values.NewMap(map[string]any{ + "maxFrequencyMs": uint64(2000), + }) + require.NoError(t, err) + + // Test trigger registration + req := capabilities.TriggerRegistrationRequest{ + TriggerID: "test-trigger-1", + Config: triggerConfig, + Metadata: capabilities.RequestMetadata{ + WorkflowID: "test-workflow", + }, + } + + ch, err := transmitter.RegisterTrigger(context.Background(), req) + require.NoError(t, err) + require.NotNil(t, ch) + + // Test duplicate registration + _, err = transmitter.RegisterTrigger(context.Background(), req) + require.Error(t, err) + assert.Contains(t, err.Error(), "already registered") + + // Test unregister + err = transmitter.UnregisterTrigger(context.Background(), req) + require.NoError(t, err) + + // Test unregister non-existent + err = transmitter.UnregisterTrigger(context.Background(), req) + require.Error(t, err) + assert.Contains(t, err.Error(), "not registered") +} + +func TestTransmitter_FromAccount(t *testing.T) { + lggr := logger.Test(t) + mockRegistry := &mockCapabilitiesRegistry{} + + config := TransmitterConfig{ + Logger: lggr, + CapabilitiesRegistry: mockRegistry, + DonID: 1, + TriggerCapabilityName: "test-trigger", + TriggerCapabilityVersion: "1.0.0", + TriggerTickerMinResolutionMs: 1000, + TriggerSendChannelBufferSize: 1000, + } + + transmitter, err := config.NewTransmitter("test-transmitter") + require.NoError(t, err) + + account, err := transmitter.FromAccount(context.Background()) + require.NoError(t, err) + require.NotEmpty(t, account) + + // Verify account format includes logger name and don ID + assert.Contains(t, string(account), lggr.Name()) + assert.Contains(t, string(account), "1") +} + +// Mock capabilities registry for testing +type mockCapabilitiesRegistry struct{} + +func (m *mockCapabilitiesRegistry) Add(ctx context.Context, c capabilities.BaseCapability) error { + return nil +} + +func (m *mockCapabilitiesRegistry) Remove(ctx context.Context, ID string) error { + return nil +} + +func (m *mockCapabilitiesRegistry) Get(ctx context.Context, ID string) (capabilities.BaseCapability, error) { + return nil, nil +} + +func (m *mockCapabilitiesRegistry) List(ctx context.Context) ([]capabilities.BaseCapability, error) { + return nil, nil +} + +func (m *mockCapabilitiesRegistry) GetExecutable(ctx context.Context, ID string) (capabilities.ExecutableCapability, error) { + return nil, nil +} + +func (m *mockCapabilitiesRegistry) ConfigForCapability(ctx context.Context, capabilityID string, donID uint32) (capabilities.CapabilityConfiguration, error) { + return capabilities.CapabilityConfiguration{}, nil +} + +func (m *mockCapabilitiesRegistry) LocalNode(ctx context.Context) (capabilities.Node, error) { + return capabilities.Node{}, nil +} + +func (m *mockCapabilitiesRegistry) GetTrigger(ctx context.Context, ID string) (capabilities.TriggerCapability, error) { + return nil, nil +} diff --git a/core/services/relay/evm/target_strategy.go b/core/services/relay/evm/target_strategy.go index 7a39cfc20da..392f2ac7a88 100644 --- a/core/services/relay/evm/target_strategy.go +++ b/core/services/relay/evm/target_strategy.go @@ -97,7 +97,7 @@ func (t *evmTargetStrategy) QueryTransmissionState(ctx context.Context, reportID binary.BigEndian.PutUint16(b, reportID) if !t.bound.Load() { - t.lggr.Debugw("Binding to forwarder address") + t.lggr.Debugw("Binding to forwarder address", "forwarder", t.forwarder) err = t.cr.Bind(ctx, []commontypes.BoundContract{t.binding}) if err != nil { return nil, err diff --git a/core/services/relay/relay.go b/core/services/relay/relay.go index 32f8b836295..feee176e509 100644 --- a/core/services/relay/relay.go +++ b/core/services/relay/relay.go @@ -65,6 +65,8 @@ func (r *ServerAdapter) NewPluginProvider(ctx context.Context, rargs types.Relay return r.Relayer.NewPluginProvider(ctx, rargs, pargs) case types.LLO: return nil, fmt.Errorf("provider type not supported: %s", rargs.ProviderType) + case types.SecureMint: + return nil, fmt.Errorf("provider type not supported: %s", rargs.ProviderType) } return nil, fmt.Errorf("provider type not recognized: %s", rargs.ProviderType) } diff --git a/deployment/go.mod b/deployment/go.mod index 1a206464239..b34e17780dd 100644 --- a/deployment/go.mod +++ b/deployment/go.mod @@ -54,7 +54,7 @@ require ( github.com/stretchr/testify v1.10.0 github.com/testcontainers/testcontainers-go v0.37.0 github.com/vmihailenco/msgpack/v5 v5.4.1 - github.com/xssnick/tonutils-go v1.13.0 + github.com/xssnick/tonutils-go v1.14.0 github.com/zksync-sdk/zksync2-go v1.1.1-0.20250620124214-2c742ee399c6 go.uber.org/zap v1.27.0 golang.org/x/exp v0.0.0-20250711185948-6ae5c78190dc @@ -131,8 +131,8 @@ require ( github.com/buger/goterm v1.0.4 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/bytecodealliance/wasmtime-go/v28 v28.0.0 // indirect - github.com/bytedance/sonic v1.12.3 // indirect - github.com/bytedance/sonic/loader v0.2.0 // indirect + github.com/bytedance/sonic v1.13.3 // indirect + github.com/bytedance/sonic/loader v0.2.4 // indirect github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.7.5 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect @@ -141,8 +141,7 @@ require ( github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240821051457-da69c6d9617a // 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/cloudwego/base64x v0.1.4 // indirect - github.com/cloudwego/iasm v0.2.0 // indirect + github.com/cloudwego/base64x v0.1.5 // indirect github.com/cockroachdb/errors v1.11.3 // indirect github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect @@ -195,14 +194,14 @@ require ( github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.8 // indirect + github.com/gabriel-vasile/mimetype v1.4.9 // indirect github.com/gagliardetto/treeout v0.1.4 // indirect github.com/gagliardetto/utilz v0.1.1 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect github.com/gibson042/canonicaljson-go v1.0.3 // indirect github.com/gin-contrib/sessions v0.0.5 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect - github.com/gin-gonic/gin v1.10.0 // indirect + github.com/gin-contrib/sse v1.1.0 // indirect + github.com/gin-gonic/gin v1.10.1 // indirect github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect github.com/go-chi/chi v1.5.5 // indirect github.com/go-errors/errors v1.4.2 // indirect @@ -296,7 +295,7 @@ require ( github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect github.com/klauspost/compress v1.18.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.10 // indirect + github.com/klauspost/cpuid/v2 v2.2.11 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect @@ -412,7 +411,7 @@ require ( github.com/tklauser/numcpus v0.10.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/tyler-smith/go-bip39 v1.1.0 // indirect - github.com/ugorji/go/codec v1.2.12 // indirect + github.com/ugorji/go/codec v1.3.0 // indirect github.com/urfave/cli v1.22.16 // indirect github.com/urfave/cli/v2 v2.27.6 // indirect github.com/valyala/fastjson v1.6.4 // indirect @@ -443,7 +442,7 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.35.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.35.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0 // indirect go.opentelemetry.io/otel/log v0.13.0 // indirect go.opentelemetry.io/otel/metric v1.37.0 // indirect go.opentelemetry.io/otel/sdk v1.37.0 // indirect @@ -455,7 +454,7 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/ratelimit v0.3.1 // indirect - golang.org/x/arch v0.11.0 // indirect + golang.org/x/arch v0.18.0 // indirect golang.org/x/crypto v0.40.0 // indirect golang.org/x/net v0.42.0 // indirect golang.org/x/sys v0.34.0 // indirect diff --git a/deployment/go.sum b/deployment/go.sum index ec63ada0c17..809a193197d 100644 --- a/deployment/go.sum +++ b/deployment/go.sum @@ -245,11 +245,11 @@ github.com/bxcodec/faker v2.0.1+incompatible h1:P0KUpUw5w6WJXwrPfv35oc91i4d8nf40 github.com/bxcodec/faker v2.0.1+incompatible/go.mod h1:BNzfpVdTwnFJ6GtfYTcQu6l6rHShT+veBxNCnjCx5XM= github.com/bytecodealliance/wasmtime-go/v28 v28.0.0 h1:aBU8cexP2rPZ0Qz488kvn2NXvWZHL2aG1/+n7Iv+xGc= github.com/bytecodealliance/wasmtime-go/v28 v28.0.0/go.mod h1:4OCU0xAW9ycwtX4nMF4zxwgJBJ5/0eMfJiHB0wAmkV4= -github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU= -github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= +github.com/bytedance/sonic v1.13.3 h1:MS8gmaH16Gtirygw7jV91pDCN33NyMrPbN7qiYhEsF0= +github.com/bytedance/sonic v1.13.3/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= -github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= -github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= +github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.7.5 h1:rvc39Ol6z3MvaBzXkxFC6Nfsnixq/dRypushKDd7Nc0= github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.7.5/go.mod h1:R/pdNYDYFQk+tuuOo7QES1kkv6OLmp5ze2XBZQIVffM= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= @@ -277,9 +277,8 @@ github.com/cloudevents/sdk-go/binding/format/protobuf/v2 v2.16.1 h1:nLaJZcVAnaqc 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/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= -github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= -github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= +github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -458,8 +457,8 @@ github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/ github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= 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/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY= +github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok= github.com/gagliardetto/binary v0.8.0 h1:U9ahc45v9HW0d15LoN++vIXSJyqR/pWw8DDlhd7zvxg= github.com/gagliardetto/binary v0.8.0/go.mod h1:2tfj51g5o9dnvsc+fL3Jxr22MuWzYXwx9wEoN0XQ7/c= github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= @@ -488,10 +487,10 @@ github.com/gin-contrib/sessions v0.0.5 h1:CATtfHmLMQrMNpJRgzjWXD7worTh7g7ritsQfm github.com/gin-contrib/sessions v0.0.5/go.mod h1:vYAuaUPqie3WUSsft6HUlCjlwwoJQs97miaG2+7neKY= github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4 h1:Z9J0PVIt1PuibOShaOw1jH8hUYz+Ak8NLsR/GI0Hv5I= github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4/go.mod h1:CEPcgZiz8998l9E8fDm16h8UfHRL7b+5oG0j/0koeVw= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= -github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= +github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= +github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ= +github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA= github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-chi/chi v1.5.5 h1:vOB/HbEMt9QqBqErz07QehcOKHaWFtuj87tTDVz2qXE= @@ -900,8 +899,8 @@ github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs 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.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -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/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU= +github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= 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= @@ -1410,8 +1409,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= -github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= -github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= +github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= github.com/ulule/limiter/v3 v3.11.2 h1:P4yOrxoEMJbOTfRJR2OzjL90oflzYPPmWg+dvwN2tHA= github.com/ulule/limiter/v3 v3.11.2/go.mod h1:QG5GnFOCV+k7lrL5Y8kgEeeflPH3+Cviqlqa8SVSQxI= github.com/umbracle/ethgo v0.1.3 h1:s8D7Rmphnt71zuqrgsGTMS5gTNbueGO1zKLh7qsFzTM= @@ -1443,8 +1442,8 @@ github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= -github.com/xssnick/tonutils-go v1.13.0 h1:LV2JzB+CuuWaLQiYNolK+YI3NRQOpS0W+T+N+ctF6VQ= -github.com/xssnick/tonutils-go v1.13.0/go.mod h1:EDe/9D/HZpAenbR+WPMQHICOF0BZWAe01TU5+Vpg08k= +github.com/xssnick/tonutils-go v1.14.0 h1:9+WXLKleINMWTSBN/uRJuE3d2BRYtxDh55hCG5PYCBE= +github.com/xssnick/tonutils-go v1.14.0/go.mod h1:68xwWjpoGGqiTbLJ0gT63sKu1Z1moCnDLLzA+DKanIg= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1491,8 +1490,8 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= 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/github.com/gin-gonic/gin/otelgin v0.49.0 h1:1f31+6grJmV3X4lxcEvUy13i5/kfDw1nJZwhd8mA4tg= -go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0/go.mod h1:1P/02zM3OwkX9uki+Wmxw3a5GVb6KUXRsa7m7bOC9Fg= +go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.62.0 h1:fZNpsQuTwFFSGC96aJexNOBrCD7PjD9Tm/HyHtXhmnk= +go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.62.0/go.mod h1:+NFxPSeYg0SoiRUO4k0ceJYMCY9FiRbYFmByUpm7GJY= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= @@ -1517,8 +1516,8 @@ go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 h1:yEX3aC9KDgvYPhuKE go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0/go.mod h1:/GXR0tBmmkxDaCUGahvksvp66mx4yh5+cFXgSlhg0vQ= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.35.0 h1:PB3Zrjs1sG1GBX51SXyTSoOTqcDglmsk7nT6tkKPb/k= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.35.0/go.mod h1:U2R3XyVPzn0WX7wOIypPuptulsMcPDPs/oiSVOMVnHY= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.35.0 h1:T0Ec2E+3YZf5bgTNQVet8iTDW7oIk03tXHq+wkwIDnE= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.35.0/go.mod h1:30v2gqH+vYGJsesLWFov8u47EpYTcIQcBjKpI6pJThg= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0 h1:SNhVp/9q4Go/XHBkQ1/d5u9P/U+L1yaGPoi0x+mStaI= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0/go.mod h1:tx8OOlGH6R4kLV67YaYO44GFXloEjGPZuMjEkaaqIp4= go.opentelemetry.io/otel/log v0.13.0 h1:yoxRoIZcohB6Xf0lNv9QIyCzQvrtGZklVbdCoyb7dls= go.opentelemetry.io/otel/log v0.13.0/go.mod h1:INKfG4k1O9CL25BaM1qLe0zIedOpvlS5Z7XgSbmN83E= go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= @@ -1563,8 +1562,8 @@ go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/arch v0.11.0 h1:KXV8WWKCXm6tRpLirl2szsO5j/oOODwZf4hATmGVNs4= -golang.org/x/arch v0.11.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.18.0 h1:WN9poc33zL4AzGxqf8VtpKUnGvMi8O9lhNyBMF/85qc= +golang.org/x/arch v0.18.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/go.md b/go.md index 0a12b349c17..9cc2b6eba13 100644 --- a/go.md +++ b/go.md @@ -100,6 +100,7 @@ flowchart LR chainlink/v2 --> chainlink-solana chainlink/v2 --> cre-sdk-go/capabilities/networking/http chainlink/v2 --> cre-sdk-go/capabilities/scheduler/cron + chainlink/v2 --> por_mock_ocr3plugin chainlink/v2 --> tdh2/go/ocr2/decryptionplugin click chainlink/v2 href "https://github.com/smartcontractkit/chainlink" cre-sdk-go --> chainlink-common/pkg/workflows/sdk/v2/pb @@ -114,6 +115,8 @@ flowchart LR click grpc-proxy href "https://github.com/smartcontractkit/grpc-proxy" libocr click libocr href "https://github.com/smartcontractkit/libocr" + por_mock_ocr3plugin --> libocr + click por_mock_ocr3plugin href "https://github.com/smartcontractkit/por_mock_ocr3plugin" tdh2/go/ocr2/decryptionplugin --> libocr tdh2/go/ocr2/decryptionplugin --> tdh2/go/tdh2 click tdh2/go/ocr2/decryptionplugin href "https://github.com/smartcontractkit/tdh2" @@ -340,6 +343,7 @@ flowchart LR chainlink/v2 --> chainlink-solana chainlink/v2 --> cre-sdk-go/capabilities/networking/http chainlink/v2 --> cre-sdk-go/capabilities/scheduler/cron + chainlink/v2 --> por_mock_ocr3plugin chainlink/v2 --> tdh2/go/ocr2/decryptionplugin click chainlink/v2 href "https://github.com/smartcontractkit/chainlink" cre-sdk-go --> chainlink-common/pkg/workflows/sdk/v2/pb @@ -360,6 +364,8 @@ flowchart LR mcms --> chainlink-ccip/chains/solana mcms --> chainlink-testing-framework/framework click mcms href "https://github.com/smartcontractkit/mcms" + por_mock_ocr3plugin --> libocr + click por_mock_ocr3plugin href "https://github.com/smartcontractkit/por_mock_ocr3plugin" tdh2/go/ocr2/decryptionplugin --> libocr tdh2/go/ocr2/decryptionplugin --> tdh2/go/tdh2 click tdh2/go/ocr2/decryptionplugin href "https://github.com/smartcontractkit/tdh2" diff --git a/go.mod b/go.mod index c0ad5bc3bd9..93cf82d680e 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( github.com/gin-contrib/expvar v0.0.1 github.com/gin-contrib/sessions v0.0.5 github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4 - github.com/gin-gonic/gin v1.10.0 + github.com/gin-gonic/gin v1.10.1 github.com/go-ldap/ldap/v3 v3.4.6 github.com/go-viper/mapstructure/v2 v2.3.0 github.com/go-webauthn/webauthn v0.9.4 @@ -104,6 +104,7 @@ require ( github.com/smartcontractkit/cre-sdk-go/capabilities/scheduler/cron v0.2.1-0.20250729191525-ac1867f3ff34 github.com/smartcontractkit/freeport v0.1.1 github.com/smartcontractkit/libocr v0.0.0-20250707144819-babe0ec4e358 + github.com/smartcontractkit/por_mock_ocr3plugin v0.0.0-20250627193309-2ff496c274dc github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20241009055228-33d0c0bf38de github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20250624150019-e49f7e125e6b github.com/smartcontractkit/wsrpc v0.8.5-0.20250502134807-c57d3d995945 @@ -117,10 +118,10 @@ require ( github.com/unrolled/secure v1.13.0 github.com/urfave/cli v1.22.14 github.com/wk8/go-ordered-map/v2 v2.1.8 - github.com/xssnick/tonutils-go v1.13.0 + github.com/xssnick/tonutils-go v1.14.0 go.dedis.ch/fixbuf v1.0.3 - go.dedis.ch/kyber/v3 v3.1.0 - go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 + go.dedis.ch/kyber/v3 v3.0.9 + go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.62.0 go.opentelemetry.io/otel v1.37.0 go.opentelemetry.io/otel/metric v1.37.0 go.opentelemetry.io/otel/sdk/metric v1.37.0 @@ -177,15 +178,14 @@ require ( github.com/buger/goterm v1.0.4 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/bytecodealliance/wasmtime-go/v28 v28.0.0 // indirect - github.com/bytedance/sonic v1.12.3 // indirect - github.com/bytedance/sonic/loader v0.2.0 // indirect + github.com/bytedance/sonic v1.13.3 // indirect + github.com/bytedance/sonic/loader v0.2.4 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.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/cloudwego/base64x v0.1.4 // indirect - github.com/cloudwego/iasm v0.2.0 // indirect + github.com/cloudwego/base64x v0.1.5 // indirect github.com/cockroachdb/errors v1.11.3 // indirect github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect @@ -219,11 +219,11 @@ require ( github.com/ethereum/go-verkle v0.2.2 // indirect github.com/expr-lang/expr v1.17.5 // indirect github.com/fsnotify/fsnotify v1.8.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.8 // indirect + github.com/gabriel-vasile/mimetype v1.4.9 // indirect github.com/gagliardetto/treeout v0.1.4 // indirect github.com/gagliardetto/utilz v0.1.1 // indirect github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect + github.com/gin-contrib/sse v1.1.0 // indirect github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect github.com/go-jose/go-jose/v4 v4.0.5 // indirect github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 // indirect @@ -235,7 +235,7 @@ require ( github.com/go-ole/go-ole v1.3.0 // 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/go-webauthn/x v0.1.5 // indirect github.com/goccy/go-json v0.10.5 // indirect github.com/goccy/go-yaml v1.12.0 // indirect @@ -285,7 +285,7 @@ require ( github.com/jmhodges/levigo v1.0.0 // 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.10 // indirect + github.com/klauspost/cpuid/v2 v2.2.11 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect @@ -350,7 +350,7 @@ require ( github.com/tklauser/numcpus v0.10.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/tyler-smith/go-bip39 v1.1.0 // indirect - github.com/ugorji/go/codec v1.2.12 // indirect + github.com/ugorji/go/codec v1.3.0 // indirect github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722 // indirect github.com/urfave/cli/v2 v2.27.6 // indirect github.com/valyala/fastjson v1.6.4 // indirect @@ -375,14 +375,14 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.35.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.35.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0 // indirect go.opentelemetry.io/otel/log v0.13.0 // indirect go.opentelemetry.io/otel/sdk v1.37.0 // indirect go.opentelemetry.io/otel/sdk/log v0.13.0 // indirect go.opentelemetry.io/proto/otlp v1.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/ratelimit v0.3.1 // indirect - golang.org/x/arch v0.11.0 // indirect + golang.org/x/arch v0.18.0 // indirect golang.org/x/net v0.42.0 // indirect golang.org/x/sys v0.34.0 // indirect golang.org/x/text v0.27.0 // indirect @@ -399,3 +399,6 @@ require ( ) replace github.com/fbsobreira/gotron-sdk => github.com/smartcontractkit/chainlink-tron/relayer/gotron-sdk v0.0.5-0.20250528121202-292529af39df + +// temporarily replace por_mock_ocr3plugin with the locally copied one +replace github.com/smartcontractkit/por_mock_ocr3plugin => ./modules/por_mock_ocr3plugin diff --git a/go.sum b/go.sum index 4977cba82dc..1f5b912e84c 100644 --- a/go.sum +++ b/go.sum @@ -180,11 +180,11 @@ github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMU github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bytecodealliance/wasmtime-go/v28 v28.0.0 h1:aBU8cexP2rPZ0Qz488kvn2NXvWZHL2aG1/+n7Iv+xGc= github.com/bytecodealliance/wasmtime-go/v28 v28.0.0/go.mod h1:4OCU0xAW9ycwtX4nMF4zxwgJBJ5/0eMfJiHB0wAmkV4= -github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU= -github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= +github.com/bytedance/sonic v1.13.3 h1:MS8gmaH16Gtirygw7jV91pDCN33NyMrPbN7qiYhEsF0= +github.com/bytedance/sonic v1.13.3/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= -github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= -github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= +github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= @@ -206,9 +206,8 @@ github.com/cloudevents/sdk-go/binding/format/protobuf/v2 v2.16.1 h1:nLaJZcVAnaqc 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/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= -github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= -github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= +github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -359,8 +358,8 @@ github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/ github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= 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/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY= +github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok= github.com/gagliardetto/binary v0.8.0 h1:U9ahc45v9HW0d15LoN++vIXSJyqR/pWw8DDlhd7zvxg= github.com/gagliardetto/binary v0.8.0/go.mod h1:2tfj51g5o9dnvsc+fL3Jxr22MuWzYXwx9wEoN0XQ7/c= github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= @@ -388,12 +387,13 @@ github.com/gin-contrib/sessions v0.0.5/go.mod h1:vYAuaUPqie3WUSsft6HUlCjlwwoJQs9 github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4 h1:Z9J0PVIt1PuibOShaOw1jH8hUYz+Ak8NLsR/GI0Hv5I= github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4/go.mod h1:CEPcgZiz8998l9E8fDm16h8UfHRL7b+5oG0j/0koeVw= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= +github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= -github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= -github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ= +github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA= github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= @@ -438,8 +438,8 @@ github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl 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.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= -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= @@ -767,8 +767,8 @@ github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs 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.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -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/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU= +github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= 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= @@ -1232,8 +1232,8 @@ github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3C github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= -github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= +github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= github.com/ulule/limiter/v3 v3.11.2 h1:P4yOrxoEMJbOTfRJR2OzjL90oflzYPPmWg+dvwN2tHA= github.com/ulule/limiter/v3 v3.11.2/go.mod h1:QG5GnFOCV+k7lrL5Y8kgEeeflPH3+Cviqlqa8SVSQxI= github.com/umbracle/ethgo v0.1.3 h1:s8D7Rmphnt71zuqrgsGTMS5gTNbueGO1zKLh7qsFzTM= @@ -1257,8 +1257,8 @@ github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= -github.com/xssnick/tonutils-go v1.13.0 h1:LV2JzB+CuuWaLQiYNolK+YI3NRQOpS0W+T+N+ctF6VQ= -github.com/xssnick/tonutils-go v1.13.0/go.mod h1:EDe/9D/HZpAenbR+WPMQHICOF0BZWAe01TU5+Vpg08k= +github.com/xssnick/tonutils-go v1.14.0 h1:9+WXLKleINMWTSBN/uRJuE3d2BRYtxDh55hCG5PYCBE= +github.com/xssnick/tonutils-go v1.14.0/go.mod h1:68xwWjpoGGqiTbLJ0gT63sKu1Z1moCnDLLzA+DKanIg= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1283,9 +1283,8 @@ github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1U go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs= go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw= go.dedis.ch/kyber/v3 v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ= +go.dedis.ch/kyber/v3 v3.0.9 h1:i0ZbOQocHUjfFasBiUql5zVeC7u/vahFd96DFA8UOWk= go.dedis.ch/kyber/v3 v3.0.9/go.mod h1:rhNjUUg6ahf8HEg5HUvVBYoWY4boAafX8tYxX+PS+qg= -go.dedis.ch/kyber/v3 v3.1.0 h1:ghu+kiRgM5JyD9TJ0hTIxTLQlJBR/ehjWvWwYW3XsC0= -go.dedis.ch/kyber/v3 v3.1.0/go.mod h1:kXy7p3STAurkADD+/aZcsznZGKVHEqbtmdIzvPfrs1U= go.dedis.ch/protobuf v1.0.5/go.mod h1:eIV4wicvi6JK0q/QnfIEGeSFNG0ZeB24kzut5+HaRLo= go.dedis.ch/protobuf v1.0.7/go.mod h1:pv5ysfkDX/EawiPqcW3ikOxsL5t+BqnV6xHSmE79KI4= go.dedis.ch/protobuf v1.0.11 h1:FTYVIEzY/bfl37lu3pR4lIj+F9Vp1jE8oh91VmxKgLo= @@ -1306,12 +1305,12 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= 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/github.com/gin-gonic/gin/otelgin v0.49.0 h1:1f31+6grJmV3X4lxcEvUy13i5/kfDw1nJZwhd8mA4tg= -go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0/go.mod h1:1P/02zM3OwkX9uki+Wmxw3a5GVb6KUXRsa7m7bOC9Fg= +go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.62.0 h1:fZNpsQuTwFFSGC96aJexNOBrCD7PjD9Tm/HyHtXhmnk= +go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.62.0/go.mod h1:+NFxPSeYg0SoiRUO4k0ceJYMCY9FiRbYFmByUpm7GJY= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= -go.opentelemetry.io/contrib/propagators/b3 v1.24.0 h1:n4xwCdTx3pZqZs2CjS/CUZAs03y3dZcGhC/FepKtEUY= -go.opentelemetry.io/contrib/propagators/b3 v1.24.0/go.mod h1:k5wRxKRU2uXx2F8uNJ4TaonuEO/V7/5xoz7kdsDACT8= +go.opentelemetry.io/contrib/propagators/b3 v1.37.0 h1:0aGKdIuVhy5l4GClAjl72ntkZJhijf2wg1S7b5oLoYA= +go.opentelemetry.io/contrib/propagators/b3 v1.37.0/go.mod h1:nhyrxEJEOQdwR15zXrCKI6+cJK60PXAkJ/jRyfhr2mg= go.opentelemetry.io/otel v1.6.3/go.mod h1:7BgNga5fNlF/iZjG06hM3yofffp0ofKCDwSXx1GC4dI= go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= @@ -1333,8 +1332,8 @@ go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 h1:yEX3aC9KDgvYPhuKE go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0/go.mod h1:/GXR0tBmmkxDaCUGahvksvp66mx4yh5+cFXgSlhg0vQ= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.35.0 h1:PB3Zrjs1sG1GBX51SXyTSoOTqcDglmsk7nT6tkKPb/k= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.35.0/go.mod h1:U2R3XyVPzn0WX7wOIypPuptulsMcPDPs/oiSVOMVnHY= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.35.0 h1:T0Ec2E+3YZf5bgTNQVet8iTDW7oIk03tXHq+wkwIDnE= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.35.0/go.mod h1:30v2gqH+vYGJsesLWFov8u47EpYTcIQcBjKpI6pJThg= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0 h1:SNhVp/9q4Go/XHBkQ1/d5u9P/U+L1yaGPoi0x+mStaI= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0/go.mod h1:tx8OOlGH6R4kLV67YaYO44GFXloEjGPZuMjEkaaqIp4= go.opentelemetry.io/otel/log v0.13.0 h1:yoxRoIZcohB6Xf0lNv9QIyCzQvrtGZklVbdCoyb7dls= go.opentelemetry.io/otel/log v0.13.0/go.mod h1:INKfG4k1O9CL25BaM1qLe0zIedOpvlS5Z7XgSbmN83E= go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= @@ -1378,8 +1377,8 @@ go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/arch v0.11.0 h1:KXV8WWKCXm6tRpLirl2szsO5j/oOODwZf4hATmGVNs4= -golang.org/x/arch v0.11.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.18.0 h1:WN9poc33zL4AzGxqf8VtpKUnGvMi8O9lhNyBMF/85qc= +golang.org/x/arch v0.18.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 994f398fe2d..e4475bd3bdd 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -69,7 +69,7 @@ require ( github.com/subosito/gotenv v1.6.0 github.com/testcontainers/testcontainers-go v0.37.0 github.com/umbracle/ethgo v0.1.3 - github.com/xssnick/tonutils-go v1.13.0 + github.com/xssnick/tonutils-go v1.14.0 go.uber.org/atomic v1.11.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.40.0 @@ -155,8 +155,8 @@ require ( github.com/buger/goterm v1.0.4 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/bytecodealliance/wasmtime-go/v28 v28.0.0 // indirect - github.com/bytedance/sonic v1.12.3 // indirect - github.com/bytedance/sonic/loader v0.2.0 // indirect + github.com/bytedance/sonic v1.13.3 // indirect + github.com/bytedance/sonic/loader v0.2.4 // indirect github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500 // indirect github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.7.5 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect @@ -168,8 +168,7 @@ require ( github.com/cli/safeexec v1.0.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/cloudwego/base64x v0.1.4 // indirect - github.com/cloudwego/iasm v0.2.0 // indirect + github.com/cloudwego/base64x v0.1.5 // indirect github.com/cockroachdb/errors v1.11.3 // indirect github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect @@ -230,15 +229,15 @@ require ( github.com/fbsobreira/gotron-sdk v0.0.0-20250403083053-2943ce8c759b // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.8 // indirect + github.com/gabriel-vasile/mimetype v1.4.9 // indirect github.com/gagliardetto/binary v0.8.0 // indirect github.com/gagliardetto/treeout v0.1.4 // indirect github.com/gagliardetto/utilz v0.1.1 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect github.com/gibson042/canonicaljson-go v1.0.3 // indirect github.com/gin-contrib/sessions v0.0.5 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect - github.com/gin-gonic/gin v1.10.0 // indirect + github.com/gin-contrib/sse v1.1.0 // indirect + github.com/gin-gonic/gin v1.10.1 // indirect github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect github.com/go-chi/chi v1.5.5 // indirect github.com/go-errors/errors v1.4.2 // indirect @@ -363,7 +362,7 @@ require ( github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect github.com/klauspost/compress v1.18.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.10 // indirect + github.com/klauspost/cpuid/v2 v2.2.11 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v0.1.0 // indirect github.com/knadh/koanf/v2 v2.1.2 // indirect @@ -512,7 +511,7 @@ require ( github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect github.com/uber/jaeger-lib v2.4.1+incompatible // indirect - github.com/ugorji/go/codec v1.2.12 // indirect + github.com/ugorji/go/codec v1.3.0 // indirect github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722 // indirect github.com/urfave/cli/v2 v2.27.6 // indirect github.com/valyala/fastjson v1.6.4 // indirect @@ -564,7 +563,7 @@ require ( go.opentelemetry.io/otel/exporters/prometheus v0.58.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/exporters/stdout/stdouttrace v1.37.0 // indirect go.opentelemetry.io/otel/log v0.13.0 // indirect go.opentelemetry.io/otel/metric v1.37.0 // indirect go.opentelemetry.io/otel/sdk v1.37.0 // indirect @@ -577,7 +576,7 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/ratelimit v0.3.1 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect - golang.org/x/arch v0.11.0 // indirect + golang.org/x/arch v0.18.0 // indirect golang.org/x/mod v0.26.0 // indirect golang.org/x/net v0.42.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 8630375a857..09d2aaeaf15 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -285,11 +285,11 @@ github.com/bxcodec/faker v2.0.1+incompatible h1:P0KUpUw5w6WJXwrPfv35oc91i4d8nf40 github.com/bxcodec/faker v2.0.1+incompatible/go.mod h1:BNzfpVdTwnFJ6GtfYTcQu6l6rHShT+veBxNCnjCx5XM= github.com/bytecodealliance/wasmtime-go/v28 v28.0.0 h1:aBU8cexP2rPZ0Qz488kvn2NXvWZHL2aG1/+n7Iv+xGc= github.com/bytecodealliance/wasmtime-go/v28 v28.0.0/go.mod h1:4OCU0xAW9ycwtX4nMF4zxwgJBJ5/0eMfJiHB0wAmkV4= -github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU= -github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= +github.com/bytedance/sonic v1.13.3 h1:MS8gmaH16Gtirygw7jV91pDCN33NyMrPbN7qiYhEsF0= +github.com/bytedance/sonic v1.13.3/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= -github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= -github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= +github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500 h1:6lhrsTEnloDPXyeZBvSYvQf8u86jbKehZPVDDlkgDl4= github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M= github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.7.5 h1:rvc39Ol6z3MvaBzXkxFC6Nfsnixq/dRypushKDd7Nc0= @@ -343,9 +343,8 @@ github.com/cloudevents/sdk-go/binding/format/protobuf/v2 v2.16.1 h1:nLaJZcVAnaqc 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/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= -github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= -github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= +github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -547,8 +546,8 @@ github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= 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/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY= +github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok= github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= github.com/gagliardetto/gofuzz v1.2.2/go.mod h1:bkH/3hYLZrMLbfYWA0pWzXmi5TTRZnu4pMGZBkqMKvY= github.com/gagliardetto/hashsearch v0.0.0-20191005111333-09dd671e19f9/go.mod h1:513DXpQPzeRo7d4dsCP3xO3XI8hgvruMl9njxyQeraQ= @@ -575,10 +574,10 @@ github.com/gin-contrib/sessions v0.0.5 h1:CATtfHmLMQrMNpJRgzjWXD7worTh7g7ritsQfm github.com/gin-contrib/sessions v0.0.5/go.mod h1:vYAuaUPqie3WUSsft6HUlCjlwwoJQs97miaG2+7neKY= github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4 h1:Z9J0PVIt1PuibOShaOw1jH8hUYz+Ak8NLsR/GI0Hv5I= github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4/go.mod h1:CEPcgZiz8998l9E8fDm16h8UfHRL7b+5oG0j/0koeVw= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= -github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= +github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= +github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ= +github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA= github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-chi/chi v1.5.5 h1:vOB/HbEMt9QqBqErz07QehcOKHaWFtuj87tTDVz2qXE= @@ -1078,8 +1077,8 @@ github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs 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.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -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/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU= +github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v0.1.0 h1:gOkxhHkemwG4LezxxN8DMOFopOPghxRVp7JbIvdvqzU= @@ -1692,8 +1691,8 @@ github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaO github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= -github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= +github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= github.com/ulule/limiter/v3 v3.11.2 h1:P4yOrxoEMJbOTfRJR2OzjL90oflzYPPmWg+dvwN2tHA= github.com/ulule/limiter/v3 v3.11.2/go.mod h1:QG5GnFOCV+k7lrL5Y8kgEeeflPH3+Cviqlqa8SVSQxI= github.com/umbracle/ethgo v0.1.3 h1:s8D7Rmphnt71zuqrgsGTMS5gTNbueGO1zKLh7qsFzTM= @@ -1725,8 +1724,8 @@ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavM github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= -github.com/xssnick/tonutils-go v1.13.0 h1:LV2JzB+CuuWaLQiYNolK+YI3NRQOpS0W+T+N+ctF6VQ= -github.com/xssnick/tonutils-go v1.13.0/go.mod h1:EDe/9D/HZpAenbR+WPMQHICOF0BZWAe01TU5+Vpg08k= +github.com/xssnick/tonutils-go v1.14.0 h1:9+WXLKleINMWTSBN/uRJuE3d2BRYtxDh55hCG5PYCBE= +github.com/xssnick/tonutils-go v1.14.0/go.mod h1:68xwWjpoGGqiTbLJ0gT63sKu1Z1moCnDLLzA+DKanIg= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1823,8 +1822,8 @@ go.opentelemetry.io/contrib/bridges/prometheus v0.61.0 h1:RyrtJzu5MAmIcbRrwg75b+ go.opentelemetry.io/contrib/bridges/prometheus v0.61.0/go.mod h1:tirr4p9NXbzjlbruiRGp53IzlYrDk5CO2fdHj0sSSaY= go.opentelemetry.io/contrib/exporters/autoexport v0.61.0 h1:XfzKtKSrbtYk9TNCF8dkO0Y9M7IOfb4idCwBOTwGBiI= go.opentelemetry.io/contrib/exporters/autoexport v0.61.0/go.mod h1:N6otC+qXTD5bAnbK2O1f/1SXq3cX+3KYSWrkBUqG0cw= -go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 h1:1f31+6grJmV3X4lxcEvUy13i5/kfDw1nJZwhd8mA4tg= -go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0/go.mod h1:1P/02zM3OwkX9uki+Wmxw3a5GVb6KUXRsa7m7bOC9Fg= +go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.62.0 h1:fZNpsQuTwFFSGC96aJexNOBrCD7PjD9Tm/HyHtXhmnk= +go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.62.0/go.mod h1:+NFxPSeYg0SoiRUO4k0ceJYMCY9FiRbYFmByUpm7GJY= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.61.0 h1:lREC4C0ilyP4WibDhQ7Gg2ygAQFP8oR07Fst/5cafwI= @@ -1860,8 +1859,8 @@ go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 h1:yEX3aC9KDgvYPhuKE 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/exporters/stdout/stdouttrace v1.37.0 h1:SNhVp/9q4Go/XHBkQ1/d5u9P/U+L1yaGPoi0x+mStaI= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0/go.mod h1:tx8OOlGH6R4kLV67YaYO44GFXloEjGPZuMjEkaaqIp4= go.opentelemetry.io/otel/log v0.13.0 h1:yoxRoIZcohB6Xf0lNv9QIyCzQvrtGZklVbdCoyb7dls= go.opentelemetry.io/otel/log v0.13.0/go.mod h1:INKfG4k1O9CL25BaM1qLe0zIedOpvlS5Z7XgSbmN83E= go.opentelemetry.io/otel/log/logtest v0.0.0-20250616193322-2cce18995527 h1:K4gsUDjRKwV+Uw9lSEM7NdFqIfTfDlwv6zoGgffbtwk= @@ -1913,8 +1912,8 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f h1:ketMxHg+vWm3yccyYiq+uK8D3fRmna2Fcj+awpQp84s= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f/go.mod h1:tgPU4N2u9RByaTN3NC2p9xOzyFpte4jYwsIIRF7XlSc= -golang.org/x/arch v0.11.0 h1:KXV8WWKCXm6tRpLirl2szsO5j/oOODwZf4hATmGVNs4= -golang.org/x/arch v0.11.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.18.0 h1:WN9poc33zL4AzGxqf8VtpKUnGvMi8O9lhNyBMF/85qc= +golang.org/x/arch v0.18.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 99b841ba7be..4f36f5f17e8 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -130,8 +130,8 @@ require ( github.com/buger/goterm v1.0.4 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/bytecodealliance/wasmtime-go/v28 v28.0.0 // indirect - github.com/bytedance/sonic v1.12.3 // indirect - github.com/bytedance/sonic/loader v0.2.0 // indirect + github.com/bytedance/sonic v1.13.3 // indirect + github.com/bytedance/sonic/loader v0.2.4 // indirect github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500 // indirect github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.7.5 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect @@ -142,8 +142,7 @@ require ( github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240821051457-da69c6d9617a // 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/cloudwego/base64x v0.1.4 // indirect - github.com/cloudwego/iasm v0.2.0 // indirect + github.com/cloudwego/base64x v0.1.5 // indirect github.com/cockroachdb/errors v1.11.3 // indirect github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect @@ -205,15 +204,15 @@ require ( github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.8 // indirect + github.com/gabriel-vasile/mimetype v1.4.9 // indirect github.com/gagliardetto/binary v0.8.0 // indirect github.com/gagliardetto/treeout v0.1.4 // indirect github.com/gagliardetto/utilz v0.1.1 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect github.com/gibson042/canonicaljson-go v1.0.3 // indirect github.com/gin-contrib/sessions v0.0.5 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect - github.com/gin-gonic/gin v1.10.0 // indirect + github.com/gin-contrib/sse v1.1.0 // indirect + github.com/gin-gonic/gin v1.10.1 // indirect github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect github.com/go-chi/chi v1.5.5 // indirect github.com/go-errors/errors v1.4.2 // indirect @@ -343,7 +342,7 @@ require ( github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect github.com/klauspost/compress v1.18.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.10 // indirect + github.com/klauspost/cpuid/v2 v2.2.11 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v0.1.0 // indirect github.com/knadh/koanf/v2 v2.1.2 // indirect @@ -508,7 +507,7 @@ require ( github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect github.com/uber/jaeger-lib v2.4.1+incompatible // indirect - github.com/ugorji/go/codec v1.2.12 // indirect + github.com/ugorji/go/codec v1.3.0 // indirect github.com/umbracle/ethgo v0.1.3 // indirect github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722 // indirect github.com/urfave/cli/v2 v2.27.6 // indirect @@ -519,7 +518,7 @@ require ( github.com/x448/float16 v0.8.4 // indirect github.com/xlab/treeprint v1.2.0 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect - github.com/xssnick/tonutils-go v1.13.0 // indirect + github.com/xssnick/tonutils-go v1.14.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect github.com/zksync-sdk/zksync2-go v1.1.1-0.20250620124214-2c742ee399c6 // indirect @@ -563,7 +562,7 @@ require ( go.opentelemetry.io/otel/exporters/prometheus v0.58.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/exporters/stdout/stdouttrace v1.37.0 // indirect go.opentelemetry.io/otel/log v0.13.0 // indirect go.opentelemetry.io/otel/metric v1.37.0 // indirect go.opentelemetry.io/otel/sdk v1.37.0 // indirect @@ -576,7 +575,7 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect - golang.org/x/arch v0.11.0 // indirect + golang.org/x/arch v0.18.0 // indirect golang.org/x/crypto v0.40.0 // indirect golang.org/x/mod v0.26.0 // indirect golang.org/x/net v0.42.0 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 99ee7acde67..f4202e52679 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -285,11 +285,11 @@ github.com/bxcodec/faker v2.0.1+incompatible h1:P0KUpUw5w6WJXwrPfv35oc91i4d8nf40 github.com/bxcodec/faker v2.0.1+incompatible/go.mod h1:BNzfpVdTwnFJ6GtfYTcQu6l6rHShT+veBxNCnjCx5XM= github.com/bytecodealliance/wasmtime-go/v28 v28.0.0 h1:aBU8cexP2rPZ0Qz488kvn2NXvWZHL2aG1/+n7Iv+xGc= github.com/bytecodealliance/wasmtime-go/v28 v28.0.0/go.mod h1:4OCU0xAW9ycwtX4nMF4zxwgJBJ5/0eMfJiHB0wAmkV4= -github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU= -github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= +github.com/bytedance/sonic v1.13.3 h1:MS8gmaH16Gtirygw7jV91pDCN33NyMrPbN7qiYhEsF0= +github.com/bytedance/sonic v1.13.3/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= -github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= -github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= +github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500 h1:6lhrsTEnloDPXyeZBvSYvQf8u86jbKehZPVDDlkgDl4= github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M= github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.7.5 h1:rvc39Ol6z3MvaBzXkxFC6Nfsnixq/dRypushKDd7Nc0= @@ -321,9 +321,8 @@ github.com/cloudevents/sdk-go/binding/format/protobuf/v2 v2.16.1 h1:nLaJZcVAnaqc 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/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= -github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= -github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= +github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -525,8 +524,8 @@ github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= 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/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY= +github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok= github.com/gagliardetto/binary v0.8.0 h1:U9ahc45v9HW0d15LoN++vIXSJyqR/pWw8DDlhd7zvxg= github.com/gagliardetto/binary v0.8.0/go.mod h1:2tfj51g5o9dnvsc+fL3Jxr22MuWzYXwx9wEoN0XQ7/c= github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= @@ -555,10 +554,10 @@ github.com/gin-contrib/sessions v0.0.5 h1:CATtfHmLMQrMNpJRgzjWXD7worTh7g7ritsQfm github.com/gin-contrib/sessions v0.0.5/go.mod h1:vYAuaUPqie3WUSsft6HUlCjlwwoJQs97miaG2+7neKY= github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4 h1:Z9J0PVIt1PuibOShaOw1jH8hUYz+Ak8NLsR/GI0Hv5I= github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4/go.mod h1:CEPcgZiz8998l9E8fDm16h8UfHRL7b+5oG0j/0koeVw= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= -github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= +github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= +github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ= +github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA= github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-chi/chi v1.5.5 h1:vOB/HbEMt9QqBqErz07QehcOKHaWFtuj87tTDVz2qXE= @@ -1060,8 +1059,8 @@ github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs 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.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -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/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU= +github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v0.1.0 h1:gOkxhHkemwG4LezxxN8DMOFopOPghxRVp7JbIvdvqzU= @@ -1666,8 +1665,8 @@ github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaO github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= -github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= +github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= github.com/ulule/limiter/v3 v3.11.2 h1:P4yOrxoEMJbOTfRJR2OzjL90oflzYPPmWg+dvwN2tHA= github.com/ulule/limiter/v3 v3.11.2/go.mod h1:QG5GnFOCV+k7lrL5Y8kgEeeflPH3+Cviqlqa8SVSQxI= github.com/umbracle/ethgo v0.1.3 h1:s8D7Rmphnt71zuqrgsGTMS5gTNbueGO1zKLh7qsFzTM= @@ -1701,8 +1700,8 @@ github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= -github.com/xssnick/tonutils-go v1.13.0 h1:LV2JzB+CuuWaLQiYNolK+YI3NRQOpS0W+T+N+ctF6VQ= -github.com/xssnick/tonutils-go v1.13.0/go.mod h1:EDe/9D/HZpAenbR+WPMQHICOF0BZWAe01TU5+Vpg08k= +github.com/xssnick/tonutils-go v1.14.0 h1:9+WXLKleINMWTSBN/uRJuE3d2BRYtxDh55hCG5PYCBE= +github.com/xssnick/tonutils-go v1.14.0/go.mod h1:68xwWjpoGGqiTbLJ0gT63sKu1Z1moCnDLLzA+DKanIg= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1799,8 +1798,8 @@ go.opentelemetry.io/contrib/bridges/prometheus v0.61.0 h1:RyrtJzu5MAmIcbRrwg75b+ go.opentelemetry.io/contrib/bridges/prometheus v0.61.0/go.mod h1:tirr4p9NXbzjlbruiRGp53IzlYrDk5CO2fdHj0sSSaY= go.opentelemetry.io/contrib/exporters/autoexport v0.61.0 h1:XfzKtKSrbtYk9TNCF8dkO0Y9M7IOfb4idCwBOTwGBiI= go.opentelemetry.io/contrib/exporters/autoexport v0.61.0/go.mod h1:N6otC+qXTD5bAnbK2O1f/1SXq3cX+3KYSWrkBUqG0cw= -go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 h1:1f31+6grJmV3X4lxcEvUy13i5/kfDw1nJZwhd8mA4tg= -go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0/go.mod h1:1P/02zM3OwkX9uki+Wmxw3a5GVb6KUXRsa7m7bOC9Fg= +go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.62.0 h1:fZNpsQuTwFFSGC96aJexNOBrCD7PjD9Tm/HyHtXhmnk= +go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.62.0/go.mod h1:+NFxPSeYg0SoiRUO4k0ceJYMCY9FiRbYFmByUpm7GJY= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.61.0 h1:lREC4C0ilyP4WibDhQ7Gg2ygAQFP8oR07Fst/5cafwI= @@ -1836,8 +1835,8 @@ go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 h1:yEX3aC9KDgvYPhuKE 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/exporters/stdout/stdouttrace v1.37.0 h1:SNhVp/9q4Go/XHBkQ1/d5u9P/U+L1yaGPoi0x+mStaI= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0/go.mod h1:tx8OOlGH6R4kLV67YaYO44GFXloEjGPZuMjEkaaqIp4= go.opentelemetry.io/otel/log v0.13.0 h1:yoxRoIZcohB6Xf0lNv9QIyCzQvrtGZklVbdCoyb7dls= go.opentelemetry.io/otel/log v0.13.0/go.mod h1:INKfG4k1O9CL25BaM1qLe0zIedOpvlS5Z7XgSbmN83E= go.opentelemetry.io/otel/log/logtest v0.0.0-20250616193322-2cce18995527 h1:K4gsUDjRKwV+Uw9lSEM7NdFqIfTfDlwv6zoGgffbtwk= @@ -1889,8 +1888,8 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f h1:ketMxHg+vWm3yccyYiq+uK8D3fRmna2Fcj+awpQp84s= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f/go.mod h1:tgPU4N2u9RByaTN3NC2p9xOzyFpte4jYwsIIRF7XlSc= -golang.org/x/arch v0.11.0 h1:KXV8WWKCXm6tRpLirl2szsO5j/oOODwZf4hATmGVNs4= -golang.org/x/arch v0.11.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.18.0 h1:WN9poc33zL4AzGxqf8VtpKUnGvMi8O9lhNyBMF/85qc= +golang.org/x/arch v0.18.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/modules/por_mock_ocr3plugin/.gitignore b/modules/por_mock_ocr3plugin/.gitignore new file mode 100644 index 00000000000..0614126f2f5 --- /dev/null +++ b/modules/por_mock_ocr3plugin/.gitignore @@ -0,0 +1,29 @@ +# If you prefer the allow list template instead of the deny list, see community template: +# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore +# +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + +# Go workspace file +go.work +go.work.sum + +# env file +.env + +# IDE specific files +.VSCodeCounter* +.DS_Store \ No newline at end of file diff --git a/modules/por_mock_ocr3plugin/README.md b/modules/por_mock_ocr3plugin/README.md new file mode 100644 index 00000000000..860cb509741 --- /dev/null +++ b/modules/por_mock_ocr3plugin/README.md @@ -0,0 +1,28 @@ +# PoR: an implementation of the OCR3 plugin that enables the safe decision (and distribution) of mintable amounts per chain for PoR. + +Background: +There are multiple tracked chains, e.g., `chains = [chain_A, chain_B, ...]` + +The EA, at each oracle, communicates (reads/interacts) with these chains, in an attempt to obtain the latest `blockNumber` for each chain, and calculate mintable information for a particular query (a query is a mapping of `chain -> blockNumber` pairs). + +The goal of this plugin is to generate honest reports based on new information from multiple EAs. +First it obtains information from the EAs on the latest status on the chains being tracked, namely the latest block number they are aware of. Based on this, the plugin settles on a query: a map of (chain -> safe block number) pairs (a block number is safe if is is guaranteed that chain has at least that many blocks). +Second, it queries the oracles for information (mintable amount + a block number) to report chain by chain. +These two steps are done in a pipelined fashion in every round of the plugin.s + +General plugin workflow: + +Every round of consensus has: +1. The leader +2. The followers (other oracles). + +Every round of consensus: + +1. The leader runs the `Query` method. +2. Followers (and leader) run the `Observation(...)` method. +3. The `ValidateObservation(query, observation)` method is run for each observation. +4. The `ObservationQuorum(observations)` method is (continuously) run on increasing sets of observations received by the leader (until it returns true) +5. The `Outcome(observations)` method is run on every oracle on a set of `observations` s.t. `ObservationQuorum(observations) = true` +6. The `Reports(...)` method is run on every oracle +7. The `ShouldAcceptAttestedReport` method is run for each attested report on every oracle when the report attestation is gathered. +8. The `ShouldTransmitAcceptedReport` method is run for each attested report, which is not filtered out by `ShouldAcceptAttestedReport` on every oracle, right before the oracle sends the report for transmission. \ No newline at end of file diff --git a/modules/por_mock_ocr3plugin/chainsupport/support.go b/modules/por_mock_ocr3plugin/chainsupport/support.go new file mode 100644 index 00000000000..12e178063e1 --- /dev/null +++ b/modules/por_mock_ocr3plugin/chainsupport/support.go @@ -0,0 +1,25 @@ +package chainsupport + +import ( + "fmt" + "log" + + "github.com/ethereum/go-ethereum/ethclient" +) + +func InfuraUrl(network string) string { + return fmt.Sprintf("wss://%s.infura.io/ws/v3/de4f73b9679f41219d9a0c386367be1b", network) +} + +var NetworkToChainID = map[string]int{ + "sepolia": 11155111, + "avalanche-fuji": 43113, +} + +func EthClient(rpcURL string) (client *ethclient.Client) { + client, err := ethclient.Dial(rpcURL) + if err != nil { + log.Fatal(err) + } + return client +} diff --git a/modules/por_mock_ocr3plugin/contractconfig/config.go b/modules/por_mock_ocr3plugin/contractconfig/config.go new file mode 100644 index 00000000000..d1a9791b190 --- /dev/null +++ b/modules/por_mock_ocr3plugin/contractconfig/config.go @@ -0,0 +1,95 @@ +package contractconfig + +import ( + "context" + "encoding/binary" + "encoding/json" + "time" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/por_mock_ocr3plugin/por" +) + +var N = 4 + +var configDigest types.ConfigDigest = types.ConfigDigest{0x13, 0x37} + +var contractConfig types.ContractConfig = mustMakeContractConfig() + +func mustMakeContractConfig() types.ContractConfig { + reportingPluginConfig, err := json.Marshal(por.PorOffchainConfig{ + MaxChains: 100, + }) + + if err != nil { + panic(err) + } + + signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, err := ocr3confighelper.ContractSetConfigArgsForTests( + 10*time.Second, + 10*time.Second, + 3*time.Second, + time.Second, + time.Second, + time.Second, + time.Second, + 10, + []int{31}, + OracleIdentities(N), + reportingPluginConfig, + nil, + time.Second, + time.Second, + time.Second, + time.Second, + 1, + nil, + ) + if err != nil { + panic(err) + } + + return types.ContractConfig{ + ConfigDigest: configDigest, + ConfigCount: 1, + Signers: signers, + Transmitters: transmitters, + F: f, + OnchainConfig: onchainConfig, + OffchainConfigVersion: offchainConfigVersion, + OffchainConfig: offchainConfig, + } +} + +var _ types.ContractConfigTracker = &FakeContractConfigTracker{} + +type FakeContractConfigTracker struct{} + +func (f *FakeContractConfigTracker) Notify() <-chan struct{} { + return nil +} + +func (f *FakeContractConfigTracker) LatestConfigDetails(ctx context.Context) (uint64, types.ConfigDigest, error) { + return 0, configDigest, nil +} + +func (f *FakeContractConfigTracker) LatestConfig(ctx context.Context, changedInBlock uint64) (types.ContractConfig, error) { + return contractConfig, nil +} + +func (f *FakeContractConfigTracker) LatestBlockHeight(ctx context.Context) (uint64, error) { + return 0, nil +} + +var _ types.OffchainConfigDigester = &FakeOffchainConfigDigester{} + +type FakeOffchainConfigDigester struct{} + +func (f *FakeOffchainConfigDigester) ConfigDigest(ctx context.Context, config types.ContractConfig) (types.ConfigDigest, error) { + return configDigest, nil +} + +func (f *FakeOffchainConfigDigester) ConfigDigestPrefix(ctx context.Context) (types.ConfigDigestPrefix, error) { + return types.ConfigDigestPrefix(binary.BigEndian.Uint16(configDigest[0:2])), nil +} diff --git a/modules/por_mock_ocr3plugin/contractconfig/identity.go b/modules/por_mock_ocr3plugin/contractconfig/identity.go new file mode 100644 index 00000000000..4161af10be5 --- /dev/null +++ b/modules/por_mock_ocr3plugin/contractconfig/identity.go @@ -0,0 +1,143 @@ +package contractconfig + +import ( + "crypto/ecdsa" + "crypto/ed25519" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/crypto/secp256k1" + "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + ragetypes "github.com/smartcontractkit/libocr/ragep2p/types" + "github.com/smartcontractkit/por_mock_ocr3plugin/myname" + "golang.org/x/crypto/curve25519" +) + +func P2pPrivateKey(i int) ed25519.PrivateKey { + return ed25519.NewKeyFromSeed([]byte(fmt.Sprintf("MontrealMontrealMontreal%8d", i))) +} + +func OffchainPrivateKey(i int) ed25519.PrivateKey { + return ed25519.NewKeyFromSeed([]byte(fmt.Sprintf("CanadaCanadaCanadaCanada%8d", i))) +} + +func ConfigEncryptionPrivateKey(i int) [curve25519.ScalarSize]byte { + var priv [curve25519.ScalarSize]byte + copy(priv[:], []byte(fmt.Sprintf("Bonjour!Bonjour!Bonjour!%8d", i))) + return priv +} + +func OnchainPrivateKey(i int) ecdsa.PrivateKey { + secret := new(big.Int) + secret.SetBytes([]byte(fmt.Sprintf("AwesomAwesomAwesomAwesom%8d", i))) + + x, y := secp256k1.S256().ScalarBaseMult(secret.Bytes()) + return ecdsa.PrivateKey{ + PublicKey: ecdsa.PublicKey{ + Curve: secp256k1.S256(), + X: x, Y: y, + }, + D: secret, + } +} + +func TransmitterPrivateKey(i int) ecdsa.PrivateKey { + secret := new(big.Int) + secret.SetBytes(crypto.Keccak256([]byte(fmt.Sprintf("Poutine!Poutine!Poutine!%s%8d", myname.Name, i)))) + + x, y := secp256k1.S256().ScalarBaseMult(secret.Bytes()) + return ecdsa.PrivateKey{ + PublicKey: ecdsa.PublicKey{ + Curve: secp256k1.S256(), + X: x, Y: y, + }, + D: secret, + } +} + +func TransmitterAddress(i int) common.Address { + return crypto.PubkeyToAddress(TransmitterPrivateKey(i).PublicKey) +} + +func GodPrivateKey() ecdsa.PrivateKey { + secret := new(big.Int) + secret.SetBytes(crypto.Keccak256([]byte("lakeshfk hadksjfhk hkjhsabdfkh bakshjdbf kahbdskf bo73yo47y23"))) + + x, y := secp256k1.S256().ScalarBaseMult(secret.Bytes()) + return ecdsa.PrivateKey{ + PublicKey: ecdsa.PublicKey{ + Curve: secp256k1.S256(), + X: x, Y: y, + }, + D: secret, + } +} + +func GodAddress() common.Address { + return crypto.PubkeyToAddress(GodPrivateKey().PublicKey) +} + +func DestinationPrivateKey() ecdsa.PrivateKey { + secret := new(big.Int) + secret.SetBytes(crypto.Keccak256([]byte(fmt.Sprintf("destination address for %s", myname.Name)))) + + x, y := secp256k1.S256().ScalarBaseMult(secret.Bytes()) + return ecdsa.PrivateKey{ + PublicKey: ecdsa.PublicKey{ + Curve: secp256k1.S256(), + X: x, Y: y, + }, + D: secret, + } +} + +func DestinationAddress() common.Address { + return crypto.PubkeyToAddress(DestinationPrivateKey().PublicKey) +} + +func offchainPublicKeyKeyFromPrivateKey(priv ed25519.PrivateKey) types.OffchainPublicKey { + var result types.OffchainPublicKey + copy(result[:], priv.Public().(ed25519.PublicKey)) + return result +} + +func peerIDFromPrivateKey(priv ed25519.PrivateKey) string { + peerID, err := ragetypes.PeerIDFromPrivateKey(priv) + if err != nil { + panic(err) + } + return peerID.String() +} + +func accountFromPrivateKey(priv ecdsa.PrivateKey) types.Account { + return types.Account(crypto.PubkeyToAddress(priv.PublicKey).Hex()) +} + +func OracleIdentity(i int) confighelper.OracleIdentityExtra { + var configEncryptionPublicKey types.ConfigEncryptionPublicKey + { + scalar := ConfigEncryptionPrivateKey(i) + curve25519.ScalarBaseMult((*[32]byte)(&configEncryptionPublicKey), &scalar) + } + + return confighelper.OracleIdentityExtra{ + OracleIdentity: confighelper.OracleIdentity{ + OffchainPublicKey: offchainPublicKeyKeyFromPrivateKey(OffchainPrivateKey(i)), + OnchainPublicKey: crypto.PubkeyToAddress(OnchainPrivateKey(i).PublicKey).Bytes(), + PeerID: peerIDFromPrivateKey(P2pPrivateKey(i)), + TransmitAccount: accountFromPrivateKey(TransmitterPrivateKey(i)), + }, + ConfigEncryptionPublicKey: configEncryptionPublicKey, + } +} + +func OracleIdentities(n int) []confighelper.OracleIdentityExtra { + var result []confighelper.OracleIdentityExtra + for i := 0; i < n; i++ { + result = append(result, OracleIdentity(i)) + } + return result +} diff --git a/modules/por_mock_ocr3plugin/db/db.go b/modules/por_mock_ocr3plugin/db/db.go new file mode 100644 index 00000000000..98e9f03574f --- /dev/null +++ b/modules/por_mock_ocr3plugin/db/db.go @@ -0,0 +1,71 @@ +package db + +import ( + "context" + "time" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" +) + +var _ ocr3types.Database = &FakeDatabase{} + +type FakeDatabase struct { +} + +func NewFakeFatabase() *FakeDatabase { + return &FakeDatabase{} +} + +// In case the key is not found, nil should be returned. +func (db *FakeDatabase) ReadProtocolState(ctx context.Context, configDigest types.ConfigDigest, key string) ([]byte, error) { + return nil, nil +} + +// Writing with a nil value is the same as deleting. +func (db *FakeDatabase) WriteProtocolState(ctx context.Context, configDigest types.ConfigDigest, key string, value []byte) error { + return nil +} + +// ReadConfig returns the stored configuration (or nil if not set). +func (db *FakeDatabase) ReadConfig(ctx context.Context) (*types.ContractConfig, error) { + return nil, nil +} + +// WriteConfig stores the given configuration. +func (db *FakeDatabase) WriteConfig(ctx context.Context, config types.ContractConfig) error { + return nil +} + +// ReadState retrieves the persistent state for a given configuration digest. +// Returns nil if no state exists. +func (db *FakeDatabase) ReadState(ctx context.Context, configDigest types.ConfigDigest) (*types.PersistentState, error) { + return nil, nil +} + +// WriteState stores the persistent state for the given configuration digest. +func (db *FakeDatabase) WriteState(ctx context.Context, configDigest types.ConfigDigest, state types.PersistentState) error { + return nil +} + +// StorePendingTransmission stores a pending transmission associated with the +// ReportTimestamp’s configuration digest. +func (db *FakeDatabase) StorePendingTransmission(ctx context.Context, ts types.ReportTimestamp, pt types.PendingTransmission) error { + return nil +} + +// PendingTransmissionsWithConfigDigest returns all pending transmissions for a given configDigest. +func (db *FakeDatabase) PendingTransmissionsWithConfigDigest(ctx context.Context, configDigest types.ConfigDigest) (map[types.ReportTimestamp]types.PendingTransmission, error) { + return nil, nil +} + +// DeletePendingTransmission removes the pending transmission identified by the ReportTimestamp. +func (db *FakeDatabase) DeletePendingTransmission(ctx context.Context, ts types.ReportTimestamp) error { + return nil +} + +// DeletePendingTransmissionsOlderThan removes any pending transmissions whose +// associated transmission time is older than the specified time. +func (db *FakeDatabase) DeletePendingTransmissionsOlderThan(ctx context.Context, t time.Time) error { + return nil +} diff --git a/modules/por_mock_ocr3plugin/funder/main.go b/modules/por_mock_ocr3plugin/funder/main.go new file mode 100644 index 00000000000..19065429eac --- /dev/null +++ b/modules/por_mock_ocr3plugin/funder/main.go @@ -0,0 +1,75 @@ +package main + +import ( + "context" + "fmt" + "math/big" + + "github.com/smartcontractkit/por_mock_ocr3plugin/chainsupport" + "github.com/smartcontractkit/por_mock_ocr3plugin/contractconfig" + "github.com/smartcontractkit/por_mock_ocr3plugin/myname" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + ethtypes "github.com/ethereum/go-ethereum/core/types" +) + +const network = "sepolia" + +func main() { + if err := fund(); err != nil { + panic(err) + } + fmt.Printf("https://sepolia.etherscan.io/address/%s\n", contractconfig.DestinationAddress().Hex()) + fmt.Println("My destination address is ", contractconfig.DestinationAddress().Hex()) +} + +func fund() error { + client := chainsupport.EthClient(chainsupport.InfuraUrl(network)) + ctx := context.Background() + + deployerPrivateKey := contractconfig.GodPrivateKey() + opts, err := bind.NewKeyedTransactorWithChainID( + &deployerPrivateKey, + big.NewInt(int64(chainsupport.NetworkToChainID[network])), + ) + fmt.Printf("Funder address: %s\n", opts.From.Hex()) + if err != nil { + panic(fmt.Sprintf("bind.NewKeyedTransactorWithChainID: %v", err)) + } + + nonce, err := client.PendingNonceAt(ctx, opts.From) + if err != nil { + return err + } + + to := contractconfig.TransmitterAddress(0) + + fmt.Println("Name of the developer whose account we are funding:", myname.Name) + fmt.Println("Funded OCR Transmitter Address", to.Hex()) + + tx := ethtypes.NewTx(ðtypes.DynamicFeeTx{ + ChainID: big.NewInt(int64(chainsupport.NetworkToChainID[network])), + Nonce: nonce, + GasTipCap: big.NewInt(1e9), + GasFeeCap: big.NewInt(100e9), + Gas: 100_000, + To: &to, + Value: big.NewInt(5e16), + Data: nil, + AccessList: nil, + + V: nil, R: nil, S: nil, + }) + + signedTx, err := opts.Signer(opts.From, tx) + if err != nil { + return err + } + + err = client.SendTransaction(ctx, signedTx) + if err != nil { + return err + } + + return nil +} diff --git a/modules/por_mock_ocr3plugin/go.mod b/modules/por_mock_ocr3plugin/go.mod new file mode 100644 index 00000000000..661a2a0325e --- /dev/null +++ b/modules/por_mock_ocr3plugin/go.mod @@ -0,0 +1,51 @@ +module github.com/smartcontractkit/por_mock_ocr3plugin + +go 1.23.2 + +require ( + github.com/ethereum/go-ethereum v1.14.11 + github.com/prometheus/client_golang v1.14.0 + github.com/sirupsen/logrus v1.9.3 + github.com/smartcontractkit/libocr v0.0.0-20250220133800-f3b940c4f298 + golang.org/x/crypto v0.40.0 +) + +require ( + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/StackExchange/wmi v1.2.1 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/bits-and-blooms/bitset v1.15.0 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect + github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/consensys/bavard v0.1.22 // indirect + github.com/consensys/gnark-crypto v0.13.0 // indirect + github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect + github.com/crate-crypto/go-kzg-4844 v1.1.0 // indirect + github.com/deckarep/golang-set/v2 v2.6.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect + github.com/ethereum/c-kzg-4844 v1.0.3 // indirect + github.com/ethereum/go-verkle v0.2.2 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/websocket v1.4.2 // indirect + github.com/holiman/uint256 v1.3.1 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mmcloughlin/addchain v0.4.0 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.39.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect + github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect + github.com/supranational/blst v0.3.13 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect + golang.org/x/sync v0.9.0 // indirect + golang.org/x/sys v0.34.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect + rsc.io/tmplfunc v0.0.3 // indirect +) diff --git a/modules/por_mock_ocr3plugin/go.sum b/modules/por_mock_ocr3plugin/go.sum new file mode 100644 index 00000000000..b47fc26d7ad --- /dev/null +++ b/modules/por_mock_ocr3plugin/go.sum @@ -0,0 +1,205 @@ +github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= +github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= +github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= +github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= +github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bits-and-blooms/bitset v1.15.0 h1:DiCRMscZsGyYePE9AR3sVhKqUXCt5IZvkX5AfAc5xLQ= +github.com/bits-and-blooms/bitset v1.15.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= +github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= +github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= +github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v1.1.2 h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA= +github.com/cockroachdb/pebble v1.1.2/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= +github.com/consensys/bavard v0.1.22 h1:Uw2CGvbXSZWhqK59X0VG/zOjpTFuOMcPLStrp1ihI0A= +github.com/consensys/bavard v0.1.22/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs= +github.com/consensys/gnark-crypto v0.13.0 h1:VPULb/v6bbYELAPTDFINEVaMTTybV5GLxDdcjnS+4oc= +github.com/consensys/gnark-crypto v0.13.0/go.mod h1:wKqwsieaKPThcFkHe0d0zMsbHEUWFmZcG7KBCse210o= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg= +github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM= +github.com/crate-crypto/go-kzg-4844 v1.1.0 h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4= +github.com/crate-crypto/go-kzg-4844 v1.1.0/go.mod h1:JolLjpSff1tCCJKaJx4psrlEdlXuJEC996PL3tTAFks= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= +github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/ethereum/c-kzg-4844 v1.0.3 h1:IEnbOHwjixW2cTvKRUlAAUOeleV7nNM/umJR+qy4WDs= +github.com/ethereum/c-kzg-4844 v1.0.3/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= +github.com/ethereum/go-ethereum v1.14.11 h1:8nFDCUUE67rPc6AKxFj7JKaOa2W/W1Rse3oS6LvvxEY= +github.com/ethereum/go-ethereum v1.14.11/go.mod h1:+l/fr42Mma+xBnhefL/+z11/hcmJ2egl+ScIVPjhc7E= +github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8= +github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= +github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs= +github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= +github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a h1:dHCfT5W7gghzPtfsW488uPmEOm85wewI+ypUwibyTdU= +github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= +github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= +github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= +github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= +github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= +github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +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/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= +github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk= +github.com/supranational/blst v0.3.13/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= +github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= +github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= +golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= +golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= +golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= +golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/modules/por_mock_ocr3plugin/keyring/offchain.go b/modules/por_mock_ocr3plugin/keyring/offchain.go new file mode 100644 index 00000000000..23c468e75f7 --- /dev/null +++ b/modules/por_mock_ocr3plugin/keyring/offchain.go @@ -0,0 +1,56 @@ +package keyring + +import ( + "crypto/ed25519" + + "github.com/smartcontractkit/libocr/offchainreporting2/types" + "golang.org/x/crypto/curve25519" +) + +// DummyOffchainKeyring is not intended to be used in production. +type DummyOffchainKeyring struct { + OffchainPrivateKey ed25519.PrivateKey + ConfigEncryptionPrivateKey [curve25519.ScalarSize]byte +} + +var _ types.OffchainKeyring = &DummyOffchainKeyring{} + +func (ring *DummyOffchainKeyring) OffchainSign(msg []byte) (signature []byte, err error) { + sig := ed25519.Sign(ring.OffchainPrivateKey, msg) + return sig, nil +} + +func (ring *DummyOffchainKeyring) ConfigDiffieHellman( + point [curve25519.PointSize]byte, +) ( + sharedPoint [curve25519.PointSize]byte, + err error, +) { + p, err := curve25519.X25519(ring.ConfigEncryptionPrivateKey[:], point[:]) + if err != nil { + return [curve25519.PointSize]byte{}, err + } + copy(sharedPoint[:], p) + return sharedPoint, nil +} + +func (ring *DummyOffchainKeyring) OffchainPublicKey() types.OffchainPublicKey { + var ocpk types.OffchainPublicKey + pubKey := ring.OffchainPrivateKey.Public().(ed25519.PublicKey) + if len(ocpk) != len(pubKey) { + // assertion + panic("OffchainPublicKey length mismatch") + } + copy(ocpk[:], pubKey) + return ocpk +} + +func (ring *DummyOffchainKeyring) ConfigEncryptionPublicKey() types.ConfigEncryptionPublicKey { + rv, err := curve25519.X25519(ring.ConfigEncryptionPrivateKey[:], curve25519.Basepoint) + if err != nil { + panic("failure while computing public key: " + err.Error()) + } + var rvFixed [curve25519.PointSize]byte + copy(rvFixed[:], rv) + return rvFixed +} diff --git a/modules/por_mock_ocr3plugin/keyring/onchain.go b/modules/por_mock_ocr3plugin/keyring/onchain.go new file mode 100644 index 00000000000..ab98441062b --- /dev/null +++ b/modules/por_mock_ocr3plugin/keyring/onchain.go @@ -0,0 +1,53 @@ +package keyring + +import ( + "bytes" + "crypto/ecdsa" + "encoding/binary" + + "github.com/ethereum/go-ethereum/crypto" + "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + "github.com/smartcontractkit/por_mock_ocr3plugin/por" +) + +// DummyEVMOnchainKeyring is not intended to be used in production. +type DummyEVMOnchainKeyring struct { + PrivateKey ecdsa.PrivateKey +} + +var _ ocr3types.OnchainKeyring[por.ChainSelector] = &DummyEVMOnchainKeyring{} + +func (ring *DummyEVMOnchainKeyring) MaxSignatureLength() int { + return 65 +} + +func (ring *DummyEVMOnchainKeyring) Sign(configDigest types.ConfigDigest, seqNr uint64, reportWithInfo ocr3types.ReportWithInfo[por.ChainSelector]) (signature []byte, err error) { + sigData := crypto.Keccak256(reportWithInfo.Report) + sigData = append(sigData, configDigest[:]...) + sigData = binary.BigEndian.AppendUint64(sigData, seqNr) + return crypto.Sign(crypto.Keccak256(sigData), &ring.PrivateKey) +} + +func (ring *DummyEVMOnchainKeyring) PublicKey() types.OnchainPublicKey { + address := crypto.PubkeyToAddress(ring.PrivateKey.PublicKey) + return address[:] +} + +func (ring *DummyEVMOnchainKeyring) Verify(pubkey types.OnchainPublicKey, configDigest types.ConfigDigest, seqNr uint64, reportWithInfo ocr3types.ReportWithInfo[por.ChainSelector], sig []byte) bool { + sigData := crypto.Keccak256(reportWithInfo.Report) + sigData = append(sigData, configDigest[:]...) + sigData = binary.BigEndian.AppendUint64(sigData, seqNr) + hash := crypto.Keccak256(sigData) + authorPubkey, err := crypto.SigToPub(hash, sig) + + // fmt.Printf("author pubkey %x\n", authorPubkey) + if err != nil { + // fmt.Printf("error while doing SigToPub: %v\n", err) + return false + } + authorAddress := crypto.PubkeyToAddress(*authorPubkey) + // fmt.Printf("author address %x\n", authorAddress) + // fmt.Printf("expected address %x\n", common.BytesToAddress(pubkey)) + return bytes.Equal(pubkey[:], authorAddress[:]) +} diff --git a/modules/por_mock_ocr3plugin/logger/logrus.go b/modules/por_mock_ocr3plugin/logger/logrus.go new file mode 100644 index 00000000000..486656455de --- /dev/null +++ b/modules/por_mock_ocr3plugin/logger/logrus.go @@ -0,0 +1,42 @@ +package logger + +import ( + "github.com/sirupsen/logrus" + "github.com/smartcontractkit/libocr/commontypes" +) + +type Logger struct { + logger *logrus.Logger +} + +func NewLogger() *Logger { + logger := logrus.New() + logger.SetLevel(logrus.TraceLevel) + return &Logger{ + logger, + } +} + +func (l *Logger) Trace(msg string, fields commontypes.LogFields) { + l.logger.WithFields(logrus.Fields(fields)).Trace(msg) +} + +func (l *Logger) Debug(msg string, fields commontypes.LogFields) { + l.logger.WithFields(logrus.Fields(fields)).Debug(msg) +} + +func (l *Logger) Info(msg string, fields commontypes.LogFields) { + l.logger.WithFields(logrus.Fields(fields)).Info(msg) +} + +func (l *Logger) Warn(msg string, fields commontypes.LogFields) { + l.logger.WithFields(logrus.Fields(fields)).Warn(msg) +} + +func (l *Logger) Error(msg string, fields commontypes.LogFields) { + l.logger.WithFields(logrus.Fields(fields)).Error(msg) +} + +func (l *Logger) Critical(msg string, fields commontypes.LogFields) { + l.logger.WithFields(logrus.Fields(fields)).Error("CRITICAL: " + msg) +} diff --git a/modules/por_mock_ocr3plugin/main.go b/modules/por_mock_ocr3plugin/main.go new file mode 100644 index 00000000000..33c82dd98e6 --- /dev/null +++ b/modules/por_mock_ocr3plugin/main.go @@ -0,0 +1,168 @@ +package main + +import ( + "fmt" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/ethclient" + "github.com/prometheus/client_golang/prometheus" + "github.com/smartcontractkit/libocr/commontypes" + "github.com/smartcontractkit/libocr/networking" + "github.com/smartcontractkit/libocr/offchainreporting2plus" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/por_mock_ocr3plugin/contractconfig" + "github.com/smartcontractkit/por_mock_ocr3plugin/db" + "github.com/smartcontractkit/por_mock_ocr3plugin/keyring" + "github.com/smartcontractkit/por_mock_ocr3plugin/logger" + por "github.com/smartcontractkit/por_mock_ocr3plugin/por" + "github.com/smartcontractkit/por_mock_ocr3plugin/transmitter" +) + +const basePort int = 1337 + +const bootstrapperIndex int = 999 + +const chainID = 11155111 //sepolia + +// var destination common.Address = common.HexToAddress("0xc0ffeec0ffeec0ffeec0ffeec0ffeec0ffeec0ff") + +var localConfig types.LocalConfig = types.LocalConfig{ + BlockchainTimeout: 10 * time.Second, + ContractConfigConfirmations: 1, + SkipContractConfigConfirmations: true, + ContractConfigTrackerPollInterval: 10 * time.Second, + ContractConfigLoadTimeout: 10 * time.Second, + ContractTransmitterTransmitTimeout: 10 * time.Second, + DatabaseTimeout: 10 * time.Second, + DefaultMaxDurationInitialization: 10 * time.Second, +} + +const url string = "wss://sepolia.infura.io/ws/v3/de4f73b9679f41219d9a0c386367be1b" + +func ethClient(rpcURL string) (client *ethclient.Client) { + // client, err := ethclient.Dial(rpcURL) + // if err != nil { + // log.Fatal(err) + // } + return nil +} + +func bootstrapperConfig() networking.PeerConfig { + return networking.PeerConfig{ + PrivKey: contractconfig.P2pPrivateKey(bootstrapperIndex), + Logger: logger.NewLogger(), + V2ListenAddresses: []string{fmt.Sprintf("localhost:%d", basePort)}, + V2AnnounceAddresses: []string{fmt.Sprintf("127.0.0.1:%d", basePort)}, + V2DeltaReconcile: 5 * time.Second, + V2DeltaDial: 5 * time.Second, + V2DiscovererDatabase: nil, + V2EndpointConfig: networking.EndpointConfigV2{ + IncomingMessageBufferSize: 5, + OutgoingMessageBufferSize: 5, + }, + MetricsRegisterer: prometheus.DefaultRegisterer, + LatencyMetricsServiceConfigs: nil, + } +} + +func peerConfig(i int) networking.PeerConfig { + return networking.PeerConfig{ + PrivKey: contractconfig.P2pPrivateKey(i), + Logger: logger.NewLogger(), + V2ListenAddresses: []string{fmt.Sprintf("localhost:%d", basePort+1+i)}, + V2AnnounceAddresses: []string{fmt.Sprintf("127.0.0.1:%d", basePort+1+i)}, + V2DeltaReconcile: 5 * time.Second, + V2DeltaDial: 5 * time.Second, + V2DiscovererDatabase: nil, + V2EndpointConfig: networking.EndpointConfigV2{ + IncomingMessageBufferSize: 5, + OutgoingMessageBufferSize: 5, + }, + MetricsRegisterer: prometheus.DefaultRegisterer, + LatencyMetricsServiceConfigs: nil, + } +} + +func oracleArgs(i int, fac types.BinaryNetworkEndpointFactory) offchainreporting2plus.OCR3OracleArgs[por.ChainSelector] { + logger := logger.NewLogger() + return offchainreporting2plus.OCR3OracleArgs[por.ChainSelector]{ + BinaryNetworkEndpointFactory: fac, + V2Bootstrappers: []commontypes.BootstrapperLocator{ + { + PeerID: contractconfig.OracleIdentity(bootstrapperIndex).PeerID, + Addrs: []string{fmt.Sprintf("localhost:%d", basePort)}, + }, + }, + ContractConfigTracker: &contractconfig.FakeContractConfigTracker{}, + ContractTransmitter: transmitter.NewBasicContractTransmitter( + ethClient(url), + big.NewInt(chainID), + contractconfig.DestinationAddress(), + contractconfig.TransmitterPrivateKey(i), + ), + Database: db.NewFakeFatabase(), + LocalConfig: localConfig, + Logger: logger, + MonitoringEndpoint: nil, + MetricsRegisterer: prometheus.DefaultRegisterer, + OffchainConfigDigester: &contractconfig.FakeOffchainConfigDigester{}, + OffchainKeyring: &keyring.DummyOffchainKeyring{ + OffchainPrivateKey: contractconfig.OffchainPrivateKey(i), + ConfigEncryptionPrivateKey: contractconfig.ConfigEncryptionPrivateKey(i), + }, + OnchainKeyring: &keyring.DummyEVMOnchainKeyring{PrivateKey: contractconfig.OnchainPrivateKey(i)}, + ReportingPluginFactory: &por.PorReportingPluginFactory{Logger: logger}, + } +} + +func main() { + bootstrapperConfig := bootstrapperConfig() + bootstrapperPeer, err := networking.NewPeer(bootstrapperConfig) + if err != nil { + panic(err) + } + defer bootstrapperPeer.Close() + + bootstrapper, err := offchainreporting2plus.NewBootstrapper(offchainreporting2plus.BootstrapperArgs{ + BootstrapperFactory: bootstrapperPeer.OCR2BootstrapperFactory(), + V2Bootstrappers: []commontypes.BootstrapperLocator{}, + ContractConfigTracker: &contractconfig.FakeContractConfigTracker{}, + Database: db.NewFakeFatabase(), + LocalConfig: localConfig, + Logger: logger.NewLogger(), + MonitoringEndpoint: nil, + OffchainConfigDigester: &contractconfig.FakeOffchainConfigDigester{}, + }) + if err != nil { + panic(err) + } + if err := bootstrapper.Start(); err != nil { + panic(err) + } + defer bootstrapper.Close() + + oargss := []offchainreporting2plus.OCR3OracleArgs[por.ChainSelector]{} + for i := 0; i < 4; i++ { + peerConfig := peerConfig(i) + peer, err := networking.NewPeer(peerConfig) + if err != nil { + panic(err) + } + defer peer.Close() + + oargss = append(oargss, oracleArgs(i, peer.OCR2BinaryNetworkEndpointFactory())) + oracle, err := offchainreporting2plus.NewOracle(oargss[i]) + if err != nil { + panic(err) + } + if err := oracle.Start(); err != nil { + panic(err) + } + defer oracle.Close() + } + select {} + // oargs := oracleArgs(2, peer.OCR2BinaryNetworkEndpointFactory()) + // <-time.After(10 * time.Second) + // _ = oargs +} diff --git a/modules/por_mock_ocr3plugin/myname/name.go b/modules/por_mock_ocr3plugin/myname/name.go new file mode 100644 index 00000000000..17726f95cc5 --- /dev/null +++ b/modules/por_mock_ocr3plugin/myname/name.go @@ -0,0 +1,3 @@ +package myname + +const Name = "Test Name" // TODO: your name here diff --git a/modules/por_mock_ocr3plugin/por/contract_reader_interface.go b/modules/por_mock_ocr3plugin/por/contract_reader_interface.go new file mode 100644 index 00000000000..8fedf87e366 --- /dev/null +++ b/modules/por_mock_ocr3plugin/por/contract_reader_interface.go @@ -0,0 +1,17 @@ +package por + +import ( + "context" +) + +type ContractReader interface { + // GetLatestTransmittedReportDetails retrieves the latest (even unfinalized) transmission details from the contract on-chain. + // (Some of the returned values, such as latestTimestamp, are not used in the current implementation but are included for future extensibility.) + GetLatestTransmittedReportDetails( + ctx context.Context, + chain ChainSelector, + ) ( + details TransmittedReportDetails, + err error, + ) +} diff --git a/modules/por_mock_ocr3plugin/por/external_adapter_interface.go b/modules/por_mock_ocr3plugin/por/external_adapter_interface.go new file mode 100644 index 00000000000..1d241f0c340 --- /dev/null +++ b/modules/por_mock_ocr3plugin/por/external_adapter_interface.go @@ -0,0 +1,50 @@ +package por + +import ( + "context" +) + +// A unique identifier for a chain, e.g., Chain.Selector from the chain-selectors package +// See https://github.com/smartcontractkit/chain-selectors +type ChainSelector uint64 + +// The External Adapter (EA) is the point of contact with PoR related events. +// An EA is expected to correspond to a single token, and track its corresponding chains. +// Its main purpose is to calculate the minting allowance per chain based on +// (1) on-chain (pre-)minting requests, +// (2) global supply across all chains, and +// (3) off-chain reserve information +// +// All methods are expected to: +// - be deterministic (given a *fixed* state of the EA) & thread-safe +// - finish within a reasonable time frame (max 500 ms) +// - return information pertaining to what is (expected to be) the *finalized* state of the chain(s). +// Determining what is considered to be the finalized state is up to the adapter implementation +type ExternalAdapter interface { + // GetPayload returns the payload (ExternalAdapterPayload) for the queried blocks. + // + // The payload contains: + // (1) the per-chain mintable information (BlockMintablePair) computed given the query (`blocks`) and the latest reserve information, + // (2) the latest reserve information (ReserveInfo), + // (3) the latest blocks for each chain (LatestBlocks). + // + // Mintables is either: + // - a map with the mintable amount for each (chain, block) in `blocks`, or + // - `nil` if the information for a chain or its block is not available. (If the information for a block is not available, + // the correct mintable amount cannot be determined.) + // + // ReserveInfo is the same used to calculate the mintable amounts. + // + // LatestBlocks are the latest blocks for each chain. Specifically: + // Specifically, given the on-chain events to PoR (namely, premints, mints, and burns): + // - LatestBlocks includes, per-chain, the latest blockNumber known by the EA for that chain. + // - LatestBlocks is monotonically non-decreasing in every chain across repeated calls to GetPayload. + // - If the `blocks` argument contains a chain which the EA does not track (yet), LatestBlocks should + // include that chain with block number of 0. + // + // Notes on usage: + // - The plugin will call GetPayload periodically and compare the new generated mintables with the previous ones to determine + // if a new report should be generated. By avoiding changing the block numbers when there are no new PoR-related events, + // the plugin can avoid generating unnecessary reports. + GetPayload(ctx context.Context, blocks Blocks) (ExternalAdapterPayload, error) +} diff --git a/modules/por_mock_ocr3plugin/por/mock_contract_reader.go b/modules/por_mock_ocr3plugin/por/mock_contract_reader.go new file mode 100644 index 00000000000..29e7b6aba06 --- /dev/null +++ b/modules/por_mock_ocr3plugin/por/mock_contract_reader.go @@ -0,0 +1,23 @@ +package por + +import ( + "context" + "time" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" +) + +// A mock implementation of the ContractReader interface for testing purposes. +type MockContractReader struct { + digest types.ConfigDigest +} + +// NewMockContractReader creates a new instance of MockContractReader. +func NewMockContractReader(configDigest types.ConfigDigest) *MockContractReader { + return &MockContractReader{configDigest} +} + +// GetLatestTransmittedReportDetails simulates the retrieval of the latest transmission details from the contract on-chain. +func (m *MockContractReader) GetLatestTransmittedReportDetails(ctx context.Context, chainId ChainSelector) (TransmittedReportDetails, error) { + return TransmittedReportDetails{m.digest, 0, time.Now()}, nil +} diff --git a/modules/por_mock_ocr3plugin/por/mock_external_adapter.go b/modules/por_mock_ocr3plugin/por/mock_external_adapter.go new file mode 100644 index 00000000000..765dada26af --- /dev/null +++ b/modules/por_mock_ocr3plugin/por/mock_external_adapter.go @@ -0,0 +1,85 @@ +package por + +import ( + "context" + "math/big" + "math/rand" + "time" +) + +// A mock implementation of the ExternalAdapter interface for testing purposes. +type MockExternalAdapterImpl struct { + latestBlocks Blocks + chains []ChainSelector + counter int +} + +func NewMockExternalAdapterImpl() *MockExternalAdapterImpl { + chains := []ChainSelector{ + 8953668971247136127, // "bitcoin-testnet-rootstock" + 729797994450396300, // "telos-evm-testnet" + } + + latestBlocks := make(Blocks) + for _, chain := range chains { + // Initialize the latest block for each chain to a random number between 1 and 100. + latestBlocks[chain] = 0 + } + return &MockExternalAdapterImpl{ + latestBlocks, + chains, + 0, + } +} + +func (m *MockExternalAdapterImpl) GetChains(ctx context.Context) ([]ChainSelector, error) { + return m.chains, nil +} + +func (m *MockExternalAdapterImpl) GetPayload(ctx context.Context, blocks Blocks) (ExternalAdapterPayload, error) { + if m.counter == 10 { + newSelector := ChainSelector(555555555555555555) + m.chains = append(m.chains, newSelector) // Example of adding a new chain dynamically. + m.latestBlocks[newSelector] = BlockNumber(rand.Intn(10) + 1) // Assign a random block number to the new chain. + } + m.counter++ + + mintables := make(Mintables) + + sameChains := (len(blocks) == len(m.chains)) + for _, chain := range m.chains { + if _, exists := blocks[chain]; !exists { + sameChains = false + break + } + } + + if !sameChains { + mintables = nil // If the blocks do not match the chains, return nil mintables. + } else { + // Simulate mintable amounts by generating deterministic values based on the block number. + for chain, block := range blocks { + mintables[chain] = BlockMintablePair{ + Block: block, + Mintable: big.NewInt(int64(block)), // Example: mintable amount is the block number itself. + } + } + } + + reserveInfo := ReserveInfo{ + ReserveAmount: big.NewInt(1000), // Example reserve amount. + Timestamp: time.Now(), // Current time as the reserve timestamp. + } + + for chain, block := range m.latestBlocks { + m.latestBlocks[chain] = block + 1 + BlockNumber(rand.Int()%2) + } + + payload := ExternalAdapterPayload{ + Mintables: mintables, + ReserveInfo: reserveInfo, + LatestBlocks: m.latestBlocks, + } + + return payload, nil +} diff --git a/modules/por_mock_ocr3plugin/por/mock_report_marshaller.go b/modules/por_mock_ocr3plugin/por/mock_report_marshaller.go new file mode 100644 index 00000000000..2f2c8cde24b --- /dev/null +++ b/modules/por_mock_ocr3plugin/por/mock_report_marshaller.go @@ -0,0 +1,34 @@ +package por + +import ( + "context" + "encoding/json" +) + +type MockReportMarshaler struct { + maxReportSize int +} + +// NewMockReportMarshaler creates a new instance of MockReportMarshaler with the specified maximum report size. +func NewMockReportMarshaler() *MockReportMarshaler { + return &MockReportMarshaler{1024} +} + +// Serialize simulates the serialization of a PorReport into bytes. +func (m *MockReportMarshaler) Serialize(ctx context.Context, chain ChainSelector, report PorReport) ([]byte, error) { + // Simulate a serialization process by encoding the report into JSON. + // In a real implementation, this would involve more complex logic to handle the report's structure and the target chain. + // E.g., using an encoding logic compatible with the DataFeedsCache contract in Chainlink. + // (See https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/data-feeds/DataFeedsCache.sol#L53) + encodedReport, err := json.Marshal(report) + if err != nil { + return nil, err + } + + return encodedReport, nil +} + +func (m *MockReportMarshaler) MaxReportSize(ctx context.Context) int { + // Return the maximum report size set during initialization. + return m.maxReportSize +} diff --git a/modules/por_mock_ocr3plugin/por/porplugin_simple.go b/modules/por_mock_ocr3plugin/por/porplugin_simple.go new file mode 100644 index 00000000000..3dba0b0175e --- /dev/null +++ b/modules/por_mock_ocr3plugin/por/porplugin_simple.go @@ -0,0 +1,624 @@ +package por + +import ( + "context" + "encoding/json" + "fmt" + + "slices" + + "github.com/smartcontractkit/libocr/commontypes" + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/libocr/quorumhelper" +) + +type PorReportingPluginFactory struct { + Logger commontypes.Logger + ExternalAdapter ExternalAdapter + ContractReader ContractReader + ReportMarshaler ReportMarshaler +} + +var _ ocr3types.ReportingPluginFactory[ChainSelector] = &PorReportingPluginFactory{} + +func (f *PorReportingPluginFactory) NewReportingPlugin(ctx context.Context, config ocr3types.ReportingPluginConfig) (ocr3types.ReportingPlugin[ChainSelector], ocr3types.ReportingPluginInfo, error) { + porOffchainConfig, err := DeserializePorOffchainConfig(config.OffchainConfig) + if err != nil { + return nil, ocr3types.ReportingPluginInfo{}, fmt.Errorf("could not deserialize offchain config: %w", err) + } + + maxChains := porOffchainConfig.MaxChains + maxObservationLength := maxPorPluginObservationLengthJsonEstimate(uint64(maxChains)) // estimate the size of the JSON-encoded observation + maxOutcomeLength := maxPorPluginOutcomeObservationJsonLengthEstimate(uint64(maxChains)) // estimate the size of the JSON-encoded outcome + + rm := f.ReportMarshaler + if rm == nil { + rm = NewMockReportMarshaler() + } + maxReportLength := rm.MaxReportSize(ctx) + + limits := ocr3types.ReportingPluginLimits{ + MaxQueryLength: 0, + MaxObservationLength: maxObservationLength, + MaxOutcomeLength: maxOutcomeLength, + MaxReportLength: maxReportLength, + MaxReportCount: int(maxChains), + } + + ea := f.ExternalAdapter + if ea == nil { + ea = NewMockExternalAdapterImpl() + } + + cr := f.ContractReader + if cr == nil { + cr = NewMockContractReader(config.ConfigDigest) + } + + // Note: it is guaranteed that 3F+1 <= N in the config file passed as argument, as it is a strict + // requirement for the OCR protocol. Hence, there is no need for an explicit check here. + + return &porReportingPlugin{ + maxChains, + ea, + cr, + rm, + config, + f.Logger, + }, ocr3types.ReportingPluginInfo{ + Name: "PorReportingPluginV1", + Limits: limits, + }, + nil +} + +type porReportingPlugin struct { + maxChains uint32 + externalAdapter ExternalAdapter + contractReader ContractReader + reportMarshaler ReportMarshaler + config ocr3types.ReportingPluginConfig + logger commontypes.Logger +} + +type porPluginObservation struct { + QueryResponse Mintables + LatestBlocks Blocks +} + +type porPluginOutcome struct { + ChangedMintables map[ChainSelector]bool // Indicates per chain if the mintable changed from the previous round + LatestAcquiredMintables Mintables + HonestBlocks Blocks +} + +var _ ocr3types.ReportingPlugin[ChainSelector] = &porReportingPlugin{} + +// We do not use the Query method in this plugin. The query is implied by the honest blocks from the previous round. +func (p *porReportingPlugin) Query(ctx context.Context, outctx ocr3types.OutcomeContext) (types.Query, error) { + return nil, nil +} + +// The Observation method is called by the OCR node to obtain an observation for this oracle for the current round. +// It queries the external adapter for mintable amounts based on the honest blocks from the previous round. +// (See the Outcome method for how the honest blocks are determined.) +// +// If the external adapter is up to date on all chains corresponding to the honest blocks query, the mintables will be +// non-nil and contain the mintable amounts for each chain that is tracked by the plugin. +// +// If the external adapter is not tracking the same set of chains as the honest blocks, or if it is not up to date +// with the latest blocks, it will return a nil mintables vector. This is expected behavior during an upgrade (adding a new +// chain), where the external adapter might not yet be aware of the new chain, or it might not have reached the latest +// block for the chains it is tracking. +// +// The latest blocks are also returned by the external adapter, which are used to track the latest blocks for +// each chain. These are used to calculate honest blocks for the next round's query to the external adapter (pipelining). +// The latest blocks should include all chains that are globally tracked by the plugin, i.e., in the honestBlocks +// vector. If it internally has not started tracking a new chain yet, it should return the latest block number as 0 for that chain. +// It is valid for the latest blocks to include more chains than the honest blocks, as long as it does +// not exceed the maximum number of chains. Including a chain not in honestBlocks suggests that the external adapter has +// started tracking a new chain and wants to extend the honestBlocks vector for the next round. +func (p *porReportingPlugin) Observation(ctx context.Context, outctx ocr3types.OutcomeContext, query types.Query) (types.Observation, error) { + honestBlockQuery, err := p.getOrInitializeHonestBlocks(outctx) + if err != nil { + return nil, fmt.Errorf("could not get 'honest blocks': %w", err) + } + + payload, err := p.externalAdapter.GetPayload(ctx, honestBlockQuery) + if err != nil { + return nil, fmt.Errorf("could not get payload from the external adapter: %w", err) + } + + if len(payload.Mintables) == 0 && len(honestBlockQuery) > 0 { + p.logger.Warn("PorReportingPlugin: external adapter could not respond to 'honest blocks' query. This could be due to a new chain being added, or the external adapter being outdated in relation to the query.", commontypes.LogFields{ + "Query": honestBlockQuery, + }) + } + + if err := p.checkValidLatestBlocks(payload.LatestBlocks, honestBlockQuery); err != nil { + return nil, fmt.Errorf("invalid 'latest blocks' in payload: %w", err) + } + + if err = checkValidMintables(payload.Mintables, honestBlockQuery); err != nil { + return nil, fmt.Errorf("invalid 'mintables' in payload: %w", err) + } + + ppo := porPluginObservation{ + payload.Mintables, + payload.LatestBlocks, + } + + observation, err := serializePorPluginObservation(ppo) + if err != nil { + return nil, fmt.Errorf("could not serialize observation: %w", err) + } + + return observation, nil +} + +// ValidateObservation checks if the observation is valid. +// We only reject observations which are *guaranteed* to come from dishonest oracles. +func (p *porReportingPlugin) ValidateObservation(ctx context.Context, outctx ocr3types.OutcomeContext, query types.Query, ao types.AttributedObservation) error { + honestBlocks, err := p.getOrInitializeHonestBlocks(outctx) + if err != nil { + return fmt.Errorf("could not get 'honest blocks': %w", err) + } + + // Deserialize the observation + ppo, err := deserializePorPluginObservation(ao.Observation) + if err != nil { + return fmt.Errorf("could not deserialize observation: %w", err) + } + + if err = p.checkValidLatestBlocks(ppo.LatestBlocks, honestBlocks); err != nil { + return fmt.Errorf("invalid observation 'latest blocks': %w", err) + } + + if err = checkValidMintables(ppo.QueryResponse, honestBlocks); err != nil { + return fmt.Errorf("invalid observation 'mintables': %w", err) + } + + return nil +} + +// ObservationQuorum checks if the number of observations reaches the minimum necessary quorum to attempt +// to acquire new mintables for the current round AND calculate honest blocks for the next round. +func (p *porReportingPlugin) ObservationQuorum(ctx context.Context, outctx ocr3types.OutcomeContext, query types.Query, aos []types.AttributedObservation) (bool, error) { + return quorumhelper.ObservationCountReachesObservationQuorum(quorumhelper.QuorumTwoFPlusOne, p.config.N, p.config.F, aos), nil +} + +// The Outcome method processes the observations and generates a new outcome, from which reports will be obtained. +// +// In the common case, the Outcome tries to simultaneously do two things (pipeline): +// 1. Deduce the honest mintables, which are mintable amounts for each chain that are reported by at least F+1 oracles. +// The mintable amounts are calculated based on the honest blocks determined in the previous round (for this round). +// 2. Deduce the latest honest blocks from the observations, which are used to track the latest blocks for each chain. +// These are used in the next round to query the external adapter for mintable amounts (see above). +// +// Exceptions: +// - If the latest honest blocks are extended with new chains, this indicates that the oracles are undergoing an upgrade, +// i.e., they are starting to track a new chain (all oracles will eventually do so). In this situation, we ALWAYS update the +// honest blocks, even if no new mintables were acquired, because the upgrade is expected to be completed eventually and is +// only a temporary, infrequent event. +// - If no new mintables were acquired (and there is no new chain) we keep the previous round's mintables. This ensures that +// we (eventually) acquire mintables, since all honest oracles will (eventually) reach the fixed mintables (as we stop +// updating it until we succeed). +// +// The outcome also keeps track of which chains had their mintable amounts or block numbers changed compared to the previous round. +// This is used to determine which reports to generate in the Reports method and avoid generating reports for chains that did not change. +func (p *porReportingPlugin) Outcome(ctx context.Context, outctx ocr3types.OutcomeContext, query types.Query, aos []types.AttributedObservation) (ocr3types.Outcome, error) { + // Deserialize the previous outcome in outcome context (outctx) + prevOutcome, err := previousPorPluginOutcome(outctx) + if err != nil { + return nil, fmt.Errorf("could not deserialize previous outcome: %w", err) + } + + // Deserialize the observations + ppos := make([]porPluginObservation, 0, len(aos)) + for i, ao := range aos { + po, err := deserializePorPluginObservation(ao.Observation) + if err != nil { + return nil, fmt.Errorf("could not deserialize %d-th observation from sender %v: %w", i, ao.Observer, err) + } + ppos = append(ppos, po) + } + + newHonestBlocks := p.deduceLatestHonestBlocks(prevOutcome.HonestBlocks, ppos) + + honestMintables, err := p.deduceHonestMintables(outctx, ppos) + if err != nil { + return nil, fmt.Errorf("error deducing honest mintables: %w", err) + } + + newOutcome := porPluginOutcome{ + ChangedMintables: make(map[ChainSelector]bool), + LatestAcquiredMintables: honestMintables, + HonestBlocks: newHonestBlocks, + } + + // If we did not acquire new mintables, we keep the previous round's mintables + if honestMintables == nil { + p.logger.Info("πŸ’₯πŸ’₯πŸ’₯πŸ’₯πŸ’₯ PorReportingPlugin: could not acquire mintables", commontypes.LogFields{ + "HonestBlocks": newOutcome.HonestBlocks, + "LatestAcquiredMintables": newOutcome.LatestAcquiredMintables, + }) + + newOutcome.LatestAcquiredMintables = prevOutcome.LatestAcquiredMintables + } else { + p.logger.Info("πŸš€πŸš€πŸš€πŸš€πŸš€ PorReportingPlugin: acquired mintables, generating a new outcome", commontypes.LogFields{ + "HonestBlocks": newOutcome.HonestBlocks, + "LatestAcquiredMintables": newOutcome.LatestAcquiredMintables, + }) + } + + // If we did not acquire new mintables and there is no new chain to track, we keep the previous round's honest blocks. + if honestMintables == nil && len(newHonestBlocks) == len(prevOutcome.HonestBlocks) { + newOutcome.HonestBlocks = prevOutcome.HonestBlocks + } + + if len(newHonestBlocks) > len(prevOutcome.HonestBlocks) { + p.logger.Info("πŸ†•πŸ†•πŸ†•πŸ†•πŸ†• PorReportingPlugin: extended honest blocks with new chains", commontypes.LogFields{ + "NewHonestBlocks": newHonestBlocks, + "PreviousHonestBlocks": prevOutcome.HonestBlocks, + }) + } + + newOutcome.ChangedMintables = getChanged(prevOutcome.LatestAcquiredMintables, honestMintables) + + outcome, err := serializePorPluginOutcome(newOutcome) + if err != nil { + return nil, fmt.Errorf("could not serialize outcome: %w", err) + } + + return outcome, nil +} + +// The Reports method generates reports based on the outcome of the previous round. +// It creates a report for each chain that had its mintable amount or block number changed compared to the previous round. +// The reports are created using the reportMarshaler, which serializes the report data into a format suitable for transmission. +func (p *porReportingPlugin) Reports(ctx context.Context, seqNr uint64, outcome ocr3types.Outcome) ([]ocr3types.ReportPlus[ChainSelector], error) { + // Deserialize the outcome + ppo, err := deserializePorPluginOutcome(outcome) + if err != nil { + return nil, fmt.Errorf("could not deserialize outcome: %w", err) + } + + // Create a report for each chain + reports := make([]ocr3types.ReportPlus[ChainSelector], 0, len(ppo.LatestAcquiredMintables)) + for chain, changed := range ppo.ChangedMintables { + if !changed { + continue // Skip chains that did not change + } + + pair := ppo.LatestAcquiredMintables[chain] + report := PorReport{ + p.config.ConfigDigest, + seqNr, + pair.Block, + pair.Mintable, + } + + encodedReport, err := p.reportMarshaler.Serialize(ctx, chain, report) + if err != nil { + return nil, fmt.Errorf("could not encode block-mintable pair (%v): %w", pair, err) + } + + // Create a report for the chain + reports = append(reports, ocr3types.ReportPlus[ChainSelector]{ + ReportWithInfo: ocr3types.ReportWithInfo[ChainSelector]{ + Report: encodedReport, + Info: chain, + }, + TransmissionScheduleOverride: nil, + }) + } + + return reports, nil +} + +// ShouldAcceptAttestedReport is called by the OCR node to determine if the attested report should be accepted. +// In this plugin, we always accept the attested report, as we do not have any specific conditions for acceptance. +func (p *porReportingPlugin) ShouldAcceptAttestedReport(context.Context, uint64, ocr3types.ReportWithInfo[ChainSelector]) (bool, error) { + return true, nil +} + +// ShouldTransmitAcceptedReport is called by the OCR node to determine if the accepted report should be transmitted on-chain. +// In the future, this responsibility might be entirely moved to the transmission infrastucture, but for now, +// we implement it in the plugin to ensure that the report is only transmitted if it is valid and has not been +// transmitted already. +func (p *porReportingPlugin) ShouldTransmitAcceptedReport(ctx context.Context, seqNr uint64, report ocr3types.ReportWithInfo[ChainSelector]) (bool, error) { + chain := report.Info + details, err := p.contractReader.GetLatestTransmittedReportDetails(ctx, chain) + if err != nil { + return false, fmt.Errorf("could not get latest transmission details from chain: %w", err) + } + if details.ConfigDigest.Hex() != p.config.ConfigDigest.Hex() { + return false, fmt.Errorf("config digest mismatch; expected: %v, got: %v", p.config.ConfigDigest.Hex(), details.ConfigDigest.Hex()) + } + // This or a later report is already posted on-chain + if details.SeqNr >= seqNr { + return false, nil + } + + return true, nil +} + +func (p *porReportingPlugin) Close() error { + return nil +} + +// checkValidLatestBlocks checks that the latestBlocks are a possible response by a correct EA for a given +// honestBlocks query. +// +// latestBlocks should contain the latest blocks for all chains that are globally tracked by the plugin, i.e., +// in the honestBlocks vector. +// +// latestBlocks including more chains than honestBlocks is valid behavior, as long as it does not exceed the +// maximum number of chains. Including a chain not in honestBlocks suggests that the EA has started tracking a new +// chain and wants to extend the honestBlocks vector for the next round. +func (p *porReportingPlugin) checkValidLatestBlocks(latestBlocks Blocks, honestBlocks Blocks) error { + if len(latestBlocks) > int(p.maxChains) { + return fmt.Errorf("'latest blocks' contains too many chains (%d), max allowed is %d", len(latestBlocks), p.maxChains) + } + + for chain := range honestBlocks { + if _, ok := latestBlocks[chain]; !ok { + return fmt.Errorf("'latest blocks' missing info on tracked chain with ID: %v", chain) + } + } + return nil +} + +// checkValidMintables checks that the mintables are a possible response by a correct EA for a given honestBlocksβ€œ query. +// +// nil mintables are considered valid, as they can happen during normal behavior or during an upgrade (adding a new chain): +// - during normal behavior, the EA *should* return nil mintables if, for at least one (chain -> block) pair in +// honestBlocks, it has not reached that block yet (so it cannot accurately calculate mintables for it) +// - during an upgrade (a new chain being added to the system), the EA *should* return nil if there is a mismatch between +// the chains the EA is tracking and the honest blocks, which might happen temporarily until the upgrade is complete. +// +// If the mintables are not nil, then they should contain exactly the same chains as honestBlocks, with block numbers not exceeding +// the corresponding honest blocks. +func checkValidMintables(mintables Mintables, honestBlocks Blocks) error { + if len(mintables) == 0 { + return nil + } + + // Check that the mintables are for the honest blocks + for chain, pair := range mintables { + if block, ok := honestBlocks[chain]; !ok { + return fmt.Errorf("'mintables' includes info on untracked chain with ID: %v", chain) + } else if pair.Block > block { + return fmt.Errorf("'mintables' bad block number; expected no more than: %v, got: %v", block, pair.Block) + } + } + for chain := range honestBlocks { + if _, ok := mintables[chain]; !ok { + return fmt.Errorf("'mintables' missing info on tracked chain with ID: %v", chain) + } + } + + return nil +} + +// This function deduces the honest mintables from the plugin observations (ppos). +// An honest mintables vector is one that is reported by at least F+1 oracles. +// It returns nil if no honest mintables could be deduced, which is expected if: +// - It is the first round of the plugin (no honest blocks yet), +// - Many oracles could not respond to the query (e.g., due to a new chain being added or their EA being outdated), +// - Mintable amounts differing, e.g., due to temporary inconsistencies between reserve amounts at different oracles. +// In these cases, the plugin will not be able to deduce honest mintables (we will retry in the next OCR round). +func (p *porReportingPlugin) deduceHonestMintables(outctx ocr3types.OutcomeContext, ppos []porPluginObservation) (Mintables, error) { + honestBlocks, err := p.getOrInitializeHonestBlocks(outctx) + if err != nil { + return nil, fmt.Errorf("could not get honest blocks: %w", err) + } + + if len(honestBlocks) == 0 { + return nil, nil // No honest blocks to deduce mintables from, this is expected in the first round + } + + mintablesFrequencyMap := make(map[string]int, len(ppos)) + for _, po := range ppos { + if len(po.QueryResponse) != len(honestBlocks) { + continue + } + + uniqueEncoding, err := po.QueryResponse.toString() + if err != nil { + return nil, fmt.Errorf("could not convert query response to string: %w", err) + } + + mintablesFrequencyMap[string(uniqueEncoding)]++ + } + + // Find mintables with enough support (seen by at least F+1 oracles) + maxMintablesWithEnoughSupport := p.config.N / (p.config.F + 1) + mintablesWithEnoughSupport := make([]Mintables, 0, maxMintablesWithEnoughSupport) + for mintablesAsString, count := range mintablesFrequencyMap { + if count <= p.config.F { + // Not enough support, skip this mintables vector + continue + } + + // If there is a mintable amount that more than F oracles reported, it is guaranteed to be honest. + mintables, err := mintablesFromString(mintablesAsString) + if err != nil { + // This error should be impossible, as the serialization comes from at least one honest oracle. + return nil, fmt.Errorf("could not deserialize mintables from string: %w", err) + } + mintablesWithEnoughSupport = append(mintablesWithEnoughSupport, mintables) + } + + if len(mintablesWithEnoughSupport) == 0 { + p.logger.Warn("PorReportingPlugin: no mintable vectors with enough support found", commontypes.LogFields{ + "MintablesFrequencyMap": mintablesFrequencyMap, + }) + return nil, nil // No mintables with enough support found, this is expected if the EA could not respond to the query + } + + if len(mintablesWithEnoughSupport) > 1 { + p.logger.Warn("PorReportingPlugin: multiple mintable vectors with enough support found, picking the first one", commontypes.LogFields{ + "MintableVectors": mintablesWithEnoughSupport, + }) + } + + return mintablesWithEnoughSupport[0], nil +} + +// deduceLatestHonestBlocks deduces the latest honest blocks from the plugin observations (ppos). +// This is done in two steps: +// 1. For each chain that is already tracked, we deduce the latest honest block by taking the maximum of the latest blocks +// reported by the oracles, ignoring the top F (which could be overestimates), and ensuring that it is at least as high +// as the original honest block. +// 2. For each chain that is not currently tracked, we check if at least F+1 oracles want to start tracking it (=> at least one +// honest oracle has started tracking, so the "upgrade" is true). +// If so, we take the maximum of the latest blocks reported by the oracles, ignoring the top F (which could be overestimates). +// (A possible more conservative alternative is to initially set a new chain's latest block to 0) +// +// Note: during an upgrade (adding a new chain), honest blocks vector will be extended with new chains, which might happen +// before all oracles start tracking those new chains in their EA. For oracles missing the new chain, it is expected behavior +// to return a nil mintables vector in this case. For the latestBlocks, the new chains must be included with +// the latest block number set to 0. +func (p *porReportingPlugin) deduceLatestHonestBlocks(honestBlocks Blocks, ppos []porPluginObservation) Blocks { + newHonestBlocks := make(Blocks) + + // First, we deduce the latest honest blocks for each chain that is already tracked. + for chain := range honestBlocks { + numbers := []BlockNumber{} + for _, ppo := range ppos { + number := ppo.LatestBlocks[chain] + numbers = append(numbers, number) + } + + slices.Sort(numbers) + + // Among |pos| >= 2F+1 observations, it is safe to pick any block index where |pos|-F > X >= F. + // In this case, we are choosing the highest block number among the safe options. + // (In practice, the number of faults will often be zero, to in the next round the top F+1 + // fastest oracles should be able to answer the query corresponding the F+1th fastest oracle.) + safeBlock := numbers[len(numbers)-p.config.F-1] + originalHonestBlock := honestBlocks[chain] + + // Ensure monotonicity of the honest blocks + newHonestBlocks[chain] = max(safeBlock, originalHonestBlock) + } + + // Second, we check if enough oracles want to start tracking a new chain. For each chain not in honestBlocks, + // we first count how many oracles want to start tracking it and what block number they suggest. + newChains := make(map[ChainSelector][]BlockNumber) + for _, ppo := range ppos { + for chain, blockNumber := range ppo.LatestBlocks { + if _, ok := honestBlocks[chain]; !ok { + // This chain is not currently tracked, so we count how many oracles want to start tracking it + // and what block number they suggest. + newChains[chain] = append(newChains[chain], blockNumber) + } + } + } + + // Then we check if enough oracles (> F) want to start tracking each new chain to avoid malicious suggestions. + for chain, blockNumbers := range newChains { + // Here, we cannot pick a higher quorum threshold than F+1, as we can only guarantee that F+1 responses + // come from honest oracles out of the total of 2F+1 responses. For the remaining F responses, we cannot + // distinguish whether the oracle is malicious, or if they are honest and have not yet started tracking + // the new chain. + if len(blockNumbers) > int(p.config.F) { + // It is safe to underestimate the block number. In theory, we could even just start at 0. + // However, it is *not* safe to overestimate. + // Here, we use highest *assuredly honest* block number suggested by the oracles, by eliminating the top F. + slices.Sort(blockNumbers) + newHonestBlocks[chain] = blockNumbers[len(blockNumbers)-p.config.F-1] + } + } + + return newHonestBlocks +} + +// getChanged compares the old and new Mintables and returns a map indicating which chains have changed. +// A chain is considered changed if its mintable amount or block number has changed compared to the old Mintables. +func getChanged(old, new Mintables) map[ChainSelector]bool { + changed := make(map[ChainSelector]bool, len(new)) + + for chain, newPair := range new { + oldPair, ok := old[chain] + if !ok || oldPair.Mintable != newPair.Mintable || oldPair.Block != newPair.Block { + changed[chain] = true + } + } + + return changed +} + +func deserializePorPluginOutcome(outcome []byte) (porPluginOutcome, error) { + var ppo porPluginOutcome + err := json.Unmarshal(outcome, &ppo) + if err != nil { + return porPluginOutcome{}, err + } + return ppo, nil +} + +func serializePorPluginOutcome(ppo porPluginOutcome) (ocr3types.Outcome, error) { + return json.Marshal(ppo) +} + +func previousPorPluginOutcome(outctx ocr3types.OutcomeContext) (porPluginOutcome, error) { + if outctx.SeqNr == 1 { + return porPluginOutcome{ + ChangedMintables: make(map[ChainSelector]bool), + LatestAcquiredMintables: make(Mintables), + HonestBlocks: make(Blocks), + }, nil + } else { + return deserializePorPluginOutcome(outctx.PreviousOutcome) + } +} + +// Deserialize the previous outcome in outcome context (outctx) +// If we are in the first round, this will be empty, which is intentional: +// We will not have any honest blocks to obtain mintables for in the first round, +// but we will extend the honestBlocks with new chains to track at the end for the next round. +// (This is done in the Outcome method.) +func (p *porReportingPlugin) getOrInitializeHonestBlocks(outctx ocr3types.OutcomeContext) (Blocks, error) { + prevOutcome, err := previousPorPluginOutcome(outctx) + if err != nil { + return nil, fmt.Errorf("could not deserialize previous outcome: %w", err) + } + + return prevOutcome.HonestBlocks, nil +} + +func deserializePorPluginObservation(raw []byte) (porPluginObservation, error) { + var ppo porPluginObservation + err := json.Unmarshal(raw, &ppo) + if err != nil { + return porPluginObservation{}, err + } + return ppo, nil +} + +func serializePorPluginObservation(rq porPluginObservation) (types.Observation, error) { + return json.Marshal(rq) +} + +func mintablesMapLength(maxChains uint64) uint64 { + // Estimate the size of the mintables map + return maxChains * (8 + 32) // 8 bytes for BlockNumber, 32 bytes for big.Int (assuming max 256-bit big.Int size) +} + +func honestBlocksMapLength(maxChains uint64) uint64 { + // Estimate the size of the honest blocks map + return maxChains * (8 + 8) // 8 bytes for BlockNumber, 8 bytes for ChainSelector (64-bit integers) +} + +func maxPorPluginOutcomeObservationJsonLengthEstimate(maxChains uint64) int { + porPluginOutcomeLength := mintablesMapLength(maxChains) + honestBlocksMapLength(maxChains) + maxChains // +1 for changedMintables map + return int((4 * porPluginOutcomeLength) + 256) // estimate the size of the JSON-encoded outcome +} + +func maxPorPluginObservationLengthJsonEstimate(maxChains uint64) int { + porObservationLength := mintablesMapLength(maxChains) + honestBlocksMapLength(maxChains) + return int((4 * porObservationLength) + 256) // estimate the size of the JSON-encoded observation +} diff --git a/modules/por_mock_ocr3plugin/por/report_marshaller_interface.go b/modules/por_mock_ocr3plugin/por/report_marshaller_interface.go new file mode 100644 index 00000000000..44c7f666dce --- /dev/null +++ b/modules/por_mock_ocr3plugin/por/report_marshaller_interface.go @@ -0,0 +1,9 @@ +package por + +import "context" + +type ReportMarshaler interface { + Serialize(ctx context.Context, chain ChainSelector, report PorReport) ([]byte, error) + + MaxReportSize(ctx context.Context) int // The maximum size of the serialized report in bytes. +} diff --git a/modules/por_mock_ocr3plugin/por/types.go b/modules/por_mock_ocr3plugin/por/types.go new file mode 100644 index 00000000000..1f389dce888 --- /dev/null +++ b/modules/por_mock_ocr3plugin/por/types.go @@ -0,0 +1,81 @@ +package por + +import ( + "encoding/json" + "math/big" + "time" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" +) + +type BlockNumber uint64 + +type Blocks map[ChainSelector]BlockNumber + +type BlockMintablePair struct { + Block BlockNumber + Mintable *big.Int +} + +type Mintables map[ChainSelector]BlockMintablePair + +func (m Mintables) toString() (string, error) { + data, err := json.Marshal(m) + if err != nil { + return "", err + } + return string(data), nil +} + +func mintablesFromString(s string) (Mintables, error) { + var m Mintables + if err := json.Unmarshal([]byte(s), &m); err != nil { + return nil, err + } + return m, nil +} + +type ReserveInfo struct { + ReserveAmount *big.Int + Timestamp time.Time +} + +type ExternalAdapterPayload struct { + Mintables Mintables // The mintable amounts for each chain and its block. + ReserveInfo ReserveInfo // The latest reserve amount and timestamp used to calculate the minting allowance above. + + LatestBlocks Blocks // The latest blocks for each chain. +} + +type TransmittedReportDetails struct { + ConfigDigest types.ConfigDigest // The OCR3 config digest. + SeqNr uint64 // The OCR3 sequence number. + LatestTimestamp time.Time // The (on-chain specific) timestamp of the block where the latest report is included. +} + +type PorOffchainConfig struct { + MaxChains uint32 // The maximum number of chains that can be tracked by the external adapter. +} + +func (p *PorOffchainConfig) Serialize() ([]byte, error) { + return json.Marshal(p) +} + +func DeserializePorOffchainConfig(data []byte) (*PorOffchainConfig, error) { + var config PorOffchainConfig + if err := json.Unmarshal(data, &config); err != nil { + return nil, err + } + return &config, nil +} + +type PorReport struct { + ConfigDigest types.ConfigDigest + SeqNr uint64 + Block BlockNumber + Mintable *big.Int + + // The following fields might be useful in the future, but are not currently used + // ReserveAmount *big.Int + // ReserveTimestamp time.Time +} diff --git a/modules/por_mock_ocr3plugin/transmitter/transmitter.go b/modules/por_mock_ocr3plugin/transmitter/transmitter.go new file mode 100644 index 00000000000..ec8bd0ea935 --- /dev/null +++ b/modules/por_mock_ocr3plugin/transmitter/transmitter.go @@ -0,0 +1,84 @@ +package transmitter + +import ( + "context" + "crypto/ecdsa" + "fmt" + "math/big" + + "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/por_mock_ocr3plugin/por" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" +) + +var _ ocr3types.ContractTransmitter[por.ChainSelector] = (*BasicContractTransmitter)(nil) + +type BasicContractTransmitter struct { + backend bind.ContractTransactor + chainID *big.Int + destination common.Address + opts *bind.TransactOpts +} + +func NewBasicContractTransmitter(backend bind.ContractTransactor, chainID *big.Int, destination common.Address, privateKey ecdsa.PrivateKey) *BasicContractTransmitter { + opts, err := bind.NewKeyedTransactorWithChainID(&privateKey, chainID) + if err != nil { + panic(fmt.Sprintf("bind.NewKeyedTransactorWithChainID: %v", err)) + } + + return &BasicContractTransmitter{ + backend, + chainID, + destination, + opts, + } +} + +func (ct *BasicContractTransmitter) Transmit( + ctx context.Context, + configDigest types.ConfigDigest, + seqNr uint64, + reportWithInfo ocr3types.ReportWithInfo[por.ChainSelector], + aos []types.AttributedOnchainSignature, +) error { + // send transaction via ct.backend using ct.opts + // ct.backend.SendTransaction(ctx, ) + + // nonce, err := ct.backend.PendingNonceAt(ctx, ct.opts.From) + // if err != nil { + // return err + // } + + // tx := ethtypes.NewTx(ðtypes.DynamicFeeTx{ + // ChainID: ct.chainID, + // Nonce: nonce, + // GasTipCap: big.NewInt(1e9), + // GasFeeCap: big.NewInt(100e9), + // Gas: 100_000, + // To: &ct.destination, + // Value: big.NewInt(0), + // Data: reportWithInfo.Report, + // AccessList: nil, + + // V: nil, R: nil, S: nil, + // }) + + // signedTx, err := ct.opts.Signer(ct.opts.From, tx) + // if err != nil { + // return err + // } + + // err = ct.backend.SendTransaction(ct.opts.Context, signedTx) + // if err != nil { + // return err + // } + + return nil +} + +func (ct *BasicContractTransmitter) FromAccount(context.Context) (types.Account, error) { + return types.Account(ct.opts.From.Hex()), nil +} diff --git a/plugins/chainlink.Dockerfile b/plugins/chainlink.Dockerfile index b9cf904f44d..53829730bed 100644 --- a/plugins/chainlink.Dockerfile +++ b/plugins/chainlink.Dockerfile @@ -13,6 +13,8 @@ COPY GNUmakefile package.json ./ COPY tools/bin/ldflags ./tools/bin/ ADD go.mod go.sum ./ +RUN mkdir -p modules +COPY modules/ ./modules/ RUN --mount=type=cache,target=/go/pkg/mod \ go mod download COPY . . diff --git a/system-tests/lib/cre/capabilities/securemint/securemint.go b/system-tests/lib/cre/capabilities/securemint/securemint.go new file mode 100644 index 00000000000..5ab68fc8635 --- /dev/null +++ b/system-tests/lib/cre/capabilities/securemint/securemint.go @@ -0,0 +1,25 @@ +package securemint + +import ( + capabilitiespb "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb" + + kcr "github.com/smartcontractkit/chainlink-evm/gethwrappers/keystone/generated/capabilities_registry_1_1_0" + keystone_changeset "github.com/smartcontractkit/chainlink/deployment/keystone/changeset" +) + +var SecureMintCapabilityFactoryFn = func(donFlags []string) []keystone_changeset.DONCapabilityWithConfig { + var capabilities []keystone_changeset.DONCapabilityWithConfig + + // if flags.HasFlag(donFlags, types.SecureMintCapability) { + capabilities = append(capabilities, keystone_changeset.DONCapabilityWithConfig{ + Capability: kcr.CapabilitiesRegistryCapability{ + LabelledName: "secure-mint-trigger", // TODO: use correct trigger name + Version: "1.0.0", + CapabilityType: 0, // TRIGGER + }, + Config: &capabilitiespb.CapabilityConfig{}, + }) + // } + + return capabilities +} diff --git a/system-tests/lib/go.mod b/system-tests/lib/go.mod index 598d25b892e..2f2b5f6bb93 100644 --- a/system-tests/lib/go.mod +++ b/system-tests/lib/go.mod @@ -116,8 +116,8 @@ require ( github.com/buger/goterm v1.0.4 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/bytecodealliance/wasmtime-go/v28 v28.0.0 // indirect - github.com/bytedance/sonic v1.12.3 // indirect - github.com/bytedance/sonic/loader v0.2.0 // indirect + github.com/bytedance/sonic v1.13.3 // indirect + github.com/bytedance/sonic/loader v0.2.4 // indirect github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.70.2 // indirect github.com/cdk8s-team/cdk8s-plus-go/cdk8splus30/v2 v2.4.8 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect @@ -127,8 +127,7 @@ require ( github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240821051457-da69c6d9617a // 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/cloudwego/base64x v0.1.4 // indirect - github.com/cloudwego/iasm v0.2.0 // indirect + github.com/cloudwego/base64x v0.1.5 // indirect github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v1.1.5 // indirect @@ -191,7 +190,7 @@ require ( github.com/getsentry/sentry-go v0.27.0 // indirect github.com/gibson042/canonicaljson-go v1.0.3 // indirect github.com/gin-contrib/sessions v0.0.5 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect + github.com/gin-contrib/sse v1.1.0 // indirect github.com/gin-gonic/gin v1.10.1 // indirect github.com/gkampitakis/ciinfo v0.3.2 // indirect github.com/gkampitakis/go-diff v1.3.2 // indirect @@ -291,7 +290,7 @@ require ( github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect github.com/klauspost/compress v1.18.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.10 // indirect + github.com/klauspost/cpuid/v2 v2.2.11 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect @@ -430,7 +429,7 @@ require ( github.com/tklauser/numcpus v0.10.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/tyler-smith/go-bip39 v1.1.0 // indirect - github.com/ugorji/go/codec v1.2.12 // indirect + github.com/ugorji/go/codec v1.3.0 // indirect github.com/urfave/cli/v2 v2.27.6 // indirect github.com/valyala/fastjson v1.6.4 // indirect github.com/vektah/gqlparser/v2 v2.5.14 // indirect @@ -438,7 +437,7 @@ require ( github.com/x448/float16 v0.8.4 // indirect github.com/xlab/treeprint v1.2.0 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect - github.com/xssnick/tonutils-go v1.13.0 // indirect + github.com/xssnick/tonutils-go v1.14.0 // indirect github.com/yuin/goldmark v1.7.12 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect @@ -462,7 +461,7 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.35.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.35.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0 // indirect go.opentelemetry.io/otel/log v0.13.0 // indirect go.opentelemetry.io/otel/metric v1.37.0 // indirect go.opentelemetry.io/otel/sdk v1.37.0 // indirect @@ -474,7 +473,7 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/arch v0.11.0 // indirect + golang.org/x/arch v0.18.0 // indirect golang.org/x/exp v0.0.0-20250711185948-6ae5c78190dc // indirect golang.org/x/lint v0.0.0-20241112194109-818c5a804067 // indirect golang.org/x/mod v0.26.0 // indirect diff --git a/system-tests/lib/go.sum b/system-tests/lib/go.sum index 0e7ef5e4366..f4d98bc1892 100644 --- a/system-tests/lib/go.sum +++ b/system-tests/lib/go.sum @@ -245,11 +245,11 @@ github.com/bxcodec/faker v2.0.1+incompatible h1:P0KUpUw5w6WJXwrPfv35oc91i4d8nf40 github.com/bxcodec/faker v2.0.1+incompatible/go.mod h1:BNzfpVdTwnFJ6GtfYTcQu6l6rHShT+veBxNCnjCx5XM= github.com/bytecodealliance/wasmtime-go/v28 v28.0.0 h1:aBU8cexP2rPZ0Qz488kvn2NXvWZHL2aG1/+n7Iv+xGc= github.com/bytecodealliance/wasmtime-go/v28 v28.0.0/go.mod h1:4OCU0xAW9ycwtX4nMF4zxwgJBJ5/0eMfJiHB0wAmkV4= -github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU= -github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= +github.com/bytedance/sonic v1.13.3 h1:MS8gmaH16Gtirygw7jV91pDCN33NyMrPbN7qiYhEsF0= +github.com/bytedance/sonic v1.13.3/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= -github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= -github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= +github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.70.2 h1:6khni3TG7XJsyXgg5gdbY/IZCiBnpAi8XVZZUBizGUc= github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.70.2/go.mod h1:JFGcyqRE2qXgHsBw27/L0D1uEJtLhUm2Vqx4dFOHSzA= github.com/cdk8s-team/cdk8s-plus-go/cdk8splus30/v2 v2.4.8 h1:vtT/G9hb1fstaeS52wcSYDKmZY0qExoroP5lhiFQe8U= @@ -279,9 +279,8 @@ github.com/cloudevents/sdk-go/binding/format/protobuf/v2 v2.16.1 h1:nLaJZcVAnaqc 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/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= -github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= -github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= +github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -493,8 +492,8 @@ github.com/gin-contrib/sessions v0.0.5 h1:CATtfHmLMQrMNpJRgzjWXD7worTh7g7ritsQfm github.com/gin-contrib/sessions v0.0.5/go.mod h1:vYAuaUPqie3WUSsft6HUlCjlwwoJQs97miaG2+7neKY= github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4 h1:Z9J0PVIt1PuibOShaOw1jH8hUYz+Ak8NLsR/GI0Hv5I= github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4/go.mod h1:CEPcgZiz8998l9E8fDm16h8UfHRL7b+5oG0j/0koeVw= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= +github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ= github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs= @@ -915,8 +914,8 @@ github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zt github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -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/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU= +github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= 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= @@ -1447,8 +1446,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= -github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= -github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= +github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= github.com/ulule/limiter/v3 v3.11.2 h1:P4yOrxoEMJbOTfRJR2OzjL90oflzYPPmWg+dvwN2tHA= github.com/ulule/limiter/v3 v3.11.2/go.mod h1:QG5GnFOCV+k7lrL5Y8kgEeeflPH3+Cviqlqa8SVSQxI= github.com/umbracle/ethgo v0.1.3 h1:s8D7Rmphnt71zuqrgsGTMS5gTNbueGO1zKLh7qsFzTM= @@ -1476,8 +1475,8 @@ github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= -github.com/xssnick/tonutils-go v1.13.0 h1:LV2JzB+CuuWaLQiYNolK+YI3NRQOpS0W+T+N+ctF6VQ= -github.com/xssnick/tonutils-go v1.13.0/go.mod h1:EDe/9D/HZpAenbR+WPMQHICOF0BZWAe01TU5+Vpg08k= +github.com/xssnick/tonutils-go v1.14.0 h1:9+WXLKleINMWTSBN/uRJuE3d2BRYtxDh55hCG5PYCBE= +github.com/xssnick/tonutils-go v1.14.0/go.mod h1:68xwWjpoGGqiTbLJ0gT63sKu1Z1moCnDLLzA+DKanIg= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1526,8 +1525,8 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= 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/github.com/gin-gonic/gin/otelgin v0.49.0 h1:1f31+6grJmV3X4lxcEvUy13i5/kfDw1nJZwhd8mA4tg= -go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0/go.mod h1:1P/02zM3OwkX9uki+Wmxw3a5GVb6KUXRsa7m7bOC9Fg= +go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.62.0 h1:fZNpsQuTwFFSGC96aJexNOBrCD7PjD9Tm/HyHtXhmnk= +go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.62.0/go.mod h1:+NFxPSeYg0SoiRUO4k0ceJYMCY9FiRbYFmByUpm7GJY= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= @@ -1552,8 +1551,8 @@ go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 h1:yEX3aC9KDgvYPhuKE go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0/go.mod h1:/GXR0tBmmkxDaCUGahvksvp66mx4yh5+cFXgSlhg0vQ= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.35.0 h1:PB3Zrjs1sG1GBX51SXyTSoOTqcDglmsk7nT6tkKPb/k= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.35.0/go.mod h1:U2R3XyVPzn0WX7wOIypPuptulsMcPDPs/oiSVOMVnHY= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.35.0 h1:T0Ec2E+3YZf5bgTNQVet8iTDW7oIk03tXHq+wkwIDnE= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.35.0/go.mod h1:30v2gqH+vYGJsesLWFov8u47EpYTcIQcBjKpI6pJThg= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0 h1:SNhVp/9q4Go/XHBkQ1/d5u9P/U+L1yaGPoi0x+mStaI= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0/go.mod h1:tx8OOlGH6R4kLV67YaYO44GFXloEjGPZuMjEkaaqIp4= go.opentelemetry.io/otel/log v0.13.0 h1:yoxRoIZcohB6Xf0lNv9QIyCzQvrtGZklVbdCoyb7dls= go.opentelemetry.io/otel/log v0.13.0/go.mod h1:INKfG4k1O9CL25BaM1qLe0zIedOpvlS5Z7XgSbmN83E= go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= @@ -1598,8 +1597,8 @@ go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/arch v0.11.0 h1:KXV8WWKCXm6tRpLirl2szsO5j/oOODwZf4hATmGVNs4= -golang.org/x/arch v0.11.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.18.0 h1:WN9poc33zL4AzGxqf8VtpKUnGvMi8O9lhNyBMF/85qc= +golang.org/x/arch v0.18.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/system-tests/tests/go.mod b/system-tests/tests/go.mod index 81a24ed0dba..fc08dde65a5 100644 --- a/system-tests/tests/go.mod +++ b/system-tests/tests/go.mod @@ -125,8 +125,8 @@ require ( github.com/buger/goterm v1.0.4 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/bytecodealliance/wasmtime-go/v28 v28.0.0 // indirect - github.com/bytedance/sonic v1.12.3 // indirect - github.com/bytedance/sonic/loader v0.2.0 // indirect + github.com/bytedance/sonic v1.13.3 // indirect + github.com/bytedance/sonic/loader v0.2.4 // indirect github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500 // indirect github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.70.2 // indirect github.com/cdk8s-team/cdk8s-plus-go/cdk8splus30/v2 v2.4.8 // indirect @@ -138,8 +138,7 @@ require ( github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240821051457-da69c6d9617a // 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/cloudwego/base64x v0.1.4 // indirect - github.com/cloudwego/iasm v0.2.0 // indirect + github.com/cloudwego/base64x v0.1.5 // indirect github.com/cockroachdb/errors v1.11.3 // indirect github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect @@ -210,7 +209,7 @@ require ( github.com/getsentry/sentry-go v0.27.0 // indirect github.com/gibson042/canonicaljson-go v1.0.3 // indirect github.com/gin-contrib/sessions v0.0.5 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect + github.com/gin-contrib/sse v1.1.0 // indirect github.com/gkampitakis/ciinfo v0.3.2 // indirect github.com/gkampitakis/go-diff v1.3.2 // indirect github.com/gkampitakis/go-snaps v0.5.13 // indirect @@ -341,7 +340,7 @@ require ( github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect github.com/klauspost/compress v1.18.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.10 // indirect + github.com/klauspost/cpuid/v2 v2.2.11 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v0.1.0 // indirect github.com/knadh/koanf/v2 v2.1.2 // indirect @@ -512,7 +511,7 @@ require ( github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect github.com/uber/jaeger-lib v2.4.1+incompatible // indirect - github.com/ugorji/go/codec v1.2.12 // indirect + github.com/ugorji/go/codec v1.3.0 // indirect github.com/urfave/cli/v2 v2.27.6 // indirect github.com/valyala/fastjson v1.6.4 // indirect github.com/vektah/gqlparser/v2 v2.5.14 // indirect @@ -520,7 +519,7 @@ require ( github.com/x448/float16 v0.8.4 // indirect github.com/xlab/treeprint v1.2.0 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect - github.com/xssnick/tonutils-go v1.13.0 // indirect + github.com/xssnick/tonutils-go v1.14.0 // indirect github.com/yuin/goldmark v1.7.12 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect @@ -565,7 +564,7 @@ require ( go.opentelemetry.io/otel/exporters/prometheus v0.58.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/exporters/stdout/stdouttrace v1.37.0 // indirect go.opentelemetry.io/otel/log v0.13.0 // indirect go.opentelemetry.io/otel/metric v1.37.0 // indirect go.opentelemetry.io/otel/sdk v1.37.0 // indirect @@ -580,7 +579,7 @@ require ( go.uber.org/ratelimit v0.3.1 // indirect go.uber.org/zap v1.27.0 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect - golang.org/x/arch v0.11.0 // indirect + golang.org/x/arch v0.18.0 // indirect golang.org/x/crypto v0.40.0 // indirect golang.org/x/exp v0.0.0-20250711185948-6ae5c78190dc // indirect golang.org/x/lint v0.0.0-20241112194109-818c5a804067 // indirect diff --git a/system-tests/tests/go.sum b/system-tests/tests/go.sum index 52cd36938bf..0906d5c53a4 100644 --- a/system-tests/tests/go.sum +++ b/system-tests/tests/go.sum @@ -285,11 +285,11 @@ github.com/bxcodec/faker v2.0.1+incompatible h1:P0KUpUw5w6WJXwrPfv35oc91i4d8nf40 github.com/bxcodec/faker v2.0.1+incompatible/go.mod h1:BNzfpVdTwnFJ6GtfYTcQu6l6rHShT+veBxNCnjCx5XM= github.com/bytecodealliance/wasmtime-go/v28 v28.0.0 h1:aBU8cexP2rPZ0Qz488kvn2NXvWZHL2aG1/+n7Iv+xGc= github.com/bytecodealliance/wasmtime-go/v28 v28.0.0/go.mod h1:4OCU0xAW9ycwtX4nMF4zxwgJBJ5/0eMfJiHB0wAmkV4= -github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU= -github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= +github.com/bytedance/sonic v1.13.3 h1:MS8gmaH16Gtirygw7jV91pDCN33NyMrPbN7qiYhEsF0= +github.com/bytedance/sonic v1.13.3/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= -github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= -github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= +github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500 h1:6lhrsTEnloDPXyeZBvSYvQf8u86jbKehZPVDDlkgDl4= github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M= github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.70.2 h1:6khni3TG7XJsyXgg5gdbY/IZCiBnpAi8XVZZUBizGUc= @@ -323,9 +323,8 @@ github.com/cloudevents/sdk-go/binding/format/protobuf/v2 v2.16.1 h1:nLaJZcVAnaqc 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/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= -github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= -github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= +github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -557,8 +556,8 @@ github.com/gin-contrib/sessions v0.0.5 h1:CATtfHmLMQrMNpJRgzjWXD7worTh7g7ritsQfm github.com/gin-contrib/sessions v0.0.5/go.mod h1:vYAuaUPqie3WUSsft6HUlCjlwwoJQs97miaG2+7neKY= github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4 h1:Z9J0PVIt1PuibOShaOw1jH8hUYz+Ak8NLsR/GI0Hv5I= github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4/go.mod h1:CEPcgZiz8998l9E8fDm16h8UfHRL7b+5oG0j/0koeVw= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= +github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ= github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs= @@ -1062,8 +1061,8 @@ github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zt github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -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/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU= +github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v0.1.0 h1:gOkxhHkemwG4LezxxN8DMOFopOPghxRVp7JbIvdvqzU= @@ -1676,8 +1675,8 @@ github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaO github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= -github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= +github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= github.com/ulule/limiter/v3 v3.11.2 h1:P4yOrxoEMJbOTfRJR2OzjL90oflzYPPmWg+dvwN2tHA= github.com/ulule/limiter/v3 v3.11.2/go.mod h1:QG5GnFOCV+k7lrL5Y8kgEeeflPH3+Cviqlqa8SVSQxI= github.com/umbracle/ethgo v0.1.3 h1:s8D7Rmphnt71zuqrgsGTMS5gTNbueGO1zKLh7qsFzTM= @@ -1707,8 +1706,8 @@ github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= -github.com/xssnick/tonutils-go v1.13.0 h1:LV2JzB+CuuWaLQiYNolK+YI3NRQOpS0W+T+N+ctF6VQ= -github.com/xssnick/tonutils-go v1.13.0/go.mod h1:EDe/9D/HZpAenbR+WPMQHICOF0BZWAe01TU5+Vpg08k= +github.com/xssnick/tonutils-go v1.14.0 h1:9+WXLKleINMWTSBN/uRJuE3d2BRYtxDh55hCG5PYCBE= +github.com/xssnick/tonutils-go v1.14.0/go.mod h1:68xwWjpoGGqiTbLJ0gT63sKu1Z1moCnDLLzA+DKanIg= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1807,8 +1806,8 @@ go.opentelemetry.io/contrib/bridges/prometheus v0.61.0 h1:RyrtJzu5MAmIcbRrwg75b+ go.opentelemetry.io/contrib/bridges/prometheus v0.61.0/go.mod h1:tirr4p9NXbzjlbruiRGp53IzlYrDk5CO2fdHj0sSSaY= go.opentelemetry.io/contrib/exporters/autoexport v0.61.0 h1:XfzKtKSrbtYk9TNCF8dkO0Y9M7IOfb4idCwBOTwGBiI= go.opentelemetry.io/contrib/exporters/autoexport v0.61.0/go.mod h1:N6otC+qXTD5bAnbK2O1f/1SXq3cX+3KYSWrkBUqG0cw= -go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 h1:1f31+6grJmV3X4lxcEvUy13i5/kfDw1nJZwhd8mA4tg= -go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0/go.mod h1:1P/02zM3OwkX9uki+Wmxw3a5GVb6KUXRsa7m7bOC9Fg= +go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.62.0 h1:fZNpsQuTwFFSGC96aJexNOBrCD7PjD9Tm/HyHtXhmnk= +go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.62.0/go.mod h1:+NFxPSeYg0SoiRUO4k0ceJYMCY9FiRbYFmByUpm7GJY= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.61.0 h1:lREC4C0ilyP4WibDhQ7Gg2ygAQFP8oR07Fst/5cafwI= @@ -1844,8 +1843,8 @@ go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 h1:yEX3aC9KDgvYPhuKE 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/exporters/stdout/stdouttrace v1.37.0 h1:SNhVp/9q4Go/XHBkQ1/d5u9P/U+L1yaGPoi0x+mStaI= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0/go.mod h1:tx8OOlGH6R4kLV67YaYO44GFXloEjGPZuMjEkaaqIp4= go.opentelemetry.io/otel/log v0.13.0 h1:yoxRoIZcohB6Xf0lNv9QIyCzQvrtGZklVbdCoyb7dls= go.opentelemetry.io/otel/log v0.13.0/go.mod h1:INKfG4k1O9CL25BaM1qLe0zIedOpvlS5Z7XgSbmN83E= go.opentelemetry.io/otel/log/logtest v0.0.0-20250616193322-2cce18995527 h1:K4gsUDjRKwV+Uw9lSEM7NdFqIfTfDlwv6zoGgffbtwk= @@ -1897,8 +1896,8 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f h1:ketMxHg+vWm3yccyYiq+uK8D3fRmna2Fcj+awpQp84s= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f/go.mod h1:tgPU4N2u9RByaTN3NC2p9xOzyFpte4jYwsIIRF7XlSc= -golang.org/x/arch v0.11.0 h1:KXV8WWKCXm6tRpLirl2szsO5j/oOODwZf4hATmGVNs4= -golang.org/x/arch v0.11.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.18.0 h1:WN9poc33zL4AzGxqf8VtpKUnGvMi8O9lhNyBMF/85qc= +golang.org/x/arch v0.18.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=