diff --git a/.github/actions/build-gauntlet/action.yml b/.github/actions/build-gauntlet/action.yml index 61c5e21..e272a95 100644 --- a/.github/actions/build-gauntlet/action.yml +++ b/.github/actions/build-gauntlet/action.yml @@ -8,7 +8,7 @@ runs: uses: actions/checkout@v4.1.5 - name: Get Tool Versions - uses: smartcontractkit/tool-versions-to-env-action@v1.0.8 + uses: goplugin/tool-versions-to-env-action@v1.0.8 id: tool-versions - name: Setup Node ${{ steps.tool-versions.outputs.nodejs_version }} diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index f55fbf0..8fddf96 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -35,5 +35,5 @@ Example: - - https://github.com/smartcontractkit/ccip/pull/7777777 + - https://github.com/goplugin/ccip/pull/7777777 --> diff --git a/.github/workflows/e2e_custom_cl.yml b/.github/workflows/e2e_custom_cl.yml index edbc70c..0b6c14f 100644 --- a/.github/workflows/e2e_custom_cl.yml +++ b/.github/workflows/e2e_custom_cl.yml @@ -236,7 +236,7 @@ jobs: steps: - name: Collect Metrics id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@v1 + uses: goplugin/push-gha-metrics-action@v1 with: basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_CLOUD_HOST }} @@ -273,7 +273,7 @@ jobs: steps: - name: Collect Metrics id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + uses: goplugin/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 with: id: solana-e2e-smoke org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} @@ -355,7 +355,7 @@ jobs: steps: - name: Collect Metrics id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + uses: goplugin/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 with: id: solana-e2e-program-upgrade org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} diff --git a/.github/workflows/e2e_testnet_daily.yml b/.github/workflows/e2e_testnet_daily.yml index 883eb65..590499c 100644 --- a/.github/workflows/e2e_testnet_daily.yml +++ b/.github/workflows/e2e_testnet_daily.yml @@ -118,7 +118,7 @@ jobs: steps: - name: Collect Metrics id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + uses: goplugin/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 with: id: solana-e2e-daily org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} diff --git a/.github/workflows/gauntlet.yml b/.github/workflows/gauntlet.yml index 231e797..513804a 100644 --- a/.github/workflows/gauntlet.yml +++ b/.github/workflows/gauntlet.yml @@ -14,7 +14,7 @@ jobs: nodejs_version: ${{ steps.tool-versions.outputs.nodejs_version }} steps: - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - - uses: smartcontractkit/tool-versions-to-env-action@v1.0.8 + - uses: goplugin/tool-versions-to-env-action@v1.0.8 id: tool-versions gauntlet_build: diff --git a/.github/workflows/integration-tests-publish.yml b/.github/workflows/integration-tests-publish.yml index 0aa81f4..3514c57 100644 --- a/.github/workflows/integration-tests-publish.yml +++ b/.github/workflows/integration-tests-publish.yml @@ -53,7 +53,7 @@ jobs: steps: - name: Collect Metrics id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + uses: goplugin/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 with: id: solana-e2e-publish org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} diff --git a/.github/workflows/open-pr.yml b/.github/workflows/open-pr.yml index 06d8426..d835cbc 100644 --- a/.github/workflows/open-pr.yml +++ b/.github/workflows/open-pr.yml @@ -72,7 +72,7 @@ jobs: - name: Setup GitHub Token if: '!steps.check.outputs.skip' id: token - uses: smartcontractkit/.github/actions/setup-github-token@ef78fa97bf3c77de6563db1175422703e9e6674f # setup-github-token@0.2.1 + uses: goplugin/.github/actions/setup-github-token@ef78fa97bf3c77de6563db1175422703e9e6674f # setup-github-token@0.2.1 with: aws-role-arn: ${{ secrets.AWS_OIDC_PLUGIN_SOLANA_CICD_TOKEN_ISSUER_ROLE_ARN }} aws-lambda-url: ${{ secrets.AWS_RELENG_TEAM_GATI_LAMBDA_URL }} diff --git a/.github/workflows/relay.yml b/.github/workflows/relay.yml index bbe7df3..e787af7 100644 --- a/.github/workflows/relay.yml +++ b/.github/workflows/relay.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Collect Metrics id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + uses: goplugin/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 with: id: solana-relay-unit org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} diff --git a/.github/workflows/soak.yml b/.github/workflows/soak.yml index cef9a81..98e7b64 100644 --- a/.github/workflows/soak.yml +++ b/.github/workflows/soak.yml @@ -74,7 +74,7 @@ jobs: steps: - name: Collect Metrics id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + uses: goplugin/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 with: id: solana-e2e-soak org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} diff --git a/.github/workflows/sonar-scan.yml b/.github/workflows/sonar-scan.yml index 55d6e4c..fd9f8e2 100644 --- a/.github/workflows/sonar-scan.yml +++ b/.github/workflows/sonar-scan.yml @@ -35,7 +35,7 @@ jobs: - name: Check out Code uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Parse tool-versions file - uses: smartcontractkit/tool-versions-to-env-action@v1.0.8 + uses: goplugin/tool-versions-to-env-action@v1.0.8 id: tool-versions outputs: go-version: ${{ steps.tool-versions.outputs.golang_version }} diff --git a/CODEOWNERS b/CODEOWNERS deleted file mode 100644 index 27eabe7..0000000 --- a/CODEOWNERS +++ /dev/null @@ -1,21 +0,0 @@ -# CODEOWNERS Best Practices -# 1. Per Github docs: "Order is important; the last matching pattern takes the most precedence." -# Please define less specific codeowner paths before more specific codeowner paths in order for the more specific rule to have priority - -# global ownership -* @smartcontractkit/bix-build - -# e2e test ownership -/integration-tests @smartcontractkit/qa @smartcontractkit/bix-build - -# gauntlet ownership -/gauntlet @smartcontractkit/devx @smartcontractkit/bix-build - -# relayer ownership -/pkg @smartcontractkit/bix-build - -# monitoring ownership -/pkg/monitoring @smartcontractkit/realtime - -# CI/CD -/.github/** @smartcontractkit/releng diff --git a/go.mod b/go.mod index 9cbce5e..aa7a47c 100644 --- a/go.mod +++ b/go.mod @@ -17,9 +17,11 @@ require ( github.com/jpillora/backoff v1.0.0 github.com/pelletier/go-toml/v2 v2.2.0 github.com/prometheus/client_golang v1.17.0 - github.com/goplugin/plugin-common v0.0.1 - github.com/goplugin/libocr v0.1.1 + github.com/goplugin/plugin-common v0.1.1 + github.com/goplugin/plugin-libocr v0.1.1 github.com/stretchr/testify v1.9.0 + //github.com/goplugin/plugin-common v0.3.1-0.20241011160913-5d432bcdc2e8 + //github.com/goplugin/plugin-libocr v0.0.0-20241007185508-adbe57025f12 go.uber.org/zap v1.27.0 golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 golang.org/x/sync v0.8.0 @@ -89,6 +91,7 @@ require ( github.com/santhosh-tekuri/jsonschema/v5 v5.2.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/goplugin/grpc-proxy v0.1.1 + //github.com/goplugin/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 // indirect diff --git a/go.sum b/go.sum index d87aed4..eb11812 100644 --- a/go.sum +++ b/go.sum @@ -435,8 +435,8 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/goplugin/plugin-common v0.3.0 h1:mUXHBzzw2qPKyw6gPAC8JhO+ryT8maY+rBi9NFtqEy0= -github.com/goplugin/plugin-common v0.3.0/go.mod h1:tsGgeEJc5SUSlfVGSX0wR0EkRU3pM58D6SKF97V68ko= +github.com/goplugin/plugin-common v0.3.1-0.20241011160913-5d432bcdc2e8 h1:S3DuS2Su9Oo+3O1kSqNHxqz+iv5y5ljbikK0xrBp8/E= +github.com/goplugin/plugin-common v0.3.1-0.20241011160913-5d432bcdc2e8/go.mod h1:tsGgeEJc5SUSlfVGSX0wR0EkRU3pM58D6SKF97V68ko= github.com/goplugin/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= github.com/goplugin/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7/go.mod h1:FX7/bVdoep147QQhsOPkYsPEXhGZjeYx6lBSaSXtZOA= github.com/goplugin/plugin-libocr v0.0.0-20241007185508-adbe57025f12 h1:NzZGjaqez21I3DU7objl3xExTH4fxYvzTqar8DC6360= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 3eb6303..a429a06 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -1,6 +1,6 @@ module github.com/goplugin/plugin-solana/integration-tests -go 1.22.7 +go 1.22.8 toolchain go1.23.2 @@ -8,30 +8,30 @@ replace github.com/goplugin/plugin-solana => ../ require ( github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df - github.com/docker/docker v25.0.2+incompatible + github.com/docker/docker v27.3.1+incompatible github.com/gagliardetto/binary v0.7.7 github.com/gagliardetto/solana-go v1.8.4 - github.com/go-resty/resty/v2 v2.11.0 + github.com/go-resty/resty/v2 v2.13.1 github.com/google/uuid v1.6.0 github.com/lib/pq v1.10.9 github.com/pelletier/go-toml/v2 v2.2.2 github.com/rs/zerolog v1.33.0 - github.com/goplugin/plugin-common v0.0.1 + //github.com/goplugin/plugin-common v0.3.1-0.20241011160913-5d432bcdc2e8 + github.com/goplugin/plugin-common v0.1.1 + //github.com/goplugin/plugin-solana v1.1.1-0.20241010140936-4e1d0ae8315a github.com/goplugin/plugin-solana v0.0.1 - github.com/goplugin/plugin-testing-framework/lib v0.3.1 - github.com/goplugin/plugin-testing-framework/seth v0.1.1 - github.com/goplugin/pluginv3.0/integration-tests v2.2.0 - github.com/goplugin/pluginv3.0/v2 v2.2.0 - github.com/goplugin/plugin-libocr v0.1.1 - //github.com/goplugin/plugin-common v0.3.0 - //github.com/goplugin/plugin-solana v1.1.1-0.20241009122043-0270b7483530 - //github.com/goplugin/plugin-testing-framework/lib v1.50.9 + //github.com/goplugin/plugin-testing-framework/lib v1.50.11 + github.com/goplugin/plugin-testing-framework/lib v0.4.1 //github.com/goplugin/plugin-testing-framework/seth v1.50.1 - //github.com/goplugin/pluginv3.0/integration-tests v0.0.0-20241010121659-f4c9b9edec10 - //github.com/goplugin/pluginv3.0/v2 v2.14.0-mercury-20240807.0.20241010121659-f4c9b9edec10 + github.com/goplugin/plugin-testing-framework/seth v0.1.1 + //github.com/goplugin/pluginv3.0/integration-tests v0.0.0-20241014200115-3af39c803201 + github.com/goplugin/pluginv3.0/integration-tests v2.4.0 + //github.com/goplugin/pluginv3.0/v2 v2.14.0-mercury-20240807.0.20241014200115-3af39c803201 + github.com/goplugin/pluginv3.0/v2 v2.4.0 //github.com/goplugin/plugin-libocr v0.0.0-20241007185508-adbe57025f12 + github.com/goplugin/plugin-libocr v0.1.1 github.com/stretchr/testify v1.9.0 - github.com/testcontainers/testcontainers-go v0.28.0 + github.com/testcontainers/testcontainers-go v0.33.0 golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 golang.org/x/sync v0.8.0 golang.org/x/text v0.18.0 @@ -50,12 +50,12 @@ require ( github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect github.com/AlekSi/pointer v1.1.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.13.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect - github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect github.com/CosmWasm/wasmd v0.40.1 // indirect github.com/CosmWasm/wasmvm v1.2.4 // indirect @@ -66,7 +66,6 @@ require ( github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Masterminds/sprig/v3 v3.2.3 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/Microsoft/hcsshim v0.11.5 // indirect github.com/NethermindEth/juno v0.3.1 // indirect github.com/NethermindEth/starknet.go v0.7.1-0.20240401080518-34a506f3cfdb // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect @@ -79,7 +78,7 @@ require ( github.com/avast/retry-go v3.0.0+incompatible // indirect github.com/avast/retry-go/v4 v4.6.0 // indirect github.com/awalterschulze/gographviz v2.0.3+incompatible // indirect - github.com/aws/aws-sdk-go v1.45.25 // indirect + github.com/aws/aws-sdk-go v1.54.19 // indirect github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect github.com/aws/aws-sdk-go-v2/config v1.27.28 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.17.28 // indirect @@ -97,6 +96,7 @@ require ( github.com/aws/jsii-runtime-go v1.75.0 // indirect github.com/aws/smithy-go v1.20.4 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect + github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect @@ -128,9 +128,8 @@ require ( github.com/confio/ics23/go v0.9.0 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect - github.com/containerd/containerd v1.7.18 // indirect - github.com/containerd/errdefs v0.1.0 // indirect github.com/containerd/log v0.1.0 // indirect + github.com/containerd/platforms v0.2.1 // indirect github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect @@ -193,15 +192,15 @@ require ( github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect - github.com/go-openapi/analysis v0.21.4 // indirect - github.com/go-openapi/errors v0.20.4 // indirect + github.com/go-openapi/analysis v0.22.2 // indirect + github.com/go-openapi/errors v0.22.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/loads v0.21.2 // indirect - github.com/go-openapi/spec v0.20.9 // indirect - github.com/go-openapi/strfmt v0.21.7 // indirect + github.com/go-openapi/loads v0.21.5 // indirect + github.com/go-openapi/spec v0.20.14 // indirect + github.com/go-openapi/strfmt v0.23.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect - github.com/go-openapi/validate v0.22.1 // indirect + github.com/go-openapi/validate v0.23.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.22.0 // indirect @@ -216,7 +215,7 @@ require ( github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.3 // indirect github.com/gogo/status v1.1.1 // indirect - github.com/golang-jwt/jwt/v5 v5.2.0 // indirect + github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang/glog v1.2.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect @@ -228,7 +227,7 @@ require ( github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-tpm v0.9.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af // indirect + github.com/google/pprof v0.0.0-20240711041743-f6c9dda6c6da // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/gorilla/context v1.1.1 // indirect github.com/gorilla/mux v1.8.0 // indirect @@ -243,7 +242,7 @@ require ( github.com/grafana/loki/pkg/push v0.0.0-20231201111602-11ef833ed3e4 // indirect github.com/grafana/pyroscope-go v1.1.2 // indirect github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect - github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect + github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect @@ -253,19 +252,19 @@ require ( github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect - github.com/hashicorp/consul/api v1.28.2 // indirect - github.com/hashicorp/consul/sdk v0.16.0 // indirect + github.com/hashicorp/consul/api v1.29.2 // indirect + github.com/hashicorp/consul/sdk v0.16.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-envparse v0.1.0 // indirect - github.com/hashicorp/go-hclog v1.5.0 // indirect + github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-msgpack v0.5.5 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-plugin v1.6.2-0.20240829161738-06afb6d7ae99 // indirect - github.com/hashicorp/go-retryablehttp v0.7.5 // indirect + github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect - github.com/hashicorp/go-sockaddr v1.0.2 // indirect + github.com/hashicorp/go-sockaddr v1.0.6 // indirect github.com/hashicorp/golang-lru v0.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/memberlist v0.5.0 // indirect @@ -317,8 +316,7 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/miekg/dns v1.1.56 // indirect + github.com/miekg/dns v1.1.61 // indirect github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect @@ -327,10 +325,12 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect + github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/patternmatcher v0.6.0 // indirect github.com/moby/spdystream v0.4.0 // indirect github.com/moby/sys/sequential v0.5.0 // indirect github.com/moby/sys/user v0.1.0 // indirect + github.com/moby/sys/userns v0.1.0 // indirect github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -357,18 +357,18 @@ require ( github.com/pelletier/go-toml v1.9.5 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect - github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect + github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect - github.com/prometheus/alertmanager v0.26.0 // indirect + github.com/prometheus/alertmanager v0.27.0 // indirect github.com/prometheus/client_golang v1.20.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.59.1 // indirect github.com/prometheus/common/sigv4 v0.1.0 // indirect - github.com/prometheus/exporter-toolkit v0.10.1-0.20230714054209-2f4150c63f97 // indirect + github.com/prometheus/exporter-toolkit v0.11.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/prometheus/prometheus v1.8.2-0.20200727090838-6f296594a852 // indirect + github.com/prometheus/prometheus v0.54.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect @@ -389,32 +389,32 @@ require ( github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/slack-go/slack v0.12.2 // indirect - github.com/goplugin/chain-selectors v0.1.1 + //github.com/goplugin/plugin-selectors v1.0.23 // indirect + github.com/goplugin/plugin-selectors v0.1.1 + //github.com/goplugin/plugin-automation v1.0.5-0.20241009152924-78acf196c332 // indirect github.com/goplugin/plugin-automation v0.0.1 + //github.com/goplugin/plugin-ccip v0.0.0-20241010120731-ae3e8f4935a0 // indirect github.com/goplugin/plugin-ccip v0.0.1 + //github.com/goplugin/plugin-cosmos v0.5.1 // indirect github.com/goplugin/plugin-cosmos v0.0.2 - github.com/goplugin/plugin-data-streams v0.1.1 - github.com/goplugin/plugin-feeds v0.1.1 // indirect - github.com/goplugin/plugin-starknet/relayer v0.0.3-beta - github.com/goplugin/plugin-testing-framework/lib/grafana v0.0.1 - github.com/goplugin/plugin-testing-framework/wasp v0.0.1 - github.com/goplugin/grpc-proxy v0.1.1 - github.com/goplugin/tdh2/go/ocr2/decryptionplugin v0.3.1 - github.com/goplugin/tdh2/go/tdh2 v0.3.1 - github.com/goplugin/wsrpc v0.1.1 - //github.com/goplugin/chain-selectors v1.0.23 // indirect - //github.com/goplugin/plugin-automation v1.0.5-0.20241009152924-78acf196c332 // indirect - //github.com/goplugin/plugin-ccip v0.0.0-20241010120731-ae3e8f4935a0 // indirect - //github.com/goplugin/plugin-cosmos v0.4.1-0.20241008135525-d75be72f25bb // indirect //github.com/goplugin/plugin-data-streams v0.1.0 // indirect + github.com/goplugin/plugin-data-streams v0.1.1 //github.com/goplugin/plugin-feeds v0.1.1 // indirect - //github.com/goplugin/plugin-starknet/relayer v0.0.1-beta-test.0.20241009122052-5e3515805bca // indirect + github.com/goplugin/plugin-feeds v0.1.1 + //github.com/goplugin/plugin-starknet/relayer v0.1.0 // indirect + github.com/goplugin/plugin-starknet/relayer v0.3.3 //github.com/goplugin/plugin-testing-framework/lib/grafana v1.50.0 // indirect + github.com/goplugin/plugin-testing-framework/lib/grafana v0.1.1 //github.com/goplugin/plugin-testing-framework/wasp v1.50.0 // indirect + github.com/goplugin/plugin-testing-framework/wasp v0.1.1 //github.com/goplugin/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect + github.com/goplugin/grpc-proxy v0.1.1 //github.com/goplugin/tdh2/go/ocr2/decryptionplugin v0.0.0-20241009055228-33d0c0bf38de // indirect + github.com/goplugin/tdh2/go/ocr2/decryptionplugin v0.3.1 //github.com/goplugin/tdh2/go/tdh2 v0.0.0-20241009055228-33d0c0bf38de // indirect + github.com/goplugin/tdh2/go/tdh2 v0.3.1 //github.com/goplugin/wsrpc v0.8.2 // indirect + github.com/goplugin/wsrpc v0.1.1 github.com/soheilhy/cmux v0.1.5 // indirect github.com/sony/gobreaker v0.5.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect @@ -462,8 +462,8 @@ require ( go.etcd.io/etcd/client/v3 v3.5.14 // indirect go.mongodb.org/mongo-driver v1.15.0 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/collector/pdata v1.0.0-rcv0016 // indirect - go.opentelemetry.io/collector/semconv v0.87.0 // indirect + go.opentelemetry.io/collector/pdata v1.12.0 // indirect + go.opentelemetry.io/collector/semconv v0.105.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect @@ -532,18 +532,5 @@ require ( sigs.k8s.io/yaml v1.4.0 // indirect ) -exclude github.com/chaos-mesh/chaos-mesh/api/v1alpha1 v0.0.0-20220226050744-799408773657 - -replace ( - github.com/go-kit/log => github.com/go-kit/log v0.2.1 - - // replicating the replace directive on cosmos SDK - github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 - - // K8s imports are weird - github.com/prometheus/client_golang => github.com/prometheus/client_golang v1.14.0 - github.com/prometheus/common => github.com/prometheus/common v0.42.0 - - // type func(a Label, b Label) bool of func(a, b Label) bool {…} does not match inferred type func(a Label, b Label) int for func(a E, b E) int - github.com/prometheus/prometheus => github.com/prometheus/prometheus v0.47.2-0.20231010075449-4b9c19fe5510 -) +// replicating the replace directive on cosmos SDK +replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 634f3a1..2a67129 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -27,7 +27,6 @@ cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUM cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/compute v1.27.2 h1:5cE5hdrwJV/92ravlwIFRGnyH9CpLGhh4N0ZDVTU+BA= -cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= @@ -79,39 +78,28 @@ github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h github.com/AlekSi/pointer v1.1.0 h1:SSDMPcXD9jSl8FPy9cRzoRaMJtm9g9ggGTxecRUbQoI= github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj48UJIZE= github.com/Azure/azure-sdk-for-go v65.0.0+incompatible h1:HzKLt3kIwMm4KeJYTdx9EbjRYTySD/t8i1Ee/W5EGXw= -github.com/Azure/azure-sdk-for-go v65.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0 h1:9kDVnTz3vbfweTqAUmk/a/pH5pWFCHtvRpHYC0G/dcA= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0/go.mod h1:3Ug6Qzto9anB6mGlEdgYMDF5zHQ+wwhEaYR4s17PHMw= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 h1:BMAjVKJM0U/CYF27gA0ZMmXGkOcvfFtD0oHVZ1TIPRI= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0/go.mod h1:1fXstnBMas5kzG+S3q8UoJcmyU6nUeunJcMDHcRYHhs= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.13.0 h1:GJHeeA2N7xrG3q30L2UXDyuWRzDM900/65j70wcM4Ww= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.13.0/go.mod h1:l38EPgmsp71HHLq9j7De57JcKOWPyhrsW1Awm1JS6K0= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH5sE0o6eCJuNDTmH09nDpbc= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0 h1:LkHbJbgF3YyvC53aqYGR+wWQDn2Rdp9AQdGndf9QvY4= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0/go.mod h1:QyiQdW4f4/BIfB8ZutZ2s+28RAgfa/pT+zS++ZHyM1I= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0 h1:bXwSugBiSbgtz7rOtbfGf+woewp4f06orW9OP5BjHLA= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0/go.mod h1:Y/HgrePTmGy9HjdSGTqZNa+apUpTVIEVKXJyARP2lrk= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= -github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.11.29 h1:I4+HL/JDvErx2LjyzaVxllw2lRDB5/BT2Bm4g20iqYw= -github.com/Azure/go-autorest/autorest v0.11.29/go.mod h1:ZtEzC4Jy2JDrZLxvWs8LrBWEBycl1hbT1eknI8MtfAs= -github.com/Azure/go-autorest/autorest/adal v0.9.23 h1:Yepx8CvFxwNKpH6ja7RZ+sKX+DWYNldbLiALMC3BTz8= -github.com/Azure/go-autorest/autorest/adal v0.9.23/go.mod h1:5pcMqFkdPhviJdlEy3kC/v1ZLnQl0MH6XA5YCcMhy4c= -github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= -github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk= -github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= -github.com/Azure/go-autorest/autorest/validation v0.3.1 h1:AgyqjAd94fwNAoTjl/WQXg4VvFeRFpO+UhNyRXqF1ac= -github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= -github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= -github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= -github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= -github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 h1:WpB/QDNLpMw72xHJc34BNNykqSOeEJDAWkhf0u12/Jk= -github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRrLeDnvGIM= github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4= +github.com/Code-Hex/go-generics-cache v1.5.1 h1:6vhZGc5M7Y/YD8cIUcY8kcuQLB4cHR7U+0KMqAA0KcU= +github.com/Code-Hex/go-generics-cache v1.5.1/go.mod h1:qxcC9kRVrct9rHeiYpFWSoW1vxyillCVzX13KZG8dl4= github.com/CosmWasm/wasmd v0.40.1 h1:LxbO78t/6S8TkeQlUrJ0m5O87HtAwLx4RGHq3rdrOEU= github.com/CosmWasm/wasmd v0.40.1/go.mod h1:6EOwnv7MpuFaEqxcUOdFV9i4yvrdOciaY6VQ1o7A3yg= github.com/CosmWasm/wasmvm v1.2.4 h1:6OfeZuEcEH/9iqwrg2pkeVtDCkMoj9U6PpKtcrCyVrQ= @@ -139,8 +127,6 @@ github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/Microsoft/hcsshim v0.11.5 h1:haEcLNpj9Ka1gd3B3tAEs9CpE0c+1IhoL59w/exYU38= -github.com/Microsoft/hcsshim v0.11.5/go.mod h1:MV8xMfmECjl5HdO7U/3/hFVnkmSBjAjmA09d4bExKcU= github.com/NethermindEth/juno v0.3.1 h1:AW72LiAm9gqUeCVJWvepnZcTnpU4Vkl0KzPMxS+42FA= github.com/NethermindEth/juno v0.3.1/go.mod h1:SGbTpgGaCsxhFsKOid7Ylnz//WZ8swtILk+NbHGsk/Q= github.com/NethermindEth/starknet.go v0.7.1-0.20240401080518-34a506f3cfdb h1:Mv8SscePPyw2ju4igIJAjFgcq5zCQfjgbz53DwYu5mc= @@ -150,8 +136,6 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= @@ -161,9 +145,11 @@ github.com/Workiva/go-datastructures v1.1.0/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5 github.com/XSAM/otelsql v0.27.0 h1:i9xtxtdcqXV768a5C6SoT/RkG+ue3JTOgkYInzlTOqs= github.com/XSAM/otelsql v0.27.0/go.mod h1:0mFB3TvLa7NCuhm/2nU7/b2wEtsczkj8Rey8ygO7V+A= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= -github.com/alecthomas/kingpin/v2 v2.3.1/go.mod h1:oYL5vtsvEHZGHxU7DMp32Dvx+qL+ptGn6lWaot2vCNE= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 h1:t3eaIm0rUkzbrIewtiFmMK5RXHej2XnoXNhxVsAYUfg= github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= @@ -191,7 +177,6 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/atombender/go-jsonschema v0.16.1-0.20240916205339-a74cd4e2851c h1:cxQVoh6kY+c4b0HUchHjGWBI8288VhH50qxKG3hdEg0= @@ -205,8 +190,8 @@ github.com/awalterschulze/gographviz v2.0.3+incompatible/go.mod h1:GEV5wmg4YquNw github.com/aws/aws-sdk-go v1.22.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= -github.com/aws/aws-sdk-go v1.45.25 h1:c4fLlh5sLdK2DCRTY1z0hyuJZU4ygxX8m1FswL6/nF4= -github.com/aws/aws-sdk-go v1.45.25/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.54.19 h1:tyWV+07jagrNiCcGRzRhdtVjQs7Vy41NwsuOcl0IbVI= +github.com/aws/aws-sdk-go v1.54.19/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/aws/aws-sdk-go-v2 v1.30.4 h1:frhcagrVNrzmT95RJImMHgabt99vkXGslubDaDagTk8= github.com/aws/aws-sdk-go-v2 v1.30.4/go.mod h1:CT+ZPWXbYrci8chcARI3OmI/qgd+f6WtuLOoaIA8PR0= github.com/aws/aws-sdk-go-v2/config v1.27.28 h1:OTxWGW/91C61QlneCtnD62NLb4W616/NM1jA8LhJqbg= @@ -243,9 +228,13 @@ github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPn github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df h1:GSoSVRLoBaFpOOds6QyY1L8AX7uoY+Ln3BHc22W40X0= github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df/go.mod h1:hiVxq5OP2bUGBRNS3Z/bt/reCLFNbdcST6gISi1fiOM= +github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3 h1:6df1vn4bBlDDo4tARvBm7l6KA9iVMnE3NWizDeWSrps= +github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3/go.mod h1:CIWtjkly68+yqLPbvwwR/fjNJA/idrtULjZWh2v1ys0= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= 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/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= @@ -295,7 +284,6 @@ github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -349,14 +337,12 @@ github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/Yj github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= -github.com/containerd/containerd v1.7.18 h1:jqjZTQNfXGoEaZdW1WwPU0RqSn1Bm2Ay/KJPUuO8nao= -github.com/containerd/containerd v1.7.18/go.mod h1:IYEk9/IO6wAPUz2bCMVUbsfXjzw5UNP5fLz4PsUygQ4= github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8= github.com/containerd/continuity v0.4.3/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= -github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM= -github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= +github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -444,16 +430,15 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WA github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/digitalocean/godo v1.99.0 h1:gUHO7n9bDaZFWvbzOum4bXE0/09ZuYA9yA8idQHX57E= -github.com/digitalocean/godo v1.99.0/go.mod h1:SsS2oXo2rznfM/nORlZ/6JaUJZFhmKTib1YhopUc8NA= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/digitalocean/godo v1.118.0 h1:lkzGFQmACrVCp7UqH1sAi4JK/PWwlc5aaxubgorKmC4= +github.com/digitalocean/godo v1.118.0/go.mod h1:Vk0vpCot2HOAJwc5WE8wljZGtJ3ZtWIc8MQ8rF38sdo= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= -github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v25.0.2+incompatible h1:/OaKeauroa10K4Nqavw4zlhcDq/WBcPMc5DbjOGgozY= -github.com/docker/docker v25.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI= +github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= @@ -554,15 +539,18 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-json-experiment/json v0.0.0-20231102232822-2e55bd4e08b0 h1:ymLjT4f35nQbASLnvxEde4XOBL+Sn7rFuV+FOJqkljg= github.com/go-json-experiment/json v0.0.0-20231102232822-2e55bd4e08b0/go.mod h1:6daplAwHHGbUGib4990V3Il26O0OC4aRyvewaaAihaA= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-ldap/ldap/v3 v3.4.6 h1:ert95MdbiG7aWo/oPYp9btL3KJlMPKnP58r09rI8T+A= github.com/go-ldap/ldap/v3 v3.4.6/go.mod h1:IGMQANNtxpsOzj7uUAMjpGBaOVTC4DYyIy8VsTdxmtc= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -575,41 +563,24 @@ github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= -github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= -github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= -github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= -github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.4 h1:unTcVm6PispJsMECE3zWgvG4xTiKda1LIR5rCRWLG6M= -github.com/go-openapi/errors v0.20.4/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/analysis v0.22.2 h1:ZBmNoP2h5omLKr/srIC9bfqrUGzT6g6gNv03HE9Vpj0= +github.com/go-openapi/analysis v0.22.2/go.mod h1:pDF4UbZsQTo/oNuRfAWWd4dAh4yuYf//LYorPTjrpvo= +github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w= +github.com/go-openapi/errors v0.22.0/go.mod h1:J3DmZScxCDufmIMsdOuDHxJbdOGC0xtUynjIx092vXE= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= -github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= -github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= -github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro= -github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw= -github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= -github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= -github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8= -github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= -github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= -github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= -github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= -github.com/go-openapi/strfmt v0.21.7 h1:rspiXgNWgeUzhjo1YU01do6qsahtJNByjLVbPLNHb8k= -github.com/go-openapi/strfmt v0.21.7/go.mod h1:adeGTkxE44sPyLk0JV235VQAO/ZXUr8KAzYjclFs3ew= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/loads v0.21.5 h1:jDzF4dSoHw6ZFADCGltDb2lE4F6De7aWSpe+IcsRzT0= +github.com/go-openapi/loads v0.21.5/go.mod h1:PxTsnFBoBe+z89riT+wYt3prmSBP6GDAQh2l9H1Flz8= +github.com/go-openapi/spec v0.20.14 h1:7CBlRnw+mtjFGlPDRZmAMnq35cRzI91xj03HVyUi/Do= +github.com/go-openapi/spec v0.20.14/go.mod h1:8EOhTpBoFiask8rrgwbLC3zmJfz4zsCUueRuPM6GNkw= +github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c= +github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= -github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= +github.com/go-openapi/validate v0.23.0 h1:2l7PJLzCis4YUGEoW6eoQw3WhyM65WSIcjX6SQnlfDw= +github.com/go-openapi/validate v0.23.0/go.mod h1:EeiAZ5bmpSIOJV1WLfyYF9qp/B1ZgSaEpHTJHtN5cbE= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= @@ -620,8 +591,8 @@ github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4 github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= -github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8= -github.com/go-resty/resty/v2 v2.11.0/go.mod h1:iiP/OpA0CkcL3IGt1O0+/SIItFUbkkyw5BGXiVdTu+A= +github.com/go-resty/resty/v2 v2.13.1 h1:x+LHXBI2nMB1vqndymf26quycC4aggYJ7DECYbiz03g= +github.com/go-resty/resty/v2 v2.13.1/go.mod h1:GznXlLxkq6Nh4sU59rPmUw3VtgpO3aS96ORAI6Q7d+0= 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= @@ -639,30 +610,6 @@ github.com/go-webauthn/x v0.1.5 h1:V2TCzDU2TGLd0kSZOXdrqDVV5JB9ILnKxA9S53CSBw0= github.com/go-webauthn/x v0.1.5/go.mod h1:qbzWwcFcv4rTwtCLOZd+icnr6B7oSsAGZJqlt8cukqY= github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg= github.com/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= -github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= -github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= -github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= -github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= -github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= -github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= -github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= -github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= -github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= -github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= -github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= -github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= -github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= -github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= -github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= -github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-yaml v1.12.0 h1:/1WHjnMsI1dlIBQutrvSMGZRQufVO3asrHfTwfACoPM= @@ -682,8 +629,8 @@ github.com/gogo/status v1.1.1 h1:DuHXlSFHNKqTQ+/ACf5Vs6r4X/dH2EgIzR9Vr+H65kg= github.com/gogo/status v1.1.1/go.mod h1:jpG3dM5QPcqu19Hg8lkUhBFBa3TcLs1DG7+2Jqci7oU= 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-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= -github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= @@ -742,10 +689,10 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -771,8 +718,8 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= -github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20240711041743-f6c9dda6c6da h1:xRmpO92tb8y+Z85iUOMOicpCfaYcv7o3Cg3wKrIpg8g= +github.com/google/pprof v0.0.0-20240711041743-f6c9dda6c6da/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= @@ -790,8 +737,8 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.12.5 h1:8gw9KZK8TiVKB6q3zHY3SBzLnrGp6HQjyfYBYGmXdxA= github.com/googleapis/gax-go/v2 v2.12.5/go.mod h1:BUDKcWo+RaKq5SC9vVYL0wLADa3VcfswbOMMRmB9H3E= -github.com/gophercloud/gophercloud v1.5.0 h1:cDN6XFCLKiiqvYpjQLq9AiM7RDRbIC9450WpPH+yvXo= -github.com/gophercloud/gophercloud v1.5.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= +github.com/gophercloud/gophercloud v1.13.0 h1:8iY9d1DAbzMW6Vok1AxbbK5ZaUjzMp0tdyt4fX9IeJ0= +github.com/gophercloud/gophercloud v1.13.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -822,8 +769,8 @@ github.com/grafana/pyroscope-go v1.1.2 h1:7vCfdORYQMCxIzI3NlYAs3FcBP760+gWuYWOyi github.com/grafana/pyroscope-go v1.1.2/go.mod h1:HSSmHo2KRn6FasBA4vK7BMiQqyQq8KSuBKvrhkXxYPU= github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= -github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww= -github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= +github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrRoT6yV5+wkrOpcszoIsO4+4ds248= +github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk= github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug= github.com/graph-gophers/dataloader v5.0.0+incompatible/go.mod h1:jk4jk0c5ZISbKaMe8WsVopGB5/15GvGHMdMdPtwlRp4= github.com/graph-gophers/graphql-go v1.5.0 h1:fDqblo50TEpD0LY7RXk/LFVYEVqo3+tXMNMPSVXA1yc= @@ -852,11 +799,13 @@ github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/b github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/api v1.28.2 h1:mXfkRHrpHN4YY3RqL09nXU1eHKLNiuAN4kHvDQ16k/8= -github.com/hashicorp/consul/api v1.28.2/go.mod h1:KyzqzgMEya+IZPcD65YFoOVAgPpbfERu4I/tzG6/ueE= +github.com/hashicorp/consul/api v1.29.2 h1:aYyRn8EdE2mSfG14S1+L9Qkjtz8RzmaWh6AcNGRNwPw= +github.com/hashicorp/consul/api v1.29.2/go.mod h1:0YObcaLNDSbtlgzIRtmRXI1ZkeuK0trCBxwZQ4MYnIk= +github.com/hashicorp/consul/proto-public v0.6.2 h1:+DA/3g/IiKlJZb88NBn0ZgXrxJp2NlvCZdEyl+qxvL0= +github.com/hashicorp/consul/proto-public v0.6.2/go.mod h1:cXXbOg74KBNGajC+o8RlA502Esf0R9prcoJgiOX/2Tg= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/consul/sdk v0.16.0 h1:SE9m0W6DEfgIVCJX7xU+iv/hUl4m/nxqMTnCdMxDpJ8= -github.com/hashicorp/consul/sdk v0.16.0/go.mod h1:7pxqqhqoaPqnBnzXD1StKed62LqJeClzVsUEy85Zr0A= +github.com/hashicorp/consul/sdk v0.16.1 h1:V8TxTnImoPD5cj0U9Spl0TUxcytjcbbJeADFF07KdHg= +github.com/hashicorp/consul/sdk v0.16.1/go.mod h1:fSXvwxB2hmh1FMZCNl6PwX0Q/1wdWtHJcZ7Ea5tns0s= github.com/hashicorp/cronexpr v1.1.2 h1:wG/ZYIKT+RT3QkOdgYc+xsKWVRgnxJ1OJtjjy84fJ9A= github.com/hashicorp/cronexpr v1.1.2/go.mod h1:P4wA0KBl9C5q2hABiMO7cp6jcIg96CDh1Efb3g1PWA4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -872,9 +821,8 @@ github.com/hashicorp/go-envparse v0.1.0 h1:bE++6bhIsNCPLvgDZkYqo3nA+/PFI51pkrHdm github.com/hashicorp/go-envparse v0.1.0/go.mod h1:OHheN1GoygLlAkTlXLXvAdnXdZxy8JUweQ1rAXx1xnc= github.com/hashicorp/go-getter v1.7.1 h1:SWiSWN/42qdpR0MdhaOc/bLR48PLuP1ZQtYLRlM69uY= github.com/hashicorp/go-getter v1.7.1/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= -github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -888,23 +836,23 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9 github.com/hashicorp/go-plugin v1.6.2-0.20240829161738-06afb6d7ae99 h1:OSQYEsRT3tRttZkk6zyC3aAaliwd7Loi/KgXgXxGtwA= github.com/hashicorp/go-plugin v1.6.2-0.20240829161738-06afb6d7ae99/go.mod h1:CkgLQ5CZqNmdL9U9JzM532t8ZiYQ35+pj3b1FD37R0Q= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M= -github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= +github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= +github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= -github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= +github.com/hashicorp/go-sockaddr v1.0.6 h1:RSG8rKU28VTUTvEKghe5gIhIQpv8evvNpnDEyqO4u9I= +github.com/hashicorp/go-sockaddr v1.0.6/go.mod h1:uoUUmtwU7n9Dv3O4SNLeFvg0SxQ3lyjsj6+CCykpaxI= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= -github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= +github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -919,8 +867,8 @@ github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= -github.com/hashicorp/nomad/api v0.0.0-20230718173136-3a687930bd3e h1:sr4lujmn9heD030xx/Pd4B/JSmvRhFzuotNXaaV0WLs= -github.com/hashicorp/nomad/api v0.0.0-20230718173136-3a687930bd3e/go.mod h1:O23qLAZuCx4htdY9zBaO4cJPXgleSFEdq6D/sezGgYE= +github.com/hashicorp/nomad/api v0.0.0-20240717122358-3d93bd3778f3 h1:fgVfQ4AC1avVOnu2cfms8VAiD8lUq3vWI8mTocOXN/w= +github.com/hashicorp/nomad/api v0.0.0-20240717122358-3d93bd3778f3/go.mod h1:svtxn6QnrQ69P23VvIWMR34tg3vmwLz4UdUzm1dSCgE= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= @@ -928,8 +876,8 @@ github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hdevalence/ed25519consensus v0.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7HsjsjeEZ6auqU= github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= -github.com/hetznercloud/hcloud-go/v2 v2.0.0 h1:Sg1DJ+MAKvbYAqaBaq9tPbwXBS2ckPIaMtVdUjKu+4g= -github.com/hetznercloud/hcloud-go/v2 v2.0.0/go.mod h1:4iUG2NG8b61IAwNx6UsMWQ6IfIf/i1RsG0BbsKAyR5Q= +github.com/hetznercloud/hcloud-go/v2 v2.10.2 h1:9gyTUPhfNbfbS40Spgij5mV5k37bOZgt8iHKCbfGs5I= +github.com/hetznercloud/hcloud-go/v2 v2.10.2/go.mod h1:xQ+8KhIS62W0D78Dpi57jsufWh844gUw1az5OUvaeq8= github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw= github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= @@ -960,8 +908,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI= github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= -github.com/ionos-cloud/sdk-go/v6 v6.1.8 h1:493wE/BkZxJf7x79UCE0cYGPZoqQcPiEBALvt7uVGY0= -github.com/ionos-cloud/sdk-go/v6 v6.1.8/go.mod h1:EzEgRIDxBELvfoa/uBN0kOQaqovLjUWEB7iW4/Q+t4k= +github.com/ionos-cloud/sdk-go/v6 v6.1.11 h1:J/uRN4UWO3wCyGOeDdMKv8LWRzKu6UIkLEaes38Kzh8= +github.com/ionos-cloud/sdk-go/v6 v6.1.11/go.mod h1:EzEgRIDxBELvfoa/uBN0kOQaqovLjUWEB7iW4/Q+t4k= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= @@ -1023,7 +971,6 @@ github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= @@ -1034,15 +981,17 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= -github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -1060,6 +1009,7 @@ github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJ github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -1086,8 +1036,8 @@ github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6 github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= -github.com/linode/linodego v1.19.0 h1:n4WJrcr9+30e9JGZ6DI0nZbm5SdAj1kSwvvt/998YUw= -github.com/linode/linodego v1.19.0/go.mod h1:XZFR+yJ9mm2kwf6itZ6SCpu+6w3KnIevV0Uu5HNWJgQ= +github.com/linode/linodego v1.37.0 h1:B/2Spzv9jYXzKA+p+GD8fVCNJ7Wuw6P91ZDD9eCkkso= +github.com/linode/linodego v1.37.0/go.mod h1:L7GXKFD3PoN2xSEtFc04wIXP5WK65O10jYQx0PQISWQ= github.com/linxGnu/grocksdb v1.7.16 h1:Q2co1xrpdkr5Hx3Fp+f+f7fRGhQFQhvi/+226dtLmA8= github.com/linxGnu/grocksdb v1.7.16/go.mod h1:JkS7pl5qWpGpuVb3bPqTz8nC12X3YtPZT+Xq7+QfQo4= github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY= @@ -1100,17 +1050,12 @@ github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f h1:tVvGiZQFjOXP+9YyGqSA6jE55x1XVxmoPYudncxrZ8U= github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f/go.mod h1:Z60vy0EZVSu0bOugCHdcN5ZxFMKSpjRgsnh0XKPFqqk= -github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= -github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -1137,15 +1082,13 @@ github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxU github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -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/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY= github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= -github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= +github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= +github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94= github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= @@ -1162,15 +1105,12 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= -github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= @@ -1181,6 +1121,8 @@ github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx 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/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= +github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= github.com/moby/spdystream v0.4.0 h1:Vy79D6mHeJJjiPdFEL2yku1kl0chZpJfZcPpb16BRl8= @@ -1189,11 +1131,14 @@ github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5 github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg= github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU= +github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= +github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= @@ -1212,14 +1157,15 @@ github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= -github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249 h1:NHrXEjTNQY7P0Zfx1aMrNhpgxHmow66XQtm0aQLY0AE= -github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249/go.mod h1:mpRZBD8SJ55OIICQ3iWH0Yz3cjzA61JdqMLoWXeB2+8= +github.com/nsf/jsondiff v0.0.0-20230430225905-43f6cf3098c1 h1:dOYG7LS/WK00RWZc8XGgcUTlTxpp3mKhdR2Q9z9HbXM= +github.com/nsf/jsondiff v0.0.0-20230430225905-43f6cf3098c1/go.mod h1:mpRZBD8SJ55OIICQ3iWH0Yz3cjzA61JdqMLoWXeB2+8= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -1262,8 +1208,8 @@ github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w= github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks= github.com/otiai10/mint v1.5.1/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM= -github.com/ovh/go-ovh v1.4.1 h1:VBGa5wMyQtTP7Zb+w97zRCh9sLtM/2YKRyy+MEJmWaM= -github.com/ovh/go-ovh v1.4.1/go.mod h1:6bL6pPyUT7tBfI0pqOegJgRjgjuO+mOo+MyXd1EEC0M= +github.com/ovh/go-ovh v1.6.0 h1:ixLOwxQdzYDx296sXcgS35TOPEahJkpjMGtzPadCjQI= +github.com/ovh/go-ovh v1.6.0/go.mod h1:cTVDnl94z4tl8pP1uZ/8jlVxntjSIf09bNcQ5TJSC7c= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -1272,7 +1218,6 @@ github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTK github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= @@ -1286,8 +1231,8 @@ github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= -github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -1303,26 +1248,46 @@ github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/pressly/goose/v3 v3.21.1 h1:5SSAKKWej8LVVzNLuT6KIvP1eFDuPvxa+B6H0w78buQ= github.com/pressly/goose/v3 v3.21.1/go.mod h1:sqthmzV8PitchEkjecFJII//l43dLOCzfWh8pHEe+vE= -github.com/prometheus/alertmanager v0.26.0 h1:uOMJWfIwJguc3NaM3appWNbbrh6G/OjvaHMk22aBBYc= -github.com/prometheus/alertmanager v0.26.0/go.mod h1:rVcnARltVjavgVaNnmevxK7kOn7IZavyf0KNgHkbEpU= -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/alertmanager v0.27.0 h1:V6nTa2J5V4s8TG4C4HtrBP/WNSebCCTYGGv4qecA/+I= +github.com/prometheus/alertmanager v0.27.0/go.mod h1:8Ia/R3urPmbzJ8OsdvmZvIprDwvwmYCmUbwBL+jlPOE= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI= +github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= -github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= +github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4= github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI= -github.com/prometheus/exporter-toolkit v0.10.1-0.20230714054209-2f4150c63f97 h1:oHcfzdJnM/SFppy2aUlvomk37GI33x9vgJULihE5Dt8= -github.com/prometheus/exporter-toolkit v0.10.1-0.20230714054209-2f4150c63f97/go.mod h1:LoBCZeRh+5hX+fSULNyFnagYlQG/gBsyA/deNzROkq8= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/prometheus/exporter-toolkit v0.11.0 h1:yNTsuZ0aNCNFQ3aFTD2uhPOvr4iD7fdBvKPAEGkNf+g= +github.com/prometheus/exporter-toolkit v0.11.0/go.mod h1:BVnENhnNecpwoTLiABx7mrPB/OLRIgN74qlQbV+FK1Q= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/prometheus/prometheus v0.47.2-0.20231010075449-4b9c19fe5510 h1:6ksZ7t1hNOzGPPs8DK7SvXQf6UfWzi+W5Z7PCBl8gx4= -github.com/prometheus/prometheus v0.47.2-0.20231010075449-4b9c19fe5510/go.mod h1:UC0TwJiF90m2T3iYPQBKnGu8gv3s55dF/EgpTq8gyvo= +github.com/prometheus/prometheus v0.54.1 h1:vKuwQNjnYN2/mDoWfHXDhAsz/68q/dQDb+YbcEqU7MQ= +github.com/prometheus/prometheus v0.54.1/go.mod h1:xlLByHhk2g3ycakQGrMaU8K7OySZx98BzeCR99991NY= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= @@ -1336,14 +1301,12 @@ github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= 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.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= -github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= +github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= @@ -1355,7 +1318,6 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD 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/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= @@ -1367,8 +1329,8 @@ github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPO github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.20 h1:a9hSJdJcd16e0HoMsnFvaHvxB3pxSD+SC7+CISp7xY0= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.20/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.29 h1:BkTk4gynLjguayxrYxZoMZjBnAOh7ntQvUkOFmkMqPU= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.29/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= github.com/scylladb/go-reflectx v1.0.1 h1:b917wZM7189pZdlND9PbIJ6NQxfDPfBvUaQ7cjj1iZQ= github.com/scylladb/go-reflectx v1.0.1/go.mod h1:rWnOfDIRWBGN0miMLIcoPt/Dhi2doCMZqwMCJ3KupFc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= @@ -1395,41 +1357,42 @@ github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFR github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ= github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= -github.com/goplugin/chain-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnjjIQAEBnutCtksPzVDY= -github.com/goplugin/chain-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= +github.com/goplugin/plugin-selectors v1.0.23 h1:D2Eaex4Cw/O7Lg3tX6WklOqnjjIQAEBnutCtksPzVDY= +github.com/goplugin/plugin-selectors v1.0.23/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/goplugin/plugin-automation v1.0.5-0.20241009152924-78acf196c332 h1:PA8owz52v9CPdHMYUxHAqfHgo+QgZqP6kOBgioJeRno= github.com/goplugin/plugin-automation v1.0.5-0.20241009152924-78acf196c332/go.mod h1:74ly9zfnQ9EwBtHZH46sIAbxQdOnX56fFjjvSQvn53k= github.com/goplugin/plugin-ccip v0.0.0-20241010120731-ae3e8f4935a0 h1:nKfjG9fufMQspKO0hFGK2B9ICL+tgajwP+nAXYP0LPc= github.com/goplugin/plugin-ccip v0.0.0-20241010120731-ae3e8f4935a0/go.mod h1:DjyfH0AGcqctKB6DaRUpRL6GJ2SbrpiaBkA4h24/oMY= -github.com/goplugin/plugin-common v0.3.0 h1:mUXHBzzw2qPKyw6gPAC8JhO+ryT8maY+rBi9NFtqEy0= -github.com/goplugin/plugin-common v0.3.0/go.mod h1:tsGgeEJc5SUSlfVGSX0wR0EkRU3pM58D6SKF97V68ko= -github.com/goplugin/plugin-cosmos v0.4.1-0.20241008135525-d75be72f25bb h1:9XiAPwKjs4iFRwrS0FyfL51EqbEa3e6HaK5nyNDBbEU= -github.com/goplugin/plugin-cosmos v0.4.1-0.20241008135525-d75be72f25bb/go.mod h1:y2S8FHoI38zslLu17kKe2jNbvI/D/F76nmOF2/A+INE= +github.com/goplugin/plugin-common v0.3.1-0.20241011160913-5d432bcdc2e8 h1:S3DuS2Su9Oo+3O1kSqNHxqz+iv5y5ljbikK0xrBp8/E= +github.com/goplugin/plugin-common v0.3.1-0.20241011160913-5d432bcdc2e8/go.mod h1:tsGgeEJc5SUSlfVGSX0wR0EkRU3pM58D6SKF97V68ko= +github.com/goplugin/plugin-cosmos v0.5.1 h1:2xeZWh+4/w7xalTdAu8jqgFuxZ291aYTEwZhlQEv/BY= +github.com/goplugin/plugin-cosmos v0.5.1/go.mod h1:c1wUtVxXUqW4PzuCQhuHaBDZFv9XAQjhKTqam7GLGIU= github.com/goplugin/plugin-data-streams v0.1.0 h1:wcRJRm7eqfbgN+Na+GjAe0/IUn6XwmSagFHqIWHHBGk= github.com/goplugin/plugin-data-streams v0.1.0/go.mod h1:lmdRVjg49Do+5tkk9V5iAhi+Jm2kXhjZXWAbzh7xg7o= github.com/goplugin/plugin-feeds v0.1.1 h1:JzvUOM/OgGQA1sOqTXXl52R6AnNt+Wg64sVG+XSA49c= github.com/goplugin/plugin-feeds v0.1.1/go.mod h1:55EZ94HlKCfAsUiKUTNI7QlE/3d3IwTlsU3YNa/nBb4= -github.com/goplugin/plugin-starknet/relayer v0.0.1-beta-test.0.20241009122052-5e3515805bca h1:tKqIrp7iyyRRkf7KQNL+7FmgipbS8ZW8Awz5F439t9M= -github.com/goplugin/plugin-starknet/relayer v0.0.1-beta-test.0.20241009122052-5e3515805bca/go.mod h1:iGSdkBJP38WEgpnAB09xG4Jor0GzZ+4U2ZhwwIdLVgA= -github.com/goplugin/plugin-testing-framework/lib v1.50.9 h1:/2kAb6y854viKigkdFMWDNNbaz3zD0gAkbZoSHC8Rrg= -github.com/goplugin/plugin-testing-framework/lib v1.50.9/go.mod h1:7R5wGWWJi0dr5Y5cXbLQ4vSeIj0ElvhBaymcfvqqUmo= +github.com/goplugin/plugin-starknet/relayer v0.1.0 h1:C00zDQ6AQdR9JFrHnOBEhC2TlYVzVSsC7k5AZ7hXwHI= +github.com/goplugin/plugin-starknet/relayer v0.1.0/go.mod h1:K6cKpFDW2hX4D4F5aq86l13AMJ3jyEz/AjZyGjYlS90= +github.com/goplugin/plugin-testing-framework/lib v1.50.11 h1:JvRVMS6aXMoux9i/xihHo/qZtNwtv4lpbjsxo2O/1gE= +github.com/goplugin/plugin-testing-framework/lib v1.50.11/go.mod h1:c5Is0W7DUUEeV369pWbAOYqEktlGeIBQXefGyIMCzvE= github.com/goplugin/plugin-testing-framework/lib/grafana v1.50.0 h1:VIxK8u0Jd0Q/VuhmsNm6Bls6Tb31H/sA3A/rbc5hnhg= github.com/goplugin/plugin-testing-framework/lib/grafana v1.50.0/go.mod h1:lyAu+oMXdNUzEDScj2DXB2IueY+SDXPPfyl/kb63tMM= github.com/goplugin/plugin-testing-framework/seth v1.50.1 h1:2OxnPfvjC+zs0ZokSsRTRnJrEGJ4NVJwZgfroS1lPHs= github.com/goplugin/plugin-testing-framework/seth v1.50.1/go.mod h1:afY3QmNgeR/VI1pRbGH8g3YXGy7C2RrFOwUzEFvL3L8= github.com/goplugin/plugin-testing-framework/wasp v1.50.0 h1:gfhfTn7HkbUHNooSF3c9vzQyN8meWJVGt6G/pNUbpYk= github.com/goplugin/plugin-testing-framework/wasp v1.50.0/go.mod h1:tqajhpUJA/9OaMCLitghBXjAgqYO4i27St0F4TUO3+M= -github.com/goplugin/pluginv3.0/integration-tests v0.0.0-20241010121659-f4c9b9edec10 h1:uUK1KMFMFcf1vAdRZneuQRMUs6ndAoNjQHCzP/6vW1A= -github.com/goplugin/pluginv3.0/integration-tests v0.0.0-20241010121659-f4c9b9edec10/go.mod h1:RkygC5/TnCHNG53/CYW/Npsr6Rbgko/zJa0rjtCVNRc= -github.com/goplugin/pluginv3.0/v2 v2.14.0-mercury-20240807.0.20241010121659-f4c9b9edec10 h1:DPxJaQ4W8J+2PRDzEVmIaNFKOYuwdVD5B6bLDK701ow= -github.com/goplugin/pluginv3.0/v2 v2.14.0-mercury-20240807.0.20241010121659-f4c9b9edec10/go.mod h1:FHbp4U77ODNWbttd7/HcFuMLCnws/zqtOHTVUXp8wC8= +github.com/goplugin/pluginv3.0/integration-tests v0.0.0-20241014200115-3af39c803201 h1:ggSgEMf475ZqHFRhXTqfIdnKVWzyH3LMWH57DG/Ty8E= +github.com/goplugin/pluginv3.0/integration-tests v0.0.0-20241014200115-3af39c803201/go.mod h1:kMiICu9TUtelsGy44wkwnKbFRINnsBBoAMXotfNm78Q= +github.com/goplugin/pluginv3.0/v2 v2.14.0-mercury-20240807.0.20241014200115-3af39c803201 h1:dWEursSoqcN1AUbaRHamPBfDCx96CirxlHgekgdtqcs= +github.com/goplugin/pluginv3.0/v2 v2.14.0-mercury-20240807.0.20241014200115-3af39c803201/go.mod h1:KbO2His3P8Lg9qcikZeZ1KdYCutV6tkoyT/sJw92bjE= github.com/goplugin/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= github.com/goplugin/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7/go.mod h1:FX7/bVdoep147QQhsOPkYsPEXhGZjeYx6lBSaSXtZOA= github.com/goplugin/plugin-libocr v0.0.0-20241007185508-adbe57025f12 h1:NzZGjaqez21I3DU7objl3xExTH4fxYvzTqar8DC6360= @@ -1459,7 +1422,6 @@ github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= @@ -1512,8 +1474,8 @@ github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 h1:3SNcvBmEPE1YlB github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0= github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE= github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU= -github.com/testcontainers/testcontainers-go v0.28.0 h1:1HLm9qm+J5VikzFDYhOd+Zw12NtOl+8drH2E8nTY1r8= -github.com/testcontainers/testcontainers-go v0.28.0/go.mod h1:COlDpUXbwW3owtpMkEB1zo9gwb1CoKVKlyrVPejF4AU= +github.com/testcontainers/testcontainers-go v0.33.0 h1:zJS9PfXYT5O0ZFXM2xxXfk4J5UMw/kRiISng037Gxdw= +github.com/testcontainers/testcontainers-go v0.33.0/go.mod h1:W80YpTa8D5C3Yy16icheD01UTDu+LmXIA2Keo+jWtT8= github.com/theodesp/go-heaps v0.0.0-20190520121037-88e35354fe0a h1:YuO+afVc3eqrjiCUizNCxI53bl/BnPiVwXqLzqYTqgU= github.com/theodesp/go-heaps v0.0.0-20190520121037-88e35354fe0a/go.mod h1:/sfW47zCZp9FrtGcWyo1VjbgDaodxX9ovZvgLb/MxaA= github.com/tidwall/btree v1.6.0 h1:LDZfKfQIBHGHWSwckhXI0RPSXzlo+KYdjK7FWSqOzzg= @@ -1571,11 +1533,8 @@ github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+x 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/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= -github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= -github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= @@ -1616,9 +1575,6 @@ go.etcd.io/etcd/client/pkg/v3 v3.5.14 h1:SaNH6Y+rVEdxfpA2Jr5wkEvN6Zykme5+YnbCkxv go.etcd.io/etcd/client/pkg/v3 v3.5.14/go.mod h1:8uMgAokyG1czCtIdsq+AGyYQMvpIKnSvPjFMunkgeZI= go.etcd.io/etcd/client/v3 v3.5.14 h1:CWfRs4FDaDoSz81giL7zPpZH2Z35tbOrAJkkjMqOupg= go.etcd.io/etcd/client/v3 v3.5.14/go.mod h1:k3XfdV/VIHy/97rqWjoUzrj9tk7GgJGH9J8L4dNXmAk= -go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= -go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= -go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= go.mongodb.org/mongo-driver v1.11.0/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8= go.mongodb.org/mongo-driver v1.15.0 h1:rJCKC8eEliewXjZGf0ddURtl7tTVy1TK3bfl0gkUSLc= go.mongodb.org/mongo-driver v1.15.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= @@ -1631,10 +1587,10 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/collector/pdata v1.0.0-rcv0016 h1:qCPXSQCoD3qeWFb1RuIks8fw9Atxpk78bmtVdi15KhE= -go.opentelemetry.io/collector/pdata v1.0.0-rcv0016/go.mod h1:OdN0alYOlYhHXu6BDlGehrZWgtBuiDsz/rlNeJeXiNg= -go.opentelemetry.io/collector/semconv v0.87.0 h1:BsG1jdLLRCBRlvUujk4QA86af7r/ZXnizczQpEs/gg8= -go.opentelemetry.io/collector/semconv v0.87.0/go.mod h1:j/8THcqVxFna1FpvA2zYIsUperEtOaRaqoLYIN4doWw= +go.opentelemetry.io/collector/pdata v1.12.0 h1:Xx5VK1p4VO0md8MWm2icwC1MnJ7f8EimKItMWw46BmA= +go.opentelemetry.io/collector/pdata v1.12.0/go.mod h1:MYeB0MmMAxeM0hstCFrCqWLzdyeYySim2dG6pDT6nYI= +go.opentelemetry.io/collector/semconv v0.105.0 h1:8p6dZ3JfxFTjbY38d8xlQGB1TQ3nPUvs+D0RERniZ1g= +go.opentelemetry.io/collector/semconv v0.105.0/go.mod h1:yMVUCNoQPZVq/IPfrHrnntZTWsLf5YGZ7qwKulIl5hw= 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/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= @@ -1651,8 +1607,8 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9RO go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 h1:j9+03ymgYhPKmeXGk5Zu+cIZOlVzd9Zv7QIiyItjFBU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0/go.mod h1:Y5+XiUG4Emn1hTfciPzGPJaSI+RpDts6BnCIir0SLqk= go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.4.0 h1:0MH3f8lZrflbUWXVxyBg/zviDFdGE062uKh5+fu8Vv0= go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.4.0/go.mod h1:Vh68vYiHY5mPdekTr0ox0sALsqjoVy0w3Os278yX5SQ= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0 h1:BJee2iLkfRfl9lc7aFmBwkWxY/RI1RDdXepSF6y8TPE= @@ -1714,14 +1670,12 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= -golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= @@ -1734,7 +1688,8 @@ golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1779,6 +1734,7 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1788,6 +1744,7 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1817,19 +1774,17 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1837,22 +1792,20 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= @@ -1863,6 +1816,7 @@ golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1870,11 +1824,9 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1891,6 +1843,7 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1904,22 +1857,24 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1940,8 +1895,9 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -1949,12 +1905,12 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1970,12 +1926,14 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1985,14 +1943,10 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= @@ -2155,14 +2109,12 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -2184,16 +2136,16 @@ gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 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.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/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= diff --git a/pkg/solana/chain.go b/pkg/solana/chain.go index 645b1b6..d8c491d 100644 --- a/pkg/solana/chain.go +++ b/pkg/solana/chain.go @@ -89,8 +89,8 @@ type chain struct { lggr logger.Logger // if multiNode is enabled, the clientCache will not be used - multiNode *mn.MultiNode[mn.StringID, *client.Client] - txSender *mn.TransactionSender[*solanago.Transaction, mn.StringID, *client.Client] + multiNode *mn.MultiNode[mn.StringID, *client.MultiNodeClient] + txSender *mn.TransactionSender[*solanago.Transaction, mn.StringID, *client.MultiNodeClient] // tracking node chain id for verification clientCache map[string]*verifiedCachedClient // map URL -> {client, chainId} [mainnet/testnet/devnet/localnet] @@ -108,7 +108,7 @@ type verifiedCachedClient struct { client.ReaderWriter } -func (v *verifiedCachedClient) verifyChainID() (bool, error) { +func (v *verifiedCachedClient) verifyChainID(ctx context.Context) (bool, error) { v.chainIDVerifiedLock.RLock() if v.chainIDVerified { v.chainIDVerifiedLock.RUnlock() @@ -121,7 +121,7 @@ func (v *verifiedCachedClient) verifyChainID() (bool, error) { v.chainIDVerifiedLock.Lock() defer v.chainIDVerifiedLock.Unlock() - strID, err := v.ReaderWriter.ChainID(context.Background()) + strID, err := v.ReaderWriter.ChainID(ctx) v.chainID = strID.String() if err != nil { v.chainIDVerified = false @@ -141,7 +141,7 @@ func (v *verifiedCachedClient) verifyChainID() (bool, error) { } func (v *verifiedCachedClient) SendTx(ctx context.Context, tx *solanago.Transaction) (solanago.Signature, error) { - verified, err := v.verifyChainID() + verified, err := v.verifyChainID(ctx) if !verified { return [64]byte{}, err } @@ -150,7 +150,7 @@ func (v *verifiedCachedClient) SendTx(ctx context.Context, tx *solanago.Transact } func (v *verifiedCachedClient) SimulateTx(ctx context.Context, tx *solanago.Transaction, opts *rpc.SimulateTransactionOpts) (*rpc.SimulateTransactionResult, error) { - verified, err := v.verifyChainID() + verified, err := v.verifyChainID(ctx) if !verified { return nil, err } @@ -159,7 +159,7 @@ func (v *verifiedCachedClient) SimulateTx(ctx context.Context, tx *solanago.Tran } func (v *verifiedCachedClient) SignatureStatuses(ctx context.Context, sigs []solanago.Signature) ([]*rpc.SignatureStatusesResult, error) { - verified, err := v.verifyChainID() + verified, err := v.verifyChainID(ctx) if !verified { return nil, err } @@ -167,35 +167,35 @@ func (v *verifiedCachedClient) SignatureStatuses(ctx context.Context, sigs []sol return v.ReaderWriter.SignatureStatuses(ctx, sigs) } -func (v *verifiedCachedClient) Balance(addr solanago.PublicKey) (uint64, error) { - verified, err := v.verifyChainID() +func (v *verifiedCachedClient) Balance(ctx context.Context, addr solanago.PublicKey) (uint64, error) { + verified, err := v.verifyChainID(ctx) if !verified { return 0, err } - return v.ReaderWriter.Balance(addr) + return v.ReaderWriter.Balance(ctx, addr) } -func (v *verifiedCachedClient) SlotHeight() (uint64, error) { - verified, err := v.verifyChainID() +func (v *verifiedCachedClient) SlotHeight(ctx context.Context) (uint64, error) { + verified, err := v.verifyChainID(ctx) if !verified { return 0, err } - return v.ReaderWriter.SlotHeight() + return v.ReaderWriter.SlotHeight(ctx) } -func (v *verifiedCachedClient) LatestBlockhash() (*rpc.GetLatestBlockhashResult, error) { - verified, err := v.verifyChainID() +func (v *verifiedCachedClient) LatestBlockhash(ctx context.Context) (*rpc.GetLatestBlockhashResult, error) { + verified, err := v.verifyChainID(ctx) if !verified { return nil, err } - return v.ReaderWriter.LatestBlockhash() + return v.ReaderWriter.LatestBlockhash(ctx) } func (v *verifiedCachedClient) ChainID(ctx context.Context) (mn.StringID, error) { - verified, err := v.verifyChainID() + verified, err := v.verifyChainID(ctx) if !verified { return "", err } @@ -203,17 +203,17 @@ func (v *verifiedCachedClient) ChainID(ctx context.Context) (mn.StringID, error) return mn.StringID(v.chainID), nil } -func (v *verifiedCachedClient) GetFeeForMessage(msg string) (uint64, error) { - verified, err := v.verifyChainID() +func (v *verifiedCachedClient) GetFeeForMessage(ctx context.Context, msg string) (uint64, error) { + verified, err := v.verifyChainID(ctx) if !verified { return 0, err } - return v.ReaderWriter.GetFeeForMessage(msg) + return v.ReaderWriter.GetFeeForMessage(ctx, msg) } func (v *verifiedCachedClient) GetAccountInfoWithOpts(ctx context.Context, addr solanago.PublicKey, opts *rpc.GetAccountInfoOpts) (*rpc.GetAccountInfoResult, error) { - verified, err := v.verifyChainID() + verified, err := v.verifyChainID(ctx) if !verified { return nil, err } @@ -235,28 +235,29 @@ func newChain(id string, cfg *config.TOMLConfig, ks loop.Keystore, lggr logger.L mnCfg := &cfg.MultiNode - var nodes []mn.Node[mn.StringID, *client.Client] - var sendOnlyNodes []mn.SendOnlyNode[mn.StringID, *client.Client] + var nodes []mn.Node[mn.StringID, *client.MultiNodeClient] + var sendOnlyNodes []mn.SendOnlyNode[mn.StringID, *client.MultiNodeClient] for i, nodeInfo := range cfg.ListNodes() { - rpcClient, err := client.NewClient(nodeInfo.URL.String(), cfg, DefaultRequestTimeout, logger.Named(lggr, "Client."+*nodeInfo.Name)) + rpcClient, err := client.NewMultiNodeClient(nodeInfo.URL.String(), cfg, DefaultRequestTimeout, logger.Named(lggr, "Client."+*nodeInfo.Name)) if err != nil { lggr.Warnw("failed to create client", "name", *nodeInfo.Name, "solana-url", nodeInfo.URL.String(), "err", err.Error()) return nil, fmt.Errorf("failed to create client: %w", err) } - newNode := mn.NewNode[mn.StringID, *client.Head, *client.Client]( - mnCfg, mnCfg, lggr, *nodeInfo.URL.URL(), nil, *nodeInfo.Name, - i, mn.StringID(id), 0, rpcClient, chainFamily) - if nodeInfo.SendOnly { - sendOnlyNodes = append(sendOnlyNodes, newNode) + newSendOnly := mn.NewSendOnlyNode[mn.StringID, *client.MultiNodeClient]( + lggr, *nodeInfo.URL.URL(), *nodeInfo.Name, mn.StringID(id), rpcClient) + sendOnlyNodes = append(sendOnlyNodes, newSendOnly) } else { + newNode := mn.NewNode[mn.StringID, *client.Head, *client.MultiNodeClient]( + mnCfg, mnCfg, lggr, *nodeInfo.URL.URL(), nil, *nodeInfo.Name, + i, mn.StringID(id), 0, rpcClient, chainFamily) nodes = append(nodes, newNode) } } - multiNode := mn.NewMultiNode[mn.StringID, *client.Client]( + multiNode := mn.NewMultiNode[mn.StringID, *client.MultiNodeClient]( lggr, mnCfg.SelectionMode(), mnCfg.LeaseDuration(), @@ -273,7 +274,7 @@ func newChain(id string, cfg *config.TOMLConfig, ks loop.Keystore, lggr logger.L return 0 // TODO ClassifySendError(err, clientErrors, logger.Sugared(logger.Nop()), tx, common.Address{}, false) } - txSender := mn.NewTransactionSender[*solanago.Transaction, mn.StringID, *client.Client]( + txSender := mn.NewTransactionSender[*solanago.Transaction, mn.StringID, *client.MultiNodeClient]( lggr, mn.StringID(id), chainFamily, @@ -293,20 +294,18 @@ func newChain(id string, cfg *config.TOMLConfig, ks loop.Keystore, lggr logger.L return ch.getClient() } ch.txm = txm.NewTxm(ch.id, tc, cfg, ks, lggr) - bc := func() (monitor.BalanceClient, error) { - return ch.getClient() - } + bc := func() (monitor.BalanceClient, error) { return ch.getClient() } ch.balanceMonitor = monitor.NewBalanceMonitor(ch.id, cfg, lggr, ks, bc) return &ch, nil } -func (c *chain) LatestHead(_ context.Context) (types.Head, error) { +func (c *chain) LatestHead(ctx context.Context) (types.Head, error) { sc, err := c.getClient() if err != nil { return types.Head{}, err } - latestBlock, err := sc.GetLatestBlock() + latestBlock, err := sc.GetLatestBlock(ctx) if err != nil { return types.Head{}, nil } @@ -397,6 +396,7 @@ func (c *chain) ChainID() string { } // getClient returns a client, randomly selecting one from available and valid nodes +// If multinode is enabled, it will return a client using the multinode selection instead. func (c *chain) getClient() (client.ReaderWriter, error) { if c.cfg.MultiNode.Enabled() { return c.multiNode.SelectRPC() @@ -536,7 +536,7 @@ func (c *chain) sendTx(ctx context.Context, from, to string, amount *big.Int, ba } amountI := amount.Uint64() - blockhash, err := reader.LatestBlockhash() + blockhash, err := reader.LatestBlockhash(ctx) if err != nil { return fmt.Errorf("failed to get latest block hash: %w", err) } @@ -556,13 +556,13 @@ func (c *chain) sendTx(ctx context.Context, from, to string, amount *big.Int, ba } if balanceCheck { - if err = solanaValidateBalance(reader, fromKey, amountI, tx.Message.ToBase64()); err != nil { + if err = solanaValidateBalance(ctx, reader, fromKey, amountI, tx.Message.ToBase64()); err != nil { return fmt.Errorf("failed to validate balance: %w", err) } } chainTxm := c.TxManager() - err = chainTxm.Enqueue("", tx, + err = chainTxm.Enqueue(ctx, "", tx, txm.SetComputeUnitLimit(500), // reduce from default 200K limit - should only take 450 compute units // no fee bumping and no additional fee - makes validating balance accurate txm.SetComputeUnitPriceMax(0), @@ -576,13 +576,13 @@ func (c *chain) sendTx(ctx context.Context, from, to string, amount *big.Int, ba return nil } -func solanaValidateBalance(reader client.Reader, from solanago.PublicKey, amount uint64, msg string) error { - balance, err := reader.Balance(from) +func solanaValidateBalance(ctx context.Context, reader client.Reader, from solanago.PublicKey, amount uint64, msg string) error { + balance, err := reader.Balance(ctx, from) if err != nil { return err } - fee, err := reader.GetFeeForMessage(msg) + fee, err := reader.GetFeeForMessage(ctx, msg) if err != nil { return err } diff --git a/pkg/solana/chain_test.go b/pkg/solana/chain_test.go index d3e9b46..8255653 100644 --- a/pkg/solana/chain_test.go +++ b/pkg/solana/chain_test.go @@ -59,6 +59,7 @@ func TestSolanaChain_GetClient(t *testing.T) { ChainID: ptr("devnet"), Chain: ch, } + cfg.SetDefaults() testChain := chain{ id: "devnet", cfg: cfg, @@ -125,7 +126,63 @@ func TestSolanaChain_GetClient(t *testing.T) { assert.NoError(t, err) } +func TestSolanaChain_MultiNode_GetClient(t *testing.T) { + mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + out := fmt.Sprintf(TestSolanaGenesisHashTemplate, client.MainnetGenesisHash) // mainnet genesis hash + if !strings.Contains(r.URL.Path, "/mismatch") { + // devnet gensis hash + out = fmt.Sprintf(TestSolanaGenesisHashTemplate, client.DevnetGenesisHash) + } + _, err := w.Write([]byte(out)) + require.NoError(t, err) + })) + defer mockServer.Close() + + ch := solcfg.Chain{} + ch.SetDefaults() + mn := solcfg.MultiNodeConfig{ + MultiNode: solcfg.MultiNode{ + Enabled: ptr(true), + }, + } + mn.SetDefaults() + + cfg := &solcfg.TOMLConfig{ + ChainID: ptr("devnet"), + Chain: ch, + MultiNode: mn, + } + cfg.Nodes = []*solcfg.Node{ + { + Name: ptr("devnet"), + URL: config.MustParseURL(mockServer.URL + "/1"), + }, + { + Name: ptr("devnet"), + URL: config.MustParseURL(mockServer.URL + "/2"), + }, + } + + testChain, err := newChain("devnet", cfg, nil, logger.Test(t)) + require.NoError(t, err) + + err = testChain.Start(tests.Context(t)) + require.NoError(t, err) + defer func() { + closeErr := testChain.Close() + require.NoError(t, closeErr) + }() + + selectedClient, err := testChain.getClient() + assert.NoError(t, err) + + id, err := selectedClient.ChainID(tests.Context(t)) + assert.NoError(t, err) + assert.Equal(t, "devnet", id.String()) +} + func TestSolanaChain_VerifiedClient(t *testing.T) { + ctx := tests.Context(t) called := false mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { out := `{ "jsonrpc": "2.0", "result": 1234, "id": 1 }` // getSlot response @@ -156,6 +213,8 @@ func TestSolanaChain_VerifiedClient(t *testing.T) { ChainID: ptr("devnet"), Chain: ch, } + cfg.SetDefaults() + testChain := chain{ cfg: cfg, lggr: logger.Test(t), @@ -175,7 +234,7 @@ func TestSolanaChain_VerifiedClient(t *testing.T) { // retrieve cached client and retrieve slot height c, err := testChain.verifiedClient(node) require.NoError(t, err) - slot, err := c.SlotHeight() + slot, err := c.SlotHeight(ctx) assert.NoError(t, err) assert.Equal(t, uint64(1234), slot) @@ -204,6 +263,7 @@ func TestSolanaChain_VerifiedClient_ParallelClients(t *testing.T) { Enabled: ptr(true), Chain: ch, } + cfg.SetDefaults() testChain := chain{ id: "devnet", cfg: cfg, diff --git a/pkg/solana/chainreader/bindings.go b/pkg/solana/chainreader/bindings.go index 29e8032..ed081a1 100644 --- a/pkg/solana/chainreader/bindings.go +++ b/pkg/solana/chainreader/bindings.go @@ -6,6 +6,7 @@ import ( "reflect" "github.com/gagliardetto/solana-go" + "github.com/goplugin/plugin-common/pkg/types" ) diff --git a/pkg/solana/client/client.go b/pkg/solana/client/client.go index 88a7e7a..ae4cfe1 100644 --- a/pkg/solana/client/client.go +++ b/pkg/solana/client/client.go @@ -4,17 +4,14 @@ import ( "context" "errors" "fmt" - "math/big" "time" - mn "github.com/goplugin/plugin-solana/pkg/solana/client/multinode" - "github.com/gagliardetto/solana-go" "github.com/gagliardetto/solana-go/rpc" - "golang.org/x/sync/singleflight" - "github.com/goplugin/plugin-common/pkg/logger" + "golang.org/x/sync/singleflight" + mn "github.com/goplugin/plugin-solana/pkg/solana/client/multinode" "github.com/goplugin/plugin-solana/pkg/solana/config" "github.com/goplugin/plugin-solana/pkg/solana/monitor" ) @@ -33,12 +30,12 @@ type ReaderWriter interface { type Reader interface { AccountReader - Balance(addr solana.PublicKey) (uint64, error) - SlotHeight() (uint64, error) - LatestBlockhash() (*rpc.GetLatestBlockhashResult, error) + Balance(ctx context.Context, addr solana.PublicKey) (uint64, error) + SlotHeight(ctx context.Context) (uint64, error) + LatestBlockhash(ctx context.Context) (*rpc.GetLatestBlockhashResult, error) ChainID(ctx context.Context) (mn.StringID, error) - GetFeeForMessage(msg string) (uint64, error) - GetLatestBlock() (*rpc.GetBlockResult, error) + GetFeeForMessage(ctx context.Context, msg string) (uint64, error) + GetLatestBlock(ctx context.Context) (*rpc.GetBlockResult, error) } // AccountReader is an interface that allows users to pass either the solana rpc client or the relay client @@ -68,27 +65,6 @@ type Client struct { requestGroup *singleflight.Group } -type Head struct { - rpc.GetBlockResult -} - -func (h *Head) BlockNumber() int64 { - if !h.IsValid() { - return 0 - } - // nolint:gosec - // G115: integer overflow conversion uint64 -> int64 - return int64(*h.BlockHeight) -} - -func (h *Head) BlockDifficulty() *big.Int { - return nil -} - -func (h *Head) IsValid() bool { - return h.BlockHeight != nil -} - func NewClient(endpoint string, cfg config.Config, requestTimeout time.Duration, log logger.Logger) (*Client, error) { return &Client{ url: endpoint, @@ -103,56 +79,6 @@ func NewClient(endpoint string, cfg config.Config, requestTimeout time.Duration, }, nil } -var _ mn.RPCClient[mn.StringID, *Head] = (*Client)(nil) -var _ mn.SendTxRPCClient[*solana.Transaction] = (*Client)(nil) - -// TODO: BCI-4061: Implement Client for MultiNode - -func (c *Client) Dial(ctx context.Context) error { - //TODO implement me - panic("implement me") -} - -func (c *Client) SubscribeToHeads(ctx context.Context) (<-chan *Head, mn.Subscription, error) { - //TODO implement me - panic("implement me") -} - -func (c *Client) SubscribeToFinalizedHeads(ctx context.Context) (<-chan *Head, mn.Subscription, error) { - //TODO implement me - panic("implement me") -} - -func (c *Client) Ping(ctx context.Context) error { - //TODO implement me - panic("implement me") -} - -func (c *Client) IsSyncing(ctx context.Context) (bool, error) { - //TODO implement me - panic("implement me") -} - -func (c *Client) UnsubscribeAllExcept(subs ...mn.Subscription) { - //TODO implement me - panic("implement me") -} - -func (c *Client) Close() { - //TODO implement me - panic("implement me") -} - -func (c *Client) GetInterceptedChainInfo() (latest, highestUserObservations mn.ChainInfo) { - //TODO implement me - panic("implement me") -} - -func (c *Client) SendTransaction(ctx context.Context, tx *solana.Transaction) error { - // TODO: Implement - return nil -} - func (c *Client) latency(name string) func() { start := time.Now() return func() { @@ -160,11 +86,11 @@ func (c *Client) latency(name string) func() { } } -func (c *Client) Balance(addr solana.PublicKey) (uint64, error) { +func (c *Client) Balance(ctx context.Context, addr solana.PublicKey) (uint64, error) { done := c.latency("balance") defer done() - ctx, cancel := context.WithTimeout(context.Background(), c.contextDuration) + ctx, cancel := context.WithTimeout(ctx, c.contextDuration) defer cancel() v, err, _ := c.requestGroup.Do(fmt.Sprintf("GetBalance(%s)", addr.String()), func() (interface{}, error) { @@ -177,15 +103,15 @@ func (c *Client) Balance(addr solana.PublicKey) (uint64, error) { return res.Value, err } -func (c *Client) SlotHeight() (uint64, error) { - return c.SlotHeightWithCommitment(rpc.CommitmentProcessed) // get the latest slot height +func (c *Client) SlotHeight(ctx context.Context) (uint64, error) { + return c.SlotHeightWithCommitment(ctx, rpc.CommitmentProcessed) // get the latest slot height } -func (c *Client) SlotHeightWithCommitment(commitment rpc.CommitmentType) (uint64, error) { +func (c *Client) SlotHeightWithCommitment(ctx context.Context, commitment rpc.CommitmentType) (uint64, error) { done := c.latency("slot_height") defer done() - ctx, cancel := context.WithTimeout(context.Background(), c.contextDuration) + ctx, cancel := context.WithTimeout(ctx, c.contextDuration) defer cancel() v, err, _ := c.requestGroup.Do("GetSlotHeight", func() (interface{}, error) { return c.rpc.GetSlot(ctx, commitment) @@ -203,11 +129,11 @@ func (c *Client) GetAccountInfoWithOpts(ctx context.Context, addr solana.PublicK return c.rpc.GetAccountInfoWithOpts(ctx, addr, opts) } -func (c *Client) LatestBlockhash() (*rpc.GetLatestBlockhashResult, error) { +func (c *Client) LatestBlockhash(ctx context.Context) (*rpc.GetLatestBlockhashResult, error) { done := c.latency("latest_blockhash") defer done() - ctx, cancel := context.WithTimeout(context.Background(), c.contextDuration) + ctx, cancel := context.WithTimeout(ctx, c.contextDuration) defer cancel() v, err, _ := c.requestGroup.Do("GetLatestBlockhash", func() (interface{}, error) { @@ -245,13 +171,13 @@ func (c *Client) ChainID(ctx context.Context) (mn.StringID, error) { return mn.StringID(network), nil } -func (c *Client) GetFeeForMessage(msg string) (uint64, error) { +func (c *Client) GetFeeForMessage(ctx context.Context, msg string) (uint64, error) { done := c.latency("fee_for_message") defer done() // msg is base58 encoded data - ctx, cancel := context.WithTimeout(context.Background(), c.contextDuration) + ctx, cancel := context.WithTimeout(ctx, c.contextDuration) defer cancel() res, err := c.rpc.GetFeeForMessage(ctx, msg, c.commitment) if err != nil { @@ -328,9 +254,9 @@ func (c *Client) SendTx(ctx context.Context, tx *solana.Transaction) (solana.Sig return c.rpc.SendTransactionWithOpts(ctx, tx, opts) } -func (c *Client) GetLatestBlock() (*rpc.GetBlockResult, error) { +func (c *Client) GetLatestBlock(ctx context.Context) (*rpc.GetBlockResult, error) { // get latest confirmed slot - slot, err := c.SlotHeightWithCommitment(c.commitment) + slot, err := c.SlotHeightWithCommitment(ctx, c.commitment) if err != nil { return nil, fmt.Errorf("GetLatestBlock.SlotHeight: %w", err) } @@ -338,7 +264,7 @@ func (c *Client) GetLatestBlock() (*rpc.GetBlockResult, error) { // get block based on slot done := c.latency("latest_block") defer done() - ctx, cancel := context.WithTimeout(context.Background(), c.txTimeout) + ctx, cancel := context.WithTimeout(ctx, c.txTimeout) defer cancel() v, err, _ := c.requestGroup.Do("GetBlockWithOpts", func() (interface{}, error) { version := uint64(0) // pull all tx types (legacy + v0) diff --git a/pkg/solana/client/client_test.go b/pkg/solana/client/client_test.go index 90b50c4..c7bab02 100644 --- a/pkg/solana/client/client_test.go +++ b/pkg/solana/client/client_test.go @@ -19,6 +19,7 @@ import ( "github.com/stretchr/testify/require" "github.com/goplugin/plugin-common/pkg/logger" + "github.com/goplugin/plugin-common/pkg/utils/tests" mn "github.com/goplugin/plugin-solana/pkg/solana/client/multinode" "github.com/goplugin/plugin-solana/pkg/solana/config" @@ -26,6 +27,7 @@ import ( ) func TestClient_Reader_Integration(t *testing.T) { + ctx := tests.Context(t) url := SetupLocalSolNode(t) privKey, err := solana.NewRandomPrivateKey() require.NoError(t, err) @@ -40,21 +42,21 @@ func TestClient_Reader_Integration(t *testing.T) { require.NoError(t, err) // check balance - bal, err := c.Balance(pubKey) + bal, err := c.Balance(ctx, pubKey) assert.NoError(t, err) assert.Equal(t, uint64(100_000_000_000), bal) // once funds get sent to the system program it should be unrecoverable (so this number should remain > 0) // check SlotHeight - slot0, err := c.SlotHeight() + slot0, err := c.SlotHeight(ctx) assert.NoError(t, err) assert.Greater(t, slot0, uint64(0)) time.Sleep(time.Second) - slot1, err := c.SlotHeight() + slot1, err := c.SlotHeight(ctx) assert.NoError(t, err) assert.Greater(t, slot1, slot0) // fetch recent blockhash - hash, err := c.LatestBlockhash() + hash, err := c.LatestBlockhash(ctx) assert.NoError(t, err) assert.NotEqual(t, hash.Value.Blockhash, solana.Hash{}) // not an empty hash @@ -72,7 +74,7 @@ func TestClient_Reader_Integration(t *testing.T) { ) assert.NoError(t, err) - fee, err := c.GetFeeForMessage(tx.Message.ToBase64()) + fee, err := c.GetFeeForMessage(ctx, tx.Message.ToBase64()) assert.NoError(t, err) assert.Equal(t, uint64(5000), fee) @@ -82,13 +84,13 @@ func TestClient_Reader_Integration(t *testing.T) { assert.Equal(t, mn.StringID("localnet"), network) // get account info (also tested inside contract_test) - res, err := c.GetAccountInfoWithOpts(context.TODO(), solana.PublicKey{}, &rpc.GetAccountInfoOpts{Commitment: rpc.CommitmentFinalized}) + res, err := c.GetAccountInfoWithOpts(ctx, solana.PublicKey{}, &rpc.GetAccountInfoOpts{Commitment: rpc.CommitmentFinalized}) assert.NoError(t, err) assert.Equal(t, uint64(1), res.Value.Lamports) assert.Equal(t, "NativeLoader1111111111111111111111111111111", res.Value.Owner.String()) // get block + check for nonzero values - block, err := c.GetLatestBlock() + block, err := c.GetLatestBlock(ctx) require.NoError(t, err) assert.NotEqual(t, solana.Hash{}, block.Blockhash) assert.NotEqual(t, uint64(0), block.ParentSlot) @@ -96,6 +98,7 @@ func TestClient_Reader_Integration(t *testing.T) { } func TestClient_Reader_ChainID(t *testing.T) { + ctx := tests.Context(t) genesisHashes := []string{ DevnetGenesisHash, // devnet TestnetGenesisHash, // testnet @@ -121,7 +124,7 @@ func TestClient_Reader_ChainID(t *testing.T) { // get chain ID based on gensis hash for _, n := range networks { - network, err := c.ChainID(context.Background()) + network, err := c.ChainID(ctx) assert.NoError(t, err) assert.Equal(t, mn.StringID(n), network) } @@ -138,13 +141,13 @@ func TestClient_Writer_Integration(t *testing.T) { lggr := logger.Test(t) cfg := config.NewDefault() - ctx := context.Background() + ctx := tests.Context(t) c, err := NewClient(url, cfg, requestTimeout, lggr) require.NoError(t, err) // create + sign transaction createTx := func(to solana.PublicKey) *solana.Transaction { - hash, hashErr := c.LatestBlockhash() + hash, hashErr := c.LatestBlockhash(ctx) assert.NoError(t, hashErr) tx, txErr := solana.NewTransaction( @@ -212,6 +215,7 @@ func TestClient_Writer_Integration(t *testing.T) { } func TestClient_SendTxDuplicates_Integration(t *testing.T) { + ctx := tests.Context(t) // set up environment url := SetupLocalSolNode(t) privKey, err := solana.NewRandomPrivateKey() @@ -227,10 +231,10 @@ func TestClient_SendTxDuplicates_Integration(t *testing.T) { require.NoError(t, err) // fetch recent blockhash - hash, err := c.LatestBlockhash() + hash, err := c.LatestBlockhash(ctx) assert.NoError(t, err) - initBal, err := c.Balance(pubKey) + initBal, err := c.Balance(ctx, pubKey) assert.NoError(t, err) // create + sign tx @@ -261,7 +265,6 @@ func TestClient_SendTxDuplicates_Integration(t *testing.T) { n := 5 sigs := make([]solana.Signature, n) var wg sync.WaitGroup - ctx := context.Background() wg.Add(5) for i := 0; i < n; i++ { go func(i int) { @@ -292,7 +295,7 @@ func TestClient_SendTxDuplicates_Integration(t *testing.T) { // expect one sender has only sent one tx // original balance - current bal = 5000 lamports (tx fee) - endBal, err := c.Balance(pubKey) + endBal, err := c.Balance(ctx, pubKey) assert.NoError(t, err) assert.Equal(t, uint64(5_000), initBal-endBal) } diff --git a/pkg/solana/client/mocks/ReaderWriter.go b/pkg/solana/client/mocks/ReaderWriter.go index 30be4e4..e580dbf 100644 --- a/pkg/solana/client/mocks/ReaderWriter.go +++ b/pkg/solana/client/mocks/ReaderWriter.go @@ -17,9 +17,9 @@ type ReaderWriter struct { mock.Mock } -// Balance provides a mock function with given fields: addr -func (_m *ReaderWriter) Balance(addr solana.PublicKey) (uint64, error) { - ret := _m.Called(addr) +// Balance provides a mock function with given fields: ctx, addr +func (_m *ReaderWriter) Balance(ctx context.Context, addr solana.PublicKey) (uint64, error) { + ret := _m.Called(ctx, addr) if len(ret) == 0 { panic("no return value specified for Balance") @@ -27,17 +27,17 @@ func (_m *ReaderWriter) Balance(addr solana.PublicKey) (uint64, error) { var r0 uint64 var r1 error - if rf, ok := ret.Get(0).(func(solana.PublicKey) (uint64, error)); ok { - return rf(addr) + if rf, ok := ret.Get(0).(func(context.Context, solana.PublicKey) (uint64, error)); ok { + return rf(ctx, addr) } - if rf, ok := ret.Get(0).(func(solana.PublicKey) uint64); ok { - r0 = rf(addr) + if rf, ok := ret.Get(0).(func(context.Context, solana.PublicKey) uint64); ok { + r0 = rf(ctx, addr) } else { r0 = ret.Get(0).(uint64) } - if rf, ok := ret.Get(1).(func(solana.PublicKey) error); ok { - r1 = rf(addr) + if rf, ok := ret.Get(1).(func(context.Context, solana.PublicKey) error); ok { + r1 = rf(ctx, addr) } else { r1 = ret.Error(1) } @@ -103,9 +103,9 @@ func (_m *ReaderWriter) GetAccountInfoWithOpts(ctx context.Context, addr solana. return r0, r1 } -// GetFeeForMessage provides a mock function with given fields: msg -func (_m *ReaderWriter) GetFeeForMessage(msg string) (uint64, error) { - ret := _m.Called(msg) +// GetFeeForMessage provides a mock function with given fields: ctx, msg +func (_m *ReaderWriter) GetFeeForMessage(ctx context.Context, msg string) (uint64, error) { + ret := _m.Called(ctx, msg) if len(ret) == 0 { panic("no return value specified for GetFeeForMessage") @@ -113,17 +113,17 @@ func (_m *ReaderWriter) GetFeeForMessage(msg string) (uint64, error) { var r0 uint64 var r1 error - if rf, ok := ret.Get(0).(func(string) (uint64, error)); ok { - return rf(msg) + if rf, ok := ret.Get(0).(func(context.Context, string) (uint64, error)); ok { + return rf(ctx, msg) } - if rf, ok := ret.Get(0).(func(string) uint64); ok { - r0 = rf(msg) + if rf, ok := ret.Get(0).(func(context.Context, string) uint64); ok { + r0 = rf(ctx, msg) } else { r0 = ret.Get(0).(uint64) } - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(msg) + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, msg) } else { r1 = ret.Error(1) } @@ -131,9 +131,9 @@ func (_m *ReaderWriter) GetFeeForMessage(msg string) (uint64, error) { return r0, r1 } -// GetLatestBlock provides a mock function with given fields: -func (_m *ReaderWriter) GetLatestBlock() (*rpc.GetBlockResult, error) { - ret := _m.Called() +// GetLatestBlock provides a mock function with given fields: ctx +func (_m *ReaderWriter) GetLatestBlock(ctx context.Context) (*rpc.GetBlockResult, error) { + ret := _m.Called(ctx) if len(ret) == 0 { panic("no return value specified for GetLatestBlock") @@ -141,19 +141,19 @@ func (_m *ReaderWriter) GetLatestBlock() (*rpc.GetBlockResult, error) { var r0 *rpc.GetBlockResult var r1 error - if rf, ok := ret.Get(0).(func() (*rpc.GetBlockResult, error)); ok { - return rf() + if rf, ok := ret.Get(0).(func(context.Context) (*rpc.GetBlockResult, error)); ok { + return rf(ctx) } - if rf, ok := ret.Get(0).(func() *rpc.GetBlockResult); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context) *rpc.GetBlockResult); ok { + r0 = rf(ctx) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*rpc.GetBlockResult) } } - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) } else { r1 = ret.Error(1) } @@ -161,9 +161,9 @@ func (_m *ReaderWriter) GetLatestBlock() (*rpc.GetBlockResult, error) { return r0, r1 } -// LatestBlockhash provides a mock function with given fields: -func (_m *ReaderWriter) LatestBlockhash() (*rpc.GetLatestBlockhashResult, error) { - ret := _m.Called() +// LatestBlockhash provides a mock function with given fields: ctx +func (_m *ReaderWriter) LatestBlockhash(ctx context.Context) (*rpc.GetLatestBlockhashResult, error) { + ret := _m.Called(ctx) if len(ret) == 0 { panic("no return value specified for LatestBlockhash") @@ -171,19 +171,19 @@ func (_m *ReaderWriter) LatestBlockhash() (*rpc.GetLatestBlockhashResult, error) var r0 *rpc.GetLatestBlockhashResult var r1 error - if rf, ok := ret.Get(0).(func() (*rpc.GetLatestBlockhashResult, error)); ok { - return rf() + if rf, ok := ret.Get(0).(func(context.Context) (*rpc.GetLatestBlockhashResult, error)); ok { + return rf(ctx) } - if rf, ok := ret.Get(0).(func() *rpc.GetLatestBlockhashResult); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context) *rpc.GetLatestBlockhashResult); ok { + r0 = rf(ctx) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*rpc.GetLatestBlockhashResult) } } - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) } else { r1 = ret.Error(1) } @@ -281,9 +281,9 @@ func (_m *ReaderWriter) SimulateTx(ctx context.Context, tx *solana.Transaction, return r0, r1 } -// SlotHeight provides a mock function with given fields: -func (_m *ReaderWriter) SlotHeight() (uint64, error) { - ret := _m.Called() +// SlotHeight provides a mock function with given fields: ctx +func (_m *ReaderWriter) SlotHeight(ctx context.Context) (uint64, error) { + ret := _m.Called(ctx) if len(ret) == 0 { panic("no return value specified for SlotHeight") @@ -291,17 +291,17 @@ func (_m *ReaderWriter) SlotHeight() (uint64, error) { var r0 uint64 var r1 error - if rf, ok := ret.Get(0).(func() (uint64, error)); ok { - return rf() + if rf, ok := ret.Get(0).(func(context.Context) (uint64, error)); ok { + return rf(ctx) } - if rf, ok := ret.Get(0).(func() uint64); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context) uint64); ok { + r0 = rf(ctx) } else { r0 = ret.Get(0).(uint64) } - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) } else { r1 = ret.Error(1) } diff --git a/pkg/solana/client/multinode_client.go b/pkg/solana/client/multinode_client.go new file mode 100644 index 0000000..3c220f8 --- /dev/null +++ b/pkg/solana/client/multinode_client.go @@ -0,0 +1,307 @@ +package client + +import ( + "context" + "errors" + "fmt" + "math/big" + "sync" + "time" + + "github.com/gagliardetto/solana-go" + "github.com/gagliardetto/solana-go/rpc" + "github.com/goplugin/plugin-common/pkg/logger" + "github.com/goplugin/plugin-common/pkg/services" + + mn "github.com/goplugin/plugin-solana/pkg/solana/client/multinode" + "github.com/goplugin/plugin-solana/pkg/solana/config" +) + +type Head struct { + BlockHeight *uint64 + BlockHash *solana.Hash +} + +func (h *Head) BlockNumber() int64 { + if !h.IsValid() { + return 0 + } + // nolint:gosec + // G115: integer overflow conversion uint64 -> int64 + return int64(*h.BlockHeight) +} + +func (h *Head) BlockDifficulty() *big.Int { + // Not relevant for Solana + return nil +} + +func (h *Head) IsValid() bool { + return h != nil && h.BlockHeight != nil && h.BlockHash != nil +} + +var _ mn.RPCClient[mn.StringID, *Head] = (*MultiNodeClient)(nil) +var _ mn.SendTxRPCClient[*solana.Transaction] = (*MultiNodeClient)(nil) + +type MultiNodeClient struct { + Client + cfg *config.TOMLConfig + stateMu sync.RWMutex // protects state* fields + subsSliceMu sync.RWMutex + subs map[mn.Subscription]struct{} + + // chStopInFlight can be closed to immediately cancel all in-flight requests on + // this RpcClient. Closing and replacing should be serialized through + // stateMu since it can happen on state transitions as well as RpcClient Close. + chStopInFlight chan struct{} + + chainInfoLock sync.RWMutex + // intercepted values seen by callers of the rpcClient excluding health check calls. Need to ensure MultiNode provides repeatable read guarantee + highestUserObservations mn.ChainInfo + // most recent chain info observed during current lifecycle (reseted on DisconnectAll) + latestChainInfo mn.ChainInfo +} + +func NewMultiNodeClient(endpoint string, cfg *config.TOMLConfig, requestTimeout time.Duration, log logger.Logger) (*MultiNodeClient, error) { + client, err := NewClient(endpoint, cfg, requestTimeout, log) + if err != nil { + return nil, err + } + + return &MultiNodeClient{ + Client: *client, + cfg: cfg, + subs: make(map[mn.Subscription]struct{}), + chStopInFlight: make(chan struct{}), + }, nil +} + +// registerSub adds the sub to the rpcClient list +func (m *MultiNodeClient) registerSub(sub mn.Subscription, stopInFLightCh chan struct{}) error { + m.subsSliceMu.Lock() + defer m.subsSliceMu.Unlock() + // ensure that the `sub` belongs to current life cycle of the `rpcClient` and it should not be killed due to + // previous `DisconnectAll` call. + select { + case <-stopInFLightCh: + sub.Unsubscribe() + return fmt.Errorf("failed to register subscription - all in-flight requests were canceled") + default: + } + // TODO: BCI-3358 - delete sub when caller unsubscribes. + m.subs[sub] = struct{}{} + return nil +} + +func (m *MultiNodeClient) Dial(ctx context.Context) error { + // Not relevant for Solana as the RPCs don't need to be dialled. + return nil +} + +func (m *MultiNodeClient) SubscribeToHeads(ctx context.Context) (<-chan *Head, mn.Subscription, error) { + ctx, cancel, chStopInFlight, _ := m.acquireQueryCtx(ctx, m.cfg.TxTimeout()) + defer cancel() + + pollInterval := m.cfg.MultiNode.PollInterval() + if pollInterval == 0 { + return nil, nil, errors.New("PollInterval is 0") + } + timeout := pollInterval + poller, channel := mn.NewPoller[*Head](pollInterval, m.LatestBlock, timeout, m.log) + if err := poller.Start(ctx); err != nil { + return nil, nil, err + } + + err := m.registerSub(&poller, chStopInFlight) + if err != nil { + poller.Unsubscribe() + return nil, nil, err + } + + return channel, &poller, nil +} + +func (m *MultiNodeClient) SubscribeToFinalizedHeads(ctx context.Context) (<-chan *Head, mn.Subscription, error) { + ctx, cancel, chStopInFlight, _ := m.acquireQueryCtx(ctx, m.contextDuration) + defer cancel() + + finalizedBlockPollInterval := m.cfg.MultiNode.FinalizedBlockPollInterval() + if finalizedBlockPollInterval == 0 { + return nil, nil, errors.New("FinalizedBlockPollInterval is 0") + } + timeout := finalizedBlockPollInterval + poller, channel := mn.NewPoller[*Head](finalizedBlockPollInterval, m.LatestFinalizedBlock, timeout, m.log) + if err := poller.Start(ctx); err != nil { + return nil, nil, err + } + + err := m.registerSub(&poller, chStopInFlight) + if err != nil { + poller.Unsubscribe() + return nil, nil, err + } + + return channel, &poller, nil +} + +func (m *MultiNodeClient) LatestBlock(ctx context.Context) (*Head, error) { + // capture chStopInFlight to ensure we are not updating chainInfo with observations related to previous life cycle + ctx, cancel, chStopInFlight, rawRPC := m.acquireQueryCtx(ctx, m.contextDuration) + defer cancel() + + result, err := rawRPC.GetLatestBlockhash(ctx, rpc.CommitmentConfirmed) + if err != nil { + return nil, err + } + + head := &Head{ + BlockHeight: &result.Value.LastValidBlockHeight, + BlockHash: &result.Value.Blockhash, + } + m.onNewHead(ctx, chStopInFlight, head) + return head, nil +} + +func (m *MultiNodeClient) LatestFinalizedBlock(ctx context.Context) (*Head, error) { + ctx, cancel, chStopInFlight, rawRPC := m.acquireQueryCtx(ctx, m.contextDuration) + defer cancel() + + result, err := rawRPC.GetLatestBlockhash(ctx, rpc.CommitmentFinalized) + if err != nil { + return nil, err + } + + head := &Head{ + BlockHeight: &result.Value.LastValidBlockHeight, + BlockHash: &result.Value.Blockhash, + } + m.onNewFinalizedHead(ctx, chStopInFlight, head) + return head, nil +} + +func (m *MultiNodeClient) onNewHead(ctx context.Context, requestCh <-chan struct{}, head *Head) { + if head == nil { + return + } + + m.chainInfoLock.Lock() + defer m.chainInfoLock.Unlock() + if !mn.CtxIsHeathCheckRequest(ctx) { + m.highestUserObservations.BlockNumber = max(m.highestUserObservations.BlockNumber, head.BlockNumber()) + } + select { + case <-requestCh: // no need to update latestChainInfo, as rpcClient already started new life cycle + return + default: + m.latestChainInfo.BlockNumber = head.BlockNumber() + } +} + +func (m *MultiNodeClient) onNewFinalizedHead(ctx context.Context, requestCh <-chan struct{}, head *Head) { + if head == nil { + return + } + m.chainInfoLock.Lock() + defer m.chainInfoLock.Unlock() + if !mn.CtxIsHeathCheckRequest(ctx) { + m.highestUserObservations.FinalizedBlockNumber = max(m.highestUserObservations.FinalizedBlockNumber, head.BlockNumber()) + } + select { + case <-requestCh: // no need to update latestChainInfo, as rpcClient already started new life cycle + return + default: + m.latestChainInfo.FinalizedBlockNumber = head.BlockNumber() + } +} + +// makeQueryCtx returns a context that cancels if: +// 1. Passed in ctx cancels +// 2. Passed in channel is closed +// 3. Default timeout is reached (queryTimeout) +func makeQueryCtx(ctx context.Context, ch services.StopChan, timeout time.Duration) (context.Context, context.CancelFunc) { + var chCancel, timeoutCancel context.CancelFunc + ctx, chCancel = ch.Ctx(ctx) + ctx, timeoutCancel = context.WithTimeout(ctx, timeout) + cancel := func() { + chCancel() + timeoutCancel() + } + return ctx, cancel +} + +func (m *MultiNodeClient) acquireQueryCtx(parentCtx context.Context, timeout time.Duration) (ctx context.Context, cancel context.CancelFunc, + chStopInFlight chan struct{}, raw *rpc.Client) { + // Need to wrap in mutex because state transition can cancel and replace context + m.stateMu.RLock() + chStopInFlight = m.chStopInFlight + cp := *m.rpc + raw = &cp + m.stateMu.RUnlock() + ctx, cancel = makeQueryCtx(parentCtx, chStopInFlight, timeout) + return +} + +func (m *MultiNodeClient) Ping(ctx context.Context) error { + version, err := m.rpc.GetVersion(ctx) + if err != nil { + return fmt.Errorf("ping failed: %v", err) + } + m.log.Debugf("ping client version: %s", version.SolanaCore) + return err +} + +func (m *MultiNodeClient) IsSyncing(ctx context.Context) (bool, error) { + // Not in use for Solana + return false, nil +} + +func (m *MultiNodeClient) UnsubscribeAllExcept(subs ...mn.Subscription) { + m.subsSliceMu.Lock() + defer m.subsSliceMu.Unlock() + + keepSubs := map[mn.Subscription]struct{}{} + for _, sub := range subs { + keepSubs[sub] = struct{}{} + } + + for sub := range m.subs { + if _, keep := keepSubs[sub]; !keep { + sub.Unsubscribe() + delete(m.subs, sub) + } + } +} + +// cancelInflightRequests closes and replaces the chStopInFlight +func (m *MultiNodeClient) cancelInflightRequests() { + m.stateMu.Lock() + defer m.stateMu.Unlock() + close(m.chStopInFlight) + m.chStopInFlight = make(chan struct{}) +} + +func (m *MultiNodeClient) Close() { + defer func() { + err := m.rpc.Close() + if err != nil { + m.log.Errorf("error closing rpc: %v", err) + } + }() + m.cancelInflightRequests() + m.UnsubscribeAllExcept() + m.chainInfoLock.Lock() + m.latestChainInfo = mn.ChainInfo{} + m.chainInfoLock.Unlock() +} + +func (m *MultiNodeClient) GetInterceptedChainInfo() (latest, highestUserObservations mn.ChainInfo) { + m.chainInfoLock.Lock() + defer m.chainInfoLock.Unlock() + return m.latestChainInfo, m.highestUserObservations +} + +func (m *MultiNodeClient) SendTransaction(ctx context.Context, tx *solana.Transaction) error { + // TODO: Use Transaction Sender + _, err := m.SendTx(ctx, tx) + return err +} diff --git a/pkg/solana/client/multinode_client_test.go b/pkg/solana/client/multinode_client_test.go new file mode 100644 index 0000000..601a5e1 --- /dev/null +++ b/pkg/solana/client/multinode_client_test.go @@ -0,0 +1,148 @@ +package client + +import ( + "context" + "testing" + "time" + + "github.com/gagliardetto/solana-go" + "github.com/goplugin/plugin-common/pkg/logger" + "github.com/goplugin/plugin-common/pkg/utils/tests" + "github.com/stretchr/testify/require" + + "github.com/goplugin/plugin-solana/pkg/solana/config" +) + +func initializeMultiNodeClient(t *testing.T) *MultiNodeClient { + url := SetupLocalSolNode(t) + privKey, err := solana.NewRandomPrivateKey() + require.NoError(t, err) + pubKey := privKey.PublicKey() + FundTestAccounts(t, []solana.PublicKey{pubKey}, url) + + requestTimeout := 5 * time.Second + lggr := logger.Test(t) + cfg := config.NewDefault() + enabled := true + cfg.MultiNode.MultiNode.Enabled = &enabled + + c, err := NewMultiNodeClient(url, cfg, requestTimeout, lggr) + require.NoError(t, err) + return c +} + +func TestMultiNodeClient_Ping(t *testing.T) { + c := initializeMultiNodeClient(t) + require.NoError(t, c.Ping(tests.Context(t))) +} + +func TestMultiNodeClient_LatestBlock(t *testing.T) { + c := initializeMultiNodeClient(t) + + t.Run("LatestBlock", func(t *testing.T) { + head, err := c.LatestBlock(tests.Context(t)) + require.NoError(t, err) + require.Equal(t, true, head.IsValid()) + require.NotEqual(t, solana.Hash{}, head.BlockHash) + }) + + t.Run("LatestFinalizedBlock", func(t *testing.T) { + finalizedHead, err := c.LatestFinalizedBlock(tests.Context(t)) + require.NoError(t, err) + require.Equal(t, true, finalizedHead.IsValid()) + require.NotEqual(t, solana.Hash{}, finalizedHead.BlockHash) + }) +} + +func TestMultiNodeClient_HeadSubscriptions(t *testing.T) { + c := initializeMultiNodeClient(t) + + t.Run("SubscribeToHeads", func(t *testing.T) { + ch, sub, err := c.SubscribeToHeads(tests.Context(t)) + require.NoError(t, err) + defer sub.Unsubscribe() + + ctx, cancel := context.WithTimeout(tests.Context(t), time.Minute) + defer cancel() + select { + case head := <-ch: + require.NotEqual(t, solana.Hash{}, head.BlockHash) + latest, _ := c.GetInterceptedChainInfo() + require.Equal(t, head.BlockNumber(), latest.BlockNumber) + case <-ctx.Done(): + t.Fatal("failed to receive head: ", ctx.Err()) + } + }) + + t.Run("SubscribeToFinalizedHeads", func(t *testing.T) { + finalizedCh, finalizedSub, err := c.SubscribeToFinalizedHeads(tests.Context(t)) + require.NoError(t, err) + defer finalizedSub.Unsubscribe() + + ctx, cancel := context.WithTimeout(tests.Context(t), time.Minute) + defer cancel() + select { + case finalizedHead := <-finalizedCh: + require.NotEqual(t, solana.Hash{}, finalizedHead.BlockHash) + latest, _ := c.GetInterceptedChainInfo() + require.Equal(t, finalizedHead.BlockNumber(), latest.FinalizedBlockNumber) + case <-ctx.Done(): + t.Fatal("failed to receive finalized head: ", ctx.Err()) + } + }) +} + +type mockSub struct { + unsubscribed bool +} + +func newMockSub() *mockSub { + return &mockSub{unsubscribed: false} +} + +func (s *mockSub) Unsubscribe() { + s.unsubscribed = true +} +func (s *mockSub) Err() <-chan error { + return nil +} + +func TestMultiNodeClient_RegisterSubs(t *testing.T) { + c := initializeMultiNodeClient(t) + + t.Run("registerSub", func(t *testing.T) { + sub := newMockSub() + err := c.registerSub(sub, make(chan struct{})) + require.NoError(t, err) + require.Len(t, c.subs, 1) + c.UnsubscribeAllExcept() + }) + + t.Run("chStopInFlight returns error and unsubscribes", func(t *testing.T) { + chStopInFlight := make(chan struct{}) + close(chStopInFlight) + sub := newMockSub() + err := c.registerSub(sub, chStopInFlight) + require.Error(t, err) + require.Equal(t, true, sub.unsubscribed) + }) + + t.Run("UnsubscribeAllExcept", func(t *testing.T) { + chStopInFlight := make(chan struct{}) + sub1 := newMockSub() + sub2 := newMockSub() + err := c.registerSub(sub1, chStopInFlight) + require.NoError(t, err) + err = c.registerSub(sub2, chStopInFlight) + require.NoError(t, err) + require.Len(t, c.subs, 2) + + c.UnsubscribeAllExcept(sub1) + require.Len(t, c.subs, 1) + require.Equal(t, true, sub2.unsubscribed) + + c.UnsubscribeAllExcept() + require.Len(t, c.subs, 0) + require.Equal(t, true, sub1.unsubscribed) + }) +} diff --git a/pkg/solana/client/test_helpers_test.go b/pkg/solana/client/test_helpers_test.go index 226f245..93c55b2 100644 --- a/pkg/solana/client/test_helpers_test.go +++ b/pkg/solana/client/test_helpers_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/require" "github.com/goplugin/plugin-common/pkg/logger" + "github.com/goplugin/plugin-common/pkg/utils/tests" "github.com/goplugin/plugin-solana/pkg/solana/config" ) @@ -28,19 +29,20 @@ func TestSetupLocalSolNode_SimultaneousNetworks(t *testing.T) { // check & fund address checkFunded := func(t *testing.T, url string) { + ctx := tests.Context(t) // create client c, err := NewClient(url, cfg, requestTimeout, lggr) require.NoError(t, err) // check init balance - bal, err := c.Balance(pubkey) + bal, err := c.Balance(ctx, pubkey) assert.NoError(t, err) assert.Equal(t, uint64(0), bal) FundTestAccounts(t, []solana.PublicKey{pubkey}, url) // check end balance - bal, err = c.Balance(pubkey) + bal, err = c.Balance(ctx, pubkey) assert.NoError(t, err) assert.Equal(t, uint64(100_000_000_000), bal) // once funds get sent to the system program it should be unrecoverable (so this number should remain > 0) } diff --git a/pkg/solana/codec/discriminator_test.go b/pkg/solana/codec/discriminator_test.go index d920a09..435a3b0 100644 --- a/pkg/solana/codec/discriminator_test.go +++ b/pkg/solana/codec/discriminator_test.go @@ -6,9 +6,10 @@ import ( "reflect" "testing" - "github.com/goplugin/plugin-common/pkg/types" "github.com/stretchr/testify/require" + "github.com/goplugin/plugin-common/pkg/types" + "github.com/goplugin/plugin-solana/pkg/solana/codec" ) diff --git a/pkg/solana/config/config.go b/pkg/solana/config/config.go index 2eac996..330ec0b 100644 --- a/pkg/solana/config/config.go +++ b/pkg/solana/config/config.go @@ -23,13 +23,14 @@ var defaultConfigSet = Chain{ MaxRetries: ptr(int64(0)), // max number of retries (default = 0). when config.MaxRetries < 0), interpreted as MaxRetries = nil and rpc node will do a reasonable number of retries // fee estimator - FeeEstimatorMode: ptr("fixed"), - ComputeUnitPriceMax: ptr(uint64(1_000)), - ComputeUnitPriceMin: ptr(uint64(0)), - ComputeUnitPriceDefault: ptr(uint64(0)), - FeeBumpPeriod: config.MustNewDuration(3 * time.Second), // set to 0 to disable fee bumping - BlockHistoryPollPeriod: config.MustNewDuration(5 * time.Second), - ComputeUnitLimitDefault: ptr(uint32(200_000)), // set to 0 to disable adding compute unit limit + FeeEstimatorMode: ptr("fixed"), + ComputeUnitPriceMax: ptr(uint64(1_000)), + ComputeUnitPriceMin: ptr(uint64(0)), + ComputeUnitPriceDefault: ptr(uint64(0)), + FeeBumpPeriod: config.MustNewDuration(3 * time.Second), // set to 0 to disable fee bumping + BlockHistoryPollPeriod: config.MustNewDuration(5 * time.Second), + ComputeUnitLimitDefault: ptr(uint32(200_000)), // set to 0 to disable adding compute unit limit + EstimateComputeUnitLimit: ptr(false), // set to false to disable compute unit limit estimation } //go:generate mockery --name Config --output ./mocks/ --case=underscore --filename config.go @@ -53,26 +54,28 @@ type Config interface { FeeBumpPeriod() time.Duration BlockHistoryPollPeriod() time.Duration ComputeUnitLimitDefault() uint32 + EstimateComputeUnitLimit() bool } type Chain struct { - BalancePollPeriod *config.Duration - ConfirmPollPeriod *config.Duration - OCR2CachePollPeriod *config.Duration - OCR2CacheTTL *config.Duration - TxTimeout *config.Duration - TxRetryTimeout *config.Duration - TxConfirmTimeout *config.Duration - SkipPreflight *bool - Commitment *string - MaxRetries *int64 - FeeEstimatorMode *string - ComputeUnitPriceMax *uint64 - ComputeUnitPriceMin *uint64 - ComputeUnitPriceDefault *uint64 - FeeBumpPeriod *config.Duration - BlockHistoryPollPeriod *config.Duration - ComputeUnitLimitDefault *uint32 + BalancePollPeriod *config.Duration + ConfirmPollPeriod *config.Duration + OCR2CachePollPeriod *config.Duration + OCR2CacheTTL *config.Duration + TxTimeout *config.Duration + TxRetryTimeout *config.Duration + TxConfirmTimeout *config.Duration + SkipPreflight *bool + Commitment *string + MaxRetries *int64 + FeeEstimatorMode *string + ComputeUnitPriceMax *uint64 + ComputeUnitPriceMin *uint64 + ComputeUnitPriceDefault *uint64 + FeeBumpPeriod *config.Duration + BlockHistoryPollPeriod *config.Duration + ComputeUnitLimitDefault *uint32 + EstimateComputeUnitLimit *bool } func (c *Chain) SetDefaults() { @@ -127,6 +130,9 @@ func (c *Chain) SetDefaults() { if c.ComputeUnitLimitDefault == nil { c.ComputeUnitLimitDefault = defaultConfigSet.ComputeUnitLimitDefault } + if c.EstimateComputeUnitLimit == nil { + c.EstimateComputeUnitLimit = defaultConfigSet.EstimateComputeUnitLimit + } } type Node struct { diff --git a/pkg/solana/config/mocks/config.go b/pkg/solana/config/mocks/config.go index 56b1cca..ab57ba6 100644 --- a/pkg/solana/config/mocks/config.go +++ b/pkg/solana/config/mocks/config.go @@ -158,6 +158,24 @@ func (_m *Config) ConfirmPollPeriod() time.Duration { return r0 } +// EstimateComputeUnitLimit provides a mock function with given fields: +func (_m *Config) EstimateComputeUnitLimit() bool { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for EstimateComputeUnitLimit") + } + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + // FeeBumpPeriod provides a mock function with given fields: func (_m *Config) FeeBumpPeriod() time.Duration { ret := _m.Called() diff --git a/pkg/solana/config/toml.go b/pkg/solana/config/toml.go index f0cc63c..2a80edd 100644 --- a/pkg/solana/config/toml.go +++ b/pkg/solana/config/toml.go @@ -282,6 +282,10 @@ func (c *TOMLConfig) ComputeUnitLimitDefault() uint32 { return *c.Chain.ComputeUnitLimitDefault } +func (c *TOMLConfig) EstimateComputeUnitLimit() bool { + return *c.Chain.EstimateComputeUnitLimit +} + func (c *TOMLConfig) ListNodes() Nodes { return c.Nodes } diff --git a/pkg/solana/config_tracker.go b/pkg/solana/config_tracker.go index f0ba367..577f13e 100644 --- a/pkg/solana/config_tracker.go +++ b/pkg/solana/config_tracker.go @@ -75,5 +75,5 @@ func (c *ConfigTracker) LatestConfig(ctx context.Context, changedInBlock uint64) // LatestBlockHeight returns the height of the most recent block in the chain. func (c *ConfigTracker) LatestBlockHeight(ctx context.Context) (blockHeight uint64, err error) { - return c.reader.SlotHeight() // this returns the latest slot height through CommitmentProcessed + return c.reader.SlotHeight(ctx) // this returns the latest slot height through CommitmentProcessed } diff --git a/pkg/solana/fees/block_history.go b/pkg/solana/fees/block_history.go index 20749b3..4fc0952 100644 --- a/pkg/solana/fees/block_history.go +++ b/pkg/solana/fees/block_history.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "sync" - "time" "github.com/goplugin/plugin-common/pkg/logger" "github.com/goplugin/plugin-common/pkg/services" @@ -19,7 +18,7 @@ var _ Estimator = &blockHistoryEstimator{} type blockHistoryEstimator struct { starter services.StateMachine - chStop chan struct{} + chStop services.StopChan done sync.WaitGroup client *utils.LazyLoad[client.ReaderWriter] @@ -54,19 +53,20 @@ func (bhe *blockHistoryEstimator) Start(ctx context.Context) error { func (bhe *blockHistoryEstimator) run() { defer bhe.done.Done() + ctx, cancel := bhe.chStop.NewCtx() + defer cancel() - tick := time.After(0) + ticker := services.NewTicker(bhe.cfg.BlockHistoryPollPeriod()) + defer ticker.Stop() for { select { - case <-bhe.chStop: + case <-ctx.Done(): return - case <-tick: - if err := bhe.calculatePrice(); err != nil { + case <-ticker.C: + if err := bhe.calculatePrice(ctx); err != nil { bhe.lgr.Error(fmt.Errorf("BlockHistoryEstimator failed to fetch price: %w", err)) } } - - tick = time.After(utils.WithJitter(bhe.cfg.BlockHistoryPollPeriod())) } } @@ -98,7 +98,7 @@ func (bhe *blockHistoryEstimator) readRawPrice() uint64 { return bhe.price } -func (bhe *blockHistoryEstimator) calculatePrice() error { +func (bhe *blockHistoryEstimator) calculatePrice(ctx context.Context) error { // fetch client c, err := bhe.client.Get() if err != nil { @@ -106,7 +106,7 @@ func (bhe *blockHistoryEstimator) calculatePrice() error { } // get latest block based on configured confirmation - block, err := c.GetLatestBlock() + block, err := c.GetLatestBlock(ctx) if err != nil { return fmt.Errorf("failed to get block in blockHistoryEstimator.getFee: %w", err) } diff --git a/pkg/solana/fees/block_history_test.go b/pkg/solana/fees/block_history_test.go index a42c025..72af409 100644 --- a/pkg/solana/fees/block_history_test.go +++ b/pkg/solana/fees/block_history_test.go @@ -9,6 +9,7 @@ import ( "github.com/gagliardetto/solana-go/rpc" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" @@ -47,7 +48,7 @@ func TestBlockHistoryEstimator(t *testing.T) { estimator, err := NewBlockHistoryEstimator(rwLoader, cfg, lgr) require.NoError(t, err) - rw.On("GetLatestBlock").Return(blockRes, nil).Once() + rw.On("GetLatestBlock", mock.Anything).Return(blockRes, nil).Once() require.NoError(t, estimator.Start(ctx)) tests.AssertLogEventually(t, logs, "BlockHistoryEstimator: updated") assert.Equal(t, uint64(55000), estimator.readRawPrice()) @@ -61,22 +62,22 @@ func TestBlockHistoryEstimator(t *testing.T) { assert.Equal(t, estimator.readRawPrice(), estimator.BaseComputeUnitPrice()) // failed to get latest block - rw.On("GetLatestBlock").Return(nil, fmt.Errorf("fail rpc call")).Once() + rw.On("GetLatestBlock", mock.Anything).Return(nil, fmt.Errorf("fail rpc call")).Once() tests.AssertLogEventually(t, logs, "failed to get block") assert.Equal(t, validPrice, estimator.BaseComputeUnitPrice(), "price should not change when getPrice fails") // failed to parse block - rw.On("GetLatestBlock").Return(nil, nil).Once() + rw.On("GetLatestBlock", mock.Anything).Return(nil, nil).Once() tests.AssertLogEventually(t, logs, "failed to parse block") assert.Equal(t, validPrice, estimator.BaseComputeUnitPrice(), "price should not change when getPrice fails") // failed to calculate median - rw.On("GetLatestBlock").Return(&rpc.GetBlockResult{}, nil).Once() + rw.On("GetLatestBlock", mock.Anything).Return(&rpc.GetBlockResult{}, nil).Once() tests.AssertLogEventually(t, logs, "failed to find median") assert.Equal(t, validPrice, estimator.BaseComputeUnitPrice(), "price should not change when getPrice fails") // back to happy path - rw.On("GetLatestBlock").Return(blockRes, nil).Once() + rw.On("GetLatestBlock", mock.Anything).Return(blockRes, nil).Once() tests.AssertEventually(t, func() bool { return logs.FilterMessageSnippet("BlockHistoryEstimator: updated").Len() == 2 }) diff --git a/pkg/solana/monitor/balance.go b/pkg/solana/monitor/balance.go index 0bd4ef6..0f3336f 100644 --- a/pkg/solana/monitor/balance.go +++ b/pkg/solana/monitor/balance.go @@ -22,7 +22,7 @@ type Keystore interface { } type BalanceClient interface { - Balance(addr solana.PublicKey) (uint64, error) + Balance(ctx context.Context, addr solana.PublicKey) (uint64, error) } // NewBalanceMonitor returns a balance monitoring services.Service which reports the SOL balance of all ks keys to prometheus. @@ -112,6 +112,9 @@ func (b *balanceMonitor) getReader() (BalanceClient, error) { } func (b *balanceMonitor) updateBalances(ctx context.Context) { + ctx, cancel := b.stop.Ctx(ctx) + defer cancel() + keys, err := b.ks.Accounts(ctx) if err != nil { b.lggr.Errorw("Failed to get keys", "err", err) @@ -129,7 +132,7 @@ func (b *balanceMonitor) updateBalances(ctx context.Context) { for _, k := range keys { // Check for shutdown signal, since Balance blocks and may be slow. select { - case <-b.stop: + case <-ctx.Done(): return default: } @@ -138,7 +141,7 @@ func (b *balanceMonitor) updateBalances(ctx context.Context) { b.lggr.Errorw("Failed parse public key", "account", k, "err", err) continue } - lamports, err := reader.Balance(pubKey) + lamports, err := reader.Balance(ctx, pubKey) if err != nil { b.lggr.Errorw("Failed to get balance", "account", k, "err", err) continue diff --git a/pkg/solana/monitor/balance_test.go b/pkg/solana/monitor/balance_test.go index cec5586..07eb12c 100644 --- a/pkg/solana/monitor/balance_test.go +++ b/pkg/solana/monitor/balance_test.go @@ -9,9 +9,11 @@ import ( "github.com/gagliardetto/solana-go" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "github.com/goplugin/plugin-common/pkg/logger" + "github.com/goplugin/plugin-common/pkg/services/servicetest" "github.com/goplugin/plugin-common/pkg/utils/tests" "github.com/goplugin/plugin-solana/pkg/solana/client/mocks" @@ -36,13 +38,12 @@ func TestBalanceMonitor(t *testing.T) { "1.000000000", } - client := new(mocks.ReaderWriter) - client.Test(t) + client := mocks.NewReaderWriter(t) type update struct{ acc, bal string } var exp []update for i := range bals { acc := ks[i] - client.On("Balance", acc).Return(bals[i], nil) + client.On("Balance", mock.Anything, acc).Return(bals[i], nil) exp = append(exp, update{acc.String(), expBals[i]}) } cfg := &config{balancePollPeriod: time.Second} @@ -63,11 +64,7 @@ func TestBalanceMonitor(t *testing.T) { } b.reader = client - require.NoError(t, b.Start(tests.Context(t))) - t.Cleanup(func() { - assert.NoError(t, b.Close()) - client.AssertExpectations(t) - }) + servicetest.Run(t, b) select { case <-time.After(tests.WaitTimeout(t)): t.Fatal("timed out waiting for balance monitor") diff --git a/pkg/solana/relay.go b/pkg/solana/relay.go index 656cfcd..7c0a8de 100644 --- a/pkg/solana/relay.go +++ b/pkg/solana/relay.go @@ -24,7 +24,7 @@ import ( var _ TxManager = (*txm.Txm)(nil) type TxManager interface { - Enqueue(accountID string, msg *solana.Transaction, txCfgs ...txm.SetTxConfig) error + Enqueue(ctx context.Context, accountID string, msg *solana.Transaction, txCfgs ...txm.SetTxConfig) error } var _ relaytypes.Relayer = &Relayer{} //nolint:staticcheck diff --git a/pkg/solana/transmitter.go b/pkg/solana/transmitter.go index 55b7f74..413fa99 100644 --- a/pkg/solana/transmitter.go +++ b/pkg/solana/transmitter.go @@ -32,7 +32,7 @@ func (c *Transmitter) Transmit( report types.Report, sigs []types.AttributedOnchainSignature, ) error { - blockhash, err := c.reader.LatestBlockhash() + blockhash, err := c.reader.LatestBlockhash(ctx) if err != nil { return fmt.Errorf("error on Transmit.GetRecentBlockhash: %w", err) } @@ -84,7 +84,7 @@ func (c *Transmitter) Transmit( // pass transmit payload to tx manager queue c.lggr.Debugf("Queuing transmit tx: state (%s) + transmissions (%s)", c.stateID.String(), c.transmissionsID.String()) - if err = c.txManager.Enqueue(c.stateID.String(), tx); err != nil { + if err = c.txManager.Enqueue(ctx, c.stateID.String(), tx); err != nil { return fmt.Errorf("error on Transmit.txManager.Enqueue: %w", err) } return nil diff --git a/pkg/solana/transmitter_test.go b/pkg/solana/transmitter_test.go index 386a08c..d208942 100644 --- a/pkg/solana/transmitter_test.go +++ b/pkg/solana/transmitter_test.go @@ -1,16 +1,19 @@ package solana import ( + "context" "testing" "github.com/gagliardetto/solana-go" "github.com/gagliardetto/solana-go/rpc" - "github.com/goplugin/plugin-common/pkg/logger" - "github.com/goplugin/plugin-common/pkg/utils/tests" "github.com/goplugin/plugin-libocr/offchainreporting2/types" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/goplugin/plugin-common/pkg/logger" + "github.com/goplugin/plugin-common/pkg/utils/tests" + clientmocks "github.com/goplugin/plugin-solana/pkg/solana/client/mocks" "github.com/goplugin/plugin-solana/pkg/solana/fees" "github.com/goplugin/plugin-solana/pkg/solana/txm" @@ -23,7 +26,7 @@ type verifyTxSize struct { s *solana.PrivateKey } -func (txm verifyTxSize) Enqueue(_ string, tx *solana.Transaction, _ ...txm.SetTxConfig) error { +func (txm verifyTxSize) Enqueue(_ context.Context, _ string, tx *solana.Transaction, _ ...txm.SetTxConfig) error { // additional components that transaction manager adds to the transaction require.NoError(txm.t, fees.SetComputeUnitPrice(tx, 0)) require.NoError(txm.t, fees.SetComputeUnitLimit(tx, 0)) @@ -55,7 +58,7 @@ func TestTransmitter_TxSize(t *testing.T) { } rw := clientmocks.NewReaderWriter(t) - rw.On("LatestBlockhash").Return(&rpc.GetLatestBlockhashResult{ + rw.On("LatestBlockhash", mock.Anything).Return(&rpc.GetLatestBlockhashResult{ Value: &rpc.LatestBlockhashResult{}, }, nil) diff --git a/pkg/solana/txm/pendingtx.go b/pkg/solana/txm/pendingtx.go index 3a4a515..4bf06c6 100644 --- a/pkg/solana/txm/pendingtx.go +++ b/pkg/solana/txm/pendingtx.go @@ -228,14 +228,21 @@ func (c *pendingTxContextWithProm) OnError(sig solana.Signature, errType int) uu switch errType { case TxFailRevert: promSolTxmRevertTxs.WithLabelValues(c.chainID).Add(1) + promSolTxmErrorTxs.WithLabelValues(c.chainID).Add(1) case TxFailDrop: promSolTxmDropTxs.WithLabelValues(c.chainID).Add(1) - case TxFailSimRevert: - promSolTxmSimRevertTxs.WithLabelValues(c.chainID).Add(1) - case TxFailSimOther: - promSolTxmSimOtherTxs.WithLabelValues(c.chainID).Add(1) + promSolTxmErrorTxs.WithLabelValues(c.chainID).Add(1) } - // increment total errors + } + + // Increment simulation error metrics even if no tx found for sig + // Simulation could have occurred before initial broadcast so tx was never stored + switch errType { + case TxFailSimRevert: + promSolTxmSimRevertTxs.WithLabelValues(c.chainID).Add(1) + promSolTxmErrorTxs.WithLabelValues(c.chainID).Add(1) + case TxFailSimOther: + promSolTxmSimOtherTxs.WithLabelValues(c.chainID).Add(1) promSolTxmErrorTxs.WithLabelValues(c.chainID).Add(1) } diff --git a/pkg/solana/txm/txm.go b/pkg/solana/txm/txm.go index 06e9cf6..0cb7257 100644 --- a/pkg/solana/txm/txm.go +++ b/pkg/solana/txm/txm.go @@ -4,6 +4,8 @@ import ( "context" "errors" "fmt" + "math" + "math/big" "strings" "sync" "time" @@ -16,6 +18,7 @@ import ( "github.com/goplugin/plugin-common/pkg/loop" "github.com/goplugin/plugin-common/pkg/services" "github.com/goplugin/plugin-common/pkg/utils" + bigmath "github.com/goplugin/plugin-common/pkg/utils/big_math" "github.com/goplugin/plugin-solana/pkg/solana/client" "github.com/goplugin/plugin-solana/pkg/solana/config" @@ -23,9 +26,10 @@ import ( ) const ( - MaxQueueLen = 1000 - MaxRetryTimeMs = 250 // max tx retry time (exponential retry will taper to retry every 0.25s) - MaxSigsToConfirm = 256 // max number of signatures in GetSignatureStatus call + MaxQueueLen = 1000 + MaxRetryTimeMs = 250 // max tx retry time (exponential retry will taper to retry every 0.25s) + MaxSigsToConfirm = 256 // max number of signatures in GetSignatureStatus call + EstimateComputeUnitLimitBuffer = 10 // percent buffer added on top of estimated compute unit limits to account for any variance ) var _ services.Service = (*Txm)(nil) @@ -63,7 +67,8 @@ type TxConfig struct { ComputeUnitPriceMin uint64 // min price ComputeUnitPriceMax uint64 // max price - ComputeUnitLimit uint32 // compute unit limit + EstimateComputeUnitLimit bool // enable compute limit estimations using simulation + ComputeUnitLimit uint32 // compute unit limit } type pendingTx struct { @@ -111,6 +116,9 @@ func (txm *Txm) Start(ctx context.Context) error { txm.done.Add(3) // waitgroup: tx retry, confirmer, simulator go txm.run() + go txm.confirm() + go txm.simulate() + return nil }) } @@ -120,10 +128,6 @@ func (txm *Txm) run() { ctx, cancel := txm.chStop.NewCtx() defer cancel() - // start confirmer + simulator - go txm.confirm(ctx) - go txm.simulate(ctx) - for { select { case msg := <-txm.chSend: @@ -152,7 +156,7 @@ func (txm *Txm) run() { } } -func (txm *Txm) sendWithRetry(chanCtx context.Context, baseTx solanaGo.Transaction, txcfg TxConfig) (solanaGo.Transaction, uuid.UUID, solanaGo.Signature, error) { +func (txm *Txm) sendWithRetry(ctx context.Context, baseTx solanaGo.Transaction, txcfg TxConfig) (solanaGo.Transaction, uuid.UUID, solanaGo.Signature, error) { // fetch client client, clientErr := txm.client.Get() if clientErr != nil { @@ -184,7 +188,7 @@ func (txm *Txm) sendWithRetry(chanCtx context.Context, baseTx solanaGo.Transacti } } - buildTx := func(base solanaGo.Transaction, retryCount int) (solanaGo.Transaction, error) { + buildTx := func(ctx context.Context, base solanaGo.Transaction, retryCount int) (solanaGo.Transaction, error) { newTx := base // make copy // set fee @@ -198,7 +202,7 @@ func (txm *Txm) sendWithRetry(chanCtx context.Context, baseTx solanaGo.Transacti if marshalErr != nil { return solanaGo.Transaction{}, fmt.Errorf("error in soltxm.SendWithRetry.MarshalBinary: %w", marshalErr) } - sigBytes, signErr := txm.ks.Sign(context.TODO(), key, txMsg) + sigBytes, signErr := txm.ks.Sign(ctx, key, txMsg) if signErr != nil { return solanaGo.Transaction{}, fmt.Errorf("error in soltxm.SendWithRetry.Sign: %w", signErr) } @@ -209,13 +213,13 @@ func (txm *Txm) sendWithRetry(chanCtx context.Context, baseTx solanaGo.Transacti return newTx, nil } - initTx, initBuildErr := buildTx(baseTx, 0) + initTx, initBuildErr := buildTx(ctx, baseTx, 0) if initBuildErr != nil { return solanaGo.Transaction{}, uuid.Nil, solanaGo.Signature{}, initBuildErr } // create timeout context - ctx, cancel := context.WithTimeout(chanCtx, txcfg.Timeout) + ctx, cancel := context.WithTimeout(ctx, txcfg.Timeout) // send initial tx (do not retry and exit early if fails) sig, initSendErr := client.SendTx(ctx, &initTx) @@ -241,10 +245,12 @@ func (txm *Txm) sendWithRetry(chanCtx context.Context, baseTx solanaGo.Transacti txm.lggr.Debugw("tx initial broadcast", "id", id, "signature", sig) + txm.done.Add(1) // retry with exponential backoff // until context cancelled by timeout or called externally // pass in copy of baseTx (used to build new tx with bumped fee) and broadcasted tx == initTx (used to retry tx without bumping) - go func(baseTx, currentTx solanaGo.Transaction) { + go func(ctx context.Context, baseTx, currentTx solanaGo.Transaction) { + defer txm.done.Done() deltaT := 1 // ms tick := time.After(0) bumpCount := 0 @@ -256,7 +262,7 @@ func (txm *Txm) sendWithRetry(chanCtx context.Context, baseTx solanaGo.Transacti case <-ctx.Done(): // stop sending tx after retry tx ctx times out (does not stop confirmation polling for tx) wg.Wait() - txm.lggr.Debugw("stopped tx retry", "id", id, "signatures", sigs.List()) + txm.lggr.Debugw("stopped tx retry", "id", id, "signatures", sigs.List(), "err", context.Cause(ctx)) return case <-tick: var shouldBump bool @@ -270,7 +276,7 @@ func (txm *Txm) sendWithRetry(chanCtx context.Context, baseTx solanaGo.Transacti // if fee should be bumped, build new tx and replace currentTx if shouldBump { var retryBuildErr error - currentTx, retryBuildErr = buildTx(baseTx, bumpCount) + currentTx, retryBuildErr = buildTx(ctx, baseTx, bumpCount) if retryBuildErr != nil { txm.lggr.Errorw("failed to build bumped retry tx", "error", retryBuildErr, "id", id) return // exit func if cannot build tx for retrying @@ -337,7 +343,7 @@ func (txm *Txm) sendWithRetry(chanCtx context.Context, baseTx solanaGo.Transacti } tick = time.After(time.Duration(deltaT) * time.Millisecond) } - }(baseTx, initTx) + }(ctx, baseTx, initTx) // return signed tx, id, signature for use in simulation return initTx, id, sig, nil @@ -345,8 +351,10 @@ func (txm *Txm) sendWithRetry(chanCtx context.Context, baseTx solanaGo.Transacti // goroutine that polls to confirm implementation // cancels the exponential retry once confirmed -func (txm *Txm) confirm(ctx context.Context) { +func (txm *Txm) confirm() { defer txm.done.Done() + ctx, cancel := txm.chStop.NewCtx() + defer cancel() tick := time.After(0) for { @@ -441,7 +449,6 @@ func (txm *Txm) confirm(ctx context.Context) { // waitgroup for processing var wg sync.WaitGroup - wg.Add(len(sigsBatch)) // loop through batch for i := 0; i < len(sigsBatch); i++ { @@ -449,10 +456,10 @@ func (txm *Txm) confirm(ctx context.Context) { statuses, err := client.SignatureStatuses(ctx, sigsBatch[i]) if err != nil { txm.lggr.Errorw("failed to get signature statuses in soltxm.confirm", "error", err) - wg.Done() // don't block if exit early - break // exit for loop + break // exit for loop } + wg.Add(1) // nonblocking: process batches as soon as they come in go func(index int) { defer wg.Done() @@ -468,26 +475,18 @@ func (txm *Txm) confirm(ctx context.Context) { // goroutine that simulates tx (use a bounded number of goroutines to pick from queue?) // simulate can cancel the send retry function early in the tx management process // additionally, it can provide reasons for why a tx failed in the logs -func (txm *Txm) simulate(ctx context.Context) { +func (txm *Txm) simulate() { defer txm.done.Done() + ctx, cancel := txm.chStop.NewCtx() + defer cancel() for { select { case <-ctx.Done(): return case msg := <-txm.chSim: - // get client - client, err := txm.client.Get() - if err != nil { - txm.lggr.Errorw("failed to get client in soltxm.simulate", "error", err) - continue - } - - res, err := client.SimulateTx(ctx, msg.tx, nil) // use default options (does not verify signatures) + res, err := txm.simulateTx(ctx, msg.tx) if err != nil { - // this error can occur if endpoint goes down or if invalid signature (invalid signature should occur further upstream in sendWithRetry) - // allow retry to continue in case temporary endpoint failure (if still invalid, confirm or timeout will cleanup) - txm.lggr.Debugw("failed to simulate tx", "id", msg.id, "signature", msg.signature, "error", err) continue } @@ -496,37 +495,13 @@ func (txm *Txm) simulate(ctx context.Context) { continue } - // handle various errors - // https://github.com/solana-labs/solana/blob/master/sdk/src/transaction/error.rs - // --- - errStr := fmt.Sprintf("%v", res.Err) // convert to string to handle various interfaces - switch { - // blockhash not found when simulating, occurs when network bank has not seen the given blockhash or tx is too old - // let confirmation process clean up - case strings.Contains(errStr, "BlockhashNotFound"): - txm.lggr.Debugw("simulate: BlockhashNotFound", "id", msg.id, "signature", msg.signature, "result", res) - continue - // transaction will encounter execution error/revert, mark as reverted to remove from confirmation + retry - case strings.Contains(errStr, "InstructionError"): - txm.txs.OnError(msg.signature, TxFailSimRevert) // cancel retry - txm.lggr.Debugw("simulate: InstructionError", "id", msg.id, "signature", msg.signature, "result", res) - continue - // transaction is already processed in the chain, letting txm confirmation handle - case strings.Contains(errStr, "AlreadyProcessed"): - txm.lggr.Debugw("simulate: AlreadyProcessed", "id", msg.id, "signature", msg.signature, "result", res) - continue - // unrecognized errors (indicates more concerning failures) - default: - txm.txs.OnError(msg.signature, TxFailSimOther) // cancel retry - txm.lggr.Errorw("simulate: unrecognized error", "id", msg.id, "signature", msg.signature, "result", res) - continue - } + txm.processSimulationError(msg.id, msg.signature, res) } } } // Enqueue enqueue a msg destined for the solana chain. -func (txm *Txm) Enqueue(accountID string, tx *solanaGo.Transaction, txCfgs ...SetTxConfig) error { +func (txm *Txm) Enqueue(ctx context.Context, accountID string, tx *solanaGo.Transaction, txCfgs ...SetTxConfig) error { if err := txm.Ready(); err != nil { return fmt.Errorf("error in soltxm.Enqueue: %w", err) } @@ -543,7 +518,7 @@ func (txm *Txm) Enqueue(accountID string, tx *solanaGo.Transaction, txCfgs ...Se // validate expected key exists by trying to sign with it // fee payer account is index 0 account // https://github.com/gagliardetto/solana-go/blob/main/transaction.go#L252 - _, err := txm.ks.Sign(context.TODO(), tx.Message.AccountKeys[0].String(), nil) + _, err := txm.ks.Sign(ctx, tx.Message.AccountKeys[0].String(), nil) if err != nil { return fmt.Errorf("error in soltxm.Enqueue.GetKey: %w", err) } @@ -554,6 +529,17 @@ func (txm *Txm) Enqueue(accountID string, tx *solanaGo.Transaction, txCfgs ...Se v(&cfg) } + if cfg.EstimateComputeUnitLimit { + computeUnitLimit, err := txm.EstimateComputeUnitLimit(ctx, tx) + if err != nil { + return fmt.Errorf("transaction failed simulation: %w", err) + } + // If estimation returns 0 compute unit limit without error, fallback to original config + if computeUnitLimit != 0 { + cfg.ComputeUnitLimit = computeUnitLimit + } + } + msg := pendingTx{ tx: tx, cfg: cfg, @@ -568,6 +554,88 @@ func (txm *Txm) Enqueue(accountID string, tx *solanaGo.Transaction, txCfgs ...Se return nil } +// EstimateComputeUnitLimit estimates the compute unit limit needed for a transaction. +// It simulates the provided transaction to determine the used compute and applies a buffer to it. +func (txm *Txm) EstimateComputeUnitLimit(ctx context.Context, tx *solanaGo.Transaction) (uint32, error) { + res, err := txm.simulateTx(ctx, tx) + if err != nil { + return 0, err + } + + // Return error if response err is non-nil to avoid broadcasting a tx destined to fail + if res.Err != nil { + sig := solanaGo.Signature{} + if len(tx.Signatures) > 0 { + sig = tx.Signatures[0] + } + txm.processSimulationError(uuid.Nil, sig, res) + return 0, fmt.Errorf("simulated tx returned error: %v", res.Err) + } + + if res.UnitsConsumed == nil || *res.UnitsConsumed == 0 { + txm.lggr.Debug("failed to get units consumed for tx") + // Do not return error to allow falling back to default compute unit limit + return 0, nil + } + + unitsConsumed := *res.UnitsConsumed + + // Add buffer to the used compute estimate + unitsConsumed = bigmath.AddPercentage(new(big.Int).SetUint64(unitsConsumed), EstimateComputeUnitLimitBuffer).Uint64() + + if unitsConsumed > math.MaxUint32 { + txm.lggr.Debug("compute units used with buffer greater than uint32 max", "unitsConsumed", unitsConsumed) + // Do not return error to allow falling back to default compute unit limit + return 0, nil + } + + return uint32(unitsConsumed), nil +} + +// simulateTx simulates transactions using the SimulateTx client method +func (txm *Txm) simulateTx(ctx context.Context, tx *solanaGo.Transaction) (res *rpc.SimulateTransactionResult, err error) { + // get client + client, err := txm.client.Get() + if err != nil { + txm.lggr.Errorw("failed to get client", "error", err) + return + } + + res, err = client.SimulateTx(ctx, tx, nil) // use default options (does not verify signatures) + if err != nil { + // This error can occur if endpoint goes down or if invalid signature + txm.lggr.Errorw("failed to simulate tx", "error", err) + return + } + return +} + +// processSimulationError parses and handles relevant errors found in simulation results +func (txm *Txm) processSimulationError(id uuid.UUID, sig solanaGo.Signature, res *rpc.SimulateTransactionResult) { + if res.Err != nil { + // handle various errors + // https://github.com/solana-labs/solana/blob/master/sdk/src/transaction/error.rs + errStr := fmt.Sprintf("%v", res.Err) // convert to string to handle various interfaces + switch { + // blockhash not found when simulating, occurs when network bank has not seen the given blockhash or tx is too old + // let confirmation process clean up + case strings.Contains(errStr, "BlockhashNotFound"): + txm.lggr.Debugw("simulate: BlockhashNotFound", "id", id, "signature", sig, "result", res) + // transaction will encounter execution error/revert, mark as reverted to remove from confirmation + retry + case strings.Contains(errStr, "InstructionError"): + txm.txs.OnError(sig, TxFailSimRevert) // cancel retry + txm.lggr.Debugw("simulate: InstructionError", "id", id, "signature", sig, "result", res) + // transaction is already processed in the chain, letting txm confirmation handle + case strings.Contains(errStr, "AlreadyProcessed"): + txm.lggr.Debugw("simulate: AlreadyProcessed", "id", id, "signature", sig, "result", res) + // unrecognized errors (indicates more concerning failures) + default: + txm.txs.OnError(sig, TxFailSimOther) // cancel retry + txm.lggr.Errorw("simulate: unrecognized error", "id", id, "signature", sig, "result", res) + } + } +} + func (txm *Txm) InflightTxs() int { return len(txm.txs.ListAll()) } @@ -586,11 +654,12 @@ func (txm *Txm) HealthReport() map[string]error { return map[string]error{txm.Na func (txm *Txm) defaultTxConfig() TxConfig { return TxConfig{ - Timeout: txm.cfg.TxRetryTimeout(), - FeeBumpPeriod: txm.cfg.FeeBumpPeriod(), - BaseComputeUnitPrice: txm.fee.BaseComputeUnitPrice(), - ComputeUnitPriceMin: txm.cfg.ComputeUnitPriceMin(), - ComputeUnitPriceMax: txm.cfg.ComputeUnitPriceMax(), - ComputeUnitLimit: txm.cfg.ComputeUnitLimitDefault(), + Timeout: txm.cfg.TxRetryTimeout(), + FeeBumpPeriod: txm.cfg.FeeBumpPeriod(), + BaseComputeUnitPrice: txm.fee.BaseComputeUnitPrice(), + ComputeUnitPriceMin: txm.cfg.ComputeUnitPriceMin(), + ComputeUnitPriceMax: txm.cfg.ComputeUnitPriceMax(), + ComputeUnitLimit: txm.cfg.ComputeUnitLimitDefault(), + EstimateComputeUnitLimit: txm.cfg.EstimateComputeUnitLimit(), } } diff --git a/pkg/solana/txm/txm_internal_test.go b/pkg/solana/txm/txm_internal_test.go index 40c46a4..0b4fdb1 100644 --- a/pkg/solana/txm/txm_internal_test.go +++ b/pkg/solana/txm/txm_internal_test.go @@ -104,7 +104,7 @@ func TestTxm(t *testing.T) { cfg := config.NewDefault() cfg.Chain.FeeEstimatorMode = &estimator mc := mocks.NewReaderWriter(t) - mc.On("GetLatestBlock").Return(&rpc.GetBlockResult{}, nil).Maybe() + mc.On("GetLatestBlock", mock.Anything).Return(&rpc.GetBlockResult{}, nil).Maybe() // mock solana keystore mkey := keyMocks.NewSimpleKeystore(t) @@ -196,7 +196,7 @@ func TestTxm(t *testing.T) { } // send tx - assert.NoError(t, txm.Enqueue(t.Name(), tx)) + assert.NoError(t, txm.Enqueue(ctx, t.Name(), tx)) wg.Wait() // no transactions stored inflight txs list @@ -227,7 +227,7 @@ func TestTxm(t *testing.T) { }).Return(solana.Signature{}, errors.New("FAIL")).Once() // tx should be able to queue - assert.NoError(t, txm.Enqueue(t.Name(), tx)) + assert.NoError(t, txm.Enqueue(ctx, t.Name(), tx)) wg.Wait() // wait to be picked up and processed // no transactions stored inflight txs list @@ -255,7 +255,7 @@ func TestTxm(t *testing.T) { // signature status is nil (handled automatically) // tx should be able to queue - assert.NoError(t, txm.Enqueue(t.Name(), tx)) + assert.NoError(t, txm.Enqueue(ctx, t.Name(), tx)) wg.Wait() // wait to be picked up and processed waitFor(empty) // txs cleared quickly @@ -287,7 +287,7 @@ func TestTxm(t *testing.T) { // all signature statuses are nil, handled automatically // tx should be able to queue - assert.NoError(t, txm.Enqueue(t.Name(), tx)) + assert.NoError(t, txm.Enqueue(ctx, t.Name(), tx)) wg.Wait() // wait to be picked up and processed waitFor(empty) // txs cleared after timeout @@ -323,7 +323,7 @@ func TestTxm(t *testing.T) { // all signature statuses are nil, handled automatically // tx should be able to queue - assert.NoError(t, txm.Enqueue(t.Name(), tx)) + assert.NoError(t, txm.Enqueue(ctx, t.Name(), tx)) wg.Wait() // wait to be picked up and processed waitFor(empty) // txs cleared after timeout @@ -366,7 +366,7 @@ func TestTxm(t *testing.T) { } // tx should be able to queue - assert.NoError(t, txm.Enqueue(t.Name(), tx)) + assert.NoError(t, txm.Enqueue(ctx, t.Name(), tx)) wg.Wait() // wait to be picked up and processed waitFor(empty) // txs cleared after timeout @@ -403,7 +403,7 @@ func TestTxm(t *testing.T) { } // tx should be able to queue - assert.NoError(t, txm.Enqueue(t.Name(), tx)) + assert.NoError(t, txm.Enqueue(ctx, t.Name(), tx)) wg.Wait() // wait to be picked up and processed waitFor(empty) // txs cleared after timeout @@ -444,7 +444,7 @@ func TestTxm(t *testing.T) { } // tx should be able to queue - assert.NoError(t, txm.Enqueue(t.Name(), tx)) + assert.NoError(t, txm.Enqueue(ctx, t.Name(), tx)) wg.Wait() // wait to be picked up and processed waitFor(empty) // inflight txs cleared after timeout @@ -492,7 +492,7 @@ func TestTxm(t *testing.T) { } // tx should be able to queue - assert.NoError(t, txm.Enqueue(t.Name(), tx)) + assert.NoError(t, txm.Enqueue(ctx, t.Name(), tx)) wg.Wait() // wait to be picked up and processed waitFor(empty) // inflight txs cleared after timeout @@ -526,7 +526,7 @@ func TestTxm(t *testing.T) { } // tx should be able to queue - assert.NoError(t, txm.Enqueue(t.Name(), tx)) + assert.NoError(t, txm.Enqueue(ctx, t.Name(), tx)) wg.Wait() // wait to be picked up and processed waitFor(empty) // inflight txs cleared after timeout @@ -568,7 +568,7 @@ func TestTxm(t *testing.T) { } // send tx - assert.NoError(t, txm.Enqueue(t.Name(), tx)) + assert.NoError(t, txm.Enqueue(ctx, t.Name(), tx)) wg.Wait() // no transactions stored inflight txs list @@ -617,7 +617,7 @@ func TestTxm(t *testing.T) { } // send tx - with disabled fee bumping - assert.NoError(t, txm.Enqueue(t.Name(), tx, SetFeeBumpPeriod(0))) + assert.NoError(t, txm.Enqueue(ctx, t.Name(), tx, SetFeeBumpPeriod(0))) wg.Wait() // no transactions stored inflight txs list @@ -657,7 +657,7 @@ func TestTxm(t *testing.T) { } // send tx - with disabled fee bumping and disabled compute unit limit - assert.NoError(t, txm.Enqueue(t.Name(), tx, SetFeeBumpPeriod(0), SetComputeUnitLimit(0))) + assert.NoError(t, txm.Enqueue(ctx, t.Name(), tx, SetFeeBumpPeriod(0), SetComputeUnitLimit(0))) wg.Wait() // no transactions stored inflight txs list @@ -721,7 +721,7 @@ func TestTxm_Enqueue(t *testing.T) { return mc, nil }, cfg, mkey, lggr) - require.ErrorContains(t, txm.Enqueue("txmUnstarted", &solana.Transaction{}), "not started") + require.ErrorContains(t, txm.Enqueue(ctx, "txmUnstarted", &solana.Transaction{}), "not started") require.NoError(t, txm.Start(ctx)) t.Cleanup(func() { require.NoError(t, txm.Close()) }) @@ -739,10 +739,10 @@ func TestTxm_Enqueue(t *testing.T) { for _, run := range txs { t.Run(run.name, func(t *testing.T) { if !run.fail { - assert.NoError(t, txm.Enqueue(run.name, run.tx)) + assert.NoError(t, txm.Enqueue(ctx, run.name, run.tx)) return } - assert.Error(t, txm.Enqueue(run.name, run.tx)) + assert.Error(t, txm.Enqueue(ctx, run.name, run.tx)) }) } } diff --git a/pkg/solana/txm/txm_test.go b/pkg/solana/txm/txm_load_test.go similarity index 69% rename from pkg/solana/txm/txm_test.go rename to pkg/solana/txm/txm_load_test.go index 1bffb5c..f8f9ec0 100644 --- a/pkg/solana/txm/txm_test.go +++ b/pkg/solana/txm/txm_load_test.go @@ -14,6 +14,7 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/goplugin/plugin-common/pkg/services/servicetest" solanaClient "github.com/goplugin/plugin-solana/pkg/solana/client" "github.com/goplugin/plugin-solana/pkg/solana/config" "github.com/goplugin/plugin-solana/pkg/solana/txm" @@ -75,19 +76,18 @@ func TestTxm_Integration(t *testing.T) { txm := txm.NewTxm("localnet", getClient, cfg, mkey, lggr) // track initial balance - initBal, err := client.Balance(pubKey) + initBal, err := client.Balance(ctx, pubKey) assert.NoError(t, err) assert.NotEqual(t, uint64(0), initBal) // should be funded - // start - require.NoError(t, txm.Start(ctx)) + servicetest.Run(t, txm) // already started assert.Error(t, txm.Start(ctx)) createTx := func(signer solana.PublicKey, sender solana.PublicKey, receiver solana.PublicKey, amt uint64) *solana.Transaction { // create transfer tx - hash, err := client.LatestBlockhash() + hash, err := client.LatestBlockhash(ctx) assert.NoError(t, err) tx, err := solana.NewTransaction( []solana.Instruction{ @@ -105,47 +105,37 @@ func TestTxm_Integration(t *testing.T) { } // enqueue txs (must pass to move on to load test) - require.NoError(t, txm.Enqueue("test_success_0", createTx(pubKey, pubKey, pubKeyReceiver, solana.LAMPORTS_PER_SOL))) - require.Error(t, txm.Enqueue("test_invalidSigner", createTx(pubKeyReceiver, pubKey, pubKeyReceiver, solana.LAMPORTS_PER_SOL))) // cannot sign tx before enqueuing - require.NoError(t, txm.Enqueue("test_invalidReceiver", createTx(pubKey, pubKey, solana.PublicKey{}, solana.LAMPORTS_PER_SOL))) + require.NoError(t, txm.Enqueue(ctx, "test_success_0", createTx(pubKey, pubKey, pubKeyReceiver, solana.LAMPORTS_PER_SOL))) + require.Error(t, txm.Enqueue(ctx, "test_invalidSigner", createTx(pubKeyReceiver, pubKey, pubKeyReceiver, solana.LAMPORTS_PER_SOL))) // cannot sign tx before enqueuing + require.NoError(t, txm.Enqueue(ctx, "test_invalidReceiver", createTx(pubKey, pubKey, solana.PublicKey{}, solana.LAMPORTS_PER_SOL))) time.Sleep(500 * time.Millisecond) // pause 0.5s for new blockhash - require.NoError(t, txm.Enqueue("test_success_1", createTx(pubKey, pubKey, pubKeyReceiver, solana.LAMPORTS_PER_SOL))) - require.NoError(t, txm.Enqueue("test_txFail", createTx(pubKey, pubKey, pubKeyReceiver, 1000*solana.LAMPORTS_PER_SOL))) + require.NoError(t, txm.Enqueue(ctx, "test_success_1", createTx(pubKey, pubKey, pubKeyReceiver, solana.LAMPORTS_PER_SOL))) + require.NoError(t, txm.Enqueue(ctx, "test_txFail", createTx(pubKey, pubKey, pubKeyReceiver, 1000*solana.LAMPORTS_PER_SOL))) // load test: try to overload txs, confirm, or simulation for i := 0; i < 1000; i++ { - assert.NoError(t, txm.Enqueue(fmt.Sprintf("load_%d", i), createTx(loadTestKey.PublicKey(), loadTestKey.PublicKey(), loadTestKey.PublicKey(), uint64(i)))) + assert.NoError(t, txm.Enqueue(ctx, fmt.Sprintf("load_%d", i), createTx(loadTestKey.PublicKey(), loadTestKey.PublicKey(), loadTestKey.PublicKey(), uint64(i)))) time.Sleep(10 * time.Millisecond) // ~100 txs per second (note: have run 5ms delays for ~200tx/s succesfully) } // check to make sure all txs are closed out from inflight list (longest should last MaxConfirmTimeout) - ctx, cancel := context.WithCancel(ctx) - t.Cleanup(cancel) - ticker := time.NewTicker(time.Second) - defer ticker.Stop() - loop: - for { - select { - case <-ctx.Done(): - assert.Equal(t, 0, txm.InflightTxs()) - break loop - case <-ticker.C: - if txm.InflightTxs() == 0 { - cancel() // exit for loop - } - } - } - assert.NoError(t, txm.Close()) + require.Eventually(t, func() bool { + txs := txm.InflightTxs() + t.Logf("Inflight txs: %d", txs) + return txs == 0 + }, tests.WaitTimeout(t), time.Second) // check balance changes - senderBal, err := client.Balance(pubKey) - assert.NoError(t, err) - assert.Greater(t, initBal, senderBal) - assert.Greater(t, initBal-senderBal, 2*solana.LAMPORTS_PER_SOL) // balance change = sent + fees + senderBal, err := client.Balance(ctx, pubKey) + if assert.NoError(t, err) { + assert.Greater(t, initBal, senderBal) + assert.Greater(t, initBal-senderBal, 2*solana.LAMPORTS_PER_SOL) // balance change = sent + fees + } - receiverBal, err := client.Balance(pubKeyReceiver) - assert.NoError(t, err) - assert.Equal(t, 2*solana.LAMPORTS_PER_SOL, receiverBal) + receiverBal, err := client.Balance(ctx, pubKeyReceiver) + if assert.NoError(t, err) { + assert.Equal(t, 2*solana.LAMPORTS_PER_SOL, receiverBal) + } }) } } diff --git a/pkg/solana/txm/txm_race_test.go b/pkg/solana/txm/txm_race_test.go index 1882c3f..c8690fc 100644 --- a/pkg/solana/txm/txm_race_test.go +++ b/pkg/solana/txm/txm_race_test.go @@ -53,6 +53,7 @@ func TestTxm_SendWithRetry_Race(t *testing.T) { cfg.On("FeeBumpPeriod").Return(txRetryDuration / 6) cfg.On("TxRetryTimeout").Return(txRetryDuration) cfg.On("ComputeUnitLimitDefault").Return(uint32(200_000)) // default value, cannot not use 0 + cfg.On("EstimateComputeUnitLimit").Return(false) // keystore mock ks.On("Sign", mock.Anything, mock.Anything, mock.Anything).Return([]byte{}, nil) diff --git a/pkg/solana/txm/txm_unit_test.go b/pkg/solana/txm/txm_unit_test.go new file mode 100644 index 0000000..7ba11ed --- /dev/null +++ b/pkg/solana/txm/txm_unit_test.go @@ -0,0 +1,134 @@ +package txm_test + +import ( + "errors" + "math/big" + "testing" + + "github.com/gagliardetto/solana-go" + "github.com/gagliardetto/solana-go/programs/system" + "github.com/gagliardetto/solana-go/rpc" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + solanaClient "github.com/goplugin/plugin-solana/pkg/solana/client" + clientmocks "github.com/goplugin/plugin-solana/pkg/solana/client/mocks" + "github.com/goplugin/plugin-solana/pkg/solana/config" + solanatxm "github.com/goplugin/plugin-solana/pkg/solana/txm" + keyMocks "github.com/goplugin/plugin-solana/pkg/solana/txm/mocks" + + "github.com/goplugin/plugin-common/pkg/logger" + bigmath "github.com/goplugin/plugin-common/pkg/utils/big_math" + "github.com/goplugin/plugin-common/pkg/utils/tests" +) + +func TestTxm_EstimateComputeUnitLimit(t *testing.T) { + t.Parallel() + + ctx := tests.Context(t) + + // setup mock keystore + mkey := keyMocks.NewSimpleKeystore(t) + + // setup key + key, err := solana.NewRandomPrivateKey() + require.NoError(t, err) + pubKey := key.PublicKey() + + // setup receiver key + privKeyReceiver, err := solana.NewRandomPrivateKey() + require.NoError(t, err) + pubKeyReceiver := privKeyReceiver.PublicKey() + + // set up txm + lggr := logger.Test(t) + cfg := config.NewDefault() + client := clientmocks.NewReaderWriter(t) + require.NoError(t, err) + getClient := func() (solanaClient.ReaderWriter, error) { + return client, nil + } + txm := solanatxm.NewTxm("localnet", getClient, cfg, mkey, lggr) + + t.Run("successfully sets estimated compute unit limit", func(t *testing.T) { + usedCompute := uint64(100) + client.On("LatestBlockhash", mock.Anything).Return(&rpc.GetLatestBlockhashResult{ + Value: &rpc.LatestBlockhashResult{ + LastValidBlockHeight: 100, + Blockhash: solana.Hash{}, + }, + }, nil).Once() + client.On("SimulateTx", mock.Anything, mock.Anything, mock.Anything).Return(&rpc.SimulateTransactionResult{ + Err: nil, + UnitsConsumed: &usedCompute, + }, nil).Once() + tx := createTx(t, client, pubKey, pubKey, pubKeyReceiver, solana.LAMPORTS_PER_SOL) + computeUnitLimit, err := txm.EstimateComputeUnitLimit(ctx, tx) + require.NoError(t, err) + usedComputeWithBuffer := bigmath.AddPercentage(new(big.Int).SetUint64(usedCompute), solanatxm.EstimateComputeUnitLimitBuffer).Uint64() + require.Equal(t, usedComputeWithBuffer, uint64(computeUnitLimit)) + }) + + t.Run("failed to simulate tx", func(t *testing.T) { + client.On("LatestBlockhash", mock.Anything).Return(&rpc.GetLatestBlockhashResult{ + Value: &rpc.LatestBlockhashResult{ + LastValidBlockHeight: 100, + Blockhash: solana.Hash{}, + }, + }, nil).Once() + client.On("SimulateTx", mock.Anything, mock.Anything, mock.Anything).Return(nil, errors.New("failed to simulate")).Once() + tx := createTx(t, client, pubKey, pubKey, pubKeyReceiver, solana.LAMPORTS_PER_SOL) + _, err := txm.EstimateComputeUnitLimit(ctx, tx) + require.Error(t, err) + }) + + t.Run("simulation returns error for tx", func(t *testing.T) { + client.On("LatestBlockhash", mock.Anything).Return(&rpc.GetLatestBlockhashResult{ + Value: &rpc.LatestBlockhashResult{ + LastValidBlockHeight: 100, + Blockhash: solana.Hash{}, + }, + }, nil).Once() + client.On("SimulateTx", mock.Anything, mock.Anything, mock.Anything).Return(&rpc.SimulateTransactionResult{ + Err: errors.New("InstructionError"), + }, nil).Once() + tx := createTx(t, client, pubKey, pubKey, pubKeyReceiver, solana.LAMPORTS_PER_SOL) + _, err := txm.EstimateComputeUnitLimit(ctx, tx) + require.Error(t, err) + }) + + t.Run("simulation returns nil err with 0 compute unit limit", func(t *testing.T) { + client.On("LatestBlockhash", mock.Anything).Return(&rpc.GetLatestBlockhashResult{ + Value: &rpc.LatestBlockhashResult{ + LastValidBlockHeight: 100, + Blockhash: solana.Hash{}, + }, + }, nil).Once() + client.On("SimulateTx", mock.Anything, mock.Anything, mock.Anything).Return(&rpc.SimulateTransactionResult{ + Err: nil, + }, nil).Once() + tx := createTx(t, client, pubKey, pubKey, pubKeyReceiver, solana.LAMPORTS_PER_SOL) + computeUnitLimit, err := txm.EstimateComputeUnitLimit(ctx, tx) + require.NoError(t, err) + require.Equal(t, uint32(0), computeUnitLimit) + }) +} + +func createTx(t *testing.T, client solanaClient.ReaderWriter, signer solana.PublicKey, sender solana.PublicKey, receiver solana.PublicKey, amt uint64) *solana.Transaction { + // create transfer tx + hash, err := client.LatestBlockhash(tests.Context(t)) + require.NoError(t, err) + tx, err := solana.NewTransaction( + []solana.Instruction{ + system.NewTransferInstruction( + amt, + sender, + receiver, + ).Build(), + }, + hash.Value.Blockhash, + solana.TransactionPayer(signer), + ) + require.NoError(t, err) + return tx +} diff --git a/pkg/solana/txm/utils.go b/pkg/solana/txm/utils.go index 5f955c1..360a233 100644 --- a/pkg/solana/txm/utils.go +++ b/pkg/solana/txm/utils.go @@ -179,3 +179,8 @@ func SetComputeUnitLimit(v uint32) SetTxConfig { cfg.ComputeUnitLimit = v } } +func SetEstimateComputeUnitLimit(v bool) SetTxConfig { + return func(cfg *TxConfig) { + cfg.EstimateComputeUnitLimit = v + } +} diff --git a/sonar-project.properties b/sonar-project.properties index 0429577..8f668af 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,5 +1,5 @@ # required (may be found under "Project Information" in SonarQube) -sonar.projectKey=smartcontractkit_plugin-solana +sonar.projectKey=goplugin_plugin-solana sonar.sources=. # Full exclusions from the static analysis