From 41fea466cb3af9554b181d93ef9ab121d14fc734 Mon Sep 17 00:00:00 2001 From: Cedric Date: Tue, 23 Apr 2024 11:33:07 +0100 Subject: [PATCH 01/77] [chore] Update type imports for core services to types/core (#12882) --- core/capabilities/remote/dispatcher.go | 6 +- core/capabilities/syncer.go | 6 +- core/capabilities/targets/write_target.go | 5 +- core/internal/testutils/evmtest/evmtest.go | 13 ++- core/scripts/go.mod | 11 ++- core/scripts/go.sum | 42 +++++--- .../mocks/relayer_chain_interoperators.go | 8 +- .../chainlink/relayer_chain_interoperators.go | 26 ++--- .../relayer_chain_interoperators_test.go | 98 +++++++++---------- core/services/chainlink/relayer_factory.go | 25 ++--- core/services/job/job_orm_test.go | 9 +- core/services/job/models.go | 34 +++---- core/services/job/models_test.go | 21 ++-- core/services/job/orm.go | 11 +-- core/services/job/spawner_test.go | 4 +- core/services/ocr2/delegate.go | 37 +++---- .../ocr2/plugins/dkg/persistence/db.go | 3 +- .../ocr2/plugins/dkg/persistence/db_test.go | 4 +- core/services/ocr2/plugins/dkg/plugin.go | 3 +- .../generic/pipeline_runner_adapter.go | 12 +-- .../generic/pipeline_runner_adapter_test.go | 8 +- .../ocr2/plugins/generic/telemetry_adapter.go | 4 +- .../ocr2/plugins/mercury/plugin_test.go | 3 +- core/services/ocr2/validate/config.go | 4 +- core/services/ocr2/validate/validate.go | 3 +- core/services/ocrbootstrap/delegate.go | 3 +- core/services/relay/relay.go | 62 ------------ core/services/relay/relay_test.go | 47 --------- core/services/workflows/delegate.go | 6 +- core/services/workflows/engine.go | 6 +- core/store/migrate/migrate_test.go | 3 +- core/web/chains_controller.go | 7 +- core/web/cosmos_chains_controller.go | 6 +- core/web/cosmos_nodes_controller.go | 4 +- core/web/cosmos_transfer_controller.go | 6 +- core/web/evm_chains_controller.go | 6 +- core/web/evm_nodes_controller.go | 4 +- core/web/loader/chain.go | 3 +- core/web/loader/node.go | 5 +- core/web/nodes_controller.go | 9 +- core/web/presenters/job.go | 5 +- core/web/resolver/query.go | 3 +- core/web/resolver/spec_test.go | 3 +- core/web/solana_chains_controller.go | 6 +- core/web/solana_nodes_controller.go | 4 +- core/web/solana_transfer_controller.go | 6 +- core/web/starknet_chains_controller.go | 6 +- core/web/starknet_nodes_controller.go | 4 +- go.mod | 11 ++- go.sum | 42 +++++--- integration-tests/go.mod | 12 +-- integration-tests/go.sum | 37 ++++--- integration-tests/load/go.mod | 12 +-- integration-tests/load/go.sum | 37 ++++--- plugins/medianpoc/data_source.go | 8 +- plugins/medianpoc/data_source_test.go | 24 ++--- plugins/medianpoc/plugin.go | 15 +-- plugins/medianpoc/plugin_test.go | 5 +- 58 files changed, 358 insertions(+), 459 deletions(-) diff --git a/core/capabilities/remote/dispatcher.go b/core/capabilities/remote/dispatcher.go index f25d8cb784a..44b00c035f1 100644 --- a/core/capabilities/remote/dispatcher.go +++ b/core/capabilities/remote/dispatcher.go @@ -9,7 +9,7 @@ import ( "google.golang.org/protobuf/proto" "github.com/smartcontractkit/chainlink-common/pkg/services" - commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/core" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" remotetypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" @@ -23,7 +23,7 @@ type dispatcher struct { peer p2ptypes.Peer peerID p2ptypes.PeerID signer p2ptypes.Signer - registry commontypes.CapabilitiesRegistry + registry core.CapabilitiesRegistry receivers map[key]remotetypes.Receiver mu sync.RWMutex stopCh services.StopChan @@ -40,7 +40,7 @@ var _ services.Service = &dispatcher{} const supportedVersion = 1 -func NewDispatcher(peerWrapper p2ptypes.PeerWrapper, signer p2ptypes.Signer, registry commontypes.CapabilitiesRegistry, lggr logger.Logger) *dispatcher { +func NewDispatcher(peerWrapper p2ptypes.PeerWrapper, signer p2ptypes.Signer, registry core.CapabilitiesRegistry, lggr logger.Logger) *dispatcher { return &dispatcher{ peerWrapper: peerWrapper, signer: signer, diff --git a/core/capabilities/syncer.go b/core/capabilities/syncer.go index 2de917b5f9f..dc9126dba36 100644 --- a/core/capabilities/syncer.go +++ b/core/capabilities/syncer.go @@ -10,7 +10,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/capabilities/mercury" "github.com/smartcontractkit/chainlink-common/pkg/capabilities/triggers" "github.com/smartcontractkit/chainlink-common/pkg/services" - "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/core" "github.com/smartcontractkit/libocr/ragep2p" ragetypes "github.com/smartcontractkit/libocr/ragep2p/types" @@ -23,7 +23,7 @@ import ( type registrySyncer struct { peerWrapper p2ptypes.PeerWrapper - registry types.CapabilitiesRegistry + registry core.CapabilitiesRegistry dispatcher remotetypes.Dispatcher subServices []services.Service lggr logger.Logger @@ -46,7 +46,7 @@ var defaultStreamConfig = p2ptypes.StreamConfig{ } // RegistrySyncer updates local Registry to match its onchain counterpart -func NewRegistrySyncer(peerWrapper p2ptypes.PeerWrapper, registry types.CapabilitiesRegistry, dispatcher remotetypes.Dispatcher, lggr logger.Logger) *registrySyncer { +func NewRegistrySyncer(peerWrapper p2ptypes.PeerWrapper, registry core.CapabilitiesRegistry, dispatcher remotetypes.Dispatcher, lggr logger.Logger) *registrySyncer { return ®istrySyncer{ peerWrapper: peerWrapper, registry: registry, diff --git a/core/capabilities/targets/write_target.go b/core/capabilities/targets/write_target.go index 43b02939c04..47f1048211e 100644 --- a/core/capabilities/targets/write_target.go +++ b/core/capabilities/targets/write_target.go @@ -14,7 +14,7 @@ import ( chainselectors "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-common/pkg/capabilities" - commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/core" "github.com/smartcontractkit/chainlink-common/pkg/values" txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" abiutil "github.com/smartcontractkit/chainlink/v2/core/chains/evm/abi" @@ -28,8 +28,7 @@ import ( var forwardABI = evmtypes.MustGetABI(forwarder.KeystoneForwarderMetaData.ABI) -func InitializeWrite(registry commontypes.CapabilitiesRegistry, legacyEVMChains legacyevm.LegacyChainContainer, - lggr logger.Logger) error { +func InitializeWrite(registry core.CapabilitiesRegistry, legacyEVMChains legacyevm.LegacyChainContainer, lggr logger.Logger) error { for _, chain := range legacyEVMChains.Slice() { capability := NewEvmWrite(chain, lggr) if err := registry.Add(context.TODO(), capability); err != nil { diff --git a/core/internal/testutils/evmtest/evmtest.go b/core/internal/testutils/evmtest/evmtest.go index 311ee2ec33a..eedc6275928 100644 --- a/core/internal/testutils/evmtest/evmtest.go +++ b/core/internal/testutils/evmtest/evmtest.go @@ -37,7 +37,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" ) @@ -175,10 +174,10 @@ chains: } } -func (mo *TestConfigs) Chains(ids ...relay.ChainID) (cs []types.ChainStatus, count int, err error) { +func (mo *TestConfigs) Chains(chainIDs ...string) (cs []types.ChainStatus, count int, err error) { mo.mu.RLock() defer mo.mu.RUnlock() - if len(ids) == 0 { + if len(chainIDs) == 0 { for _, c := range mo.EVMConfigs { c2 := types.ChainStatus{ ID: c.ChainID.String(), @@ -196,7 +195,7 @@ func (mo *TestConfigs) Chains(ids ...relay.ChainID) (cs []types.ChainStatus, cou for i := range mo.EVMConfigs { c := mo.EVMConfigs[i] chainID := c.ChainID.String() - if !slices.Contains(ids, chainID) { + if !slices.Contains(chainIDs, chainID) { continue } c2 := types.ChainStatus{ @@ -214,19 +213,19 @@ func (mo *TestConfigs) Chains(ids ...relay.ChainID) (cs []types.ChainStatus, cou } // Nodes implements evmtypes.Configs -func (mo *TestConfigs) Nodes(id relay.ChainID) (nodes []evmtypes.Node, err error) { +func (mo *TestConfigs) Nodes(chainID string) (nodes []evmtypes.Node, err error) { mo.mu.RLock() defer mo.mu.RUnlock() for i := range mo.EVMConfigs { c := mo.EVMConfigs[i] - if id == c.ChainID.String() { + if chainID == c.ChainID.String() { for _, n := range c.Nodes { nodes = append(nodes, legacyNode(n, c.ChainID)) } } } - err = fmt.Errorf("no nodes: chain %s: %w", id, chains.ErrNotFound) + err = fmt.Errorf("no nodes: chain %s: %w", chainID, chains.ErrNotFound) return } diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 7ffb16dd563..9441180e763 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -21,7 +21,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink-automation v1.0.3 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419105123-fc5d616c7d2e + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9 github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c @@ -58,7 +58,6 @@ require ( github.com/XSAM/otelsql v0.27.0 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/avast/retry-go/v4 v4.5.1 // indirect - github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -117,8 +116,8 @@ require ( github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fxamacker/cbor/v2 v2.5.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect - github.com/gagliardetto/binary v0.7.1 // indirect - github.com/gagliardetto/solana-go v1.4.1-0.20220428092759-5250b4abbb27 // indirect + github.com/gagliardetto/binary v0.7.7 // indirect + github.com/gagliardetto/solana-go v1.8.4 // indirect github.com/gagliardetto/treeout v0.1.4 // indirect github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect @@ -260,7 +259,7 @@ require ( github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab // indirect - github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e // indirect + github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58 // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect @@ -270,6 +269,7 @@ require ( github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/status-im/keycard-go v0.2.0 // indirect + github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 // indirect github.com/subosito/gotenv v1.4.2 // indirect github.com/supranational/blst v0.3.11 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect @@ -297,6 +297,7 @@ require ( github.com/zondax/ledger-go v0.14.1 // indirect go.dedis.ch/fixbuf v1.0.3 // indirect go.etcd.io/bbolt v1.3.7 // indirect + go.mongodb.org/mongo-driver v1.15.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 24444b0f1cc..1f881b15778 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -156,11 +156,10 @@ github.com/aws/aws-sdk-go v1.22.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= 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/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 h1:WWB576BN5zNSZc/M9d/10pqEx5VHNhaQ/yOVAkmj5Yo= -github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -427,13 +426,12 @@ github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADi github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= -github.com/gagliardetto/binary v0.6.1/go.mod h1:aOfYkc20U0deHaHn/LVZXiqlkDbFAX0FpTlDhsXa0S0= -github.com/gagliardetto/binary v0.7.1 h1:6ggDQ26vR+4xEvl/S13NcdLK3MUCi4oSy73pS9aI1cI= -github.com/gagliardetto/binary v0.7.1/go.mod h1:aOfYkc20U0deHaHn/LVZXiqlkDbFAX0FpTlDhsXa0S0= +github.com/gagliardetto/binary v0.7.7 h1:QZpT38+sgoPg+TIQjH94sLbl/vX+nlIRA37pEyOsjfY= +github.com/gagliardetto/binary v0.7.7/go.mod h1:mUuay5LL8wFVnIlecHakSZMvcdqfs+CsotR5n77kyjM= github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= github.com/gagliardetto/gofuzz v1.2.2/go.mod h1:bkH/3hYLZrMLbfYWA0pWzXmi5TTRZnu4pMGZBkqMKvY= -github.com/gagliardetto/solana-go v1.4.1-0.20220428092759-5250b4abbb27 h1:q2IztKyRQUxJ6abXRsawaBtvDFvM+szj4jDqV4od1gs= -github.com/gagliardetto/solana-go v1.4.1-0.20220428092759-5250b4abbb27/go.mod h1:NFuoDwHPvw858ZMHUJr6bkhN8qHt4x6e+U3EYHxAwNY= +github.com/gagliardetto/solana-go v1.8.4 h1:vmD/JmTlonyXGy39bAo0inMhmbdAwV7rXZtLDMZeodE= +github.com/gagliardetto/solana-go v1.8.4/go.mod h1:i+7aAyNDTHG0jK8GZIBSI4OVvDqkt2Qx+LklYclRNG8= github.com/gagliardetto/treeout v0.1.4 h1:ozeYerrLCmCubo1TcIjFiOWTTGteOOHND1twdFpgwaw= github.com/gagliardetto/treeout v0.1.4/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= @@ -581,6 +579,7 @@ github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= @@ -995,6 +994,7 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN 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= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= @@ -1185,16 +1185,16 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfsE3+8OEzT3Q0Z9au0z1BPWs= github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419105123-fc5d616c7d2e h1:nHs5mFOR7FPII20GrCGIPywDW43MhEUlD7DqHnTgu6Q= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419105123-fc5d616c7d2e/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9 h1:elDIBChe7ByPNvCyrSjMLTPKrgY+sKgzzlWe2p3wokY= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 h1:MvaNzuaQh1vX4CAYLM8qFd99cf0ZF1JNwtDZtLU7WvU= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540/go.mod h1:sjAmX8K2kbQhvDarZE1ZZgDgmHJ50s0BBc/66vKY2ek= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab h1:Ct1oUlyn03HDUVdFHJqtRGRUujMqdoMzvf/Cjhe30Ag= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab/go.mod h1:RPUY7r8GxgzXxS1ijtU1P/fpJomOXztXgUbEziNmbCA= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e h1:k8HS3GsAFZnxXIW3141VsQP2+EL1XrTtOi/HDt7sdBE= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e/go.mod h1:JiykN+8W5TA4UD2ClrzQCVvcH3NcyLEVv7RwY0busrw= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58 h1:jc4ab5QrKZfkICyxJysCt7mSExuSPbePjgZsnJR3nRQ= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58/go.mod h1:oV5gIuSKrPEcjQ6uB6smBsm5kXHxyydVLNyAs4V9CoQ= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595 h1:y6ks0HsSOhPUueOmTcoxDQ50RCS1XINlRDTemZyHjFw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595/go.mod h1:vV6WfnVIbK5Q1JsIru4YcTG0T1uRpLJm6t2BgCnCSsg= github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 h1:LQmRsrzzaYYN3wEU1l5tWiccznhvbyGnu2N+wHSXZAo= @@ -1240,6 +1240,8 @@ github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= +github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 h1:ZqpS7rAhhKD7S7DnrpEdrnW1/gZcv82ytpMviovkli4= +github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75/go.mod h1:VlduQ80JcGJSargkRU4Sg9Xo63wZD/l8A5NC/Uo1/uU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= @@ -1287,6 +1289,7 @@ github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM= github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= @@ -1335,6 +1338,9 @@ github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/ github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= 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.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= +github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -1351,6 +1357,7 @@ github.com/ydb-platform/ydb-go-genproto v0.0.0-20231012155159-f85a672542fd h1:dz github.com/ydb-platform/ydb-go-genproto v0.0.0-20231012155159-f85a672542fd/go.mod h1:Er+FePu1dNUieD+XTMDduGpQuCPssK5Q4BjF+IIXJ3I= github.com/ydb-platform/ydb-go-sdk/v3 v3.54.2 h1:E0yUuuX7UmPxXm92+yQCjMveLFO3zfvYFIJVuAqsVRA= github.com/ydb-platform/ydb-go-sdk/v3 v3.54.2/go.mod h1:fjBLQ2TdQNl4bMjuWl9adoTGBypwUTPoGC+EqYqiIcU= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= @@ -1380,6 +1387,9 @@ go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYr go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +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= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= @@ -1418,6 +1428,7 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -1435,6 +1446,7 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= @@ -1460,11 +1472,12 @@ golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= @@ -1559,8 +1572,8 @@ golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 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= @@ -1659,7 +1672,6 @@ golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/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-20210514084401-e8d321eab015/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-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1760,7 +1772,6 @@ golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWc golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200601175630-2caf76543d99/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= @@ -1776,6 +1787,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= diff --git a/core/services/chainlink/mocks/relayer_chain_interoperators.go b/core/services/chainlink/mocks/relayer_chain_interoperators.go index 4c552551008..6e47f6a1f9b 100644 --- a/core/services/chainlink/mocks/relayer_chain_interoperators.go +++ b/core/services/chainlink/mocks/relayer_chain_interoperators.go @@ -11,8 +11,6 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/loop" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" - "github.com/smartcontractkit/chainlink-common/pkg/types" ) @@ -29,7 +27,7 @@ func (f *FakeRelayerChainInteroperators) LegacyEVMChains() legacyevm.LegacyChain return f.EVMChains } -func (f *FakeRelayerChainInteroperators) NodeStatuses(ctx context.Context, offset, limit int, relayIDs ...relay.ID) (nodes []types.NodeStatus, count int, err error) { +func (f *FakeRelayerChainInteroperators) NodeStatuses(ctx context.Context, offset, limit int, relayIDs ...types.RelayID) (nodes []types.NodeStatus, count int, err error) { return slices.Clone(f.Nodes), len(f.Nodes), f.NodesErr } @@ -41,7 +39,7 @@ func (f *FakeRelayerChainInteroperators) List(filter chainlink.FilterFn) chainli panic("unimplemented") } -func (f *FakeRelayerChainInteroperators) Get(id relay.ID) (loop.Relayer, error) { +func (f *FakeRelayerChainInteroperators) Get(id types.RelayID) (loop.Relayer, error) { panic("unimplemented") } @@ -53,7 +51,7 @@ func (f *FakeRelayerChainInteroperators) LegacyCosmosChains() chainlink.LegacyCo panic("unimplemented") } -func (f *FakeRelayerChainInteroperators) ChainStatus(ctx context.Context, id relay.ID) (types.ChainStatus, error) { +func (f *FakeRelayerChainInteroperators) ChainStatus(ctx context.Context, id types.RelayID) (types.ChainStatus, error) { panic("unimplemented") } diff --git a/core/services/chainlink/relayer_chain_interoperators.go b/core/services/chainlink/relayer_chain_interoperators.go index 673f71e3c65..e17d4d516e9 100644 --- a/core/services/chainlink/relayer_chain_interoperators.go +++ b/core/services/chainlink/relayer_chain_interoperators.go @@ -51,14 +51,14 @@ type LegacyChainer interface { } type ChainStatuser interface { - ChainStatus(ctx context.Context, id relay.ID) (types.ChainStatus, error) + ChainStatus(ctx context.Context, id types.RelayID) (types.ChainStatus, error) ChainStatuses(ctx context.Context, offset, limit int) ([]types.ChainStatus, int, error) } // NodesStatuser is an interface for node configuration and state. // TODO BCF-2440, BCF-2511 may need Node(ctx,name) to get a node status by name type NodesStatuser interface { - NodeStatuses(ctx context.Context, offset, limit int, relayIDs ...relay.ID) (nodes []types.NodeStatus, count int, err error) + NodeStatuses(ctx context.Context, offset, limit int, relayIDs ...types.RelayID) (nodes []types.NodeStatus, count int, err error) } // ChainsNodesStatuser report statuses about chains and nodes @@ -73,7 +73,7 @@ var _ RelayerChainInteroperators = &CoreRelayerChainInteroperators{} // as needed for the core [chainlink.Application] type CoreRelayerChainInteroperators struct { mu sync.Mutex - loopRelayers map[relay.ID]loop.Relayer + loopRelayers map[types.RelayID]loop.Relayer legacyChains legacyChains // we keep an explicit list of services because the legacy implementations have more than @@ -83,7 +83,7 @@ type CoreRelayerChainInteroperators struct { func NewCoreRelayerChainInteroperators(initFuncs ...CoreRelayerChainInitFunc) (*CoreRelayerChainInteroperators, error) { cr := &CoreRelayerChainInteroperators{ - loopRelayers: make(map[relay.ID]loop.Relayer), + loopRelayers: make(map[types.RelayID]loop.Relayer), srvs: make([]services.ServiceCtx, 0), } for _, initFn := range initFuncs { @@ -173,7 +173,7 @@ func InitStarknet(ctx context.Context, factory RelayerFactory, config StarkNetFa } // Get a [loop.Relayer] by id -func (rs *CoreRelayerChainInteroperators) Get(id relay.ID) (loop.Relayer, error) { +func (rs *CoreRelayerChainInteroperators) Get(id types.RelayID) (loop.Relayer, error) { rs.mu.Lock() defer rs.mu.Unlock() lr, exist := rs.loopRelayers[id] @@ -200,7 +200,7 @@ func (rs *CoreRelayerChainInteroperators) LegacyCosmosChains() LegacyCosmosConta } // ChainStatus gets [types.ChainStatus] -func (rs *CoreRelayerChainInteroperators) ChainStatus(ctx context.Context, id relay.ID) (types.ChainStatus, error) { +func (rs *CoreRelayerChainInteroperators) ChainStatus(ctx context.Context, id types.RelayID) (types.ChainStatus, error) { lr, err := rs.Get(id) if err != nil { @@ -219,7 +219,7 @@ func (rs *CoreRelayerChainInteroperators) ChainStatuses(ctx context.Context, off rs.mu.Lock() defer rs.mu.Unlock() - relayerIds := make([]relay.ID, 0) + relayerIds := make([]types.RelayID, 0) for rid := range rs.loopRelayers { relayerIds = append(relayerIds, rid) } @@ -263,7 +263,7 @@ func (rs *CoreRelayerChainInteroperators) Node(ctx context.Context, name string) // ids must be a string representation of relay.Identifier // ids are a filter; if none are specified, all are returned. -func (rs *CoreRelayerChainInteroperators) NodeStatuses(ctx context.Context, offset, limit int, relayerIDs ...relay.ID) (nodes []types.NodeStatus, count int, err error) { +func (rs *CoreRelayerChainInteroperators) NodeStatuses(ctx context.Context, offset, limit int, relayerIDs ...types.RelayID) (nodes []types.NodeStatus, count int, err error) { var ( totalErr error result []types.NodeStatus @@ -304,15 +304,15 @@ func (rs *CoreRelayerChainInteroperators) NodeStatuses(ctx context.Context, offs return result[offset:], count, nil } -type FilterFn func(id relay.ID) bool +type FilterFn func(id types.RelayID) bool -var AllRelayers = func(id relay.ID) bool { +var AllRelayers = func(id types.RelayID) bool { return true } // Returns true if the given network matches id.Network -func FilterRelayersByType(network relay.Network) func(id relay.ID) bool { - return func(id relay.ID) bool { +func FilterRelayersByType(network string) func(id types.RelayID) bool { + return func(id types.RelayID) bool { return id.Network == network } } @@ -322,7 +322,7 @@ func FilterRelayersByType(network relay.Network) func(id relay.ID) bool { // for a given chain func (rs *CoreRelayerChainInteroperators) List(filter FilterFn) RelayerChainInteroperators { - matches := make(map[relay.ID]loop.Relayer) + matches := make(map[types.RelayID]loop.Relayer) rs.mu.Lock() for id, relayer := range rs.loopRelayers { if filter(id) { diff --git a/core/services/chainlink/relayer_chain_interoperators_test.go b/core/services/chainlink/relayer_chain_interoperators_test.go index 38aae37c134..7126c73927c 100644 --- a/core/services/chainlink/relayer_chain_interoperators_test.go +++ b/core/services/chainlink/relayer_chain_interoperators_test.go @@ -11,6 +11,7 @@ import ( commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" coscfg "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/config" @@ -25,7 +26,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/plugins" evmcfg "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" @@ -187,23 +187,23 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { tests := []struct { name string initFuncs []chainlink.CoreRelayerChainInitFunc - expectedRelayerNetworks map[relay.Network]struct{} + expectedRelayerNetworks map[string]struct{} expectedEVMChainCnt int expectedEVMNodeCnt int - expectedEVMRelayerIds []relay.ID + expectedEVMRelayerIds []types.RelayID expectedSolanaChainCnt int expectedSolanaNodeCnt int - expectedSolanaRelayerIds []relay.ID + expectedSolanaRelayerIds []types.RelayID expectedStarknetChainCnt int expectedStarknetNodeCnt int - expectedStarknetRelayerIds []relay.ID + expectedStarknetRelayerIds []types.RelayID expectedCosmosChainCnt int expectedCosmosNodeCnt int - expectedCosmosRelayerIds []relay.ID + expectedCosmosRelayerIds []types.RelayID }{ {name: "2 evm chains with 3 nodes", @@ -220,11 +220,11 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { }, expectedEVMChainCnt: 2, expectedEVMNodeCnt: 3, - expectedEVMRelayerIds: []relay.ID{ - {Network: relay.EVM, ChainID: evmChainID1.String()}, - {Network: relay.EVM, ChainID: evmChainID2.String()}, + expectedEVMRelayerIds: []types.RelayID{ + {Network: types.NetworkEVM, ChainID: evmChainID1.String()}, + {Network: types.NetworkEVM, ChainID: evmChainID2.String()}, }, - expectedRelayerNetworks: map[relay.Network]struct{}{relay.EVM: {}}, + expectedRelayerNetworks: map[string]struct{}{types.NetworkEVM: {}}, }, {name: "2 solana chain with 2 node", @@ -236,11 +236,11 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { }, expectedSolanaChainCnt: 2, expectedSolanaNodeCnt: 2, - expectedSolanaRelayerIds: []relay.ID{ - {Network: relay.Solana, ChainID: solanaChainID1}, - {Network: relay.Solana, ChainID: solanaChainID2}, + expectedSolanaRelayerIds: []types.RelayID{ + {Network: types.NetworkSolana, ChainID: solanaChainID1}, + {Network: types.NetworkSolana, ChainID: solanaChainID2}, }, - expectedRelayerNetworks: map[relay.Network]struct{}{relay.Solana: {}}, + expectedRelayerNetworks: map[string]struct{}{types.NetworkSolana: {}}, }, {name: "2 starknet chain with 4 nodes", @@ -252,11 +252,11 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { }, expectedStarknetChainCnt: 2, expectedStarknetNodeCnt: 4, - expectedStarknetRelayerIds: []relay.ID{ - {Network: relay.StarkNet, ChainID: starknetChainID1}, - {Network: relay.StarkNet, ChainID: starknetChainID2}, + expectedStarknetRelayerIds: []types.RelayID{ + {Network: types.NetworkStarkNet, ChainID: starknetChainID1}, + {Network: types.NetworkStarkNet, ChainID: starknetChainID2}, }, - expectedRelayerNetworks: map[relay.Network]struct{}{relay.StarkNet: {}}, + expectedRelayerNetworks: map[string]struct{}{types.NetworkStarkNet: {}}, }, { @@ -270,11 +270,11 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { }, expectedCosmosChainCnt: 2, expectedCosmosNodeCnt: 2, - expectedCosmosRelayerIds: []relay.ID{ - {Network: relay.Cosmos, ChainID: cosmosChainID1}, - {Network: relay.Cosmos, ChainID: cosmosChainID2}, + expectedCosmosRelayerIds: []types.RelayID{ + {Network: types.NetworkCosmos, ChainID: cosmosChainID1}, + {Network: types.NetworkCosmos, ChainID: cosmosChainID2}, }, - expectedRelayerNetworks: map[relay.Network]struct{}{relay.Cosmos: {}}, + expectedRelayerNetworks: map[string]struct{}{types.NetworkCosmos: {}}, }, {name: "all chains", @@ -304,33 +304,33 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { }, expectedEVMChainCnt: 2, expectedEVMNodeCnt: 3, - expectedEVMRelayerIds: []relay.ID{ - {Network: relay.EVM, ChainID: evmChainID1.String()}, - {Network: relay.EVM, ChainID: evmChainID2.String()}, + expectedEVMRelayerIds: []types.RelayID{ + {Network: types.NetworkEVM, ChainID: evmChainID1.String()}, + {Network: types.NetworkEVM, ChainID: evmChainID2.String()}, }, expectedSolanaChainCnt: 2, expectedSolanaNodeCnt: 2, - expectedSolanaRelayerIds: []relay.ID{ - {Network: relay.Solana, ChainID: solanaChainID1}, - {Network: relay.Solana, ChainID: solanaChainID2}, + expectedSolanaRelayerIds: []types.RelayID{ + {Network: types.NetworkSolana, ChainID: solanaChainID1}, + {Network: types.NetworkSolana, ChainID: solanaChainID2}, }, expectedStarknetChainCnt: 2, expectedStarknetNodeCnt: 4, - expectedStarknetRelayerIds: []relay.ID{ - {Network: relay.StarkNet, ChainID: starknetChainID1}, - {Network: relay.StarkNet, ChainID: starknetChainID2}, + expectedStarknetRelayerIds: []types.RelayID{ + {Network: types.NetworkStarkNet, ChainID: starknetChainID1}, + {Network: types.NetworkStarkNet, ChainID: starknetChainID2}, }, expectedCosmosChainCnt: 2, expectedCosmosNodeCnt: 2, - expectedCosmosRelayerIds: []relay.ID{ - {Network: relay.Cosmos, ChainID: cosmosChainID1}, - {Network: relay.Cosmos, ChainID: cosmosChainID2}, + expectedCosmosRelayerIds: []types.RelayID{ + {Network: types.NetworkCosmos, ChainID: cosmosChainID1}, + {Network: types.NetworkCosmos, ChainID: cosmosChainID2}, }, - expectedRelayerNetworks: map[relay.Network]struct{}{relay.EVM: {}, relay.Cosmos: {}, relay.Solana: {}, relay.StarkNet: {}}, + expectedRelayerNetworks: map[string]struct{}{types.NetworkEVM: {}, types.NetworkCosmos: {}, types.NetworkSolana: {}, types.NetworkStarkNet: {}}, }, } for _, tt := range tests { @@ -362,17 +362,17 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { assert.Equal(t, cnt, len(allNodeStats)) } - gotRelayerNetworks := make(map[relay.Network]struct{}) - for relayNetwork := range relay.SupportedRelays { + gotRelayerNetworks := make(map[string]struct{}) + for relayNetwork := range types.SupportedRelays { var expectedChainCnt, expectedNodeCnt int switch relayNetwork { - case relay.EVM: + case types.NetworkEVM: expectedChainCnt, expectedNodeCnt = tt.expectedEVMChainCnt, tt.expectedEVMNodeCnt - case relay.Cosmos: + case types.NetworkCosmos: expectedChainCnt, expectedNodeCnt = tt.expectedCosmosChainCnt, tt.expectedCosmosNodeCnt - case relay.Solana: + case types.NetworkSolana: expectedChainCnt, expectedNodeCnt = tt.expectedSolanaChainCnt, tt.expectedSolanaNodeCnt - case relay.StarkNet: + case types.NetworkStarkNet: expectedChainCnt, expectedNodeCnt = tt.expectedStarknetChainCnt, tt.expectedStarknetNodeCnt default: require.Fail(t, "untested relay network", relayNetwork) @@ -385,16 +385,16 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { } // check legacy chains for those that haven't migrated fully to the loop relayer interface - if relayNetwork == relay.EVM { - _, wantEVM := tt.expectedRelayerNetworks[relay.EVM] + if relayNetwork == types.NetworkEVM { + _, wantEVM := tt.expectedRelayerNetworks[types.NetworkEVM] if wantEVM { assert.Len(t, cr.LegacyEVMChains().Slice(), expectedChainCnt) } else { assert.Nil(t, cr.LegacyEVMChains()) } } - if relayNetwork == relay.Cosmos { - _, wantCosmos := tt.expectedRelayerNetworks[relay.Cosmos] + if relayNetwork == types.NetworkCosmos { + _, wantCosmos := tt.expectedRelayerNetworks[types.NetworkCosmos] if wantCosmos { assert.Len(t, cr.LegacyCosmosChains().Slice(), expectedChainCnt) } else { @@ -410,7 +410,7 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { } assert.EqualValues(t, gotRelayerNetworks, tt.expectedRelayerNetworks) - allRelayerIds := [][]relay.ID{ + allRelayerIds := [][]types.RelayID{ tt.expectedEVMRelayerIds, tt.expectedCosmosRelayerIds, tt.expectedSolanaRelayerIds, @@ -426,13 +426,13 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { assert.NoError(t, err) assert.Equal(t, wantId.ChainID, stat.ID) // check legacy chains for evm and cosmos - if wantId.Network == relay.EVM { + if wantId.Network == types.NetworkEVM { c, err := cr.LegacyEVMChains().Get(wantId.ChainID) assert.NoError(t, err) assert.NotNil(t, c) assert.Equal(t, wantId.ChainID, c.ID().String()) } - if wantId.Network == relay.Cosmos { + if wantId.Network == types.NetworkCosmos { c, err := cr.LegacyCosmosChains().Get(wantId.ChainID) assert.NoError(t, err) assert.NotNil(t, c) @@ -441,7 +441,7 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { } } - expectedMissing := relay.ID{Network: relay.Cosmos, ChainID: "not a chain id"} + expectedMissing := types.RelayID{Network: types.NetworkCosmos, ChainID: "not a chain id"} unwanted, err := cr.Get(expectedMissing) assert.Nil(t, unwanted) assert.ErrorIs(t, err, chainlink.ErrNoSuchRelayer) diff --git a/core/services/chainlink/relayer_factory.go b/core/services/chainlink/relayer_factory.go index 2dd5e1eb68a..5902555f79c 100644 --- a/core/services/chainlink/relayer_factory.go +++ b/core/services/chainlink/relayer_factory.go @@ -9,6 +9,7 @@ import ( "github.com/pelletier/go-toml/v2" "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos" coscfg "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/config" "github.com/smartcontractkit/chainlink-solana/pkg/solana" @@ -40,10 +41,10 @@ type EVMFactoryConfig struct { evmrelay.CSAETHKeystore } -func (r *RelayerFactory) NewEVM(ctx context.Context, config EVMFactoryConfig) (map[relay.ID]evmrelay.LoopRelayAdapter, error) { +func (r *RelayerFactory) NewEVM(ctx context.Context, config EVMFactoryConfig) (map[types.RelayID]evmrelay.LoopRelayAdapter, error) { // TODO impl EVM loop. For now always 'fallback' to an adapter and embedded chain - relayers := make(map[relay.ID]evmrelay.LoopRelayAdapter) + relayers := make(map[types.RelayID]evmrelay.LoopRelayAdapter) lggr := r.Logger.Named("EVM") @@ -60,7 +61,7 @@ func (r *RelayerFactory) NewEVM(ctx context.Context, config EVMFactoryConfig) (m } legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(evmRelayExtenders) for _, ext := range evmRelayExtenders.Slice() { - relayID := relay.ID{Network: relay.EVM, ChainID: ext.Chain().ID().String()} + relayID := types.RelayID{Network: types.NetworkEVM, ChainID: ext.Chain().ID().String()} chain, err2 := legacyChains.Get(relayID.ChainID) if err2 != nil { return nil, err2 @@ -91,8 +92,8 @@ type SolanaFactoryConfig struct { solana.TOMLConfigs } -func (r *RelayerFactory) NewSolana(ks keystore.Solana, chainCfgs solana.TOMLConfigs) (map[relay.ID]loop.Relayer, error) { - solanaRelayers := make(map[relay.ID]loop.Relayer) +func (r *RelayerFactory) NewSolana(ks keystore.Solana, chainCfgs solana.TOMLConfigs) (map[types.RelayID]loop.Relayer, error) { + solanaRelayers := make(map[types.RelayID]loop.Relayer) var ( solLggr = r.Logger.Named("Solana") signer = &keystore.SolanaSigner{Solana: ks} @@ -102,7 +103,7 @@ func (r *RelayerFactory) NewSolana(ks keystore.Solana, chainCfgs solana.TOMLConf // create one relayer per chain id for _, chainCfg := range chainCfgs { - relayID := relay.ID{Network: relay.Solana, ChainID: *chainCfg.ChainID} + relayID := types.RelayID{Network: types.NetworkSolana, ChainID: *chainCfg.ChainID} _, alreadyExists := unique[relayID.Name()] if alreadyExists { return nil, fmt.Errorf("duplicate chain definitions for %s", relayID.Name()) @@ -166,8 +167,8 @@ type StarkNetFactoryConfig struct { // TODO BCF-2606 consider consolidating the driving logic with that of NewSolana above via generics // perhaps when we implement a Cosmos LOOP -func (r *RelayerFactory) NewStarkNet(ks keystore.StarkNet, chainCfgs config.TOMLConfigs) (map[relay.ID]loop.Relayer, error) { - starknetRelayers := make(map[relay.ID]loop.Relayer) +func (r *RelayerFactory) NewStarkNet(ks keystore.StarkNet, chainCfgs config.TOMLConfigs) (map[types.RelayID]loop.Relayer, error) { + starknetRelayers := make(map[types.RelayID]loop.Relayer) var ( starkLggr = r.Logger.Named("StarkNet") @@ -177,7 +178,7 @@ func (r *RelayerFactory) NewStarkNet(ks keystore.StarkNet, chainCfgs config.TOML unique := make(map[string]struct{}) // create one relayer per chain id for _, chainCfg := range chainCfgs { - relayID := relay.ID{Network: relay.StarkNet, ChainID: *chainCfg.ChainID} + relayID := types.RelayID{Network: types.NetworkStarkNet, ChainID: *chainCfg.ChainID} _, alreadyExists := unique[relayID.Name()] if alreadyExists { return nil, fmt.Errorf("duplicate chain definitions for %s", relayID.Name()) @@ -263,12 +264,12 @@ func (c CosmosFactoryConfig) Validate() error { return err } -func (r *RelayerFactory) NewCosmos(config CosmosFactoryConfig) (map[relay.ID]CosmosLoopRelayerChainer, error) { +func (r *RelayerFactory) NewCosmos(config CosmosFactoryConfig) (map[types.RelayID]CosmosLoopRelayerChainer, error) { err := config.Validate() if err != nil { return nil, fmt.Errorf("cannot create Cosmos relayer: %w", err) } - relayers := make(map[relay.ID]CosmosLoopRelayerChainer) + relayers := make(map[types.RelayID]CosmosLoopRelayerChainer) var ( cosmosLggr = r.Logger.Named("Cosmos") @@ -277,7 +278,7 @@ func (r *RelayerFactory) NewCosmos(config CosmosFactoryConfig) (map[relay.ID]Cos // create one relayer per chain id for _, chainCfg := range config.TOMLConfigs { - relayID := relay.ID{Network: relay.Cosmos, ChainID: *chainCfg.ChainID} + relayID := types.RelayID{Network: types.NetworkCosmos, ChainID: *chainCfg.ChainID} lggr := cosmosLggr.Named(relayID.ChainID) diff --git a/core/services/job/job_orm_test.go b/core/services/job/job_orm_test.go index 91018ef6f55..ffbd02c512b 100644 --- a/core/services/job/job_orm_test.go +++ b/core/services/job/job_orm_test.go @@ -40,7 +40,6 @@ import ( ocr2validate "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrfcommon" "github.com/smartcontractkit/chainlink/v2/core/services/webhook" @@ -927,7 +926,7 @@ func TestORM_ValidateKeyStoreMatch(t *testing.T) { t.Run("test ETH key validation", func(t *testing.T) { ctx := testutils.Context(t) - jb.OCR2OracleSpec.Relay = relay.EVM + jb.OCR2OracleSpec.Relay = types.NetworkEVM err := job.ValidateKeyStoreMatch(ctx, jb.OCR2OracleSpec, keyStore, "bad key") require.EqualError(t, err, "no EVM key matching: \"bad key\"") @@ -938,7 +937,7 @@ func TestORM_ValidateKeyStoreMatch(t *testing.T) { t.Run("test Cosmos key validation", func(t *testing.T) { ctx := testutils.Context(t) - jb.OCR2OracleSpec.Relay = relay.Cosmos + jb.OCR2OracleSpec.Relay = types.NetworkCosmos err := job.ValidateKeyStoreMatch(ctx, jb.OCR2OracleSpec, keyStore, "bad key") require.EqualError(t, err, "no Cosmos key matching: \"bad key\"") @@ -950,7 +949,7 @@ func TestORM_ValidateKeyStoreMatch(t *testing.T) { t.Run("test Solana key validation", func(t *testing.T) { ctx := testutils.Context(t) - jb.OCR2OracleSpec.Relay = relay.Solana + jb.OCR2OracleSpec.Relay = types.NetworkSolana err := job.ValidateKeyStoreMatch(ctx, jb.OCR2OracleSpec, keyStore, "bad key") require.EqualError(t, err, "no Solana key matching: \"bad key\"") @@ -963,7 +962,7 @@ func TestORM_ValidateKeyStoreMatch(t *testing.T) { t.Run("test Starknet key validation", func(t *testing.T) { ctx := testutils.Context(t) - jb.OCR2OracleSpec.Relay = relay.StarkNet + jb.OCR2OracleSpec.Relay = types.NetworkStarkNet err := job.ValidateKeyStoreMatch(ctx, jb.OCR2OracleSpec, keyStore, "bad key") require.EqualError(t, err, "no Starknet key matching: \"bad key\"") diff --git a/core/services/job/models.go b/core/services/job/models.go index 8621d6cd5dd..0c6390b3dbf 100644 --- a/core/services/job/models.go +++ b/core/services/job/models.go @@ -25,7 +25,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" clnull "github.com/smartcontractkit/chainlink/v2/core/null" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/services/signatures/secp256k1" "github.com/smartcontractkit/chainlink/v2/core/store/models" "github.com/smartcontractkit/chainlink/v2/core/utils/stringutils" @@ -348,10 +347,11 @@ var ForwardersSupportedPlugins = []types.OCR2PluginType{types.Median, types.DKG, // OCR2OracleSpec defines the job spec for OCR2 jobs. // Relay config is chain specific config for a relay (chain adapter). type OCR2OracleSpec struct { - ID int32 `toml:"-"` - ContractID string `toml:"contractID"` - FeedID *common.Hash `toml:"feedID"` - Relay relay.Network `toml:"relay"` + ID int32 `toml:"-"` + ContractID string `toml:"contractID"` + FeedID *common.Hash `toml:"feedID"` + // Network + Relay string `toml:"relay"` // TODO BCF-2442 implement ChainID as top level parameter rathe than buried in RelayConfig. ChainID string `toml:"chainID"` RelayConfig JSONConfig `toml:"relayConfig"` @@ -370,9 +370,9 @@ type OCR2OracleSpec struct { CaptureAutomationCustomTelemetry bool `toml:"captureAutomationCustomTelemetry"` } -func validateRelayID(id relay.ID) error { +func validateRelayID(id types.RelayID) error { // only the EVM has specific requirements - if id.Network == relay.EVM { + if id.Network == types.NetworkEVM { _, err := toml.ChainIDInt64(id.ChainID) if err != nil { return fmt.Errorf("invalid EVM chain id %s: %w", id.ChainID, err) @@ -381,20 +381,20 @@ func validateRelayID(id relay.ID) error { return nil } -func (s *OCR2OracleSpec) RelayID() (relay.ID, error) { +func (s *OCR2OracleSpec) RelayID() (types.RelayID, error) { cid, err := s.getChainID() if err != nil { - return relay.ID{}, err + return types.RelayID{}, err } - rid := relay.NewID(s.Relay, cid) + rid := types.NewRelayID(s.Relay, cid) err = validateRelayID(rid) if err != nil { - return relay.ID{}, err + return types.RelayID{}, err } return rid, nil } -func (s *OCR2OracleSpec) getChainID() (relay.ChainID, error) { +func (s *OCR2OracleSpec) getChainID() (string, error) { if s.ChainID != "" { return s.ChainID, nil } @@ -402,7 +402,7 @@ func (s *OCR2OracleSpec) getChainID() (relay.ChainID, error) { return s.getChainIdFromRelayConfig() } -func (s *OCR2OracleSpec) getChainIdFromRelayConfig() (relay.ChainID, error) { +func (s *OCR2OracleSpec) getChainIdFromRelayConfig() (string, error) { v, exists := s.RelayConfig["chainID"] if !exists { @@ -754,10 +754,10 @@ type LegacyGasStationSidecarSpec struct { // BootstrapSpec defines the spec to handles the node communication setup process. type BootstrapSpec struct { - ID int32 `toml:"-"` - ContractID string `toml:"contractID"` - FeedID *common.Hash `toml:"feedID"` - Relay relay.Network `toml:"relay"` + ID int32 `toml:"-"` + ContractID string `toml:"contractID"` + FeedID *common.Hash `toml:"feedID"` + Relay string `toml:"relay"` // RelayID.Network RelayConfig JSONConfig MonitoringEndpoint null.String `toml:"monitoringEndpoint"` BlockchainTimeout models.Interval `toml:"blockchainTimeout"` diff --git a/core/services/job/models_test.go b/core/services/job/models_test.go index fa15e3b1b22..4d10fbb43c4 100644 --- a/core/services/job/models_test.go +++ b/core/services/job/models_test.go @@ -12,51 +12,50 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/codec" "github.com/smartcontractkit/chainlink-common/pkg/types" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" evmtypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" "github.com/smartcontractkit/chainlink/v2/core/store/models" ) func TestOCR2OracleSpec_RelayIdentifier(t *testing.T) { type fields struct { - Relay relay.Network + Relay string ChainID string RelayConfig JSONConfig } tests := []struct { name string fields fields - want relay.ID + want types.RelayID wantErr bool }{ {name: "err no chain id", fields: fields{}, - want: relay.ID{}, + want: types.RelayID{}, wantErr: true, }, { name: "evm explicitly configured", fields: fields{ - Relay: relay.EVM, + Relay: types.NetworkEVM, ChainID: "1", }, - want: relay.ID{Network: relay.EVM, ChainID: "1"}, + want: types.RelayID{Network: types.NetworkEVM, ChainID: "1"}, }, { name: "evm implicitly configured", fields: fields{ - Relay: relay.EVM, + Relay: types.NetworkEVM, RelayConfig: map[string]any{"chainID": 1}, }, - want: relay.ID{Network: relay.EVM, ChainID: "1"}, + want: types.RelayID{Network: types.NetworkEVM, ChainID: "1"}, }, { name: "evm implicitly configured with bad value", fields: fields{ - Relay: relay.EVM, + Relay: types.NetworkEVM, RelayConfig: map[string]any{"chainID": float32(1)}, }, - want: relay.ID{}, + want: types.RelayID{}, wantErr: true, }, } @@ -91,7 +90,7 @@ var ( func TestOCR2OracleSpec(t *testing.T) { val := OCR2OracleSpec{ - Relay: relay.EVM, + Relay: types.NetworkEVM, PluginType: types.Median, ContractID: "foo", OCRKeyBundleID: null.StringFrom("bar"), diff --git a/core/services/job/orm.go b/core/services/job/orm.go index 9d2a6545163..f7238799634 100644 --- a/core/services/job/orm.go +++ b/core/services/job/orm.go @@ -31,7 +31,6 @@ import ( medianconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/median/config" "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/store/models" ) @@ -488,24 +487,24 @@ func ValidateKeyStoreMatch(ctx context.Context, spec *OCR2OracleSpec, keyStore k return } -func validateKeyStoreMatchForRelay(ctx context.Context, network relay.Network, keyStore keystore.Master, key string) error { +func validateKeyStoreMatchForRelay(ctx context.Context, network string, keyStore keystore.Master, key string) error { switch network { - case relay.EVM: + case types.NetworkEVM: _, err := keyStore.Eth().Get(ctx, key) if err != nil { return errors.Errorf("no EVM key matching: %q", key) } - case relay.Cosmos: + case types.NetworkCosmos: _, err := keyStore.Cosmos().Get(key) if err != nil { return errors.Errorf("no Cosmos key matching: %q", key) } - case relay.Solana: + case types.NetworkSolana: _, err := keyStore.Solana().Get(key) if err != nil { return errors.Errorf("no Solana key matching: %q", key) } - case relay.StarkNet: + case types.NetworkStarkNet: _, err := keyStore.StarkNet().Get(key) if err != nil { return errors.Errorf("no Starknet key matching: %q", key) diff --git a/core/services/job/spawner_test.go b/core/services/job/spawner_test.go index 5f4f933b9c3..ae8ffaa2161 100644 --- a/core/services/job/spawner_test.go +++ b/core/services/job/spawner_test.go @@ -15,6 +15,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/loop" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" + "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox/mailboxtest" "github.com/smartcontractkit/chainlink/v2/core/capabilities" @@ -34,7 +35,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" evmrelayer "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/plugins" @@ -69,7 +69,7 @@ type relayGetter struct { r *evmrelayer.Relayer } -func (g *relayGetter) Get(id relay.ID) (loop.Relayer, error) { +func (g *relayGetter) Get(id types.RelayID) (loop.Relayer, error) { return evmrelayer.NewLoopRelayServerAdapter(g.r, g.e), nil } diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index 22c655b6230..7a2ef532fd2 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -38,6 +38,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/loop" "github.com/smartcontractkit/chainlink-common/pkg/loop/reportingplugins" "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/core" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" @@ -107,7 +108,7 @@ func (e ErrRelayNotEnabled) Error() string { } type RelayGetter interface { - Get(id relay.ID) (loop.Relayer, error) + Get(id types.RelayID) (loop.Relayer, error) } type Delegate struct { db *sqlx.DB // legacy: prefer to use ds instead @@ -130,7 +131,7 @@ type Delegate struct { mailMon *mailbox.Monitor legacyChains legacyevm.LegacyChainContainer // legacy: use relayers instead - capabilitiesRegistry types.CapabilitiesRegistry + capabilitiesRegistry core.CapabilitiesRegistry } type DelegateConfig interface { @@ -244,7 +245,7 @@ func NewDelegate( ethKs keystore.Eth, relayers RelayGetter, mailMon *mailbox.Monitor, - capabilitiesRegistry types.CapabilitiesRegistry, + capabilitiesRegistry core.CapabilitiesRegistry, ) *Delegate { return &Delegate{ db: db, @@ -296,14 +297,14 @@ func (d *Delegate) OnDeleteJob(ctx context.Context, jb job.Job) error { return nil } // we only have clean to do for the EVM - if rid.Network == relay.EVM { + if rid.Network == types.NetworkEVM { return d.cleanupEVM(ctx, jb, rid) } return nil } // cleanupEVM is a helper for clean up EVM specific state when a job is deleted -func (d *Delegate) cleanupEVM(ctx context.Context, jb job.Job, relayID relay.ID) error { +func (d *Delegate) cleanupEVM(ctx context.Context, jb job.Job, relayID types.RelayID) error { // If UnregisterFilter returns an // error, that means it failed to remove a valid active filter from the db. We do abort the job deletion // in that case, since it should be easy for the user to retry and will avoid leaving the db in @@ -388,7 +389,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) ([]job.Servi return nil, ErrJobSpecNoRelayer{Err: err, PluginName: string(spec.PluginType)} } - if rid.Network == relay.EVM { + if rid.Network == types.NetworkEVM { lggr = logger.Sugared(lggr.With("evmChainID", rid.ChainID)) chain, err2 := d.legacyChains.Get(rid.ChainID) @@ -539,8 +540,8 @@ func (d *Delegate) newServicesGenericPlugin( ocrDB *db, lc ocrtypes.LocalConfig, ocrLogger commontypes.Logger, - capabilitiesRegistry types.CapabilitiesRegistry, - keyValueStore types.KeyValueStore, + capabilitiesRegistry core.CapabilitiesRegistry, + keyValueStore core.KeyValueStore, ) (srvs []job.ServiceCtx, err error) { spec := jb.OCR2OracleSpec // NOTE: we don't need to validate this config, since that happens as part of creating the job. @@ -638,7 +639,7 @@ func (d *Delegate) newServicesGenericPlugin( return nil, fmt.Errorf("cannot dump plugin config to string before sending to plugin: %s", err) } - pluginConfig := types.ReportingPluginServiceConfig{ + pluginConfig := core.ReportingPluginServiceConfig{ PluginName: pCfg.PluginName, Command: command, ProviderType: pCfg.ProviderType, @@ -742,7 +743,7 @@ func (d *Delegate) newServicesMercury( if err != nil { return nil, ErrJobSpecNoRelayer{Err: err, PluginName: "mercury"} } - if rid.Network != relay.EVM { + if rid.Network != types.NetworkEVM { return nil, fmt.Errorf("mercury services: expected EVM relayer got %s", rid.Network) } relayer, err := d.RelayGetter.Get(rid) @@ -826,7 +827,7 @@ func (d *Delegate) newServicesLLO( if err != nil { return nil, ErrJobSpecNoRelayer{Err: err, PluginName: "streams"} } - if rid.Network != relay.EVM { + if rid.Network != types.NetworkEVM { return nil, fmt.Errorf("streams services: expected EVM relayer got %s", rid.Network) } relayer, err := d.RelayGetter.Get(rid) @@ -1001,7 +1002,7 @@ func (d *Delegate) newServicesDKG( if err != nil { return nil, ErrJobSpecNoRelayer{Err: err, PluginName: "DKG"} } - if rid.Network != relay.EVM { + if rid.Network != types.NetworkEVM { return nil, fmt.Errorf("DKG services: expected EVM relayer got %s", rid.Network) } @@ -1071,7 +1072,7 @@ func (d *Delegate) newServicesOCR2VRF( if err != nil { return nil, ErrJobSpecNoRelayer{Err: err, PluginName: "VRF"} } - if rid.Network != relay.EVM { + if rid.Network != types.NetworkEVM { return nil, fmt.Errorf("VRF services: expected EVM relayer got %s", rid.Network) } chain, err2 := d.legacyChains.Get(rid.ChainID) @@ -1185,10 +1186,10 @@ func (d *Delegate) newServicesOCR2VRF( lggr.ErrorIf(d.jobORM.RecordError(jb.ID, msg), "unable to record error") }) dkgReportingPluginFactoryDecorator := func(wrapped ocrtypes.ReportingPluginFactory) ocrtypes.ReportingPluginFactory { - return promwrapper.NewPromFactory(wrapped, "DKG", string(relay.EVM), chain.ID()) + return promwrapper.NewPromFactory(wrapped, "DKG", string(types.NetworkEVM), chain.ID()) } vrfReportingPluginFactoryDecorator := func(wrapped ocrtypes.ReportingPluginFactory) ocrtypes.ReportingPluginFactory { - return promwrapper.NewPromFactory(wrapped, "OCR2VRF", string(relay.EVM), chain.ID()) + return promwrapper.NewPromFactory(wrapped, "OCR2VRF", string(types.NetworkEVM), chain.ID()) } noopMonitoringEndpoint := telemetry.NoopAgent{} oracles, err2 := ocr2vrf.NewOCR2VRF(ocr2vrf.DKGVRFArgs{ @@ -1289,7 +1290,7 @@ func (d *Delegate) newServicesOCR2Keepers21( if err != nil { return nil, ErrJobSpecNoRelayer{Err: err, PluginName: "keeper2"} } - if rid.Network != relay.EVM { + if rid.Network != types.NetworkEVM { return nil, fmt.Errorf("keeper2 services: expected EVM relayer got %s", rid.Network) } @@ -1440,7 +1441,7 @@ func (d *Delegate) newServicesOCR2Keepers20( if err != nil { return nil, ErrJobSpecNoRelayer{Err: err, PluginName: "keepers2.0"} } - if rid.Network != relay.EVM { + if rid.Network != types.NetworkEVM { return nil, fmt.Errorf("keepers2.0 services: expected EVM relayer got %s", rid.Network) } chain, err2 := d.legacyChains.Get(rid.ChainID) @@ -1564,7 +1565,7 @@ func (d *Delegate) newServicesOCR2Functions( if err != nil { return nil, ErrJobSpecNoRelayer{Err: err, PluginName: "functions"} } - if rid.Network != relay.EVM { + if rid.Network != types.NetworkEVM { return nil, fmt.Errorf("functions services: expected EVM relayer got %s", rid.Network) } chain, err := d.legacyChains.Get(rid.ChainID) diff --git a/core/services/ocr2/plugins/dkg/persistence/db.go b/core/services/ocr2/plugins/dkg/persistence/db.go index 72997e28699..b8ecfbaceb4 100644 --- a/core/services/ocr2/plugins/dkg/persistence/db.go +++ b/core/services/ocr2/plugins/dkg/persistence/db.go @@ -21,7 +21,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/pg" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" ) var ( @@ -60,7 +59,7 @@ type shareDB struct { } // NewShareDB creates a new DKG share database. -func NewShareDB(db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig, chainID *big.Int, chainType relay.Network) ocr2vrftypes.DKGSharePersistence { +func NewShareDB(db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig, chainID *big.Int, chainType string) ocr2vrftypes.DKGSharePersistence { return &shareDB{ q: pg.NewQ(db, lggr, cfg), lggr: lggr, diff --git a/core/services/ocr2/plugins/dkg/persistence/db_test.go b/core/services/ocr2/plugins/dkg/persistence/db_test.go index 53a5ae26758..a3949ea70dc 100644 --- a/core/services/ocr2/plugins/dkg/persistence/db_test.go +++ b/core/services/ocr2/plugins/dkg/persistence/db_test.go @@ -10,19 +10,19 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/types" ocr2vrftypes "github.com/smartcontractkit/chainlink-vrf/types" "github.com/smartcontractkit/chainlink-vrf/types/hash" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" ) func setup(t testing.TB) (ocr2vrftypes.DKGSharePersistence, *sqlx.DB) { db := pgtest.NewSqlxDB(t) lggr := logger.TestLogger(t) - return NewShareDB(db, lggr, pgtest.NewQConfig(true), big.NewInt(1337), relay.EVM), db + return NewShareDB(db, lggr, pgtest.NewQConfig(true), big.NewInt(1337), types.NetworkEVM), db } func TestShareDB_WriteShareRecords(t *testing.T) { diff --git a/core/services/ocr2/plugins/dkg/plugin.go b/core/services/ocr2/plugins/dkg/plugin.go index 0310122655f..65216ac1115 100644 --- a/core/services/ocr2/plugins/dkg/plugin.go +++ b/core/services/ocr2/plugins/dkg/plugin.go @@ -22,7 +22,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/dkg/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/dkg/persistence" "github.com/smartcontractkit/chainlink/v2/core/services/pg" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" ) @@ -38,7 +37,7 @@ func NewDKGServices( db *sqlx.DB, qConfig pg.QConfig, chainID *big.Int, - network relay.Network, + network string, ) ([]job.ServiceCtx, error) { var pluginConfig config.PluginConfig err := json.Unmarshal(jb.OCR2OracleSpec.PluginConfig.Bytes(), &pluginConfig) diff --git a/core/services/ocr2/plugins/generic/pipeline_runner_adapter.go b/core/services/ocr2/plugins/generic/pipeline_runner_adapter.go index e6a429a5f73..22217b83660 100644 --- a/core/services/ocr2/plugins/generic/pipeline_runner_adapter.go +++ b/core/services/ocr2/plugins/generic/pipeline_runner_adapter.go @@ -4,7 +4,7 @@ import ( "context" "time" - "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/core" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" @@ -12,7 +12,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/store/models" ) -var _ types.PipelineRunnerService = (*PipelineRunnerAdapter)(nil) +var _ core.PipelineRunnerService = (*PipelineRunnerAdapter)(nil) type pipelineRunner interface { ExecuteAndInsertFinishedRun(ctx context.Context, spec pipeline.Spec, vars pipeline.Vars, l logger.Logger, saveSuccessfulTaskRuns bool) (runID int64, results pipeline.TaskRunResults, err error) @@ -24,7 +24,7 @@ type PipelineRunnerAdapter struct { logger logger.Logger } -func (p *PipelineRunnerAdapter) ExecuteRun(ctx context.Context, spec string, vars types.Vars, options types.Options) (types.TaskResults, error) { +func (p *PipelineRunnerAdapter) ExecuteRun(ctx context.Context, spec string, vars core.Vars, options core.Options) (core.TaskResults, error) { s := pipeline.Spec{ DotDagSource: spec, CreatedAt: time.Now(), @@ -50,13 +50,13 @@ func (p *PipelineRunnerAdapter) ExecuteRun(ctx context.Context, spec string, var return nil, err } - taskResults := make([]types.TaskResult, len(trrs)) + taskResults := make([]core.TaskResult, len(trrs)) for i, trr := range trrs { - taskResults[i] = types.TaskResult{ + taskResults[i] = core.TaskResult{ ID: trr.ID.String(), Type: string(trr.Task.Type()), Index: int(trr.Task.OutputIndex()), - TaskValue: types.TaskValue{ + TaskValue: core.TaskValue{ Value: trr.Result.OutputDB(), Error: trr.Result.Error, IsTerminal: len(trr.Task.Outputs()) == 0, diff --git a/core/services/ocr2/plugins/generic/pipeline_runner_adapter_test.go b/core/services/ocr2/plugins/generic/pipeline_runner_adapter_test.go index ae74cb218ee..0d6bc02e198 100644 --- a/core/services/ocr2/plugins/generic/pipeline_runner_adapter_test.go +++ b/core/services/ocr2/plugins/generic/pipeline_runner_adapter_test.go @@ -12,7 +12,7 @@ import ( "github.com/stretchr/testify/require" "gopkg.in/guregu/null.v4" - "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/core" "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" @@ -78,7 +78,7 @@ func TestAdapter_Integration(t *testing.T) { err = jobORM.CreateJob(&jb) require.NoError(t, err) pra := generic.NewPipelineRunnerAdapter(logger, jb, pr) - results, err := pra.ExecuteRun(testutils.Context(t), spec, types.Vars{Vars: map[string]interface{}{"val": 1}}, types.Options{}) + results, err := pra.ExecuteRun(testutils.Context(t), spec, core.Vars{Vars: map[string]interface{}{"val": 1}}, core.Options{}) require.NoError(t, err) finalResult := results[0].Value.Val.(decimal.Decimal) @@ -110,7 +110,7 @@ func TestAdapter_AddsDefaultVars(t *testing.T) { jobID, externalJobID, name := int32(100), uuid.New(), null.StringFrom("job-name") pra := generic.NewPipelineRunnerAdapter(logger, job.Job{ID: jobID, ExternalJobID: externalJobID, Name: name}, mpr) - _, err := pra.ExecuteRun(testutils.Context(t), spec, types.Vars{}, types.Options{}) + _, err := pra.ExecuteRun(testutils.Context(t), spec, core.Vars{}, core.Options{}) require.NoError(t, err) gotName, err := mpr.vars.Get("jb.name") @@ -133,7 +133,7 @@ func TestPipelineRunnerAdapter_SetsVarsOnSpec(t *testing.T) { pra := generic.NewPipelineRunnerAdapter(logger, job.Job{ID: jobID, ExternalJobID: externalJobID, Name: name, Type: jobType}, mpr) maxDuration := 100 * time.Second - _, err := pra.ExecuteRun(testutils.Context(t), spec, types.Vars{}, types.Options{MaxTaskDuration: maxDuration}) + _, err := pra.ExecuteRun(testutils.Context(t), spec, core.Vars{}, core.Options{MaxTaskDuration: maxDuration}) require.NoError(t, err) assert.Equal(t, jobID, mpr.spec.JobID) diff --git a/core/services/ocr2/plugins/generic/telemetry_adapter.go b/core/services/ocr2/plugins/generic/telemetry_adapter.go index a2ec6ba20cf..ea2206202ee 100644 --- a/core/services/ocr2/plugins/generic/telemetry_adapter.go +++ b/core/services/ocr2/plugins/generic/telemetry_adapter.go @@ -9,10 +9,10 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/synchronization" "github.com/smartcontractkit/chainlink/v2/core/services/telemetry" - "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/core" ) -var _ types.TelemetryService = (*TelemetryAdapter)(nil) +var _ core.TelemetryService = (*TelemetryAdapter)(nil) type TelemetryAdapter struct { endpointGenerator telemetry.MonitoringEndpointGenerator diff --git a/core/services/ocr2/plugins/mercury/plugin_test.go b/core/services/ocr2/plugins/mercury/plugin_test.go index 131f51af4b4..1d3260fdb1f 100644 --- a/core/services/ocr2/plugins/mercury/plugin_test.go +++ b/core/services/ocr2/plugins/mercury/plugin_test.go @@ -27,7 +27,6 @@ import ( libocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/types" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" "github.com/smartcontractkit/chainlink/v2/plugins" @@ -74,7 +73,7 @@ var ( ID: 7, ContractID: "phony", FeedID: ptr(common.BytesToHash([]byte{1, 2, 3})), - Relay: relay.EVM, + Relay: commontypes.NetworkEVM, ChainID: "1", }, PipelineSpec: &pipeline.Spec{}, diff --git a/core/services/ocr2/validate/config.go b/core/services/ocr2/validate/config.go index 980933e7d97..d22bd781d19 100644 --- a/core/services/ocr2/validate/config.go +++ b/core/services/ocr2/validate/config.go @@ -7,9 +7,9 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/config/env" "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" ) // OCR2Config contains OCR2 configurations for a job. @@ -51,7 +51,7 @@ func ToLocalConfig(ocr2Config OCR2Config, insConf InsecureConfig, spec job.OCR2O ContractTransmitterTransmitTimeout: ocr2Config.ContractTransmitterTransmitTimeout(), DatabaseTimeout: ocr2Config.DatabaseTimeout(), } - if spec.Relay == relay.Solana && env.MedianPlugin.Cmd.Get() != "" { + if spec.Relay == commontypes.NetworkSolana && env.MedianPlugin.Cmd.Get() != "" { // Work around for Solana Feeds configured with zero values to support LOOP Plugins. minOCR2MaxDurationQuery, err := getMinOCR2MaxDurationQuery() if err != nil { diff --git a/core/services/ocr2/validate/validate.go b/core/services/ocr2/validate/validate.go index 19c8043f25b..59f7053de56 100644 --- a/core/services/ocr2/validate/validate.go +++ b/core/services/ocr2/validate/validate.go @@ -23,7 +23,6 @@ import ( mercuryconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/mercury/config" ocr2vrfconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2vrf/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/plugins" ) @@ -54,7 +53,7 @@ func ValidatedOracleSpecToml(ctx context.Context, config OCR2Config, insConf Ins if jb.Type != job.OffchainReporting2 { return jb, pkgerrors.Errorf("the only supported type is currently 'offchainreporting2', got %s", jb.Type) } - if _, ok := relay.SupportedRelays[spec.Relay]; !ok { + if _, ok := types.SupportedRelays[spec.Relay]; !ok { return jb, pkgerrors.Errorf("no such relay %v supported", spec.Relay) } if len(spec.P2PV2Bootstrappers) > 0 { diff --git a/core/services/ocrbootstrap/delegate.go b/core/services/ocrbootstrap/delegate.go index bd8f7765119..84f473088bb 100644 --- a/core/services/ocrbootstrap/delegate.go +++ b/core/services/ocrbootstrap/delegate.go @@ -19,11 +19,10 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" ) type RelayGetter interface { - Get(relay.ID) (loop.Relayer, error) + Get(types.RelayID) (loop.Relayer, error) } // Delegate creates Bootstrap jobs diff --git a/core/services/relay/relay.go b/core/services/relay/relay.go index db8cb03d431..b4cc4517390 100644 --- a/core/services/relay/relay.go +++ b/core/services/relay/relay.go @@ -3,73 +3,11 @@ package relay import ( "context" "fmt" - "regexp" "github.com/smartcontractkit/chainlink-common/pkg/loop" "github.com/smartcontractkit/chainlink-common/pkg/types" ) -type Network = string -type ChainID = string - -const ( - EVM = "evm" - Cosmos = "cosmos" - Solana = "solana" - StarkNet = "starknet" -) - -var SupportedRelays = map[Network]struct{}{ - EVM: {}, - Cosmos: {}, - Solana: {}, - StarkNet: {}, -} - -// ID uniquely identifies a relayer by network and chain id -type ID struct { - Network Network - ChainID ChainID -} - -func (i *ID) Name() string { - return fmt.Sprintf("%s.%s", i.Network, i.ChainID) -} - -func (i *ID) String() string { - return i.Name() -} -func NewID(n Network, c ChainID) ID { - return ID{Network: n, ChainID: c} -} - -var idRegex = regexp.MustCompile( - fmt.Sprintf("^((%s)|(%s)|(%s)|(%s))\\.", EVM, Cosmos, Solana, StarkNet), -) - -func (i *ID) UnmarshalString(s string) error { - idxs := idRegex.FindStringIndex(s) - if idxs == nil { - return fmt.Errorf("error unmarshaling Identifier. %q does not match expected pattern", s) - } - // ignore the `.` in the match by dropping last rune - network := s[idxs[0] : idxs[1]-1] - chainID := s[idxs[1]:] - newID := &ID{ChainID: chainID} - for n := range SupportedRelays { - if network == n { - newID.Network = n - break - } - } - if newID.Network == "" { - return fmt.Errorf("error unmarshaling identifier: did not find network in supported list %q", network) - } - i.ChainID = newID.ChainID - i.Network = newID.Network - return nil -} - // ServerAdapter extends [loop.RelayerAdapter] by overriding NewPluginProvider to dispatches calls according to `RelayArgs.ProviderType`. // This should only be used to adapt relayers not running via GRPC in a LOOPP. type ServerAdapter struct { diff --git a/core/services/relay/relay_test.go b/core/services/relay/relay_test.go index dc12b769609..c0b2248ed1a 100644 --- a/core/services/relay/relay_test.go +++ b/core/services/relay/relay_test.go @@ -15,53 +15,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" ) -func TestIdentifier_UnmarshalString(t *testing.T) { - type fields struct { - Network Network - ChainID ChainID - } - type args struct { - s string - } - tests := []struct { - name string - want fields - args args - wantErr bool - }{ - {name: "evm", - args: args{s: "evm.1"}, - wantErr: false, - want: fields{Network: EVM, ChainID: "1"}, - }, - {name: "bad network", - args: args{s: "notANetwork.1"}, - wantErr: true, - }, - {name: "bad pattern", - args: args{s: "evm_1"}, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - i := &ID{} - err := i.UnmarshalString(tt.args.s) - if (err != nil) != tt.wantErr { - t.Errorf("Identifier.UnmarshalString() error = %v, wantErr %v", err, tt.wantErr) - } - assert.Equal(t, tt.want.Network, i.Network) - assert.Equal(t, tt.want.ChainID, i.ChainID) - }) - } -} - -func TestNewID(t *testing.T) { - rid := NewID(EVM, "chain id") - assert.Equal(t, EVM, rid.Network) - assert.Equal(t, "chain id", rid.ChainID) -} - type staticMedianProvider struct { } diff --git a/core/services/workflows/delegate.go b/core/services/workflows/delegate.go index ed7d266131a..e22a78212d2 100644 --- a/core/services/workflows/delegate.go +++ b/core/services/workflows/delegate.go @@ -7,7 +7,7 @@ import ( "github.com/google/uuid" "github.com/pelletier/go-toml" - "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/core" "github.com/smartcontractkit/chainlink/v2/core/capabilities/targets" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -15,7 +15,7 @@ import ( ) type Delegate struct { - registry types.CapabilitiesRegistry + registry core.CapabilitiesRegistry logger logger.Logger legacyEVMChains legacyevm.LegacyChainContainer } @@ -55,7 +55,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) ([]job.Ser return []job.ServiceCtx{engine}, nil } -func NewDelegate(logger logger.Logger, registry types.CapabilitiesRegistry, legacyEVMChains legacyevm.LegacyChainContainer) *Delegate { +func NewDelegate(logger logger.Logger, registry core.CapabilitiesRegistry, legacyEVMChains legacyevm.LegacyChainContainer) *Delegate { return &Delegate{logger: logger, registry: registry, legacyEVMChains: legacyEVMChains} } diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go index 4694ca4286f..052c2c86647 100644 --- a/core/services/workflows/engine.go +++ b/core/services/workflows/engine.go @@ -10,7 +10,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/services" - "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/core" "github.com/smartcontractkit/chainlink-common/pkg/values" "github.com/smartcontractkit/chainlink/v2/core/logger" ) @@ -25,7 +25,7 @@ const ( type Engine struct { services.StateMachine logger logger.Logger - registry types.CapabilitiesRegistry + registry core.CapabilitiesRegistry workflow *workflow executionStates *inMemoryStore pendingStepRequests chan stepRequest @@ -591,7 +591,7 @@ type Config struct { Spec string WorkflowID string Lggr logger.Logger - Registry types.CapabilitiesRegistry + Registry core.CapabilitiesRegistry MaxWorkerLimit int QueueSize int NewWorkerTimeout time.Duration diff --git a/core/store/migrate/migrate_test.go b/core/store/migrate/migrate_test.go index b3a15123efa..3c0c2dc2158 100644 --- a/core/store/migrate/migrate_test.go +++ b/core/store/migrate/migrate_test.go @@ -27,7 +27,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/store/migrate" "github.com/smartcontractkit/chainlink/v2/core/store/models" ) @@ -37,7 +36,7 @@ var migrationDir = "migrations" type OffchainReporting2OracleSpec100 struct { ID int32 `toml:"-"` ContractID string `toml:"contractID"` - Relay relay.Network `toml:"relay"` + Relay string `toml:"relay"` // RelayID.Network RelayConfig job.JSONConfig `toml:"relayConfig"` P2PBootstrapPeers pq.StringArray `toml:"p2pBootstrapPeers"` OCRKeyBundleID null.String `toml:"ocrKeyBundleID"` diff --git a/core/web/chains_controller.go b/core/web/chains_controller.go index 61c8d1dc84d..bcaaf909540 100644 --- a/core/web/chains_controller.go +++ b/core/web/chains_controller.go @@ -12,7 +12,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/logger/audit" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" ) type ChainsController interface { @@ -23,7 +22,7 @@ type ChainsController interface { } type chainsController[R jsonapi.EntityNamer] struct { - network relay.Network + network string resourceName string chainStats chainlink.ChainStatuser errNotEnabled error @@ -41,7 +40,7 @@ func (e errChainDisabled) Error() string { return fmt.Sprintf("%s is disabled: Set %s=true to enable", e.name, e.tomlKey) } -func newChainsController[R jsonapi.EntityNamer](network relay.Network, chainStats chainlink.ChainsNodesStatuser, errNotEnabled error, +func newChainsController[R jsonapi.EntityNamer](network string, chainStats chainlink.ChainsNodesStatuser, errNotEnabled error, newResource func(types.ChainStatus) R, lggr logger.Logger, auditLogger audit.AuditLogger) *chainsController[R] { return &chainsController[R]{ network: network, @@ -79,7 +78,7 @@ func (cc *chainsController[R]) Show(c *gin.Context) { jsonAPIError(c, http.StatusBadRequest, cc.errNotEnabled) return } - relayID := relay.ID{Network: cc.network, ChainID: c.Param("ID")} + relayID := types.RelayID{Network: cc.network, ChainID: c.Param("ID")} chain, err := cc.chainStats.ChainStatus(c, relayID) if err != nil { jsonAPIError(c, http.StatusBadRequest, err) diff --git a/core/web/cosmos_chains_controller.go b/core/web/cosmos_chains_controller.go index 20a0738c5eb..56ae007128f 100644 --- a/core/web/cosmos_chains_controller.go +++ b/core/web/cosmos_chains_controller.go @@ -1,15 +1,15 @@ package web import ( + "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) func NewCosmosChainsController(app chainlink.Application) ChainsController { return newChainsController[presenters.CosmosChainResource]( - relay.Cosmos, - app.GetRelayers().List(chainlink.FilterRelayersByType(relay.Cosmos)), + types.NetworkCosmos, + app.GetRelayers().List(chainlink.FilterRelayersByType(types.NetworkCosmos)), ErrCosmosNotEnabled, presenters.NewCosmosChainResource, app.GetLogger(), diff --git a/core/web/cosmos_nodes_controller.go b/core/web/cosmos_nodes_controller.go index 121d7d8422b..c384c10247f 100644 --- a/core/web/cosmos_nodes_controller.go +++ b/core/web/cosmos_nodes_controller.go @@ -1,8 +1,8 @@ package web import ( + "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) @@ -10,7 +10,7 @@ import ( var ErrCosmosNotEnabled = errChainDisabled{name: "Cosmos", tomlKey: "Cosmos.Enabled"} func NewCosmosNodesController(app chainlink.Application) NodesController { - scopedNodeStatuser := NewNetworkScopedNodeStatuser(app.GetRelayers(), relay.Cosmos) + scopedNodeStatuser := NewNetworkScopedNodeStatuser(app.GetRelayers(), types.NetworkCosmos) return newNodesController[presenters.CosmosNodeResource]( scopedNodeStatuser, ErrCosmosNotEnabled, presenters.NewCosmosNodeResource, app.GetAuditLogger(), diff --git a/core/web/cosmos_transfer_controller.go b/core/web/cosmos_transfer_controller.go index 9b958346642..d0de1fd727e 100644 --- a/core/web/cosmos_transfer_controller.go +++ b/core/web/cosmos_transfer_controller.go @@ -10,10 +10,10 @@ import ( "github.com/google/uuid" "github.com/pkg/errors" + "github.com/smartcontractkit/chainlink-common/pkg/types" coscfg "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/config" "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/db" "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/denom" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/logger/audit" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" @@ -28,7 +28,7 @@ type CosmosTransfersController struct { // Create sends native coins from the Chainlink's account to a specified address. func (tc *CosmosTransfersController) Create(c *gin.Context) { - relayers := tc.App.GetRelayers().List(chainlink.FilterRelayersByType(relay.Cosmos)) + relayers := tc.App.GetRelayers().List(chainlink.FilterRelayersByType(types.NetworkCosmos)) if relayers == nil { jsonAPIError(c, http.StatusBadRequest, ErrSolanaNotEnabled) return @@ -48,7 +48,7 @@ func (tc *CosmosTransfersController) Create(c *gin.Context) { return } - relayerID := relay.ID{Network: relay.Cosmos, ChainID: tr.CosmosChainID} + relayerID := types.RelayID{Network: types.NetworkCosmos, ChainID: tr.CosmosChainID} relayer, err := relayers.Get(relayerID) if err != nil { if errors.Is(err, chainlink.ErrNoSuchRelayer) { diff --git a/core/web/evm_chains_controller.go b/core/web/evm_chains_controller.go index 45b4964c215..3d939a9f9bc 100644 --- a/core/web/evm_chains_controller.go +++ b/core/web/evm_chains_controller.go @@ -1,8 +1,8 @@ package web import ( + "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) @@ -10,8 +10,8 @@ var ErrEVMNotEnabled = errChainDisabled{name: "EVM", tomlKey: "EVM.Enabled"} func NewEVMChainsController(app chainlink.Application) ChainsController { return newChainsController[presenters.EVMChainResource]( - relay.EVM, - app.GetRelayers().List(chainlink.FilterRelayersByType(relay.EVM)), + types.NetworkEVM, + app.GetRelayers().List(chainlink.FilterRelayersByType(types.NetworkEVM)), ErrEVMNotEnabled, presenters.NewEVMChainResource, app.GetLogger(), diff --git a/core/web/evm_nodes_controller.go b/core/web/evm_nodes_controller.go index c8d0b91c0f7..ba8e112c365 100644 --- a/core/web/evm_nodes_controller.go +++ b/core/web/evm_nodes_controller.go @@ -1,13 +1,13 @@ package web import ( + "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) func NewEVMNodesController(app chainlink.Application) NodesController { - scopedNodeStatuser := NewNetworkScopedNodeStatuser(app.GetRelayers(), relay.EVM) + scopedNodeStatuser := NewNetworkScopedNodeStatuser(app.GetRelayers(), types.NetworkEVM) return newNodesController[presenters.EVMNodeResource]( scopedNodeStatuser, ErrEVMNotEnabled, presenters.NewEVMNodeResource, app.GetAuditLogger()) diff --git a/core/web/loader/chain.go b/core/web/loader/chain.go index 34ca4bd5f82..215c643f3c5 100644 --- a/core/web/loader/chain.go +++ b/core/web/loader/chain.go @@ -9,7 +9,6 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/chains" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" ) type chainBatcher struct { @@ -20,7 +19,7 @@ func (b *chainBatcher) loadByIDs(ctx context.Context, keys dataloader.Keys) []*d // Create a map for remembering the order of keys passed in keyOrder := make(map[string]int, len(keys)) // Collect the keys to search for - var chainIDs []relay.ChainID + var chainIDs []string for ix, key := range keys { chainIDs = append(chainIDs, key.String()) keyOrder[key.String()] = ix diff --git a/core/web/loader/node.go b/core/web/loader/node.go index 3d229813101..e67f1fd4d41 100644 --- a/core/web/loader/node.go +++ b/core/web/loader/node.go @@ -8,7 +8,6 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" ) type nodeBatcher struct { @@ -20,10 +19,10 @@ func (b *nodeBatcher) loadByChainIDs(ctx context.Context, keys dataloader.Keys) keyOrder := make(map[string]int, len(keys)) // Collect the keys to search for // note backward compatibility -- this only ever supported evm chains - evmrelayIDs := make([]relay.ID, 0, len(keys)) + evmrelayIDs := make([]types.RelayID, 0, len(keys)) for ix, key := range keys { - rid := relay.ID{Network: relay.EVM, ChainID: key.String()} + rid := types.RelayID{Network: types.NetworkEVM, ChainID: key.String()} evmrelayIDs = append(evmrelayIDs, rid) keyOrder[key.String()] = ix } diff --git a/core/web/nodes_controller.go b/core/web/nodes_controller.go index 04c4693983f..bf5bb0e65e1 100644 --- a/core/web/nodes_controller.go +++ b/core/web/nodes_controller.go @@ -11,7 +11,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger/audit" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" ) type NodesController interface { @@ -20,11 +19,11 @@ type NodesController interface { } type NetworkScopedNodeStatuser struct { - network relay.Network + network string relayers chainlink.RelayerChainInteroperators } -func NewNetworkScopedNodeStatuser(relayers chainlink.RelayerChainInteroperators, network relay.Network) *NetworkScopedNodeStatuser { +func NewNetworkScopedNodeStatuser(relayers chainlink.RelayerChainInteroperators, network string) *NetworkScopedNodeStatuser { scoped := relayers.List(chainlink.FilterRelayersByType(network)) return &NetworkScopedNodeStatuser{ network: network, @@ -32,7 +31,7 @@ func NewNetworkScopedNodeStatuser(relayers chainlink.RelayerChainInteroperators, } } -func (n *NetworkScopedNodeStatuser) NodeStatuses(ctx context.Context, offset, limit int, relayIDs ...relay.ID) (nodes []types.NodeStatus, count int, err error) { +func (n *NetworkScopedNodeStatuser) NodeStatuses(ctx context.Context, offset, limit int, relayIDs ...types.RelayID) (nodes []types.NodeStatus, count int, err error) { return n.relayers.NodeStatuses(ctx, offset, limit, relayIDs...) } @@ -75,7 +74,7 @@ func (n *nodesController[R]) Index(c *gin.Context, size, page, offset int) { } else { // fetch nodes for chain ID // backward compatibility - var rid relay.ID + var rid types.RelayID err = rid.UnmarshalString(id) if err != nil { rid.ChainID = id diff --git a/core/web/presenters/job.go b/core/web/presenters/job.go index 296add4ee25..12b958a346d 100644 --- a/core/web/presenters/job.go +++ b/core/web/presenters/job.go @@ -15,7 +15,6 @@ import ( clnull "github.com/smartcontractkit/chainlink/v2/core/null" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/services/signatures/secp256k1" "github.com/smartcontractkit/chainlink/v2/core/store/models" ) @@ -167,7 +166,7 @@ func NewOffChainReportingSpec(spec *job.OCROracleSpec) *OffChainReportingSpec { // OffChainReporting2Spec defines the spec details of a OffChainReporting2 Job type OffChainReporting2Spec struct { ContractID string `json:"contractID"` - Relay relay.Network `json:"relay"` + Relay string `json:"relay"` // RelayID.Network RelayConfig map[string]interface{} `json:"relayConfig"` P2PV2Bootstrappers pq.StringArray `json:"p2pv2Bootstrappers"` OCRKeyBundleID null.String `json:"ocrKeyBundleID"` @@ -392,7 +391,7 @@ func NewBlockHeaderFeederSpec(spec *job.BlockHeaderFeederSpec) *BlockHeaderFeede // BootstrapSpec defines the spec details of a BootstrapSpec Job type BootstrapSpec struct { ContractID string `json:"contractID"` - Relay relay.Network `json:"relay"` + Relay string `json:"relay"` // RelayID.Network RelayConfig map[string]interface{} `json:"relayConfig"` BlockchainTimeout models.Interval `json:"blockchainTimeout"` ContractConfigTrackerSubscribeInterval models.Interval `json:"contractConfigTrackerSubscribeInterval"` diff --git a/core/web/resolver/query.go b/core/web/resolver/query.go index 5a016599dc9..e24974e765d 100644 --- a/core/web/resolver/query.go +++ b/core/web/resolver/query.go @@ -15,7 +15,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/vrfkey" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/utils/stringutils" ) @@ -69,7 +68,7 @@ func (r *Resolver) Chain(ctx context.Context, args struct{ ID graphql.ID }) (*Ch return nil, err } - cs, _, err := r.App.EVMORM().Chains(relay.ChainID(args.ID)) + cs, _, err := r.App.EVMORM().Chains(string(args.ID)) if err != nil { return nil, err } diff --git a/core/web/resolver/spec_test.go b/core/web/resolver/spec_test.go index 1b65549488f..7021576fdcf 100644 --- a/core/web/resolver/spec_test.go +++ b/core/web/resolver/spec_test.go @@ -17,7 +17,6 @@ import ( ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" clnull "github.com/smartcontractkit/chainlink/v2/core/null" "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/services/signatures/secp256k1" "github.com/smartcontractkit/chainlink/v2/core/store/models" ) @@ -485,7 +484,7 @@ func TestResolver_OCR2Spec(t *testing.T) { OCRKeyBundleID: null.StringFrom(keyBundleID.String()), MonitoringEndpoint: null.StringFrom("https://monitor.endpoint"), P2PV2Bootstrappers: pq.StringArray{"12D3KooWL3XJ9EMCyZvmmGXL2LMiVBtrVa2BuESsJiXkSj7333Jw@localhost:5001"}, - Relay: relay.EVM, + Relay: types.NetworkEVM, RelayConfig: relayConfig, TransmitterID: null.StringFrom(transmitterAddress.String()), PluginType: types.Median, diff --git a/core/web/solana_chains_controller.go b/core/web/solana_chains_controller.go index 8e2d4393a5f..ffb39cddba1 100644 --- a/core/web/solana_chains_controller.go +++ b/core/web/solana_chains_controller.go @@ -1,15 +1,15 @@ package web import ( + "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) func NewSolanaChainsController(app chainlink.Application) ChainsController { return newChainsController( - relay.Solana, - app.GetRelayers().List(chainlink.FilterRelayersByType(relay.Solana)), + types.NetworkSolana, + app.GetRelayers().List(chainlink.FilterRelayersByType(types.NetworkSolana)), ErrSolanaNotEnabled, presenters.NewSolanaChainResource, app.GetLogger(), diff --git a/core/web/solana_nodes_controller.go b/core/web/solana_nodes_controller.go index d5fbc05ccf5..b3e03b8c320 100644 --- a/core/web/solana_nodes_controller.go +++ b/core/web/solana_nodes_controller.go @@ -1,8 +1,8 @@ package web import ( + "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) @@ -10,7 +10,7 @@ import ( var ErrSolanaNotEnabled = errChainDisabled{name: "Solana", tomlKey: "Solana.Enabled"} func NewSolanaNodesController(app chainlink.Application) NodesController { - scopedNodeStatuser := NewNetworkScopedNodeStatuser(app.GetRelayers(), relay.Solana) + scopedNodeStatuser := NewNetworkScopedNodeStatuser(app.GetRelayers(), types.NetworkSolana) return newNodesController[presenters.SolanaNodeResource]( scopedNodeStatuser, ErrSolanaNotEnabled, presenters.NewSolanaNodeResource, app.GetAuditLogger()) diff --git a/core/web/solana_transfer_controller.go b/core/web/solana_transfer_controller.go index 70218080a87..7885c73bf7a 100644 --- a/core/web/solana_transfer_controller.go +++ b/core/web/solana_transfer_controller.go @@ -8,10 +8,10 @@ import ( "github.com/google/uuid" "github.com/pkg/errors" + "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/chains" "github.com/smartcontractkit/chainlink/v2/core/logger/audit" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" solanamodels "github.com/smartcontractkit/chainlink/v2/core/store/models/solana" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) @@ -23,7 +23,7 @@ type SolanaTransfersController struct { // Create sends SOL and other native coins from the Chainlink's account to a specified address. func (tc *SolanaTransfersController) Create(c *gin.Context) { - relayers := tc.App.GetRelayers().List(chainlink.FilterRelayersByType(relay.Solana)) + relayers := tc.App.GetRelayers().List(chainlink.FilterRelayersByType(types.NetworkSolana)) if relayers == nil { jsonAPIError(c, http.StatusBadRequest, ErrSolanaNotEnabled) return @@ -48,7 +48,7 @@ func (tc *SolanaTransfersController) Create(c *gin.Context) { } amount := new(big.Int).SetUint64(tr.Amount) - relayerID := relay.ID{Network: relay.Solana, ChainID: tr.SolanaChainID} + relayerID := types.RelayID{Network: types.NetworkSolana, ChainID: tr.SolanaChainID} relayer, err := relayers.Get(relayerID) if err != nil { if errors.Is(err, chainlink.ErrNoSuchRelayer) { diff --git a/core/web/starknet_chains_controller.go b/core/web/starknet_chains_controller.go index 414e17d9823..35a06899117 100644 --- a/core/web/starknet_chains_controller.go +++ b/core/web/starknet_chains_controller.go @@ -1,15 +1,15 @@ package web import ( + "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) func NewStarkNetChainsController(app chainlink.Application) ChainsController { return newChainsController( - relay.StarkNet, - app.GetRelayers().List(chainlink.FilterRelayersByType(relay.StarkNet)), + types.NetworkStarkNet, + app.GetRelayers().List(chainlink.FilterRelayersByType(types.NetworkStarkNet)), ErrStarkNetNotEnabled, presenters.NewStarkNetChainResource, app.GetLogger(), diff --git a/core/web/starknet_nodes_controller.go b/core/web/starknet_nodes_controller.go index d2881f2e65a..5d059d357f0 100644 --- a/core/web/starknet_nodes_controller.go +++ b/core/web/starknet_nodes_controller.go @@ -1,8 +1,8 @@ package web import ( + "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) @@ -10,7 +10,7 @@ import ( var ErrStarkNetNotEnabled = errChainDisabled{name: "StarkNet", tomlKey: "Starknet.Enabled"} func NewStarkNetNodesController(app chainlink.Application) NodesController { - scopedNodeStatuser := NewNetworkScopedNodeStatuser(app.GetRelayers(), relay.StarkNet) + scopedNodeStatuser := NewNetworkScopedNodeStatuser(app.GetRelayers(), types.NetworkStarkNet) return newNodesController[presenters.StarkNetNodeResource]( scopedNodeStatuser, ErrStarkNetNotEnabled, presenters.NewStarkNetNodeResource, app.GetAuditLogger()) diff --git a/go.mod b/go.mod index febf4a8003d..ff9993618c1 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/ethereum/go-ethereum v1.13.8 github.com/fatih/color v1.16.0 github.com/fxamacker/cbor/v2 v2.5.0 - github.com/gagliardetto/solana-go v1.4.1-0.20220428092759-5250b4abbb27 + github.com/gagliardetto/solana-go v1.8.4 github.com/getsentry/sentry-go v0.19.0 github.com/gin-contrib/cors v1.5.0 github.com/gin-contrib/expvar v0.0.1 @@ -72,11 +72,11 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chain-selectors v1.0.10 github.com/smartcontractkit/chainlink-automation v1.0.3 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419105123-fc5d616c7d2e + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab - github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e + github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595 github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c @@ -132,7 +132,6 @@ require ( github.com/Microsoft/go-winio v0.6.1 // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect github.com/armon/go-metrics v0.4.1 // indirect - github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -181,7 +180,7 @@ require ( github.com/ethereum/c-kzg-4844 v0.4.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect - github.com/gagliardetto/binary v0.7.1 // indirect + github.com/gagliardetto/binary v0.7.7 // indirect github.com/gagliardetto/treeout v0.1.4 // indirect github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect @@ -291,6 +290,7 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.15.0 // indirect github.com/status-im/keycard-go v0.2.0 // indirect + github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.4.2 // indirect github.com/supranational/blst v0.3.11 // indirect @@ -315,6 +315,7 @@ require ( github.com/zondax/ledger-go v0.14.1 // indirect go.dedis.ch/protobuf v1.0.11 // indirect go.etcd.io/bbolt v1.3.7 // indirect + go.mongodb.org/mongo-driver v1.15.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect diff --git a/go.sum b/go.sum index 32e6ebbdb59..1f94c3dfc9f 100644 --- a/go.sum +++ b/go.sum @@ -160,11 +160,10 @@ github.com/aws/aws-sdk-go v1.22.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= 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/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 h1:WWB576BN5zNSZc/M9d/10pqEx5VHNhaQ/yOVAkmj5Yo= -github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -410,13 +409,12 @@ github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADi github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= -github.com/gagliardetto/binary v0.6.1/go.mod h1:aOfYkc20U0deHaHn/LVZXiqlkDbFAX0FpTlDhsXa0S0= -github.com/gagliardetto/binary v0.7.1 h1:6ggDQ26vR+4xEvl/S13NcdLK3MUCi4oSy73pS9aI1cI= -github.com/gagliardetto/binary v0.7.1/go.mod h1:aOfYkc20U0deHaHn/LVZXiqlkDbFAX0FpTlDhsXa0S0= +github.com/gagliardetto/binary v0.7.7 h1:QZpT38+sgoPg+TIQjH94sLbl/vX+nlIRA37pEyOsjfY= +github.com/gagliardetto/binary v0.7.7/go.mod h1:mUuay5LL8wFVnIlecHakSZMvcdqfs+CsotR5n77kyjM= github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= github.com/gagliardetto/gofuzz v1.2.2/go.mod h1:bkH/3hYLZrMLbfYWA0pWzXmi5TTRZnu4pMGZBkqMKvY= -github.com/gagliardetto/solana-go v1.4.1-0.20220428092759-5250b4abbb27 h1:q2IztKyRQUxJ6abXRsawaBtvDFvM+szj4jDqV4od1gs= -github.com/gagliardetto/solana-go v1.4.1-0.20220428092759-5250b4abbb27/go.mod h1:NFuoDwHPvw858ZMHUJr6bkhN8qHt4x6e+U3EYHxAwNY= +github.com/gagliardetto/solana-go v1.8.4 h1:vmD/JmTlonyXGy39bAo0inMhmbdAwV7rXZtLDMZeodE= +github.com/gagliardetto/solana-go v1.8.4/go.mod h1:i+7aAyNDTHG0jK8GZIBSI4OVvDqkt2Qx+LklYclRNG8= github.com/gagliardetto/treeout v0.1.4 h1:ozeYerrLCmCubo1TcIjFiOWTTGteOOHND1twdFpgwaw= github.com/gagliardetto/treeout v0.1.4/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= @@ -571,6 +569,7 @@ github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= @@ -995,6 +994,7 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN 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= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 h1:mPMvm6X6tf4w8y7j9YIt6V9jfWhL6QlbEc7CCmeQlWk= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1/go.mod h1:ye2e/VUEtE2BHE+G/QcKkcLQVAEJoYRFj5VUOQatCRE= github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= @@ -1180,16 +1180,16 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfsE3+8OEzT3Q0Z9au0z1BPWs= github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419105123-fc5d616c7d2e h1:nHs5mFOR7FPII20GrCGIPywDW43MhEUlD7DqHnTgu6Q= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419105123-fc5d616c7d2e/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9 h1:elDIBChe7ByPNvCyrSjMLTPKrgY+sKgzzlWe2p3wokY= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 h1:MvaNzuaQh1vX4CAYLM8qFd99cf0ZF1JNwtDZtLU7WvU= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540/go.mod h1:sjAmX8K2kbQhvDarZE1ZZgDgmHJ50s0BBc/66vKY2ek= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab h1:Ct1oUlyn03HDUVdFHJqtRGRUujMqdoMzvf/Cjhe30Ag= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab/go.mod h1:RPUY7r8GxgzXxS1ijtU1P/fpJomOXztXgUbEziNmbCA= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e h1:k8HS3GsAFZnxXIW3141VsQP2+EL1XrTtOi/HDt7sdBE= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e/go.mod h1:JiykN+8W5TA4UD2ClrzQCVvcH3NcyLEVv7RwY0busrw= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58 h1:jc4ab5QrKZfkICyxJysCt7mSExuSPbePjgZsnJR3nRQ= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58/go.mod h1:oV5gIuSKrPEcjQ6uB6smBsm5kXHxyydVLNyAs4V9CoQ= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595 h1:y6ks0HsSOhPUueOmTcoxDQ50RCS1XINlRDTemZyHjFw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595/go.mod h1:vV6WfnVIbK5Q1JsIru4YcTG0T1uRpLJm6t2BgCnCSsg= github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 h1:LQmRsrzzaYYN3wEU1l5tWiccznhvbyGnu2N+wHSXZAo= @@ -1236,6 +1236,8 @@ github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= +github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 h1:ZqpS7rAhhKD7S7DnrpEdrnW1/gZcv82ytpMviovkli4= +github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75/go.mod h1:VlduQ80JcGJSargkRU4Sg9Xo63wZD/l8A5NC/Uo1/uU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= @@ -1282,6 +1284,7 @@ github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM= github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= @@ -1330,6 +1333,9 @@ github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/ github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= 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.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= +github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -1346,6 +1352,7 @@ github.com/ydb-platform/ydb-go-genproto v0.0.0-20231012155159-f85a672542fd h1:dz github.com/ydb-platform/ydb-go-genproto v0.0.0-20231012155159-f85a672542fd/go.mod h1:Er+FePu1dNUieD+XTMDduGpQuCPssK5Q4BjF+IIXJ3I= github.com/ydb-platform/ydb-go-sdk/v3 v3.54.2 h1:E0yUuuX7UmPxXm92+yQCjMveLFO3zfvYFIJVuAqsVRA= github.com/ydb-platform/ydb-go-sdk/v3 v3.54.2/go.mod h1:fjBLQ2TdQNl4bMjuWl9adoTGBypwUTPoGC+EqYqiIcU= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= @@ -1375,6 +1382,9 @@ go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYr go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +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= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= @@ -1413,6 +1423,7 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -1430,6 +1441,7 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= @@ -1454,11 +1466,12 @@ golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +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.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= @@ -1552,8 +1565,8 @@ golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 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= @@ -1651,7 +1664,6 @@ golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/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-20210514084401-e8d321eab015/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-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1755,7 +1767,6 @@ golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWc golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200601175630-2caf76543d99/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= @@ -1771,6 +1782,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index ff0343639ba..9c978bf69bd 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -24,7 +24,7 @@ require ( github.com/segmentio/ksuid v1.0.4 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.3 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419105123-fc5d616c7d2e + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9 github.com/smartcontractkit/chainlink-testing-framework v1.28.3 github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 @@ -94,7 +94,6 @@ require ( github.com/aws/aws-sdk-go v1.45.25 // indirect github.com/aws/constructs-go/constructs/v10 v10.1.255 // indirect github.com/aws/jsii-runtime-go v1.75.0 // indirect - github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -176,8 +175,8 @@ require ( github.com/fvbommel/sortorder v1.0.2 // indirect github.com/fxamacker/cbor/v2 v2.5.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect - github.com/gagliardetto/binary v0.7.1 // indirect - github.com/gagliardetto/solana-go v1.4.1-0.20220428092759-5250b4abbb27 // indirect + github.com/gagliardetto/binary v0.7.7 // indirect + github.com/gagliardetto/solana-go v1.8.4 // indirect github.com/gagliardetto/treeout v0.1.4 // indirect github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect @@ -381,7 +380,7 @@ require ( github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab // indirect - github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e // indirect + github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58 // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect @@ -394,6 +393,7 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.15.0 // indirect github.com/status-im/keycard-go v0.2.0 // indirect + github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.4.2 // indirect github.com/supranational/blst v0.3.11 // indirect @@ -426,7 +426,7 @@ require ( go.etcd.io/etcd/api/v3 v3.5.7 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.7 // indirect go.etcd.io/etcd/client/v3 v3.5.7 // indirect - go.mongodb.org/mongo-driver v1.12.0 // 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 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 6756177bdb8..5a8b091ebcc 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -216,13 +216,12 @@ github.com/aws/constructs-go/constructs/v10 v10.1.255 h1:5hARfEmhBqHSTQf/C3QLA3s github.com/aws/constructs-go/constructs/v10 v10.1.255/go.mod h1:DCdBSjN04Ck2pajCacTD4RKFqSA7Utya8d62XreYctI= github.com/aws/jsii-runtime-go v1.75.0 h1:NhpUfyiL7/wsRuUekFsz8FFBCYLfPD/l61kKg9kL/a4= github.com/aws/jsii-runtime-go v1.75.0/go.mod h1:TKCyrtM0pygEPo4rDZzbMSDNCDNTSYSN6/mGyHI6O3I= -github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 h1:WWB576BN5zNSZc/M9d/10pqEx5VHNhaQ/yOVAkmj5Yo= -github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= 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/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= @@ -528,13 +527,12 @@ github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADi github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= -github.com/gagliardetto/binary v0.6.1/go.mod h1:aOfYkc20U0deHaHn/LVZXiqlkDbFAX0FpTlDhsXa0S0= -github.com/gagliardetto/binary v0.7.1 h1:6ggDQ26vR+4xEvl/S13NcdLK3MUCi4oSy73pS9aI1cI= -github.com/gagliardetto/binary v0.7.1/go.mod h1:aOfYkc20U0deHaHn/LVZXiqlkDbFAX0FpTlDhsXa0S0= +github.com/gagliardetto/binary v0.7.7 h1:QZpT38+sgoPg+TIQjH94sLbl/vX+nlIRA37pEyOsjfY= +github.com/gagliardetto/binary v0.7.7/go.mod h1:mUuay5LL8wFVnIlecHakSZMvcdqfs+CsotR5n77kyjM= github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= github.com/gagliardetto/gofuzz v1.2.2/go.mod h1:bkH/3hYLZrMLbfYWA0pWzXmi5TTRZnu4pMGZBkqMKvY= -github.com/gagliardetto/solana-go v1.4.1-0.20220428092759-5250b4abbb27 h1:q2IztKyRQUxJ6abXRsawaBtvDFvM+szj4jDqV4od1gs= -github.com/gagliardetto/solana-go v1.4.1-0.20220428092759-5250b4abbb27/go.mod h1:NFuoDwHPvw858ZMHUJr6bkhN8qHt4x6e+U3EYHxAwNY= +github.com/gagliardetto/solana-go v1.8.4 h1:vmD/JmTlonyXGy39bAo0inMhmbdAwV7rXZtLDMZeodE= +github.com/gagliardetto/solana-go v1.8.4/go.mod h1:i+7aAyNDTHG0jK8GZIBSI4OVvDqkt2Qx+LklYclRNG8= github.com/gagliardetto/treeout v0.1.4 h1:ozeYerrLCmCubo1TcIjFiOWTTGteOOHND1twdFpgwaw= github.com/gagliardetto/treeout v0.1.4/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= @@ -1519,16 +1517,16 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfsE3+8OEzT3Q0Z9au0z1BPWs= github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419105123-fc5d616c7d2e h1:nHs5mFOR7FPII20GrCGIPywDW43MhEUlD7DqHnTgu6Q= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419105123-fc5d616c7d2e/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9 h1:elDIBChe7ByPNvCyrSjMLTPKrgY+sKgzzlWe2p3wokY= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 h1:MvaNzuaQh1vX4CAYLM8qFd99cf0ZF1JNwtDZtLU7WvU= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540/go.mod h1:sjAmX8K2kbQhvDarZE1ZZgDgmHJ50s0BBc/66vKY2ek= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab h1:Ct1oUlyn03HDUVdFHJqtRGRUujMqdoMzvf/Cjhe30Ag= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab/go.mod h1:RPUY7r8GxgzXxS1ijtU1P/fpJomOXztXgUbEziNmbCA= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e h1:k8HS3GsAFZnxXIW3141VsQP2+EL1XrTtOi/HDt7sdBE= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e/go.mod h1:JiykN+8W5TA4UD2ClrzQCVvcH3NcyLEVv7RwY0busrw= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58 h1:jc4ab5QrKZfkICyxJysCt7mSExuSPbePjgZsnJR3nRQ= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58/go.mod h1:oV5gIuSKrPEcjQ6uB6smBsm5kXHxyydVLNyAs4V9CoQ= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595 h1:y6ks0HsSOhPUueOmTcoxDQ50RCS1XINlRDTemZyHjFw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595/go.mod h1:vV6WfnVIbK5Q1JsIru4YcTG0T1uRpLJm6t2BgCnCSsg= github.com/smartcontractkit/chainlink-testing-framework v1.28.3 h1:rZ622PUSE9jJvI2g1SNNcMJedXyMzq9XJ8SbV2j9TvA= @@ -1587,6 +1585,8 @@ github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jH github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 h1:ZqpS7rAhhKD7S7DnrpEdrnW1/gZcv82ytpMviovkli4= +github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75/go.mod h1:VlduQ80JcGJSargkRU4Sg9Xo63wZD/l8A5NC/Uo1/uU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= @@ -1691,10 +1691,8 @@ github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcY 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/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= 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/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= @@ -1746,8 +1744,9 @@ go.etcd.io/etcd/client/v3 v3.5.7/go.mod h1:sOWmj9DZUMyAngS7QQwCyAXXAL6WhgTOPLNS/ 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.12.0 h1:aPx33jmn/rQuJXPQLZQ8NtfPQG8CaqgLThFtqRb0PiE= -go.mongodb.org/mongo-driver v1.12.0/go.mod h1:AZkxhPnFJUoH7kZlFkVKucV20K387miPfm7oimrSmK0= +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= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= @@ -1797,6 +1796,7 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -1814,6 +1814,7 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f h1:ketMxHg+vWm3yccyYiq+uK8D3fRmna2Fcj+awpQp84s= @@ -1843,11 +1844,11 @@ golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= @@ -1947,7 +1948,6 @@ golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -2064,7 +2064,6 @@ golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/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-20210514084401-e8d321eab015/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= @@ -2180,7 +2179,6 @@ golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWc golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200601175630-2caf76543d99/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= @@ -2196,6 +2194,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index b9a5df79bcf..95870bad6a2 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.30.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.3 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419105123-fc5d616c7d2e + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9 github.com/smartcontractkit/chainlink-testing-framework v1.28.3 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 @@ -72,7 +72,6 @@ require ( github.com/aws/aws-sdk-go v1.45.25 // indirect github.com/aws/constructs-go/constructs/v10 v10.1.255 // indirect github.com/aws/jsii-runtime-go v1.75.0 // indirect - github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df // indirect github.com/benbjohnson/clock v1.3.5 // indirect @@ -154,8 +153,8 @@ require ( github.com/fvbommel/sortorder v1.0.2 // indirect github.com/fxamacker/cbor/v2 v2.5.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect - github.com/gagliardetto/binary v0.7.1 // indirect - github.com/gagliardetto/solana-go v1.4.1-0.20220428092759-5250b4abbb27 // indirect + github.com/gagliardetto/binary v0.7.7 // indirect + github.com/gagliardetto/solana-go v1.8.4 // indirect github.com/gagliardetto/treeout v0.1.4 // indirect github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect @@ -370,7 +369,7 @@ require ( github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab // indirect - github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e // indirect + github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58 // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595 // indirect github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240227164431-18a7065e23ea // indirect github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 // indirect @@ -385,6 +384,7 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.15.0 // indirect github.com/status-im/keycard-go v0.2.0 // indirect + github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.4.2 // indirect github.com/supranational/blst v0.3.11 // indirect @@ -421,7 +421,7 @@ require ( go.etcd.io/etcd/api/v3 v3.5.7 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.7 // indirect go.etcd.io/etcd/client/v3 v3.5.7 // indirect - go.mongodb.org/mongo-driver v1.12.0 // 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 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 5a04cbbcff0..051fdf9cd6e 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -216,13 +216,12 @@ github.com/aws/constructs-go/constructs/v10 v10.1.255 h1:5hARfEmhBqHSTQf/C3QLA3s github.com/aws/constructs-go/constructs/v10 v10.1.255/go.mod h1:DCdBSjN04Ck2pajCacTD4RKFqSA7Utya8d62XreYctI= github.com/aws/jsii-runtime-go v1.75.0 h1:NhpUfyiL7/wsRuUekFsz8FFBCYLfPD/l61kKg9kL/a4= github.com/aws/jsii-runtime-go v1.75.0/go.mod h1:TKCyrtM0pygEPo4rDZzbMSDNCDNTSYSN6/mGyHI6O3I= -github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 h1:WWB576BN5zNSZc/M9d/10pqEx5VHNhaQ/yOVAkmj5Yo= -github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= 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/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= @@ -518,13 +517,12 @@ github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADi github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= -github.com/gagliardetto/binary v0.6.1/go.mod h1:aOfYkc20U0deHaHn/LVZXiqlkDbFAX0FpTlDhsXa0S0= -github.com/gagliardetto/binary v0.7.1 h1:6ggDQ26vR+4xEvl/S13NcdLK3MUCi4oSy73pS9aI1cI= -github.com/gagliardetto/binary v0.7.1/go.mod h1:aOfYkc20U0deHaHn/LVZXiqlkDbFAX0FpTlDhsXa0S0= +github.com/gagliardetto/binary v0.7.7 h1:QZpT38+sgoPg+TIQjH94sLbl/vX+nlIRA37pEyOsjfY= +github.com/gagliardetto/binary v0.7.7/go.mod h1:mUuay5LL8wFVnIlecHakSZMvcdqfs+CsotR5n77kyjM= github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= github.com/gagliardetto/gofuzz v1.2.2/go.mod h1:bkH/3hYLZrMLbfYWA0pWzXmi5TTRZnu4pMGZBkqMKvY= -github.com/gagliardetto/solana-go v1.4.1-0.20220428092759-5250b4abbb27 h1:q2IztKyRQUxJ6abXRsawaBtvDFvM+szj4jDqV4od1gs= -github.com/gagliardetto/solana-go v1.4.1-0.20220428092759-5250b4abbb27/go.mod h1:NFuoDwHPvw858ZMHUJr6bkhN8qHt4x6e+U3EYHxAwNY= +github.com/gagliardetto/solana-go v1.8.4 h1:vmD/JmTlonyXGy39bAo0inMhmbdAwV7rXZtLDMZeodE= +github.com/gagliardetto/solana-go v1.8.4/go.mod h1:i+7aAyNDTHG0jK8GZIBSI4OVvDqkt2Qx+LklYclRNG8= github.com/gagliardetto/treeout v0.1.4 h1:ozeYerrLCmCubo1TcIjFiOWTTGteOOHND1twdFpgwaw= github.com/gagliardetto/treeout v0.1.4/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= @@ -1502,16 +1500,16 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfsE3+8OEzT3Q0Z9au0z1BPWs= github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419105123-fc5d616c7d2e h1:nHs5mFOR7FPII20GrCGIPywDW43MhEUlD7DqHnTgu6Q= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419105123-fc5d616c7d2e/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9 h1:elDIBChe7ByPNvCyrSjMLTPKrgY+sKgzzlWe2p3wokY= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 h1:MvaNzuaQh1vX4CAYLM8qFd99cf0ZF1JNwtDZtLU7WvU= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540/go.mod h1:sjAmX8K2kbQhvDarZE1ZZgDgmHJ50s0BBc/66vKY2ek= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab h1:Ct1oUlyn03HDUVdFHJqtRGRUujMqdoMzvf/Cjhe30Ag= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab/go.mod h1:RPUY7r8GxgzXxS1ijtU1P/fpJomOXztXgUbEziNmbCA= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e h1:k8HS3GsAFZnxXIW3141VsQP2+EL1XrTtOi/HDt7sdBE= -github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240216142700-c5869534c19e/go.mod h1:JiykN+8W5TA4UD2ClrzQCVvcH3NcyLEVv7RwY0busrw= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58 h1:jc4ab5QrKZfkICyxJysCt7mSExuSPbePjgZsnJR3nRQ= +github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58/go.mod h1:oV5gIuSKrPEcjQ6uB6smBsm5kXHxyydVLNyAs4V9CoQ= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595 h1:y6ks0HsSOhPUueOmTcoxDQ50RCS1XINlRDTemZyHjFw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595/go.mod h1:vV6WfnVIbK5Q1JsIru4YcTG0T1uRpLJm6t2BgCnCSsg= github.com/smartcontractkit/chainlink-testing-framework v1.28.3 h1:rZ622PUSE9jJvI2g1SNNcMJedXyMzq9XJ8SbV2j9TvA= @@ -1572,6 +1570,8 @@ github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jH github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75 h1:ZqpS7rAhhKD7S7DnrpEdrnW1/gZcv82ytpMviovkli4= +github.com/streamingfast/logging v0.0.0-20220405224725-2755dab2ce75/go.mod h1:VlduQ80JcGJSargkRU4Sg9Xo63wZD/l8A5NC/Uo1/uU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= @@ -1676,10 +1676,8 @@ github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcY 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/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= 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/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= @@ -1731,8 +1729,9 @@ go.etcd.io/etcd/client/v3 v3.5.7/go.mod h1:sOWmj9DZUMyAngS7QQwCyAXXAL6WhgTOPLNS/ 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.12.0 h1:aPx33jmn/rQuJXPQLZQ8NtfPQG8CaqgLThFtqRb0PiE= -go.mongodb.org/mongo-driver v1.12.0/go.mod h1:AZkxhPnFJUoH7kZlFkVKucV20K387miPfm7oimrSmK0= +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= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= @@ -1782,6 +1781,7 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -1799,6 +1799,7 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f h1:ketMxHg+vWm3yccyYiq+uK8D3fRmna2Fcj+awpQp84s= @@ -1828,11 +1829,11 @@ golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= @@ -1933,7 +1934,6 @@ golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -2049,7 +2049,6 @@ golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/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-20210514084401-e8d321eab015/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= @@ -2167,7 +2166,6 @@ golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWc golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200601175630-2caf76543d99/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= @@ -2183,6 +2181,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= diff --git a/plugins/medianpoc/data_source.go b/plugins/medianpoc/data_source.go index 455f3241fd8..3bb6e51593e 100644 --- a/plugins/medianpoc/data_source.go +++ b/plugins/medianpoc/data_source.go @@ -11,13 +11,13 @@ import ( ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink-common/pkg/logger" - "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/core" "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/utils" ) type DataSource struct { - pipelineRunner types.PipelineRunnerService + pipelineRunner core.PipelineRunnerService spec string lggr logger.Logger @@ -32,13 +32,13 @@ func (d *DataSource) Observe(ctx context.Context, reportTimestamp ocrtypes.Repor } // NOTE: job metadata is automatically attached by the pipeline runner service - vars := types.Vars{ + vars := core.Vars{ Vars: map[string]interface{}{ "jobRun": md, }, } - results, err := d.pipelineRunner.ExecuteRun(ctx, d.spec, vars, types.Options{}) + results, err := d.pipelineRunner.ExecuteRun(ctx, d.spec, vars, core.Options{}) if err != nil { return nil, err } diff --git a/plugins/medianpoc/data_source_test.go b/plugins/medianpoc/data_source_test.go index e9d95b01b02..6680ad0e79c 100644 --- a/plugins/medianpoc/data_source_test.go +++ b/plugins/medianpoc/data_source_test.go @@ -15,18 +15,18 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/core" ) type mockPipelineRunner struct { - results types.TaskResults + results core.TaskResults err error spec string - vars types.Vars - options types.Options + vars core.Vars + options core.Options } -func (m *mockPipelineRunner) ExecuteRun(ctx context.Context, spec string, vars types.Vars, options types.Options) (types.TaskResults, error) { +func (m *mockPipelineRunner) ExecuteRun(ctx context.Context, spec string, vars core.Vars, options core.Options) (core.TaskResults, error) { m.spec = spec m.vars = vars m.options = options @@ -37,9 +37,9 @@ func TestDataSource(t *testing.T) { lggr := logger.TestLogger(t) expect := jsonserializable.JSONSerializable{Val: int64(3), Valid: true} pr := &mockPipelineRunner{ - results: types.TaskResults{ + results: core.TaskResults{ { - TaskValue: types.TaskValue{ + TaskValue: core.TaskValue{ Value: expect, Error: nil, IsTerminal: true, @@ -47,7 +47,7 @@ func TestDataSource(t *testing.T) { Index: 2, }, { - TaskValue: types.TaskValue{ + TaskValue: core.TaskValue{ Value: jsonserializable.JSONSerializable{Val: int64(4), Valid: true}, Error: nil, IsTerminal: false, @@ -73,9 +73,9 @@ func TestDataSource(t *testing.T) { func TestDataSource_ResultErrors(t *testing.T) { lggr := logger.TestLogger(t) pr := &mockPipelineRunner{ - results: types.TaskResults{ + results: core.TaskResults{ { - TaskValue: types.TaskValue{ + TaskValue: core.TaskValue{ Error: errors.New("something went wrong"), IsTerminal: true, }, @@ -98,9 +98,9 @@ func TestDataSource_ResultNotAnInt(t *testing.T) { expect := jsonserializable.JSONSerializable{Val: "string-result", Valid: true} pr := &mockPipelineRunner{ - results: types.TaskResults{ + results: core.TaskResults{ { - TaskValue: types.TaskValue{ + TaskValue: core.TaskValue{ Value: expect, IsTerminal: true, }, diff --git a/plugins/medianpoc/plugin.go b/plugins/medianpoc/plugin.go index 4f58cf0f3d6..b937361b9ec 100644 --- a/plugins/medianpoc/plugin.go +++ b/plugins/medianpoc/plugin.go @@ -13,6 +13,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/loop/reportingplugins" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/core" ) func NewPlugin(lggr logger.Logger) *Plugin { @@ -29,7 +30,7 @@ type Plugin struct { reportingplugins.MedianProviderServer } -func (p *Plugin) NewValidationService(ctx context.Context) (types.ValidationService, error) { +func (p *Plugin) NewValidationService(ctx context.Context) (core.ValidationService, error) { s := &reportingPluginValidationService{lggr: p.Logger} p.SubService(s) return s, nil @@ -59,12 +60,12 @@ func (j jsonConfig) getPipeline(key string) (string, error) { func (p *Plugin) NewReportingPluginFactory( ctx context.Context, - config types.ReportingPluginServiceConfig, + config core.ReportingPluginServiceConfig, provider types.MedianProvider, - pipelineRunner types.PipelineRunnerService, - telemetry types.TelemetryClient, - errorLog types.ErrorLog, - keyValueStore types.KeyValueStore, + pipelineRunner core.PipelineRunnerService, + telemetry core.TelemetryClient, + errorLog core.ErrorLog, + keyValueStore core.KeyValueStore, ) (types.ReportingPluginFactory, error) { f, err := p.newFactory(ctx, config, provider, pipelineRunner, telemetry, errorLog) if err != nil { @@ -75,7 +76,7 @@ func (p *Plugin) NewReportingPluginFactory( return s, nil } -func (p *Plugin) newFactory(ctx context.Context, config types.ReportingPluginServiceConfig, provider types.MedianProvider, pipelineRunner types.PipelineRunnerService, telemetry types.TelemetryClient, errorLog types.ErrorLog) (*median.NumericalMedianFactory, error) { +func (p *Plugin) newFactory(ctx context.Context, config core.ReportingPluginServiceConfig, provider types.MedianProvider, pipelineRunner core.PipelineRunnerService, telemetry core.TelemetryClient, errorLog core.ErrorLog) (*median.NumericalMedianFactory, error) { jc := &jsonConfig{} err := json.Unmarshal([]byte(config.PluginConfig), jc) if err != nil { diff --git a/plugins/medianpoc/plugin_test.go b/plugins/medianpoc/plugin_test.go index d4470eef70a..673c1fabc7d 100644 --- a/plugins/medianpoc/plugin_test.go +++ b/plugins/medianpoc/plugin_test.go @@ -11,13 +11,14 @@ import ( ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/core" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink/v2/core/logger" ) type mockErrorLog struct { - types.ErrorLog + core.ErrorLog } type mockOffchainConfigDigester struct { @@ -86,7 +87,7 @@ func TestNewPlugin(t *testing.T) { defaultSpec := "default-spec" juelsPerFeeCoinSpec := "jpfc-spec" - config := types.ReportingPluginServiceConfig{ + config := core.ReportingPluginServiceConfig{ PluginConfig: fmt.Sprintf( `{"pipelines": [{"name": "__DEFAULT_PIPELINE__", "spec": "%s"},{"name": "juelsPerFeeCoinPipeline", "spec": "%s"}]}`, defaultSpec, From 1c35398f4ea87febc6546143e53eb114e895d9ef Mon Sep 17 00:00:00 2001 From: Clement Date: Tue, 23 Apr 2024 12:45:58 +0200 Subject: [PATCH 02/77] feat(dashboard): add dashboard for core node components health (#12716) * feat(dashboard): add dashboard for core node components health * feat(dashboard): core_components cleanup code --- .../chainlink-cluster/dashboard/cmd/deploy.go | 13 +- .../core-node-components/component.go | 175 ++++++++++++++++++ .../core-node-components/platform.go | 29 +++ 3 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 dashboard-lib/core-node-components/component.go create mode 100644 dashboard-lib/core-node-components/platform.go diff --git a/charts/chainlink-cluster/dashboard/cmd/deploy.go b/charts/chainlink-cluster/dashboard/cmd/deploy.go index 24c3af4589b..6ee19b909a4 100644 --- a/charts/chainlink-cluster/dashboard/cmd/deploy.go +++ b/charts/chainlink-cluster/dashboard/cmd/deploy.go @@ -5,6 +5,7 @@ import ( lib "github.com/smartcontractkit/chainlink/dashboard-lib" atlas_don "github.com/smartcontractkit/chainlink/dashboard-lib/atlas-don" core_don "github.com/smartcontractkit/chainlink/dashboard-lib/core-don" + core_node_components "github.com/smartcontractkit/chainlink/dashboard-lib/core-node-components" k8spods "github.com/smartcontractkit/chainlink/dashboard-lib/k8s-pods" waspdb "github.com/smartcontractkit/wasp/dashboard" "strings" @@ -30,6 +31,16 @@ func main() { // TODO: refactor as a component later addWASPRows(db, cfg) } + if cfg.PanelsIncluded["core_components"] { + db.Add( + core_node_components.New( + core_node_components.Props{ + PrometheusDataSource: cfg.DataSources.Prometheus, + PlatformOpts: core_node_components.PlatformPanelOpts(), + }, + ), + ) + } if cfg.PanelsIncluded["ocr"] || cfg.PanelsIncluded["ocr2"] || cfg.PanelsIncluded["ocr3"] { for key := range cfg.PanelsIncluded { if strings.Contains(key, "ocr") { @@ -45,7 +56,7 @@ func main() { } } } - if cfg.Platform == "kubernetes" { + if !cfg.PanelsIncluded["core_components"] && cfg.Platform == "kubernetes" { db.Add( k8spods.New( k8spods.Props{ diff --git a/dashboard-lib/core-node-components/component.go b/dashboard-lib/core-node-components/component.go new file mode 100644 index 00000000000..47e23c073ba --- /dev/null +++ b/dashboard-lib/core-node-components/component.go @@ -0,0 +1,175 @@ +package core_node_components + +import ( + "github.com/K-Phoen/grabana/dashboard" + "github.com/K-Phoen/grabana/row" + "github.com/K-Phoen/grabana/stat" + "github.com/K-Phoen/grabana/table" + "github.com/K-Phoen/grabana/target/prometheus" + "github.com/K-Phoen/grabana/timeseries" + "github.com/K-Phoen/grabana/timeseries/axis" + "github.com/K-Phoen/grabana/variable/interval" + "github.com/K-Phoen/grabana/variable/query" +) + +type Props struct { + PrometheusDataSource string + PlatformOpts PlatformOpts +} + +func vars(p Props) []dashboard.Option { + return []dashboard.Option{ + dashboard.VariableAsInterval( + "interval", + interval.Values([]string{"30s", "1m", "5m", "15m", "30m", "1h", "6h", "12h"}), + interval.Default("15m"), + ), + dashboard.VariableAsQuery( + "env", + query.DataSource(p.PrometheusDataSource), + query.IncludeAll(), + query.Request("label_values(up, env)"), + query.Sort(query.NumericalAsc), + ), + dashboard.VariableAsQuery( + "cluster", + query.DataSource(p.PrometheusDataSource), + query.IncludeAll(), + query.Request(`label_values(up{env="$env"}, cluster)`), + query.Sort(query.NumericalAsc), + ), + dashboard.VariableAsQuery( + "blockchain", + query.DataSource(p.PrometheusDataSource), + query.IncludeAll(), + query.Request(`label_values(up{env="$env", cluster="$cluster"}, blockchain)`), + query.Sort(query.NumericalAsc), + ), + dashboard.VariableAsQuery( + "product", + query.DataSource(p.PrometheusDataSource), + query.IncludeAll(), + query.Request(`label_values(up{env="$env", cluster="$cluster", blockchain="$blockchain"}, product)`), + query.Sort(query.NumericalAsc), + ), + dashboard.VariableAsQuery( + "network_type", + query.DataSource(p.PrometheusDataSource), + query.IncludeAll(), + query.Request(`label_values(up{env="$env", cluster="$cluster", blockchain="$blockchain", product="$product"}, network_type)`), + query.Sort(query.NumericalAsc), + ), + dashboard.VariableAsQuery( + "component", + query.DataSource(p.PrometheusDataSource), + query.IncludeAll(), + query.Request(`label_values(up{env="$env", cluster="$cluster", blockchain="$blockchain", network_type="$network_type"}, component)`), + query.Sort(query.NumericalAsc), + ), + dashboard.VariableAsQuery( + "service", + query.DataSource(p.PrometheusDataSource), + query.IncludeAll(), + query.Request(`label_values(up{env="$env", cluster="$cluster", blockchain="$blockchain", network_type="$network_type", component="$component"}, service)`), + query.Sort(query.NumericalAsc), + ), + dashboard.VariableAsQuery( + "service_id", + query.DataSource(p.PrometheusDataSource), + query.Multiple(), + query.IncludeAll(), + query.Request(`label_values(health{env="$env", cluster="$cluster", blockchain="$blockchain", network_type="$network_type", component="$component", service="$service"}, service_id)`), + query.Sort(query.NumericalAsc), + ), + } +} + +func generalInfoRow(p Props) []dashboard.Option { + return []dashboard.Option{ + dashboard.Row( + "General CL Cluster Info", + row.WithTable( + "List Nodes", + table.Span(12), + table.HideColumn("Time"), + table.HideColumn("Value"), + table.DataSource(p.PrometheusDataSource), + table.WithPrometheusTarget( + `max(up{`+p.PlatformOpts.LabelQuery+`}) by (env, cluster, blockchain, product, network_type, network, version, team, component, service)`, + prometheus.Legend(""), + prometheus.Format("table"), + prometheus.Instant(), + ), + ), + row.WithTimeSeries( + "Uptime", + timeseries.Span(12), + timeseries.Height("200px"), + timeseries.DataSource(p.PrometheusDataSource), + timeseries.Axis( + axis.Max(1), + axis.Max(0), + axis.Unit("bool"), + axis.Label("Alive"), + ), + timeseries.WithPrometheusTarget( + `up{`+p.PlatformOpts.LabelQuery+`}`, + //prometheus.Legend(""), + prometheus.Legend("Team: {{team}} env: {{env}} cluster: {{cluster}} namespace: {{namespace}} job: {{job}} blockchain: {{blockchain}} product: {{product}} networkType: {{network_type}} component: {{component}} service: {{service}}"), + ), + ), + row.WithTimeSeries( + "Service Components Health by Service", + timeseries.Span(12), + timeseries.Height("200px"), + timeseries.DataSource(p.PrometheusDataSource), + timeseries.Legend(timeseries.ToTheRight), + timeseries.WithPrometheusTarget( + `health{`+p.PlatformOpts.LabelQuery+`service_id=~"${service_id}"}`, + prometheus.Legend("{{service_id}}"), + ), + ), + row.WithTimeSeries( + "Service Components Health Avg by Service", + timeseries.Span(12), + timeseries.Height("200px"), + timeseries.DataSource(p.PrometheusDataSource), + timeseries.Legend(timeseries.ToTheRight), + timeseries.WithPrometheusTarget( + `avg(avg_over_time(health{`+p.PlatformOpts.LabelQuery+`service_id=~"${service_id}"}[$interval])) by (service_id, version, service, cluster, env)`, + prometheus.Legend("{{service_id}}"), + ), + ), + row.WithStat( + "Service Components Health Avg by Service", + stat.Span(12), + stat.Height("200px"), + stat.DataSource(p.PrometheusDataSource), + stat.Text(stat.TextValueAndName), + stat.Orientation(stat.OrientationVertical), + stat.SparkLine(), + stat.TitleFontSize(8), + stat.ValueFontSize(12), + stat.WithPrometheusTarget( + `avg(avg_over_time(health{`+p.PlatformOpts.LabelQuery+`service_id=~"${service_id}"}[$interval])) by (service_id, version, service, cluster, env)`, + prometheus.Legend("{{service_id}}"), + ), + stat.AbsoluteThresholds([]stat.ThresholdStep{ + {Color: "#FF0000", Value: float64Ptr(0.0)}, + {Color: "#FF0000", Value: float64Ptr(0.8)}, + {Color: "#008000", Value: float64Ptr(1.0)}, + }), + ), + ), + } +} + +func New(p Props) []dashboard.Option { + opts := vars(p) + opts = append(opts, generalInfoRow(p)...) + return opts +} + +func float64Ptr(input float64) *float64 { + return &input +} diff --git a/dashboard-lib/core-node-components/platform.go b/dashboard-lib/core-node-components/platform.go new file mode 100644 index 00000000000..9d85cf82c77 --- /dev/null +++ b/dashboard-lib/core-node-components/platform.go @@ -0,0 +1,29 @@ +package core_node_components + +type PlatformOpts struct { + // Platform is infrastructure deployment platform: docker or k8s + Platform string + LabelFilters map[string]string + LabelFilter string + LegendString string + LabelQuery string +} + +// PlatformPanelOpts generate different queries for "docker" and "k8s" deployment platforms +func PlatformPanelOpts() PlatformOpts { + po := PlatformOpts{ + LabelFilters: map[string]string{ + "env": `=~"${env}"`, + "cluster": `=~"${cluster}"`, + "blockchain": `=~"${blockchain}"`, + "product": `=~"${product}"`, + "network_type": `=~"${network_type}"`, + "component": `=~"${component}"`, + "service": `=~"${service}"`, + }, + } + for key, value := range po.LabelFilters { + po.LabelQuery += key + value + ", " + } + return po +} From c48b61a23f6ec129ee0caaf663f11bf16b266de4 Mon Sep 17 00:00:00 2001 From: Ilja Pavlovs Date: Tue, 23 Apr 2024 16:22:24 +0300 Subject: [PATCH 03/77] =?UTF-8?q?VRF-1027:=20minor=20improvements=20in=20o?= =?UTF-8?q?rder=20to=20run=20VRF=20e2e=20test=20against=20exi=E2=80=A6=20(?= =?UTF-8?q?#12898)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * VRF-1027: minor improvements in order to run VRF e2e test against existing envs * VRF-1027: PR comments and tech debt fixes from Sonar * VRF-1027: fixing lint * VRF-1027: fixing tests --- .../actions/vrf/common/errors.go | 1 + .../actions/vrf/vrfv2/contract_steps.go | 3 +- .../actions/vrf/vrfv2plus/contract_steps.go | 111 ++++++------------ .../actions/vrf/vrfv2plus/setup_steps.go | 37 +++--- .../contracts/contract_vrf_models.go | 14 ++- integration-tests/go.mod | 2 +- integration-tests/smoke/vrfv2_test.go | 2 +- integration-tests/smoke/vrfv2plus_test.go | 53 ++++++--- .../testconfig/common/vrf/common.go | 11 +- integration-tests/testconfig/vrfv2/config.go | 9 +- .../testconfig/vrfv2/example.toml | 2 +- integration-tests/testconfig/vrfv2/vrfv2.toml | 2 +- .../testconfig/vrfv2plus/config.go | 23 ++-- .../testconfig/vrfv2plus/example.toml | 6 +- .../testconfig/vrfv2plus/vrfv2plus.toml | 16 +-- 15 files changed, 152 insertions(+), 140 deletions(-) diff --git a/integration-tests/actions/vrf/common/errors.go b/integration-tests/actions/vrf/common/errors.go index 287403ecfdf..f174609823f 100644 --- a/integration-tests/actions/vrf/common/errors.go +++ b/integration-tests/actions/vrf/common/errors.go @@ -1,6 +1,7 @@ package common const ( + ErrGenericFormat = "%s, err %w" ErrNodePrimaryKey = "error getting node's primary ETH key" ErrNodeNewTxKey = "error creating node's EVM transaction key" ErrCreatingProvingKeyHash = "error creating a keyHash from the proving key" diff --git a/integration-tests/actions/vrf/vrfv2/contract_steps.go b/integration-tests/actions/vrf/vrfv2/contract_steps.go index bd4535ebf77..fef780b695b 100644 --- a/integration-tests/actions/vrf/vrfv2/contract_steps.go +++ b/integration-tests/actions/vrf/vrfv2/contract_steps.go @@ -8,6 +8,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/rs/zerolog" + "github.com/shopspring/decimal" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" @@ -212,7 +213,7 @@ func SetupVRFV2Contracts( *vrfv2Config.MaxGasLimitCoordinatorConfig, *vrfv2Config.StalenessSeconds, *vrfv2Config.GasAfterPaymentCalculation, - big.NewInt(*vrfv2Config.FallbackWeiPerUnitLink), + decimal.RequireFromString(*vrfv2Config.FallbackWeiPerUnitLink).BigInt(), vrfCoordinatorV2FeeConfig, ) if err != nil { diff --git a/integration-tests/actions/vrf/vrfv2plus/contract_steps.go b/integration-tests/actions/vrf/vrfv2plus/contract_steps.go index 77937dd8de9..143b1e2cd9b 100644 --- a/integration-tests/actions/vrf/vrfv2plus/contract_steps.go +++ b/integration-tests/actions/vrf/vrfv2plus/contract_steps.go @@ -8,6 +8,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/rs/zerolog" + "github.com/shopspring/decimal" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" @@ -27,15 +28,15 @@ func DeployVRFV2_5Contracts( ) (*vrfcommon.VRFContracts, error) { bhs, err := contractDeployer.DeployBlockhashStore() if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrDeployBlockHashStore, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrDeployBlockHashStore, err) } err = chainClient.WaitForEvents() if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err) } batchBHS, err := contractDeployer.DeployBatchBlockhashStore(bhs.Address()) if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrDeployBatchBlockHashStore, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrDeployBatchBlockHashStore, err) } err = chainClient.WaitForEvents() if err != nil { @@ -43,11 +44,11 @@ func DeployVRFV2_5Contracts( } coordinator, err := contractDeployer.DeployVRFCoordinatorV2_5(bhs.Address()) if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrDeployCoordinator, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrDeployCoordinator, err) } err = chainClient.WaitForEvents() if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err) } return &vrfcommon.VRFContracts{ CoordinatorV2Plus: coordinator, @@ -62,7 +63,7 @@ func DeployVRFV2PlusConsumers(contractDeployer contracts.ContractDeployer, coord for i := 1; i <= consumerContractsAmount; i++ { loadTestConsumer, err := contractDeployer.DeployVRFv2PlusLoadTestConsumer(coordinator.Address()) if err != nil { - return nil, fmt.Errorf("%s, err %w", ErrAdvancedConsumer, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrAdvancedConsumer, err) } consumers = append(consumers, loadTestConsumer) } @@ -76,14 +77,14 @@ func VRFV2_5RegisterProvingKey( ) (vrfcommon.VRFEncodedProvingKey, error) { provingKey, err := actions.EncodeOnChainVRFProvingKey(*vrfKey) if err != nil { - return vrfcommon.VRFEncodedProvingKey{}, fmt.Errorf("%s, err %w", vrfcommon.ErrEncodingProvingKey, err) + return vrfcommon.VRFEncodedProvingKey{}, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrEncodingProvingKey, err) } err = coordinator.RegisterProvingKey( provingKey, gasLaneMaxGas, ) if err != nil { - return vrfcommon.VRFEncodedProvingKey{}, fmt.Errorf("%s, err %w", vrfcommon.ErrRegisterProvingKey, err) + return vrfcommon.VRFEncodedProvingKey{}, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrRegisterProvingKey, err) } return provingKey, nil } @@ -95,14 +96,14 @@ func VRFV2PlusUpgradedVersionRegisterProvingKey( ) (vrfcommon.VRFEncodedProvingKey, error) { provingKey, err := actions.EncodeOnChainVRFProvingKey(*vrfKey) if err != nil { - return vrfcommon.VRFEncodedProvingKey{}, fmt.Errorf("%s, err %w", vrfcommon.ErrEncodingProvingKey, err) + return vrfcommon.VRFEncodedProvingKey{}, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrEncodingProvingKey, err) } err = coordinator.RegisterProvingKey( provingKey, gasLaneMaxGasPrice, ) if err != nil { - return vrfcommon.VRFEncodedProvingKey{}, fmt.Errorf("%s, err %w", vrfcommon.ErrRegisterProvingKey, err) + return vrfcommon.VRFEncodedProvingKey{}, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrRegisterProvingKey, err) } return provingKey, nil } @@ -116,11 +117,11 @@ func FundVRFCoordinatorV2_5Subscription( ) error { encodedSubId, err := chainlinkutils.ABIEncode(`[{"type":"uint256"}]`, subscriptionID) if err != nil { - return fmt.Errorf("%s, err %w", vrfcommon.ErrABIEncodingFunding, err) + return fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrABIEncodingFunding, err) } _, err = linkToken.TransferAndCall(coordinator.Address(), linkFundingAmountJuels, encodedSubId) if err != nil { - return fmt.Errorf("%s, err %w", vrfcommon.ErrSendingLinkToken, err) + return fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrSendingLinkToken, err) } return chainClient.WaitForEvents() } @@ -169,7 +170,7 @@ func CreateFundSubsAndAddConsumers( err = evmClient.WaitForEvents() if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err) } return subIDs, nil } @@ -194,7 +195,7 @@ func CreateSubsAndFund( err = evmClient.WaitForEvents() if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err) } err = FundSubscriptions( env, @@ -237,7 +238,7 @@ func AddConsumersToSubs( for _, consumer := range consumers { err := coordinator.AddConsumer(subID, consumer.Address()) if err != nil { - return fmt.Errorf("%s, err %w", ErrAddConsumerToSub, err) + return fmt.Errorf(vrfcommon.ErrGenericFormat, ErrAddConsumerToSub, err) } } } @@ -247,7 +248,7 @@ func AddConsumersToSubs( func CreateSubAndFindSubID(env *test_env.CLClusterTestEnv, chainID int64, coordinator contracts.VRFCoordinatorV2_5) (*big.Int, error) { tx, err := coordinator.CreateSubscription() if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrCreateVRFSubscription, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrCreateVRFSubscription, err) } evmClient, err := env.GetEVMClient(chainID) if err != nil { @@ -255,12 +256,12 @@ func CreateSubAndFindSubID(env *test_env.CLClusterTestEnv, chainID int64, coordi } err = evmClient.WaitForEvents() if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err) } receipt, err := evmClient.GetTxReceipt(tx.Hash()) if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err) } //SubscriptionsCreated Log should be emitted with the subscription ID @@ -291,18 +292,18 @@ func FundSubscriptions( amountWei, ) if err != nil { - return fmt.Errorf("%s, err %w", ErrFundSubWithNativeToken, err) + return fmt.Errorf(vrfcommon.ErrGenericFormat, ErrFundSubWithNativeToken, err) } //Link Billing amountJuels := conversions.EtherToWei(subscriptionFundingAmountLink) err = FundVRFCoordinatorV2_5Subscription(linkAddress, coordinator, evmClient, subID, amountJuels) if err != nil { - return fmt.Errorf("%s, err %w", vrfcommon.ErrFundSubWithLinkToken, err) + return fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrFundSubWithLinkToken, err) } } err = evmClient.WaitForEvents() if err != nil { - return fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err) + return fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err) } return nil } @@ -310,11 +311,11 @@ func FundSubscriptions( func GetUpgradedCoordinatorTotalBalance(coordinator contracts.VRFCoordinatorV2PlusUpgradedVersion) (linkTotalBalance *big.Int, nativeTokenTotalBalance *big.Int, err error) { linkTotalBalance, err = coordinator.GetLinkTotalBalance(context.Background()) if err != nil { - return nil, nil, fmt.Errorf("%s, err %w", ErrLinkTotalBalance, err) + return nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrLinkTotalBalance, err) } nativeTokenTotalBalance, err = coordinator.GetNativeTokenTotalBalance(context.Background()) if err != nil { - return nil, nil, fmt.Errorf("%s, err %w", ErrNativeTokenBalance, err) + return nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrNativeTokenBalance, err) } return } @@ -322,11 +323,11 @@ func GetUpgradedCoordinatorTotalBalance(coordinator contracts.VRFCoordinatorV2Pl func GetCoordinatorTotalBalance(coordinator contracts.VRFCoordinatorV2_5) (linkTotalBalance *big.Int, nativeTokenTotalBalance *big.Int, err error) { linkTotalBalance, err = coordinator.GetLinkTotalBalance(context.Background()) if err != nil { - return nil, nil, fmt.Errorf("%s, err %w", ErrLinkTotalBalance, err) + return nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrLinkTotalBalance, err) } nativeTokenTotalBalance, err = coordinator.GetNativeTokenTotalBalance(context.Background()) if err != nil { - return nil, nil, fmt.Errorf("%s, err %w", ErrNativeTokenBalance, err) + return nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrNativeTokenBalance, err) } return } @@ -360,7 +361,7 @@ func RequestRandomness( *config.RandomnessRequestCountPerRequest, ) if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrRequestRandomness, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrRequestRandomness, err) } vrfcommon.LogRandomnessRequestedEvent(l, coordinator, randomWordsRequestedEvent, isNativeBilling) @@ -404,40 +405,6 @@ func RequestRandomnessAndWaitForFulfillment( } -//func RequestRandomnessAndWaitForFulfillmentUpgraded( -// consumer contracts.VRFv2PlusLoadTestConsumer, -// coordinator contracts.Coordinator, -// vrfKeyData *vrfcommon.VRFKeyData, -// subID *big.Int, -// isNativeBilling bool, -// config *vrfv2plus_config.General, -// l zerolog.Logger, -//) (*contracts.CoordinatorRandomWordsFulfilled, error) { -// -// randomWordsRequestedEvent, err := RequestRandomness( -// consumer, -// coordinator, -// vrfKeyData, -// subID, -// isNativeBilling, -// config, -// l, -// ) -// -// if err != nil { -// return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrRequestRandomness, err) -// } -// -// return WaitForRandomWordsFulfilledEventUpgraded( -// coordinator, -// randomWordsRequestedEvent.RequestId, -// subID, -// isNativeBilling, -// config.RandomWordsFulfilledEventTimeout.Duration, -// l, -// ) -//} - func DeployVRFV2PlusDirectFundingContracts( contractDeployer contracts.ContractDeployer, chainClient blockchain.EVMClient, @@ -450,11 +417,11 @@ func DeployVRFV2PlusDirectFundingContracts( vrfv2PlusWrapper, err := contractDeployer.DeployVRFV2PlusWrapper(linkTokenAddress, linkEthFeedAddress, coordinator.Address(), wrapperSubId) if err != nil { - return nil, fmt.Errorf("%s, err %w", ErrDeployWrapper, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrDeployWrapper, err) } err = chainClient.WaitForEvents() if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err) } consumers, err := DeployVRFV2PlusWrapperConsumers(contractDeployer, vrfv2PlusWrapper, consumerContractsAmount) @@ -463,7 +430,7 @@ func DeployVRFV2PlusDirectFundingContracts( } err = chainClient.WaitForEvents() if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err) } return &VRFV2PlusWrapperContracts{vrfv2PlusWrapper, consumers}, nil } @@ -489,7 +456,7 @@ func WrapperRequestRandomness(consumer contracts.VRFv2PlusWrapperLoadTestConsume *config.RandomnessRequestCountPerRequest, ) if err != nil { - return nil, "", fmt.Errorf("%s, err %w", ErrRequestRandomnessDirectFundingNativePayment, err) + return nil, "", fmt.Errorf(vrfcommon.ErrGenericFormat, ErrRequestRandomnessDirectFundingNativePayment, err) } } else { randomWordsRequestedEvent, err = consumer.RequestRandomness( @@ -500,7 +467,7 @@ func WrapperRequestRandomness(consumer contracts.VRFv2PlusWrapperLoadTestConsume *config.RandomnessRequestCountPerRequest, ) if err != nil { - return nil, "", fmt.Errorf("%s, err %w", ErrRequestRandomnessDirectFundingLinkPayment, err) + return nil, "", fmt.Errorf(vrfcommon.ErrGenericFormat, ErrRequestRandomnessDirectFundingLinkPayment, err) } } vrfcommon.LogRandomnessRequestedEvent(l, coordinator, randomWordsRequestedEvent, isNativeBilling) @@ -551,7 +518,7 @@ func WaitRandomWordsFulfilledEvent( }, ) if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitRandomWordsFulfilledEvent, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitRandomWordsFulfilledEvent, err) } vrfcommon.LogRandomWordsFulfilledEvent(l, coordinator, randomWordsFulfilledEvent, isNativeBilling) @@ -563,7 +530,7 @@ func DeployVRFV2PlusWrapperConsumers(contractDeployer contracts.ContractDeployer for i := 1; i <= consumerContractsAmount; i++ { loadTestConsumer, err := contractDeployer.DeployVRFV2PlusWrapperLoadTestConsumer(vrfV2PlusWrapper.Address()) if err != nil { - return nil, fmt.Errorf("%s, err %w", ErrAdvancedConsumer, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrAdvancedConsumer, err) } consumers = append(consumers, loadTestConsumer) } @@ -585,7 +552,7 @@ func SetupVRFV2PlusContracts( } vrfContracts, err := DeployVRFV2_5Contracts(env.ContractDeployer, evmClient) if err != nil { - return nil, fmt.Errorf("%s, err %w", ErrDeployVRFV2_5Contracts, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrDeployVRFV2_5Contracts, err) } vrfContracts.LinkToken = linkToken vrfContracts.MockETHLINKFeed = mockNativeLINKFeed @@ -596,24 +563,24 @@ func SetupVRFV2PlusContracts( *configGeneral.MaxGasLimitCoordinatorConfig, *configGeneral.StalenessSeconds, *configGeneral.GasAfterPaymentCalculation, - big.NewInt(*configGeneral.FallbackWeiPerUnitLink), + decimal.RequireFromString(*configGeneral.FallbackWeiPerUnitLink).BigInt(), *configGeneral.FulfillmentFlatFeeNativePPM, *configGeneral.FulfillmentFlatFeeLinkDiscountPPM, *configGeneral.NativePremiumPercentage, *configGeneral.LinkPremiumPercentage, ) if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrSetVRFCoordinatorConfig, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrSetVRFCoordinatorConfig, err) } l.Info().Str("Coordinator", vrfContracts.CoordinatorV2Plus.Address()).Msg("Setting Link and ETH/LINK feed") err = vrfContracts.CoordinatorV2Plus.SetLINKAndLINKNativeFeed(linkToken.Address(), mockNativeLINKFeed.Address()) if err != nil { - return nil, fmt.Errorf("%s, err %w", ErrSetLinkNativeLinkFeed, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrSetLinkNativeLinkFeed, err) } err = evmClient.WaitForEvents() if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err) } return vrfContracts, nil diff --git a/integration-tests/actions/vrf/vrfv2plus/setup_steps.go b/integration-tests/actions/vrf/vrfv2plus/setup_steps.go index f2e91f83ac6..0b7be600cc2 100644 --- a/integration-tests/actions/vrf/vrfv2plus/setup_steps.go +++ b/integration-tests/actions/vrf/vrfv2plus/setup_steps.go @@ -7,6 +7,7 @@ import ( "testing" "time" + "github.com/shopspring/decimal" "golang.org/x/sync/errgroup" "github.com/ethereum/go-ethereum/common" @@ -39,7 +40,7 @@ func CreateVRFV2PlusJob( } ost, err := os.String() if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrParseJob, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrParseJob, err) } job, err := chainlinkNode.MustCreateJob(&client.VRFV2PlusJobSpec{ @@ -57,7 +58,7 @@ func CreateVRFV2PlusJob( RequestTimeout: vrfJobSpecConfig.RequestTimeout, }) if err != nil { - return nil, fmt.Errorf("%s, err %w", ErrCreatingVRFv2PlusJob, err) + return nil, fmt.Errorf(vrfcommon.ErrGenericFormat, ErrCreatingVRFv2PlusJob, err) } return job, nil @@ -100,11 +101,11 @@ func SetupVRFV2_5Environment( l.Info().Str("Coordinator", vrfContracts.CoordinatorV2Plus.Address()).Msg("Registering Proving Key") provingKey, err := VRFV2_5RegisterProvingKey(vrfKey, vrfContracts.CoordinatorV2Plus, uint64(assets.GWei(*configGeneral.CLNodeMaxGasPriceGWei).Int64())) if err != nil { - return nil, nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrRegisteringProvingKey, err) + return nil, nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrRegisteringProvingKey, err) } keyHash, err := vrfContracts.CoordinatorV2Plus.HashOfKey(ctx, provingKey) if err != nil { - return nil, nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrCreatingProvingKeyHash, err) + return nil, nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrCreatingProvingKeyHash, err) } evmClient, err := env.GetEVMClient(chainID) @@ -124,7 +125,7 @@ func SetupVRFV2_5Environment( } err = evmClient.WaitForEvents() if err != nil { - return nil, nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err) + return nil, nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err) } nodeTypeToNodeMap[vrfcommon.VRF].TXKeyAddressStrings = vrfTXKeyAddressStrings @@ -219,7 +220,7 @@ func setupVRFNode(contracts *vrfcommon.VRFContracts, chainID *big.Int, config *v vrfJobSpecConfig, ) if err != nil { - return fmt.Errorf("%s, err %w", ErrCreateVRFV2PlusJobs, err) + return fmt.Errorf(vrfcommon.ErrGenericFormat, ErrCreateVRFV2PlusJobs, err) } vrfNode.Job = job @@ -233,7 +234,7 @@ func setupVRFNode(contracts *vrfcommon.VRFContracts, chainID *big.Int, config *v l.Info().Msg("Restarting Node with new sending key PriceMax configuration") err = vrfNode.CLNode.Restart(nodeConfig) if err != nil { - return fmt.Errorf("%s, err %w", vrfcommon.ErrRestartCLNode, err) + return fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrRestartCLNode, err) } return nil } @@ -278,7 +279,7 @@ func SetupVRFV2PlusWrapperEnvironment( err = evmClient.WaitForEvents() if err != nil { - return nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err) + return nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err) } // once the wrapper is deployed, wrapper address will become consumer of external EOA subscription @@ -289,23 +290,21 @@ func SetupVRFV2PlusWrapperEnvironment( err = evmClient.WaitForEvents() if err != nil { - return nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err) + return nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err) } - err = wrapperContracts.VRFV2PlusWrapper.SetConfig( *vrfv2PlusConfig.WrapperGasOverhead, *vrfv2PlusConfig.CoordinatorGasOverheadNative, *vrfv2PlusConfig.CoordinatorGasOverheadLink, *vrfv2PlusConfig.CoordinatorGasOverheadPerWord, - //todo - introduce separate config for Wrapper Premium Percentage - *vrfv2PlusConfig.NativePremiumPercentage, - *vrfv2PlusConfig.LinkPremiumPercentage, + *vrfv2PlusConfig.CoordinatorNativePremiumPercentage, + *vrfv2PlusConfig.CoordinatorLinkPremiumPercentage, keyHash, *vrfv2PlusConfig.WrapperMaxNumberOfWords, *vrfv2PlusConfig.StalenessSeconds, - big.NewInt(*vrfv2PlusConfig.FallbackWeiPerUnitLink), - *vrfv2PlusConfig.FulfillmentFlatFeeLinkPPM, + decimal.RequireFromString(*vrfv2PlusConfig.FallbackWeiPerUnitLink).BigInt(), *vrfv2PlusConfig.FulfillmentFlatFeeNativePPM, + *vrfv2PlusConfig.FulfillmentFlatFeeLinkDiscountPPM, ) if err != nil { return nil, nil, err @@ -313,7 +312,7 @@ func SetupVRFV2PlusWrapperEnvironment( err = evmClient.WaitForEvents() if err != nil { - return nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err) + return nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err) } //fund sub @@ -324,7 +323,7 @@ func SetupVRFV2PlusWrapperEnvironment( err = evmClient.WaitForEvents() if err != nil { - return nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err) + return nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err) } err = FundSubscriptions( @@ -350,7 +349,7 @@ func SetupVRFV2PlusWrapperEnvironment( } err = evmClient.WaitForEvents() if err != nil { - return nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err) + return nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err) } //fund consumer with Eth @@ -360,7 +359,7 @@ func SetupVRFV2PlusWrapperEnvironment( } err = evmClient.WaitForEvents() if err != nil { - return nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err) + return nil, nil, fmt.Errorf(vrfcommon.ErrGenericFormat, vrfcommon.ErrWaitTXsComplete, err) } return wrapperContracts, wrapperSubID, nil } diff --git a/integration-tests/contracts/contract_vrf_models.go b/integration-tests/contracts/contract_vrf_models.go index 2816c17d00c..aaccbad0602 100644 --- a/integration-tests/contracts/contract_vrf_models.go +++ b/integration-tests/contracts/contract_vrf_models.go @@ -171,7 +171,19 @@ type VRFV2Wrapper interface { type VRFV2PlusWrapper interface { Address() string - SetConfig(wrapperGasOverhead uint32, coordinatorGasOverheadNative uint32, coordinatorGasOverheadLink uint32, coordinatorGasOverheadPerWord uint16, wrapperNativePremiumPercentage uint8, wrapperLinkPremiumPercentage uint8, keyHash [32]byte, maxNumWords uint8, stalenessSeconds uint32, fallbackWeiPerUnitLink *big.Int, fulfillmentFlatFeeNativePPM uint32, fulfillmentFlatFeeLinkDiscountPPM uint32) error + SetConfig( + wrapperGasOverhead uint32, + coordinatorGasOverheadNative uint32, + coordinatorGasOverheadLink uint32, + coordinatorGasOverheadPerWord uint16, + wrapperNativePremiumPercentage uint8, + wrapperLinkPremiumPercentage uint8, + keyHash [32]byte, maxNumWords uint8, + stalenessSeconds uint32, + fallbackWeiPerUnitLink *big.Int, + fulfillmentFlatFeeNativePPM uint32, + fulfillmentFlatFeeLinkDiscountPPM uint32, + ) error GetSubID(ctx context.Context) (*big.Int, error) Coordinator(ctx context.Context) (common.Address, error) } diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 9c978bf69bd..e3afe782e95 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -22,6 +22,7 @@ require ( github.com/rs/zerolog v1.30.0 github.com/scylladb/go-reflectx v1.0.1 github.com/segmentio/ksuid v1.0.4 + github.com/shopspring/decimal v1.3.1 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.3 github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9 @@ -374,7 +375,6 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.23.12 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect - github.com/shopspring/decimal v1.3.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.10 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 // indirect diff --git a/integration-tests/smoke/vrfv2_test.go b/integration-tests/smoke/vrfv2_test.go index be29ba45182..77fe49f422d 100644 --- a/integration-tests/smoke/vrfv2_test.go +++ b/integration-tests/smoke/vrfv2_test.go @@ -772,7 +772,7 @@ func TestVRFOwner(t *testing.T) { require.Equal(t, *configCopy.VRFv2.General.MinimumConfirmations, coordinatorConfig.MinimumRequestConfirmations) require.Equal(t, *configCopy.VRFv2.General.FulfillmentFlatFeeLinkPPMTier1, coordinatorFeeConfig.FulfillmentFlatFeeLinkPPMTier1) require.Equal(t, *configCopy.VRFv2.General.ReqsForTier2, coordinatorFeeConfig.ReqsForTier2.Int64()) - require.Equal(t, *configCopy.VRFv2.General.FallbackWeiPerUnitLink, coordinatorFallbackWeiPerUnitLinkConfig.Int64()) + require.Equal(t, *configCopy.VRFv2.General.FallbackWeiPerUnitLink, coordinatorFallbackWeiPerUnitLinkConfig.String()) }) } diff --git a/integration-tests/smoke/vrfv2plus_test.go b/integration-tests/smoke/vrfv2plus_test.go index 20871a12b77..36fc9d5268d 100644 --- a/integration-tests/smoke/vrfv2plus_test.go +++ b/integration-tests/smoke/vrfv2plus_test.go @@ -105,9 +105,6 @@ func TestVRFv2Plus(t *testing.T) { subBalanceBeforeRequest := subscription.Balance - jobRunsBeforeTest, err := nodeTypeToNodeMap[vrfcommon.VRF].CLNode.API.MustReadRunsByJob(nodeTypeToNodeMap[vrfcommon.VRF].Job.Data.ID) - require.NoError(t, err, "error reading job runs") - // test and assert randomWordsFulfilledEvent, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment( consumers[0], @@ -130,10 +127,6 @@ func TestVRFv2Plus(t *testing.T) { subBalanceAfterRequest := subscription.Balance require.Equal(t, expectedSubBalanceJuels, subBalanceAfterRequest) - jobRuns, err := nodeTypeToNodeMap[vrfcommon.VRF].CLNode.API.MustReadRunsByJob(nodeTypeToNodeMap[vrfcommon.VRF].Job.Data.ID) - require.NoError(t, err, "error reading job runs") - require.Equal(t, len(jobRunsBeforeTest.Data)+1, len(jobRuns.Data)) - status, err := consumers[0].GetRequestStatus(testcontext.Get(t), randomWordsFulfilledEvent.RequestId) require.NoError(t, err, "error getting rand request status") require.True(t, status.Fulfilled) @@ -169,9 +162,6 @@ func TestVRFv2Plus(t *testing.T) { subNativeTokenBalanceBeforeRequest := subscription.NativeBalance - jobRunsBeforeTest, err := nodeTypeToNodeMap[vrfcommon.VRF].CLNode.API.MustReadRunsByJob(nodeTypeToNodeMap[vrfcommon.VRF].Job.Data.ID) - require.NoError(t, err, "error reading job runs") - // test and assert randomWordsFulfilledEvent, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment( consumers[0], @@ -192,10 +182,6 @@ func TestVRFv2Plus(t *testing.T) { subBalanceAfterRequest := subscription.NativeBalance require.Equal(t, expectedSubBalanceWei, subBalanceAfterRequest) - jobRuns, err := nodeTypeToNodeMap[vrfcommon.VRF].CLNode.API.MustReadRunsByJob(nodeTypeToNodeMap[vrfcommon.VRF].Job.Data.ID) - require.NoError(t, err, "error reading job runs") - require.Equal(t, len(jobRunsBeforeTest.Data)+1, len(jobRuns.Data)) - status, err := consumers[0].GetRequestStatus(testcontext.Get(t), randomWordsFulfilledEvent.RequestId) require.NoError(t, err, "error getting rand request status") require.True(t, status.Fulfilled) @@ -207,6 +193,45 @@ func TestVRFv2Plus(t *testing.T) { require.Equal(t, 1, w.Cmp(big.NewInt(0)), "Expected the VRF job give an answer bigger than 0") } }) + t.Run("CL Node VRF Job Runs", func(t *testing.T) { + configCopy := config.MustCopy().(tc.TestConfig) + var isNativeBilling = false + consumers, subIDsForRequestRandomness, err := vrfv2plus.SetupNewConsumersAndSubs( + env, + chainID, + vrfContracts.CoordinatorV2Plus, + configCopy, + vrfContracts.LinkToken, + 1, + 1, + l, + ) + require.NoError(t, err, "error setting up new consumers and subs") + subIDForRequestRandomness := subIDsForRequestRandomness[0] + subscription, err := vrfContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subIDForRequestRandomness) + require.NoError(t, err, "error getting subscription information") + vrfcommon.LogSubDetails(l, subscription, subIDForRequestRandomness.String(), vrfContracts.CoordinatorV2Plus) + subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDsForRequestRandomness...) + + jobRunsBeforeTest, err := nodeTypeToNodeMap[vrfcommon.VRF].CLNode.API.MustReadRunsByJob(nodeTypeToNodeMap[vrfcommon.VRF].Job.Data.ID) + require.NoError(t, err, "error reading job runs") + + // test and assert + _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillment( + consumers[0], + vrfContracts.CoordinatorV2Plus, + vrfKey, + subIDForRequestRandomness, + isNativeBilling, + configCopy.VRFv2Plus.General, + l, + ) + require.NoError(t, err, "error requesting randomness and waiting for fulfilment") + + jobRuns, err := nodeTypeToNodeMap[vrfcommon.VRF].CLNode.API.MustReadRunsByJob(nodeTypeToNodeMap[vrfcommon.VRF].Job.Data.ID) + require.NoError(t, err, "error reading job runs") + require.Equal(t, len(jobRunsBeforeTest.Data)+1, len(jobRuns.Data)) + }) t.Run("Direct Funding (VRFV2PlusWrapper)", func(t *testing.T) { configCopy := config.MustCopy().(tc.TestConfig) wrapperContracts, wrapperSubID, err := vrfv2plus.SetupVRFV2PlusWrapperEnvironment( diff --git a/integration-tests/testconfig/common/vrf/common.go b/integration-tests/testconfig/common/vrf/common.go index d7c2bc805db..a5b4078f429 100644 --- a/integration-tests/testconfig/common/vrf/common.go +++ b/integration-tests/testconfig/common/vrf/common.go @@ -142,7 +142,7 @@ type General struct { NumberOfWords *uint32 `toml:"number_of_words"` // Number of words to request CallbackGasLimit *uint32 `toml:"callback_gas_limit"` // Gas limit for the callback MaxGasLimitCoordinatorConfig *uint32 `toml:"max_gas_limit_coordinator_config"` // Max gas limit for the VRF Coordinator config - FallbackWeiPerUnitLink *int64 `toml:"fallback_wei_per_unit_link"` // Fallback wei per unit LINK for the VRF Coordinator config + FallbackWeiPerUnitLink *string `toml:"fallback_wei_per_unit_link"` // Fallback wei per unit LINK for the VRF Coordinator config StalenessSeconds *uint32 `toml:"staleness_seconds"` // Staleness in seconds for the VRF Coordinator config GasAfterPaymentCalculation *uint32 `toml:"gas_after_payment_calculation"` // Gas after payment calculation for the VRF Coordinator @@ -156,8 +156,9 @@ type General struct { WaitFor256BlocksTimeout *blockchain.StrDuration `toml:"wait_for_256_blocks_timeout"` // How long to wait for 256 blocks to be mined // Wrapper Config - WrapperGasOverhead *uint32 `toml:"wrapped_gas_overhead"` - WrapperMaxNumberOfWords *uint8 `toml:"wrapper_max_number_of_words"` + WrapperGasOverhead *uint32 `toml:"wrapped_gas_overhead"` + WrapperMaxNumberOfWords *uint8 `toml:"wrapper_max_number_of_words"` + WrapperConsumerFundingAmountNativeToken *float64 `toml:"wrapper_consumer_funding_amount_native_token"` WrapperConsumerFundingAmountLink *int64 `toml:"wrapper_consumer_funding_amount_link"` @@ -211,8 +212,8 @@ func (c *General) Validate() error { if c.MaxGasLimitCoordinatorConfig == nil || *c.MaxGasLimitCoordinatorConfig == 0 { return errors.New("max_gas_limit_coordinator_config must be set to a positive value") } - if c.FallbackWeiPerUnitLink == nil || *c.FallbackWeiPerUnitLink == 0 { - return errors.New("fallback_wei_per_unit_link must be set to a positive value") + if c.FallbackWeiPerUnitLink == nil { + return errors.New("fallback_wei_per_unit_link must be set") } if c.StalenessSeconds == nil || *c.StalenessSeconds == 0 { return errors.New("staleness_seconds must be set to a positive value") diff --git a/integration-tests/testconfig/vrfv2/config.go b/integration-tests/testconfig/vrfv2/config.go index 96e6dfbe45a..76d54a45d5b 100644 --- a/integration-tests/testconfig/vrfv2/config.go +++ b/integration-tests/testconfig/vrfv2/config.go @@ -72,10 +72,8 @@ type General struct { ReqsForTier3 *int64 `toml:"reqs_for_tier_3"` ReqsForTier4 *int64 `toml:"reqs_for_tier_4"` ReqsForTier5 *int64 `toml:"reqs_for_tier_5"` - - // Wrapper Config - CoordinatorGasOverhead *uint32 `toml:"coordinator_gas_overhead"` - WrapperPremiumPercentage *uint8 `toml:"wrapper_premium_percentage"` + CoordinatorGasOverhead *uint32 `toml:"coordinator_gas_overhead"` + WrapperPremiumPercentage *uint8 `toml:"wrapper_premium_percentage"` } func (c *General) Validate() error { @@ -112,11 +110,10 @@ func (c *General) Validate() error { return errors.New("reqs_for_tier_5 must be set to a non-negative value") } if c.CoordinatorGasOverhead == nil || *c.CoordinatorGasOverhead == 0 { - return errors.New("coordinator_gas_overhead_link must be set to a non-negative value") + return errors.New("coordinator_gas_overhead must be set to a non-negative value") } if c.WrapperPremiumPercentage == nil || *c.WrapperPremiumPercentage == 0 { return errors.New("wrapper_premium_percentage must be set to a positive value") } - return nil } diff --git a/integration-tests/testconfig/vrfv2/example.toml b/integration-tests/testconfig/vrfv2/example.toml index 53d0888f6d4..8a8139b92d4 100644 --- a/integration-tests/testconfig/vrfv2/example.toml +++ b/integration-tests/testconfig/vrfv2/example.toml @@ -84,7 +84,7 @@ subscription_funding_amount_link = 5.0 number_of_words = 3 callback_gas_limit = 1000000 max_gas_limit_coordinator_config = 2500000 -fallback_wei_per_unit_link = 60000000000000000 +fallback_wei_per_unit_link = "60000000000000000" staleness_seconds = 86400 gas_after_payment_calculation = 33825 fulfilment_flat_fee_link_ppm_tier_1 = 500 diff --git a/integration-tests/testconfig/vrfv2/vrfv2.toml b/integration-tests/testconfig/vrfv2/vrfv2.toml index 6d92e2fd6b0..012352f49b8 100644 --- a/integration-tests/testconfig/vrfv2/vrfv2.toml +++ b/integration-tests/testconfig/vrfv2/vrfv2.toml @@ -16,7 +16,7 @@ minimum_confirmations = 3 number_of_words = 3 callback_gas_limit = 1000000 max_gas_limit_coordinator_config = 2500000 -fallback_wei_per_unit_link = 60000000000000000 +fallback_wei_per_unit_link = "60000000000000000" staleness_seconds = 86400 gas_after_payment_calculation = 33825 fulfilment_flat_fee_link_ppm_tier_1 = 500 diff --git a/integration-tests/testconfig/vrfv2plus/config.go b/integration-tests/testconfig/vrfv2plus/config.go index 8655cb4334f..eb5ba061984 100644 --- a/integration-tests/testconfig/vrfv2plus/config.go +++ b/integration-tests/testconfig/vrfv2plus/config.go @@ -45,15 +45,16 @@ type General struct { SubscriptionFundingAmountNative *float64 `toml:"subscription_funding_amount_native"` // Amount of LINK to fund the subscription with SubscriptionRefundingAmountNative *float64 `toml:"subscription_refunding_amount_native"` // Amount of LINK to fund the subscription with FulfillmentFlatFeeNativePPM *uint32 `toml:"fulfillment_flat_fee_native_ppm"` // Flat fee in ppm for native currency for the VRF Coordinator config - FulfillmentFlatFeeLinkPPM *uint32 `toml:"fulfillment_flat_fee_link_ppm"` // Flat fee in ppm for LINK for the VRF Coordinator config FulfillmentFlatFeeLinkDiscountPPM *uint32 `toml:"fulfillment_flat_fee_link_discount_ppm"` // Flat fee discount in ppm for LINK for the VRF Coordinator config NativePremiumPercentage *uint8 `toml:"native_premium_percentage"` // Native Premium Percentage LinkPremiumPercentage *uint8 `toml:"link_premium_percentage"` // LINK Premium Percentage - // Wrapper Config - CoordinatorGasOverheadNative *uint32 `toml:"coordinator_gas_overhead_native"` - CoordinatorGasOverheadLink *uint32 `toml:"coordinator_gas_overhead_link"` - CoordinatorGasOverheadPerWord *uint16 `toml:"coordinator_gas_overhead_per_word"` + //Wrapper config + CoordinatorGasOverheadPerWord *uint16 `toml:"coordinator_gas_overhead_per_word"` + CoordinatorGasOverheadNative *uint32 `toml:"coordinator_gas_overhead_native"` + CoordinatorGasOverheadLink *uint32 `toml:"coordinator_gas_overhead_link"` + CoordinatorNativePremiumPercentage *uint8 `toml:"coordinator_native_premium_percentage"` + CoordinatorLinkPremiumPercentage *uint8 `toml:"coordinator_link_premium_percentage"` } func (c *General) Validate() error { @@ -72,9 +73,6 @@ func (c *General) Validate() error { if c.FulfillmentFlatFeeNativePPM == nil { return errors.New("fulfillment_flat_fee_native_ppm must not be nil") } - if c.FulfillmentFlatFeeLinkPPM == nil { - return errors.New("fulfillment_flat_fee_link_ppm must not be nil") - } if c.FulfillmentFlatFeeLinkDiscountPPM == nil { return errors.New("fulfillment_flat_fee_link_discount_ppm must not be nil") } @@ -84,12 +82,21 @@ func (c *General) Validate() error { if c.LinkPremiumPercentage == nil { return errors.New("link_premium_percentage must not be nil") } + if c.CoordinatorGasOverheadPerWord == nil { + return errors.New("coordinator_gas_overhead_per_word must not be nil") + } if c.CoordinatorGasOverheadNative == nil || *c.CoordinatorGasOverheadNative == 0 { return errors.New("coordinator_gas_overhead_native must be set to a non-negative value") } if c.CoordinatorGasOverheadLink == nil || *c.CoordinatorGasOverheadLink == 0 { return errors.New("coordinator_gas_overhead_link must be set to a non-negative value") } + if c.CoordinatorNativePremiumPercentage == nil { + return errors.New("coordinator_native_premium_percentage must not be nil") + } + if c.CoordinatorLinkPremiumPercentage == nil { + return errors.New("coordinator_link_premium_percentage must not be nil") + } return nil } diff --git a/integration-tests/testconfig/vrfv2plus/example.toml b/integration-tests/testconfig/vrfv2plus/example.toml index a0db80bdc2f..76fe23a2e70 100644 --- a/integration-tests/testconfig/vrfv2plus/example.toml +++ b/integration-tests/testconfig/vrfv2plus/example.toml @@ -85,7 +85,7 @@ subscription_funding_amount_link = 5.0 number_of_words = 3 callback_gas_limit = 1000000 max_gas_limit_coordinator_config = 2500000 -fallback_wei_per_unit_link = 60000000000000000 +fallback_wei_per_unit_link = "60000000000000000" staleness_seconds = 86400 gas_after_payment_calculation = 33825 fulfilment_flat_fee_link_ppm_tier_1 = 500 @@ -102,14 +102,14 @@ randomness_request_count_per_request = 1 randomness_request_count_per_request_deviation = 0 random_words_fulfilled_event_timeout = "2m" wrapped_gas_overhead = 50000 -coordinator_gas_overhead = 52000 +coordinator_gas_overhead_native = 52000 +coordinator_gas_overhead_link = 74000 coordinator_gas_overhead_per_word = 440 wrapper_premium_percentage = 25 wrapper_max_number_of_words = 10 wrapper_consumer_funding_amount_native_token = 1.0 wrapper_consumer_funding_amount_link = 10 subscription_funding_amount_native=1 -fulfillment_flat_fee_link_ppm=500 fulfillment_flat_fee_native_ppm=500 fulfillment_flat_fee_link_discount_ppm=100 native_premium_percentage=1 diff --git a/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml b/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml index 1382dbc09eb..902ca3a2966 100644 --- a/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml +++ b/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml @@ -20,7 +20,7 @@ subscription_billing_type = "LINK_AND_NATIVE" number_of_words = 3 callback_gas_limit = 1000000 max_gas_limit_coordinator_config = 2500000 -fallback_wei_per_unit_link = 60000000000000000 +fallback_wei_per_unit_link = "60000000000000000" staleness_seconds = 86400 gas_after_payment_calculation = 33825 number_of_sub_to_create = 1 @@ -29,19 +29,21 @@ randomness_request_count_per_request = 1 randomness_request_count_per_request_deviation = 0 random_words_fulfilled_event_timeout = "2m" wait_for_256_blocks_timeout = "10m" + +fulfillment_flat_fee_native_ppm=0 +fulfillment_flat_fee_link_discount_ppm=0 +native_premium_percentage=24 +link_premium_percentage=20 + wrapped_gas_overhead = 50000 coordinator_gas_overhead_native = 52000 coordinator_gas_overhead_link = 74000 coordinator_gas_overhead_per_word = 440 -wrapper_premium_percentage = 25 wrapper_max_number_of_words = 10 wrapper_consumer_funding_amount_native_token = 1.0 wrapper_consumer_funding_amount_link = 10 -fulfillment_flat_fee_link_ppm=500 -fulfillment_flat_fee_native_ppm=500 -fulfillment_flat_fee_link_discount_ppm=100 -native_premium_percentage=1 -link_premium_percentage=1 +coordinator_native_premium_percentage=24 +coordinator_link_premium_percentage=20 # VRF Job config vrf_job_forwarding_allowed = false From 566fdc43e043e34f258e627583fb3b653d8bed29 Mon Sep 17 00:00:00 2001 From: Radek Scheibinger Date: Tue, 23 Apr 2024 15:44:26 +0200 Subject: [PATCH 04/77] Decouple crib config from cl-cluster helm chart (#12877) --- .gitignore | 1 + charts/chainlink-cluster/README.md | 156 +----------------- .../chainlink-cluster => crib}/.env.example | 0 crib/README.md | 156 ++++++++++++++++++ .../dashboard/cmd/delete.go | 0 .../dashboard/cmd/deploy.go | 0 .../chainlink-cluster => crib}/devspace.yaml | 4 +- .../devspace_start.sh | 0 {charts/chainlink-cluster => crib}/go.mod | 2 +- {charts/chainlink-cluster => crib}/go.sum | 0 .../scripts/ingress_check.sh | 0 {charts/chainlink-cluster => crib}/setup.sh | 0 dashboard-lib/README.md | 2 +- integration-tests/load/ocr/README.md | 2 +- 14 files changed, 165 insertions(+), 158 deletions(-) rename {charts/chainlink-cluster => crib}/.env.example (100%) create mode 100644 crib/README.md rename {charts/chainlink-cluster => crib}/dashboard/cmd/delete.go (100%) rename {charts/chainlink-cluster => crib}/dashboard/cmd/deploy.go (100%) rename {charts/chainlink-cluster => crib}/devspace.yaml (99%) rename {charts/chainlink-cluster => crib}/devspace_start.sh (100%) rename {charts/chainlink-cluster => crib}/go.mod (95%) rename {charts/chainlink-cluster => crib}/go.sum (100%) rename {charts/chainlink-cluster => crib}/scripts/ingress_check.sh (100%) rename {charts/chainlink-cluster => crib}/setup.sh (100%) diff --git a/.gitignore b/.gitignore index bcd526fbc43..0a938ff9123 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ tools/clroot/db.sqlite3-wal .env* .dbenv !charts/chainlink-cluster/.env.example +!crib/.env.example !.github/actions/setup-postgres/.env .direnv .idea diff --git a/charts/chainlink-cluster/README.md b/charts/chainlink-cluster/README.md index a0a4b8a78cc..b76d55090dd 100644 --- a/charts/chainlink-cluster/README.md +++ b/charts/chainlink-cluster/README.md @@ -2,112 +2,9 @@ Example CL nodes cluster for system level tests -Install `kubefwd` (no nixpkg for it yet, planned) - -``` -brew install txn2/tap/kubefwd -``` - -If you want to build images you need [docker](https://docs.docker.com/engine/install/) service running - -Enter the shell (from the root project dir) - -``` -nix develop -``` - # Develop - -## New cluster - -We are using [devspace](https://www.devspace.sh/docs/getting-started/installation?x0=3) - -Configure the cluster, see `deployments.app.helm.values` and [values.yaml](./values.yaml) comments for more details - -Set up your K8s access - -``` -export DEVSPACE_IMAGE="..." -./setup.sh ${my-personal-namespace-name-crib} -``` - -Create a .env file based on the .env.sample file - -```sh -cp .env.sample .env -# Fill in the required values in .env -``` - -Build and deploy the current state of your repository - -``` -devspace deploy -``` - -Default `ttl` is `72h`, use `ttl` command to update if you need more time - -Valid values are `1h`, `2m`, `3s`, etc. Go time format is invalid `1h2m3s` - -``` -devspace run ttl ${namespace} 120h -``` - -If you want to deploy an image tag that is already available in ECR, use: - -``` -devspace deploy --override-image-tag "" -``` - -If you want to deploy an image tag from a public ECR repo, use: - -``` -export DEVSPACE_IMAGE=public.ecr.aws/chainlink/chainlink -devspace deploy --override-image-tag 2.9.0 -``` - -Forward ports to check UI or run tests - -``` -devspace run connect ${my-personal-namespace-name-crib} -``` - -List ingress hostnames - -``` -devspace run ingress-hosts -``` - -Destroy the cluster - -``` -devspace purge -``` - -## Running load tests - -Check this [doc](../../integration-tests/load/ocr/README.md) - -If you used `devspace dev ...` always use `devspace reset pods` to switch the pods back - -# Helm - -If you would like to use `helm` directly, please uncomment data in `values.yaml` - -## Install from local files - -``` -helm install -f values.yaml cl-cluster . -``` - -Forward all apps (in another terminal) - -``` -sudo kubefwd svc -n cl-cluster -``` - -Then you can connect and run your tests - ## Install from release +Note: The setup below doesn't work at the moment. Add the repository @@ -130,6 +27,7 @@ helm install -f values.yaml cl-cluster . ``` ## Create a new release +Note: The setup below doesn't work at the moment. Bump version in `Chart.yml` add your changes and add `helm_release` label to any PR to trigger a release @@ -143,52 +41,4 @@ helm test cl-cluster ``` helm uninstall cl-cluster -``` - -# Grafana dashboard - -We are using [Grabana](https://github.com/K-Phoen/grabana) lib to create dashboards programmatically - -You can also select dashboard platform in `INFRA_PLATFORM` either `kubernetes` or `docker` - -You can select the dashboard panels with `PANELS_INCLUDED` which is a list of panel names separated by comma -If you don't specify it will include core panels by default - -``` -export LOKI_TENANT_ID=promtail -export LOKI_URL=... -export GRAFANA_URL=... -export GRAFANA_TOKEN=... -export PROMETHEUS_DATA_SOURCE_NAME=Thanos -export LOKI_DATA_SOURCE_NAME=Loki -export INFRA_PLATFORM=kubernetes -export GRAFANA_FOLDER=DashboardCoreDebug -export DASHBOARD_NAME=CL-Cluster - -devspace run dashboard_deploy -``` - -Open Grafana folder `DashboardCoreDebug` and find dashboard `ChainlinkClusterDebug` - -# Testing - -Deploy your dashboard and run soak/load [tests](../../integration-tests/load/), check [README](../../integration-tests/README.md) for further explanations - -``` -devspace run dashboard_deploy -devspace run workload -devspace run dashboard_test -``` - -# Local Testing - -Go to [dashboard-lib](../../dashboard) and link the modules locally - -``` -cd dashboard -pnpm link --global -cd charts/chainlink-cluster/dashboard/tests -pnpm link --global dashboard-tests -``` - -Then run the tests with commands mentioned above +``` \ No newline at end of file diff --git a/charts/chainlink-cluster/.env.example b/crib/.env.example similarity index 100% rename from charts/chainlink-cluster/.env.example rename to crib/.env.example diff --git a/crib/README.md b/crib/README.md new file mode 100644 index 00000000000..c9106d401cd --- /dev/null +++ b/crib/README.md @@ -0,0 +1,156 @@ +# Crib Devspace Setup + +CRIB is a devspace configuration to launch chainlink cluster for system level tests + +Install `kubefwd` (no nixpkg for it yet, planned) + +``` +brew install txn2/tap/kubefwd +``` + +If you want to build images you need [docker](https://docs.docker.com/engine/install/) service running + +Enter the shell (from the root project dir) + +``` +nix develop +``` + +# Develop + +## New cluster + +We are using [devspace](https://www.devspace.sh/docs/getting-started/installation?x0=3) + +Configure the cluster, see `deployments.app.helm.values` and [values.yaml](../charts/chainlink-cluster/values.yaml) comments for more details + +Set up your K8s access + +``` +export DEVSPACE_IMAGE="..." +./setup.sh ${my-personal-namespace-name-crib} +``` + +Create a .env file based on the .env.sample file + +```sh +cp .env.sample .env +# Fill in the required values in .env +``` + +Build and deploy the current state of your repository + +``` +devspace deploy +``` + +Default `ttl` is `72h`, use `ttl` command to update if you need more time + +Valid values are `1h`, `2m`, `3s`, etc. Go time format is invalid `1h2m3s` + +``` +devspace run ttl ${namespace} 120h +``` + +If you want to deploy an image tag that is already available in ECR, use: + +``` +devspace deploy --override-image-tag "" +``` + +If you want to deploy an image tag from a public ECR repo, use: + +``` +export DEVSPACE_IMAGE=public.ecr.aws/chainlink/chainlink +devspace deploy --override-image-tag 2.9.0 +``` + +Forward ports to check UI or run tests + +``` +devspace run connect ${my-personal-namespace-name-crib} +``` + +List ingress hostnames + +``` +devspace run ingress-hosts +``` + +Destroy the cluster + +``` +devspace purge +``` + +## Running load tests + +Check this [doc](../../integration-tests/load/ocr/README.md) + +If you used `devspace dev ...` always use `devspace reset pods` to switch the pods back + +# Helm + +If you would like to use `helm` directly, please uncomment data in `values.yaml` + +## Install from local files + +``` +helm install -f values.yaml cl-cluster . +``` + +Forward all apps (in another terminal) + +``` +sudo kubefwd svc -n cl-cluster +``` + +Then you can connect and run your tests + +# Grafana dashboard + +We are using [Grabana](https://github.com/K-Phoen/grabana) lib to create dashboards programmatically + +You can also select dashboard platform in `INFRA_PLATFORM` either `kubernetes` or `docker` + +You can select the dashboard panels with `PANELS_INCLUDED` which is a list of panel names separated by comma +If you don't specify it will include core panels by default + +``` +export LOKI_TENANT_ID=promtail +export LOKI_URL=... +export GRAFANA_URL=... +export GRAFANA_TOKEN=... +export PROMETHEUS_DATA_SOURCE_NAME=Thanos +export LOKI_DATA_SOURCE_NAME=Loki +export INFRA_PLATFORM=kubernetes +export GRAFANA_FOLDER=DashboardCoreDebug +export DASHBOARD_NAME=CL-Cluster + +devspace run dashboard_deploy +``` + +Open Grafana folder `DashboardCoreDebug` and find dashboard `ChainlinkClusterDebug` + +# Testing + +Deploy your dashboard and run soak/load [tests](../../integration-tests/load/), check [README](../../integration-tests/README.md) for further explanations + +``` +devspace run dashboard_deploy +devspace run workload +devspace run dashboard_test +``` + +# Local Testing + +Go to [dashboard-lib](../dashboard-lib) and link the modules locally + +``` +cd dashboard +pnpm link --global +cd crib/dashboard/tests +pnpm link --global dashboard-tests +``` + +Then run the tests with commands mentioned above diff --git a/charts/chainlink-cluster/dashboard/cmd/delete.go b/crib/dashboard/cmd/delete.go similarity index 100% rename from charts/chainlink-cluster/dashboard/cmd/delete.go rename to crib/dashboard/cmd/delete.go diff --git a/charts/chainlink-cluster/dashboard/cmd/deploy.go b/crib/dashboard/cmd/deploy.go similarity index 100% rename from charts/chainlink-cluster/dashboard/cmd/deploy.go rename to crib/dashboard/cmd/deploy.go diff --git a/charts/chainlink-cluster/devspace.yaml b/crib/devspace.yaml similarity index 99% rename from charts/chainlink-cluster/devspace.yaml rename to crib/devspace.yaml index d46e28572bb..ca12e1ed205 100644 --- a/charts/chainlink-cluster/devspace.yaml +++ b/crib/devspace.yaml @@ -52,7 +52,7 @@ commands: ttl: |- kubectl label namespace $1 cleanup.kyverno.io/ttl=$2 --overwrite workload: |- - cd ../../integration-tests/load/ocr && go test -v -run TestOCRLoad || cd - + cd ../integration-tests/load/ocr && go test -v -run TestOCRLoad || cd - dashboard_deploy: |- go run dashboard/cmd/deploy.go dashboard_test: |- @@ -98,7 +98,7 @@ deployments: releaseName: "app" chart: name: cl-cluster - path: . + path: ../charts/chainlink-cluster # for simplicity, we define all the values here # they can be defined the same way in values.yml # devspace merges these "values" with the "values.yaml" before deploy diff --git a/charts/chainlink-cluster/devspace_start.sh b/crib/devspace_start.sh similarity index 100% rename from charts/chainlink-cluster/devspace_start.sh rename to crib/devspace_start.sh diff --git a/charts/chainlink-cluster/go.mod b/crib/go.mod similarity index 95% rename from charts/chainlink-cluster/go.mod rename to crib/go.mod index 4a8dd43fd5f..28bcaece757 100644 --- a/charts/chainlink-cluster/go.mod +++ b/crib/go.mod @@ -34,5 +34,5 @@ replace ( github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f github.com/sercand/kuberesolver/v4 => github.com/sercand/kuberesolver/v5 v5.1.1 - github.com/smartcontractkit/chainlink/dashboard-lib => ../../dashboard-lib + github.com/smartcontractkit/chainlink/dashboard-lib => ./../dashboard-lib ) diff --git a/charts/chainlink-cluster/go.sum b/crib/go.sum similarity index 100% rename from charts/chainlink-cluster/go.sum rename to crib/go.sum diff --git a/charts/chainlink-cluster/scripts/ingress_check.sh b/crib/scripts/ingress_check.sh similarity index 100% rename from charts/chainlink-cluster/scripts/ingress_check.sh rename to crib/scripts/ingress_check.sh diff --git a/charts/chainlink-cluster/setup.sh b/crib/setup.sh similarity index 100% rename from charts/chainlink-cluster/setup.sh rename to crib/setup.sh diff --git a/dashboard-lib/README.md b/dashboard-lib/README.md index 44fd655c72a..ee8fa66a7c7 100644 --- a/dashboard-lib/README.md +++ b/dashboard-lib/README.md @@ -16,7 +16,7 @@ dashboard Each component should contain rows, logic and unique variables in `component.go` -Components should be imported from this module, see [example](../charts/chainlink-cluster/dashboard/cmd/deploy.go) +Components should be imported from this module, see [example](../crib/dashboard/cmd/deploy.go) ## How to convert from JSON using Grabana codegen utility 1. Download Grabana binary [here](https://github.com/K-Phoen/grabana/releases) diff --git a/integration-tests/load/ocr/README.md b/integration-tests/load/ocr/README.md index 61951ba700f..e63828a7d93 100644 --- a/integration-tests/load/ocr/README.md +++ b/integration-tests/load/ocr/README.md @@ -13,7 +13,7 @@ sudo kubefwd svc -n cl-cluster Change environment connection configuration [here](../../../charts/chainlink-cluster/connect.toml) -If you haven't changed anything in [devspace.yaml](../../../charts/chainlink-cluster/devspace.yaml) then default connection configuration will work +If you haven't changed anything in [devspace.yaml](../../crib/devspace.yaml) then default connection configuration will work ## Usage From 8efaa2fbf1da59ee82f10b4ce58afc9cc9f645c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deividas=20Kar=C5=BEinauskas?= Date: Tue, 23 Apr 2024 18:05:02 +0300 Subject: [PATCH 05/77] Style guide updates (#12928) * Add Interfaces Purpose rule * Grammarly fixes --- contracts/STYLE_GUIDE.md | 64 ++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/contracts/STYLE_GUIDE.md b/contracts/STYLE_GUIDE.md index 212cd979e39..b9294de5765 100644 --- a/contracts/STYLE_GUIDE.md +++ b/contracts/STYLE_GUIDE.md @@ -6,11 +6,11 @@ Rules are all enforced through CI, this can be through Solhint rules or other to ## Background -Our starting point is the [official Solidity Style Guide](https://docs.soliditylang.org/en/v0.8.21/style-guide.html) and [ConsenSys's Secure Development practices](https://consensys.github.io/smart-contract-best-practices/), but we deviate in some ways. We lean heavily on [Prettier](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/.prettierrc) for formatting, and if you have to set up a new Solidity project we recommend starting with [our prettier config](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/.prettierrc). We are trying to automate as much of this styleguide with Solhint as possible. +Our starting point is the [official Solidity Style Guide](https://docs.soliditylang.org/en/v0.8.21/style-guide.html) and [ConsenSys's Secure Development practices](https://consensys.github.io/smart-contract-best-practices/), but we deviate in some ways. We lean heavily on [Prettier](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/.prettierrc) for formatting, and if you have to set up a new Solidity project we recommend starting with [our prettier config](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/.prettierrc). We are trying to automate as much of this style guide with Solhint as possible. -This guide is not meant to be applied retroactively. There is no need to rewrite existing code to adhere to this guide, and when making (small) changes in existing files, it is not required to do so in accordance to this guide if it would conflict with other practices in that existing file. Consistency is preferred. +This guide is not meant to be applied retroactively. There is no need to rewrite existing code to adhere to this guide, and when making (small) changes in existing files, it is not required to adhere to this guide if it conflicts with other practices in that existing file. Consistency is preferred. -We will be looking into `forge fmt`, but for now we still use `prettier`. +We will be looking into `forge fmt`, but for now, we still use `prettier`. # Guidelines @@ -22,17 +22,17 @@ We will be looking into `forge fmt`, but for now we still use `prettier`. ### Delineate Unaudited Code -- In a large repo it is worthwhile to keep code that has not yet been audited separate from the code that has been audited. This allows you to easily keep track of which files need to be reviewed. - - E.g. we keep unaudited code in a directory named `dev` that exists within each projects folder. Only once it has been audited we move the audited files out of `dev` and only then is it considered safe to deploy. +- In a large repo, it is worthwhile to keep code that has not yet been audited separately from the code that has been audited. This allows you to easily keep track of which files need to be reviewed. + - E.g. we keep unaudited code in a directory named `dev` that exists within each project's folder. Only once it has been audited we move the audited files out of `dev` and only then is it considered safe to deploy. - This `dev` folder also has implications for when code is valid for bug bounties, so be extra careful to move functionality out of a `dev` folder. -## comments -- Besides comment above functions/structs, comments should live everywhere a reader might be confused. +## Comments +- Besides comments above functions and structs, comments should live everywhere a reader might be confused. Don’t overestimate the reader of your contract, expect confusion in many places and document accordingly. This will help massively during audits and onboarding new team members. -- Headers should be used to group functionality, the following header style and length is recommended. - - Don’t use headers for a single function, or to say “getters”. Group by functionality e.g. the `Tokens and pools` , or `fees` logic within the CCIP OnRamp. +- Headers should be used to group functionality, the following header style and length are recommended. + - Don’t use headers for a single function, or to say “getters”. Group by functionality e.g. the `Tokens and pools`, or `fees` logic within the CCIP OnRamp. ```solidity // ================================================================ @@ -48,7 +48,7 @@ We will be looking into `forge fmt`, but for now we still use `prettier`. ## Variables -- Function arguments are named like this: `argumentName`. No leading or trailing underscores necessary. +- Function arguments are named like this: `argumentName`. No leading or trailing underscores are necessary. - Names should be explicit on the unit it contains, e.g. a network fee that is charged in USD cents ```solidity @@ -64,11 +64,11 @@ uint256 networkFeeUSDCents; // good ### Structs -- Structs should contain struct packing comments to clearly indicate the storage slot layout +- Structs should contain struct packing comments to indicate the storage slot layout - Using the exact characters from the example below will ensure visually appealing struct packing comments. - Notice there is no line on the unpacked last `fee` item. - Struct should contain comments, clearly indicating the denomination of values e.g. 0.01 USD if the variable name doesn’t already do that (which it should). - - Simple tool that could help packing structs and adding comments: https://github.com/RensR/Spack + - A simple tool that could help with packing structs and adding comments: https://github.com/RensR/Spack ```solidity /// @dev Struct to hold the fee configuration for a fee token, same as the FeeTokenConfig but with @@ -98,13 +98,13 @@ struct FeeTokenConfigArgs { ### Return Values - If an address is cast as a contract type, return the type, do not cast back to the address type. - This prevents the consumer of the method signature from having to cast again, but presents an equivalent API for off-chain APIs. + This prevents the consumer of the method signature from having to cast again but presents an equivalent API for off-chain APIs. Additionally, it is a more declarative API, providing more context if we return a type. ## Modifiers - Only extract a modifier once a check is duplicated in multiple places. Modifiers arguably hurt readability, so we have found that they are not worth extracting until there is duplication. -- Modifiers should be treated as if they are view functions. They should not change state, only read it. While it is possible to change state in a modifier, it is unconventional and surprising. +- Modifiers should be treated as if they are view functions. They should not change state, only read it. While it is possible to change the state in a modifier, it is unconventional and surprising. - Modifiers tend to bloat contract size because the code is duplicated wherever the modifier is used. ## Events @@ -146,7 +146,7 @@ assembly { return (success, retData); ``` -This will cost slightly more gas to copy the response into memory, but will ultimately make contract usage more understandable and easier to debug. Whether it is worth the extra gas is a judgement call you’ll have to make based on your needs. +This will cost slightly more gas to copy the response into memory, but will ultimately make contract usage more understandable and easier to debug. Whether it is worth the extra gas is a judgment call you’ll have to make based on your needs. The original error will not be human-readable in an off-chain explorer because it is RLP hex encoded but is easily decoded with standard Solidity ABI decoding tools, or a hex to UTF-8 converter and some basic ABI knowledge. @@ -158,13 +158,13 @@ The original error will not be human-readable in an off-chain explorer because i ## Dependencies - Prefer not reinventing the wheel, especially if there is an Openzeppelin wheel. -- The `shared` folder can be treated as a first party dependency and it is recommend to check if some functionality might already be in there before either writing it yourself or adding a third party dependency. +- The `shared` folder can be treated as a first-party dependency and it is recommended to check if some functionality might already be in there before either writing it yourself or adding a third party dependency. - When we have reinvented the wheel already (like with ownership), it is OK to keep using these contracts. If there are clear benefits of using another standard like OZ, we can deprecate the custom implementation and start using the new standard in all new projects. Migration will not be required unless there are serious issues with the old implementation. - When the decision is made to use a new standard, it is no longer allowed to use the old standard for new projects. ### Vendor dependencies -- That’s it, vendor your Solidity dependencies. Supply chain attacks are all the rage these days. There is not yet a silver bullet for best way to vendor, it depends on the size of your project and your needs. You should be as explicit as possible about where the code comes from and make sure that this is enforced in some way; e.g. reference a hash. Some options: +- That’s it, vendor your Solidity dependencies. Supply chain attacks are all the rage these days. There is not yet a silver bullet for the best way to vendor, it depends on the size of your project and your needs. You should be as explicit as possible about where the code comes from and make sure that this is enforced in some way; e.g. reference a hash. Some options: - NPM packages work for repos already in the JavaScript ecosystem. If you go this route you should lock to a hash of the repo or use a proxy registry like GitHub Packages. - Copy and paste the code into a `vendor` directory. Record attribution of the code and license in the repo along with the commit or version that you pulled the code from. - Foundry uses git submodules for its dependencies. We only use the `forge-std` lib through submodules, we don’t import any non-Foundry-testing code through this method. @@ -174,7 +174,7 @@ The original error will not be human-readable in an off-chain explorer because i ### Transferring Ownership -- When transferring control, whether it is of a token or a role in a contract, prefer "safe ownership" transfer patterns where the recipient must accept ownership. This avoids accidentally burning the control. This is also inline with the secure pattern of [prefer pull over push](https://consensys.github.io/smart-contract-best-practices/recommendations/#favor-pull-over-push-for-external-calls). +- When transferring control, whether it is of a token or a role in a contract, prefer "safe ownership" transfer patterns where the recipient must accept ownership. This avoids accidentally burning the control. This is also in line with the secure pattern of [prefer pull over push](https://consensys.github.io/smart-contract-best-practices/recommendations/#favor-pull-over-push-for-external-calls). ### Call with Exact Gas @@ -192,7 +192,7 @@ The original error will not be human-readable in an off-chain explorer because i - Calling other contracts will also be costly - Common types to safely use are - uint40 for timestamps (or uint32 if you really need the space) - - uint96 for link, as there are only 1b link tokens + - uint96 for LINK, as there are only 1b LINK tokens - prefer `++i` over `i++` - If you’re unsure about golfing, ask in the #tech-solidity channel @@ -214,13 +214,13 @@ The original error will not be human-readable in an off-chain explorer because i ## Picking a Pragma -- If a contract or library is expected to be imported by outside parties then the pragma should be kept as loose as possible without sacrificing safety. We publish versions for every minor semver version of Solidity, and maintain a corresponding set of tests for each published version. +- If a contract or library is expected to be imported by outside parties then the pragma should be kept as loose as possible without sacrificing safety. We publish versions for every minor Semver version of Solidity and maintain a corresponding set of tests for each published version. - Examples: libraries, interfaces, abstract contracts, and contracts expected to be inherited from -- Otherwise, Solidity contracts should have a pragma which is locked to a specific version. +- Otherwise, Solidity contracts should have a pragma that is locked to a specific version. - Example: Most concrete contracts. -- Avoid changing pragmas after audit. Unless there is a bug that has affects your contract, then you should try to stick to a known good pragma. In practice this means we typically only support one (occasionally two) pragma for any “major”(minor by semver naming) Solidity version. +- Avoid changing pragmas after the audit. Unless there is a bug that affects your contract, then you should try to stick to a known good pragma. In practice, this means we typically only support one (occasionally two) pragma for any “major”(minor by Semver naming) Solidity version. - The current advised pragma is `0.8.19` or higher, lower versions should be avoided when starting a new project. Newer versions can be considered. -- All contracts should have a SPDX license identifier. If unsure about which one to pick, please consult with legal. Most older contracts have been MIT, but some of the newer products have been using BUSL-1.1 +- All contracts should have an SPDX license identifier. If unsure about which one to pick, please consult with legal. Most older contracts have been MIT, but some of the newer products have been using BUSL-1.1 ## Versioning @@ -262,7 +262,7 @@ contract SuperDuperAggregator is ITypeAndVersion { All contracts will expose a `typeAndVersion` constant. The string has the following format: `-` with the `-dev` part only being applicable to contracts that have not been fully released. -Try to fit it into 32 bytes to keep impact on contract sizes minimal. +Try to fit it into 32 bytes to keep the impact on contract sizes minimal. Solhint will complain about a public constant variable that isn’t FULL_CAPS without the solhint-disable comment. @@ -276,12 +276,12 @@ Solhint will complain about a public constant variable that isn’t FULL_CAPS wi # Rules -All rules have a `rule` tag which indicated how the rule is enforced. +All rules have a `rule` tag which indicates how the rule is enforced. ## Comments -- Comments should be in the `//` (default) or `///` (natspec) format, not the `/* */` format. +- Comments should be in the `//` (default) or `///` (Natspec) format, not the `/* */` format. - rule: `tbd` - Comments should follow [NatSpec](https://docs.soliditylang.org/en/latest/natspec-format.html) - rule: `tbd` @@ -290,7 +290,7 @@ All rules have a `rule` tag which indicated how the rule is enforced. - Imports should always be explicit - rule: `no-global-import` -- Imports have follow the following format: +- Imports have to follow the following format: - rule: `tbd` ```solidity @@ -321,7 +321,7 @@ import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ All contract variables should be private by default. Getters should be explicitly written and documented when you want to expose a variable publicly. Whether a getter function reads from storage, a constant, or calculates a value from somewhere else, that’s all implementation details that should not be exposed to the consumer by casing or other conventions. -rule: tbd +rule: `tbd` ### Naming and Casing @@ -380,6 +380,14 @@ rule: `gas-custom-errors` ## Interfaces +### Purpose + +Interfaces separate NatSpec from contract logic, requiring readers to do more work to understand the code. For this reason, you shouldn’t create an interface by default. + +If created, interfaces should have a documented purpose. For example, an interface is useful if 3rd party on-chain contracts will interact with your contract. CCIP’s [`IRouterClient` interface](https://github.com/smartcontractkit/ccip/blob/ccip-develop/contracts/src/v0.8/ccip/interfaces/IRouterClient.sol) is a good example here. + +### Naming + Interfaces should be named `IFoo` instead of `FooInterface`. This follows the patterns of popular [libraries like OpenZeppelin’s](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol#L9). rule: `interface-starts-with-i` From 394844e5e5dab89e8196803f9d7feb590a0bb973 Mon Sep 17 00:00:00 2001 From: Lei Date: Tue, 23 Apr 2024 08:48:51 -0700 Subject: [PATCH 06/77] Enumberable set cleanup (#12885) * support decimals * address comments * properly cleanup the enumberable set * add unit test and remove in reverse order --- .changeset/sour-needles-collect.md | 5 ++ contracts/.changeset/hungry-days-occur.md | 5 ++ .../dev/test/AutomationRegistry2_3.t.sol | 76 +++++++++++++++---- .../dev/v2_3/AutomationRegistry2_3.sol | 4 +- .../dev/v2_3/AutomationRegistryLogicC2_3.sol | 5 +- .../automation_registry_wrapper_2_3.go | 2 +- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 7 files changed, 81 insertions(+), 18 deletions(-) create mode 100644 .changeset/sour-needles-collect.md create mode 100644 contracts/.changeset/hungry-days-occur.md diff --git a/.changeset/sour-needles-collect.md b/.changeset/sour-needles-collect.md new file mode 100644 index 00000000000..5d1ae86fd7c --- /dev/null +++ b/.changeset/sour-needles-collect.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +cleanup set #bugfix diff --git a/contracts/.changeset/hungry-days-occur.md b/contracts/.changeset/hungry-days-occur.md new file mode 100644 index 00000000000..ca1a703a472 --- /dev/null +++ b/contracts/.changeset/hungry-days-occur.md @@ -0,0 +1,5 @@ +--- +"@chainlink/contracts": patch +--- + +set cleanup #bugfix diff --git a/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol b/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol index 4d2cfbbec36..19e1cdc7460 100644 --- a/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol +++ b/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol @@ -5,7 +5,7 @@ import {Vm} from "forge-std/Test.sol"; import {BaseTest} from "./BaseTest.t.sol"; import {AutomationRegistryBase2_3 as AutoBase} from "../v2_3/AutomationRegistryBase2_3.sol"; import {AutomationRegistrar2_3 as Registrar} from "../v2_3/AutomationRegistrar2_3.sol"; -import {IAutomationRegistryMaster2_3 as Registry, AutomationRegistryBase2_3} from "../interfaces/v2_3/IAutomationRegistryMaster2_3.sol"; +import {IAutomationRegistryMaster2_3 as Registry, AutomationRegistryBase2_3, IAutomationV21PlusCommon} from "../interfaces/v2_3/IAutomationRegistryMaster2_3.sol"; import {ChainModuleBase} from "../../chains/ChainModuleBase.sol"; import {IERC20Metadata as IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import {IWrappedNative} from "../interfaces/v2_3/IWrappedNative.sol"; @@ -334,6 +334,7 @@ contract SetConfig is SetUp { ); address module = address(new ChainModuleBase()); + AutomationRegistryBase2_3.OnchainConfig cfg = AutomationRegistryBase2_3.OnchainConfig({ checkGasLimit: 5_000_000, @@ -347,7 +348,7 @@ contract SetConfig is SetUp { fallbackLinkPrice: 2_000_000_000, // $20 fallbackNativePrice: 400_000_000_000, // $4,000 transcoder: 0xB1e66855FD67f6e85F0f0fA38cd6fBABdf00923c, - registrars: new address[](0), + registrars: _getRegistrars(), upkeepPrivilegeManager: PRIVILEGE_MANAGER, chainModule: module, reorgProtectionEnabled: true, @@ -507,8 +508,22 @@ contract SetConfig is SetUp { decimals: 18 }); + // the first time uses the default onchain config with 2 registrars bytes memory onchainConfigBytesWithBilling1 = abi.encode(cfg, billingTokens1, billingConfigs1); + // set config once + registry.setConfig( + SIGNERS, + TRANSMITTERS, + F, + onchainConfigBytesWithBilling1, + OFFCHAIN_CONFIG_VERSION, + offchainConfigBytes + ); + + (, IAutomationV21PlusCommon.OnchainConfigLegacy memory onchainConfig1, , , ) = registry.getState(); + assertEq(onchainConfig1.registrars.length, 2); + // BillingConfig2 address billingTokenAddress2 = address(usdToken18); address[] memory billingTokens2 = new address[](1); @@ -524,17 +539,33 @@ contract SetConfig is SetUp { decimals: 18 }); - bytes memory onchainConfigBytesWithBilling2 = abi.encode(cfg, billingTokens2, billingConfigs2); + address[] memory newRegistrars = new address[](3); + newRegistrars[0] = address(uint160(uint256(keccak256("newRegistrar1")))); + newRegistrars[1] = address(uint160(uint256(keccak256("newRegistrar2")))); + newRegistrars[2] = address(uint160(uint256(keccak256("newRegistrar3")))); - // set config once - registry.setConfig( - SIGNERS, - TRANSMITTERS, - F, - onchainConfigBytesWithBilling1, - OFFCHAIN_CONFIG_VERSION, - offchainConfigBytes - ); + // new onchain config with 3 new registrars, all other fields stay the same as the default + AutomationRegistryBase2_3.OnchainConfig memory cfg2 = AutomationRegistryBase2_3.OnchainConfig({ + checkGasLimit: 5_000_000, + stalenessSeconds: 90_000, + gasCeilingMultiplier: 0, + maxPerformGas: 10_000_000, + maxCheckDataSize: 5_000, + maxPerformDataSize: 5_000, + maxRevertDataSize: 5_000, + fallbackGasPrice: 20_000_000_000, + fallbackLinkPrice: 2_000_000_000, // $20 + fallbackNativePrice: 400_000_000_000, // $4,000 + transcoder: 0xB1e66855FD67f6e85F0f0fA38cd6fBABdf00923c, + registrars: newRegistrars, + upkeepPrivilegeManager: PRIVILEGE_MANAGER, + chainModule: module, + reorgProtectionEnabled: true, + financeAdmin: FINANCE_ADMIN + }); + + // the second time uses the new onchain config with 3 new registrars and also new billing tokens/configs + bytes memory onchainConfigBytesWithBilling2 = abi.encode(cfg2, billingTokens2, billingConfigs2); // set config twice registry.setConfig( @@ -546,8 +577,18 @@ contract SetConfig is SetUp { offchainConfigBytes ); - (, , address[] memory signers, address[] memory transmitters, uint8 f) = registry.getState(); - + ( + , + IAutomationV21PlusCommon.OnchainConfigLegacy memory onchainConfig2, + address[] memory signers, + address[] memory transmitters, + uint8 f + ) = registry.getState(); + + assertEq(onchainConfig2.registrars.length, 3); + for (uint256 i = 0; i < newRegistrars.length; i++) { + assertEq(newRegistrars[i], onchainConfig2.registrars[i]); + } assertEq(signers, SIGNERS); assertEq(transmitters, TRANSMITTERS); assertEq(f, F); @@ -766,6 +807,13 @@ contract SetConfig is SetUp { assertEq(transmitters, NEW_TRANSMITTERS); } + function _getRegistrars() private pure returns (address[] memory) { + address[] memory registrars = new address[](2); + registrars[0] = address(uint160(uint256(keccak256("registrar1")))); + registrars[1] = address(uint160(uint256(keccak256("registrar2")))); + return registrars; + } + function _configDigestFromConfigData( uint256 chainId, address contractAddress, diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistry2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistry2_3.sol index c95c2138f71..93d3376a4f6 100644 --- a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistry2_3.sol +++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistry2_3.sol @@ -355,7 +355,9 @@ contract AutomationRegistry2_3 is AutomationRegistryBase2_3, OCR2Abstract, Chain offchainConfig ); - delete s_registrars; + for (uint256 idx = s_registrars.length(); idx > 0; idx--) { + s_registrars.remove(s_registrars.at(idx - 1)); + } for (uint256 idx = 0; idx < onchainConfig.registrars.length; idx++) { s_registrars.add(onchainConfig.registrars[idx]); diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicC2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicC2_3.sol index 0a429730bdb..546c85454f7 100644 --- a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicC2_3.sol +++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicC2_3.sol @@ -184,7 +184,10 @@ contract AutomationRegistryLogicC2_3 is AutomationRegistryBase2_3 { payments[i + activeTransmittersLength] = transmitter.balance; s_transmitters[deactivatedAddr].balance = 0; } - delete s_deactivatedTransmitters; + + for (uint256 idx = s_deactivatedTransmitters.length(); idx > 0; idx--) { + s_deactivatedTransmitters.remove(s_deactivatedTransmitters.at(idx - 1)); + } emit NOPsSettledOffchain(payees, payments); } diff --git a/core/gethwrappers/generated/automation_registry_wrapper_2_3/automation_registry_wrapper_2_3.go b/core/gethwrappers/generated/automation_registry_wrapper_2_3/automation_registry_wrapper_2_3.go index d648604895b..1edcb07dc6f 100644 --- a/core/gethwrappers/generated/automation_registry_wrapper_2_3/automation_registry_wrapper_2_3.go +++ b/core/gethwrappers/generated/automation_registry_wrapper_2_3/automation_registry_wrapper_2_3.go @@ -65,7 +65,7 @@ type AutomationRegistryBase23OnchainConfig struct { var AutomationRegistryMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicA2_3\",\"name\":\"logicA\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLinkLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFeed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOffchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOnchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyFinanceAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"overrides\",\"type\":\"tuple\"}],\"name\":\"BillingConfigOverridden\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"BillingConfigOverrideRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contractIERC20Metadata\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"BillingConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeesWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"payments\",\"type\":\"uint256[]\"}],\"name\":\"NOPsSettledOffchain\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfigBytes\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"financeAdmin\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackNativePrice\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"contractIChainModule\",\"name\":\"chainModule\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"contractIERC20Metadata[]\",\"name\":\"billingTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig[]\",\"name\":\"billingConfigs\",\"type\":\"tuple[]\"}],\"name\":\"setConfigTypeSafe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101806040523480156200001257600080fd5b50604051620065e2380380620065e283398101604081905262000035916200062f565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b91906200062f565b826001600160a01b031663226cf83c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200010091906200062f565b836001600160a01b031663614486af6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016591906200062f565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca91906200062f565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f91906200062f565b866001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029491906200062f565b876001600160a01b031663c5b964e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f9919062000656565b886001600160a01b031663ac4dc59a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000338573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200035e91906200062f565b3380600081620003b55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620003e857620003e8816200056b565b5050506001600160a01b0380891660805287811660a05286811660c05285811660e052848116610100528316610120526025805483919060ff19166001838181111562000439576200043962000679565b0217905550806001600160a01b0316610140816001600160a01b03168152505060c0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200049a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004c091906200068f565b60ff1660a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200052a91906200068f565b60ff16146200054c576040516301f86e1760e41b815260040160405180910390fd5b5050506001600160a01b039095166101605250620006b4945050505050565b336001600160a01b03821603620005c55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620003ac565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200062c57600080fd5b50565b6000602082840312156200064257600080fd5b81516200064f8162000616565b9392505050565b6000602082840312156200066957600080fd5b8151600281106200064f57600080fd5b634e487b7160e01b600052602160045260246000fd5b600060208284031215620006a257600080fd5b815160ff811681146200064f57600080fd5b60805160a05160c05160e05161010051610120516101405161016051615eae620007346000396000818160be015261019101526000505060005050600050506000505060006139a301526000505060008181610db101528181610ebf01528181610fea01528181611034015281816116b601526130ce0152615eae6000f3fe6080604052600436106100bc5760003560e01c80638da5cb5b11610074578063b1dc65a41161004e578063b1dc65a4146102f6578063e3d0e71214610316578063f2fde38b14610336576100bc565b80638da5cb5b14610265578063a4c0ed3614610290578063afcb95d7146102b0576100bc565b8063349e8cca116100a5578063349e8cca1461018257806379ba5097146101d657806381ff7048146101eb576100bc565b80630870d3a114610103578063181f5a7714610123575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e8080156100fc573d6000f35b3d6000fd5b005b34801561010f57600080fd5b5061010161011e366004614c23565b610356565b34801561012f57600080fd5b5061016c6040518060400160405280601881526020017f4175746f6d6174696f6e526567697374727920322e332e30000000000000000081525081565b6040516101799190614d9f565b60405180910390f35b34801561018e57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610179565b3480156101e257600080fd5b50610101610c97565b3480156101f757600080fd5b5061024260175460135463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610179565b34801561027157600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166101b1565b34801561029c57600080fd5b506101016102ab366004614dfb565b610d99565b3480156102bc57600080fd5b50601354601454604080516000815260208101939093526c0100000000000000000000000090910463ffffffff1690820152606001610179565b34801561030257600080fd5b50610101610311366004614e9c565b6110b5565b34801561032257600080fd5b50610101610331366004614f53565b611396565b34801561034257600080fd5b50610101610351366004615020565b6113d0565b61035e6113e4565b601f8851111561039a576040517f25d0209c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560ff166000036103d7576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b865188511415806103f657506103ee866003615073565b60ff16885111155b1561042d576040517f1d2d1c5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051825114610468576040517fcf54c06a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104728282611467565b61047c8888611a9f565b604051806101200160405280601460000160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff168152602001600063ffffffff1681526020018660a0015162ffffff16815260200186610120015161ffff1681526020018760ff168152602001601460000160169054906101000a900460ff1615158152602001601460000160179054906101000a900460ff1615158152602001866080015115158152602001866101e0015173ffffffffffffffffffffffffffffffffffffffff16815250601460008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160106101000a81548162ffffff021916908362ffffff16021790555060608201518160000160136101000a81548161ffff021916908361ffff16021790555060808201518160000160156101000a81548160ff021916908360ff16021790555060a08201518160000160166101000a81548160ff02191690831515021790555060c08201518160000160176101000a81548160ff02191690831515021790555060e08201518160000160186101000a81548160ff0219169083151502179055506101008201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050604051806101600160405280866060015173ffffffffffffffffffffffffffffffffffffffff168152602001866000015163ffffffff168152602001866020015163ffffffff1681526020016016600001601c9054906101000a900463ffffffff1663ffffffff16815260200186610100015173ffffffffffffffffffffffffffffffffffffffff168152602001601660010160149054906101000a900463ffffffff1663ffffffff168152602001601660010160189054906101000a900463ffffffff1663ffffffff168152602001866040015163ffffffff16815260200186610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018660c0015163ffffffff1681526020018660e0015163ffffffff16815250601660008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160186101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060a08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101208201518160020160146101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160186101000a81548163ffffffff021916908363ffffffff160217905550905050846101600151601981905550846101800151601a81905550846101a00151601b819055506000601660010160189054906101000a900463ffffffff169050856101e0015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa6919061508f565b601780547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000063ffffffff9384160217808255600192601491610b1d918591740100000000000000000000000000000000000000009004166150a8565b92506101000a81548163ffffffff021916908363ffffffff160217905550600086604051602001610b4e9190615116565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018152919052601754909150610bb3904690309074010000000000000000000000000000000000000000900463ffffffff168d8d8d878d8d612160565b601355600960008181610bc68282614677565b5050505060005b876101c0015151811015610c2057610c0d886101c001518281518110610bf557610bf561529c565b6020026020010151600961220a90919063ffffffff16565b5080610c18816152cb565b915050610bcd565b506013546017546040517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0592610c839286927401000000000000000000000000000000000000000090910463ffffffff16908f908f908f9089908f908f90615303565b60405180910390a150505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610e08576040517fc8bad78d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208114610e42576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610e5082840184615399565b6000818152600460205260409020549091506601000000000000900463ffffffff90811614610eab576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600460205260409020600201547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614610f2f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260046020526040902060010154610f6e90859070010000000000000000000000000000000090046bffffffffffffffffffffffff166153b2565b600082815260046020908152604080832060010180546bffffffffffffffffffffffff95909516700100000000000000000000000000000000027fffffffff000000000000000000000000ffffffffffffffffffffffffffffffff9095169490941790935573ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016825260219052205461101d9085906153d7565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660009081526021602090815260409182902093909355516bffffffffffffffffffffffff871681529087169183917fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa734891506203910160405180910390a35050505050565b60005a60408051610120810182526014546bffffffffffffffffffffffff8116825263ffffffff6c01000000000000000000000000820416602083015262ffffff7001000000000000000000000000000000008204169282019290925261ffff730100000000000000000000000000000000000000830416606082015260ff75010000000000000000000000000000000000000000008304811660808301527601000000000000000000000000000000000000000000008304811615801560a08401527701000000000000000000000000000000000000000000000084048216151560c0840152780100000000000000000000000000000000000000000000000090930416151560e082015260155473ffffffffffffffffffffffffffffffffffffffff16610100820152919250611219576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604090205460ff16611262576040517f1099ed7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6013548a351461129e576040517fdfdcf8e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60808101516112ae9060016153ea565b60ff16861415806112bf5750858414155b156112f6576040517f0244f71a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113068a8a8a8a8a8a8a8a612235565b60006113128a8a61249e565b905060208b0135600881901c63ffffffff1661132f848487612557565b836020015163ffffffff168163ffffffff16111561138757601480547fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c0100000000000000000000000063ffffffff8416021790555b50505050505050505050505050565b6000806000858060200190518101906113af91906155d4565b9250925092506113c58989898689898888610356565b505050505050505050565b6113d86113e4565b6113e181613144565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611465576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610d14565b565b60005b60245481101561152557602260006024838154811061148b5761148b61529c565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffff00000000000000000000000000000000000000000000000000000000168155600181019190915560020180547fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001690558061151d816152cb565b91505061146a565b5061153260246000614677565b60255460ff1660005b8351811015611a995760008482815181106115585761155861529c565b6020026020010151905060008483815181106115765761157661529c565b602002602001015190508173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ef919061577f565b60ff16816060015160ff1614158061167d5750806040015173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611651573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611675919061577f565b60ff16600814155b156116b4576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161480156117205750600184600181111561171e5761171e61579c565b145b15611757576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821615806117925750604081015173ffffffffffffffffffffffffffffffffffffffff16155b156117c9576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82811660009081526022602052604090205467010000000000000090041615611833576040517f357d0cc400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6024805460018181019092557f7cd332d19b93bcabe3cce7ca0c18a052f57e5fd03b4758a09f30f5ddc4b22ec401805473ffffffffffffffffffffffffffffffffffffffff8086167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216821790925560008181526022602090815260409182902086518154928801518489015160608a015160ff167b01000000000000000000000000000000000000000000000000000000027fffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffff9190981667010000000000000002167fffffffff000000000000000000000000000000000000000000ffffffffffffff62ffffff909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000090951663ffffffff9093169290921793909317929092169190911793909317835560808501519383019390935560a0840151600290920180546bffffffffffffffffffffffff9093167fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009093169290921790915590517fca93cbe727c73163ec538f71be6c0a64877d7f1f6dd35d5ca7cbaef3a3e34ba390611a7c908490600060c08201905063ffffffff835116825262ffffff602084015116602083015273ffffffffffffffffffffffffffffffffffffffff604084015116604083015260ff6060840151166060830152608083015160808301526bffffffffffffffffffffffff60a08401511660a083015292915050565b60405180910390a250508080611a91906152cb565b91505061153b565b50505050565b60005b600e54811015611b1657611b03600e8281548110611ac257611ac261529c565b600091825260209091200154601454600e5473ffffffffffffffffffffffffffffffffffffffff909216916bffffffffffffffffffffffff90911690613239565b5080611b0e816152cb565b915050611aa2565b5060255460009060ff16815b600e54811015611c8757600e8181548110611b3f57611b3f61529c565b6000918252602082200154600d805473ffffffffffffffffffffffffffffffffffffffff9092169550600c929184908110611b7c57611b7c61529c565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff9081168452838201949094526040928301822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690559286168152600b909252902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556001826001811115611c1e57611c1e61579c565b148015611c63575073ffffffffffffffffffffffffffffffffffffffff83166000908152600b60205260409020546201000090046bffffffffffffffffffffffff1615155b15611c7557611c73600f8461220a565b505b80611c7f816152cb565b915050611b22565b50611c94600d6000614677565b611ca0600e6000614677565b6040805160808101825260008082526020820181905291810182905260608101829052905b855181101561213057600c6000878381518110611ce457611ce461529c565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff1615611d4f576040517f77cea0fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16868281518110611d7957611d7961529c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611dce576040517f815e1d6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806001151581526020018260ff16815250600c6000888481518110611dff57611dff61529c565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909316929092171790558451859082908110611ea757611ea761529c565b60200260200101519350600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611f17576040517f58a70a0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152600b60209081526040918290208251608081018452905460ff80821615801584526101008304909116938301939093526bffffffffffffffffffffffff6201000082048116948301949094526e01000000000000000000000000000090049092166060830152909250611fd2576040517f6a7281ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180835260ff80831660208086019182526014546bffffffffffffffffffffffff9081166060880190815273ffffffffffffffffffffffffffffffffffffffff8a166000908152600b909352604092839020885181549551948a0151925184166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff939094166201000002929092167fffffffffffff000000000000000000000000000000000000000000000000ffff94909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009095169490941717919091169290921791909117905583600181111561210c5761210c61579c565b0361211e5761211c600f85613441565b505b80612128816152cb565b915050611cc5565b50845161214490600d906020880190614695565b50835161215890600e906020870190614695565b505050505050565b6000808a8a8a8a8a8a8a8a8a604051602001612184999897969594939291906157cb565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179b9a5050505050505050505050565b600061222c8373ffffffffffffffffffffffffffffffffffffffff8416613463565b90505b92915050565b60008787604051612247929190615860565b60405190819003812061225e918b90602001615870565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201208383019092526000808452908301819052909250906000805b88811015612435576001858783602081106122ca576122ca61529c565b6122d791901a601b6153ea565b8c8c858181106122e9576122e961529c565b905060200201358b8b868181106123025761230261529c565b905060200201356040516000815260200160405260405161233f949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612361573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff81166000908152600c602090815290849020838501909452925460ff808216151580855261010090920416938301939093529095509350905061240f576040517f0f4c073700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015160080260ff166001901b84019350808061242d906152cb565b9150506122ad565b50827e01010101010101010101010101010101010101010101010101010101010101841614612490576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050565b6124d76040518060c001604052806000815260200160008152602001606081526020016060815260200160608152602001606081525090565b60006124e583850185615961565b604081015151606082015151919250908114158061250857508082608001515114155b806125185750808260a001515114155b1561254f576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b509392505050565b600082604001515167ffffffffffffffff8111156125775761257761472c565b60405190808252806020026020018201604052801561264357816020015b6040805161020081018252600060e08201818152610100830182905261012083018290526101408301829052610160830182905261018083018290526101a083018290526101c083018290526101e0830182905282526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816125955790505b50905060006040518060800160405280600061ffff16815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff16815260200160008152509050600085610100015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156126e1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612705919061508f565b9050600086610100015173ffffffffffffffffffffffffffffffffffffffff166318b8f6136040518163ffffffff1660e01b8152600401602060405180830381865afa158015612759573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061277d919061508f565b905060005b866040015151811015612c0d5760046000886040015183815181106127a9576127a961529c565b6020908102919091018101518252818101929092526040908101600020815161012081018352815460ff8082161515835261010080830490911615159583019590955263ffffffff620100008204811694830194909452660100000000000081048416606083015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009091048116608083015260018301546fffffffffffffffffffffffffffffffff811660a08401526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08401527c0100000000000000000000000000000000000000000000000000000000900490931660e08201526002909101549091169181019190915285518690839081106128cc576128cc61529c565b602002602001015160000181905250612901876040015182815181106128f4576128f461529c565b60200260200101516134b2565b8582815181106129135761291361529c565b60200260200101516060019060018111156129305761293061579c565b908160018111156129435761294361579c565b815250506129a7876040015182815181106129605761296061529c565b6020026020010151848960800151848151811061297f5761297f61529c565b60200260200101518885815181106129995761299961529c565b60200260200101518c61355d565b8683815181106129b9576129b961529c565b60200260200101516020018784815181106129d6576129d661529c565b602002602001015160c0018281525082151515158152505050848181518110612a0157612a0161529c565b60200260200101516020015115612a3157600184600001818151612a259190615a4e565b61ffff16905250612a36565b612bfb565b612a9c858281518110612a4b57612a4b61529c565b6020026020010151600001516080015188606001518381518110612a7157612a7161529c565b60200260200101518960a001518481518110612a8f57612a8f61529c565b602002602001015161367c565b868381518110612aae57612aae61529c565b6020026020010151604001878481518110612acb57612acb61529c565b6020026020010151608001828152508215151515815250505087608001516001612af591906153ea565b612b039060ff166040615a69565b6103a48860a001518381518110612b1c57612b1c61529c565b602002602001015151612b2f91906153d7565b612b3991906153d7565b858281518110612b4b57612b4b61529c565b602002602001015160a0018181525050848181518110612b6d57612b6d61529c565b602002602001015160a0015184606001818151612b8a91906153d7565b9052508451859082908110612ba157612ba161529c565b60200260200101516080015186612bb89190615a80565b9550612bfb87604001518281518110612bd357612bd361529c565b602002602001015184878481518110612bee57612bee61529c565b6020026020010151613897565b80612c05816152cb565b915050612782565b50825161ffff16600003612c245750505050505050565b61c800612c32366010615a69565b5a612c3d9088615a80565b612c4791906153d7565b612c5191906153d7565b83519095506123f090612c689061ffff1687615ac2565b612c7291906153d7565b6040805160808101825260008082526020820181905291810182905260608101829052919650612ca18961399c565b905060005b886040015151811015612fdd57868181518110612cc557612cc561529c565b60200260200101516020015115612fcb57801580612d5d575086612cea600183615a80565b81518110612cfa57612cfa61529c565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff16878281518110612d3357612d3361529c565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff1614155b15612d9157612d8e8a888381518110612d7857612d7861529c565b6020026020010151600001516101000151613a8d565b92505b6000612eaf8b6040518061012001604052808b8681518110612db557612db561529c565b60200260200101516080015181526020018c81526020018a606001518c8781518110612de357612de361529c565b602002602001015160a001518a612dfa9190615a69565b612e049190615ac2565b81526020018d6000015181526020018d6020015181526020018681526020018b8681518110612e3557612e3561529c565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff168152602001878152602001600115158152508c604001518581518110612e8457612e8461529c565b60200260200101518b8681518110612e9e57612e9e61529c565b602002602001015160000151613c09565b9050806060015187604001818151612ec791906153b2565b6bffffffffffffffffffffffff169052506040810151602088018051612eee9083906153b2565b6bffffffffffffffffffffffff169052508751889083908110612f1357612f1361529c565b60200260200101516040015115158a604001518381518110612f3757612f3761529c565b60200260200101517fad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b83606001518460400151612f7491906153b2565b8b8681518110612f8657612f8661529c565b6020026020010151608001518d8f608001518881518110612fa957612fa961529c565b6020026020010151604051612fc19493929190615ad6565b60405180910390a3505b80612fd5816152cb565b915050612ca6565b505050602083810151336000908152600b9092526040909120805460029061301a9084906201000090046bffffffffffffffffffffffff166153b2565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508260400151601460000160008282829054906101000a90046bffffffffffffffffffffffff1661307891906153b2565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550826040015183602001516130ba91906153b2565b6bffffffffffffffffffffffff16602160007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461313691906153d7565b909155505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036131c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610d14565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e01000000000000000000000000000090049091166060820152906134355760008160600151856132d19190615b13565b905060006132df8583615b38565b905080836040018181516132f391906153b2565b6bffffffffffffffffffffffff1690525061330e8582615b63565b8360600181815161331f91906153b2565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b600061222c8373ffffffffffffffffffffffffffffffffffffffff8416613f05565b60008181526001830160205260408120546134aa5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561222f565b50600061222f565b6000818160045b600f81101561353f577fff0000000000000000000000000000000000000000000000000000000000000082168382602081106134f7576134f761529c565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461352d57506000949350505050565b80613537816152cb565b9150506134b9565b5081600f1a60018111156135555761355561579c565b949350505050565b6000808080856060015160018111156135785761357861579c565b0361359e5761358a8888888888613ff8565b61359957600092509050613672565b613616565b6001856060015160018111156135b6576135b661579c565b036135e45760006135c989898988614182565b92509050806135de5750600092509050613672565b50613616565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516060015163ffffffff16871061366b57877fc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636876040516136589190614d9f565b60405180910390a2600092509050613672565b6001925090505b9550959350505050565b601454600090819077010000000000000000000000000000000000000000000000900460ff16156136d9576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16770100000000000000000000000000000000000000000000001790556040517f4585e33b000000000000000000000000000000000000000000000000000000009061374e908590602401614d9f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d16906138219087908790600401615b93565b60408051808303816000875af115801561383f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138639190615bac565b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16905590969095509350505050565b6000816060015160018111156138af576138af61579c565b0361391357600083815260046020526040902060010180547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff851602179055505050565b60018160600151600181111561392b5761392b61579c565b036139975760c08101805160009081526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055915191517fa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f29190a25b505050565b60008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613a0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a309190615bf4565b50935050925050600082131580613a4657508042105b80613a7657506000846040015162ffffff16118015613a765750613a6a8142615a80565b846040015162ffffff16105b15613a86575050601b5492915050565b5092915050565b60408051608081018252600080825260208083018281528385018381526060850184905273ffffffffffffffffffffffffffffffffffffffff878116855260229093528584208054640100000000810462ffffff1690925263ffffffff82169092527b01000000000000000000000000000000000000000000000000000000810460ff16855285517ffeaf968c00000000000000000000000000000000000000000000000000000000815295519495919484936701000000000000009092049091169163feaf968c9160048083019260a09291908290030181865afa158015613b7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b9e9190615bf4565b50935050925050600082131580613bb457508042105b80613be457506000866040015162ffffff16118015613be45750613bd88142615a80565b866040015162ffffff16105b15613bf85760018301546060850152613c00565b606084018290525b50505092915050565b604080516080810182526000808252602080830182905292820181905260608201529082015115613c825760008381526023602090815260409182902082518084018452905463ffffffff811680835262ffffff640100000000909204821692840192835260e089018051909401529051915191169101525b6000613c8e868661438f565b60c0840151602082015182519293509091600091613cab916153b2565b905082600001516bffffffffffffffffffffffff16826bffffffffffffffffffffffff161015613d3057819050613d1187608001518860e0015160600151846bffffffffffffffffffffffff16613d029190615a69565b613d0c9190615ac2565b6145d5565b6bffffffffffffffffffffffff16604084015260006060840152613dbc565b806bffffffffffffffffffffffff16826bffffffffffffffffffffffff161015613dbc57819050613da883604001516bffffffffffffffffffffffff1688608001518960e0015160600151856bffffffffffffffffffffffff16613d949190615a69565b613d9e9190615ac2565b613d0c9190615a80565b6bffffffffffffffffffffffff1660608401525b60008681526004602052604090206001018054829190601090613e0290849070010000000000000000000000000000000090046bffffffffffffffffffffffff16615b13565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008881526004602052604081206001018054928516935091613e5d9084906fffffffffffffffffffffffffffffffff16615c44565b92506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550806bffffffffffffffffffffffff16602160008960c0015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254613ef49190615a80565b909155509298975050505050505050565b60008181526001830160205260408120548015613fee576000613f29600183615a80565b8554909150600090613f3d90600190615a80565b9050818114613fa2576000866000018281548110613f5d57613f5d61529c565b9060005260206000200154905080876000018481548110613f8057613f8061529c565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613fb357613fb3615c6d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061222f565b600091505061222f565b6000808480602001905181019061400f9190615c9c565b845160e00151815191925063ffffffff9081169116101561406c57867f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e88660405161405a9190614d9f565b60405180910390a26000915050614179565b8260e00151801561412c575060208101511580159061412c5750602081015161010084015182516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa158015614105573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614129919061508f565b14155b8061413e5750805163ffffffff168611155b1561417357867f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc3018660405161405a9190614d9f565b60019150505b95945050505050565b60008060008480602001905181019061419b9190615cf4565b90506000878260000151836020015184604001516040516020016141fd94939291909384526020840192909252604083015260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016606082015260640190565b6040516020818303038152906040528051906020012090508460e0015180156142d857506080820151158015906142d85750608082015161010086015160608401516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa1580156142b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142d5919061508f565b14155b806142ed575086826060015163ffffffff1610155b1561433757877f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301876040516143229190614d9f565b60405180910390a26000935091506143869050565b60008181526008602052604090205460ff161561437e57877f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8876040516143229190614d9f565b600193509150505b94509492505050565b60408051608081018252600080825260208201819052918101829052606081019190915260008260e001516000015160ff1690506000846060015161ffff1684606001516143dd9190615a69565b905083610100015180156143f05750803a105b156143f857503a5b60006012831161440957600161441f565b614414601284615a80565b61441f90600a615e95565b9050600060128410614432576001614448565b61443d846012615a80565b61444890600a615e95565b905060008660a0015187604001518860200151896000015161446a91906153d7565b6144749087615a69565b61447e91906153d7565b6144889190615a69565b90506144ab828860e00151606001516144a19190615a69565b613d028584615a69565b6bffffffffffffffffffffffff16865260808701516144ce90613d0c9083615ac2565b6bffffffffffffffffffffffff1660408088019190915260e088015101516000906145079062ffffff16683635c9adc5dea00000615a69565b9050600081633b9aca008a60a001518b60e001516020015163ffffffff168c604001518d600001518b61453a9190615a69565b61454491906153d7565b61454e9190615a69565b6145589190615a69565b6145629190615ac2565b61456c91906153d7565b905061458f848a60e00151606001516145859190615a69565b613d028784615a69565b6bffffffffffffffffffffffff16602089015260808901516145b590613d0c9083615ac2565b6bffffffffffffffffffffffff1660608901525050505050505092915050565b60006bffffffffffffffffffffffff821115614673576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610d14565b5090565b50805460008255906000526020600020908101906113e19190614717565b82805482825590600052602060002090810192821561470f579160200282015b8281111561470f57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906146b5565b506146739291505b5b808211156146735760008155600101614718565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610200810167ffffffffffffffff8111828210171561477f5761477f61472c565b60405290565b60405160c0810167ffffffffffffffff8111828210171561477f5761477f61472c565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156147ef576147ef61472c565b604052919050565b600067ffffffffffffffff8211156148115761481161472c565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff811681146113e157600080fd5b80356148488161481b565b919050565b600082601f83011261485e57600080fd5b8135602061487361486e836147f7565b6147a8565b82815260059290921b8401810191818101908684111561489257600080fd5b8286015b848110156148b65780356148a98161481b565b8352918301918301614896565b509695505050505050565b60ff811681146113e157600080fd5b8035614848816148c1565b63ffffffff811681146113e157600080fd5b8035614848816148db565b80151581146113e157600080fd5b8035614848816148f8565b62ffffff811681146113e157600080fd5b803561484881614911565b61ffff811681146113e157600080fd5b80356148488161492d565b6000610200828403121561495b57600080fd5b61496361475b565b905061496e826148ed565b815261497c602083016148ed565b602082015261498d604083016148ed565b604082015261499e6060830161483d565b60608201526149af60808301614906565b60808201526149c060a08301614922565b60a08201526149d160c083016148ed565b60c08201526149e260e083016148ed565b60e08201526101006149f581840161483d565b90820152610120614a0783820161493d565b90820152610140614a1983820161483d565b90820152610160828101359082015261018080830135908201526101a080830135908201526101c08083013567ffffffffffffffff811115614a5a57600080fd5b614a668582860161484d565b8284015250506101e0614a7a81840161483d565b9082015292915050565b803567ffffffffffffffff8116811461484857600080fd5b600082601f830112614aad57600080fd5b813567ffffffffffffffff811115614ac757614ac761472c565b614af860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016147a8565b818152846020838601011115614b0d57600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff811681146113e157600080fd5b600082601f830112614b5557600080fd5b81356020614b6561486e836147f7565b82815260c09283028501820192828201919087851115614b8457600080fd5b8387015b85811015614c165781818a031215614ba05760008081fd5b614ba8614785565b8135614bb3816148db565b815281860135614bc281614911565b81870152604082810135614bd58161481b565b90820152606082810135614be8816148c1565b908201526080828101359082015260a080830135614c0581614b2a565b908201528452928401928101614b88565b5090979650505050505050565b600080600080600080600080610100898b031215614c4057600080fd5b883567ffffffffffffffff80821115614c5857600080fd5b614c648c838d0161484d565b995060208b0135915080821115614c7a57600080fd5b614c868c838d0161484d565b9850614c9460408c016148d0565b975060608b0135915080821115614caa57600080fd5b614cb68c838d01614948565b9650614cc460808c01614a84565b955060a08b0135915080821115614cda57600080fd5b614ce68c838d01614a9c565b945060c08b0135915080821115614cfc57600080fd5b614d088c838d0161484d565b935060e08b0135915080821115614d1e57600080fd5b50614d2b8b828c01614b44565b9150509295985092959890939650565b6000815180845260005b81811015614d6157602081850181015186830182015201614d45565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061222c6020830184614d3b565b60008083601f840112614dc457600080fd5b50813567ffffffffffffffff811115614ddc57600080fd5b602083019150836020828501011115614df457600080fd5b9250929050565b60008060008060608587031215614e1157600080fd5b8435614e1c8161481b565b935060208501359250604085013567ffffffffffffffff811115614e3f57600080fd5b614e4b87828801614db2565b95989497509550505050565b60008083601f840112614e6957600080fd5b50813567ffffffffffffffff811115614e8157600080fd5b6020830191508360208260051b8501011115614df457600080fd5b60008060008060008060008060e0898b031215614eb857600080fd5b606089018a811115614ec957600080fd5b8998503567ffffffffffffffff80821115614ee357600080fd5b614eef8c838d01614db2565b909950975060808b0135915080821115614f0857600080fd5b614f148c838d01614e57565b909750955060a08b0135915080821115614f2d57600080fd5b50614f3a8b828c01614e57565b999c989b50969995989497949560c00135949350505050565b60008060008060008060c08789031215614f6c57600080fd5b863567ffffffffffffffff80821115614f8457600080fd5b614f908a838b0161484d565b97506020890135915080821115614fa657600080fd5b614fb28a838b0161484d565b9650614fc060408a016148d0565b95506060890135915080821115614fd657600080fd5b614fe28a838b01614a9c565b9450614ff060808a01614a84565b935060a089013591508082111561500657600080fd5b5061501389828a01614a9c565b9150509295509295509295565b60006020828403121561503257600080fd5b813561503d8161481b565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff8181168382160290811690818114613a8657613a86615044565b6000602082840312156150a157600080fd5b5051919050565b63ffffffff818116838216019080821115613a8657613a86615044565b600081518084526020808501945080840160005b8381101561510b57815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016150d9565b509495945050505050565b6020815261512d60208201835163ffffffff169052565b60006020830151615146604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015180151560a08401525060a083015162ffffff811660c08401525060c083015163ffffffff811660e08401525060e08301516101006151c58185018363ffffffff169052565b84015190506101206151ee8482018373ffffffffffffffffffffffffffffffffffffffff169052565b84015190506101406152058482018361ffff169052565b840151905061016061522e8482018373ffffffffffffffffffffffffffffffffffffffff169052565b840151610180848101919091528401516101a0808501919091528401516101c0808501919091528401516102006101e0808601829052919250906152766102208601846150c5565b95015173ffffffffffffffffffffffffffffffffffffffff169301929092525090919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036152fc576152fc615044565b5060010190565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526153338184018a6150c5565b9050828103608084015261534781896150c5565b905060ff871660a084015282810360c08401526153648187614d3b565b905067ffffffffffffffff851660e08401528281036101008401526153898185614d3b565b9c9b505050505050505050505050565b6000602082840312156153ab57600080fd5b5035919050565b6bffffffffffffffffffffffff818116838216019080821115613a8657613a86615044565b8082018082111561222f5761222f615044565b60ff818116838216019081111561222f5761222f615044565b8051614848816148db565b80516148488161481b565b8051614848816148f8565b805161484881614911565b80516148488161492d565b600082601f83011261544b57600080fd5b8151602061545b61486e836147f7565b82815260059290921b8401810191818101908684111561547a57600080fd5b8286015b848110156148b65780516154918161481b565b835291830191830161547e565b600082601f8301126154af57600080fd5b815160206154bf61486e836147f7565b82815260059290921b840181019181810190868411156154de57600080fd5b8286015b848110156148b65780516154f58161481b565b83529183019183016154e2565b600082601f83011261551357600080fd5b8151602061552361486e836147f7565b82815260c0928302850182019282820191908785111561554257600080fd5b8387015b85811015614c165781818a03121561555e5760008081fd5b615566614785565b8151615571816148db565b81528186015161558081614911565b818701526040828101516155938161481b565b908201526060828101516155a6816148c1565b908201526080828101519082015260a0808301516155c381614b2a565b908201528452928401928101615546565b6000806000606084860312156155e957600080fd5b835167ffffffffffffffff8082111561560157600080fd5b90850190610200828803121561561657600080fd5b61561e61475b565b61562783615403565b815261563560208401615403565b602082015261564660408401615403565b60408201526156576060840161540e565b606082015261566860808401615419565b608082015261567960a08401615424565b60a082015261568a60c08401615403565b60c082015261569b60e08401615403565b60e08201526101006156ae81850161540e565b908201526101206156c084820161542f565b908201526101406156d284820161540e565b90820152610160838101519082015261018080840151908201526101a080840151908201526101c0808401518381111561570b57600080fd5b6157178a82870161543a565b8284015250506101e061572b81850161540e565b90820152602087015190955091508082111561574657600080fd5b6157528783880161549e565b9350604086015191508082111561576857600080fd5b5061577586828701615502565b9150509250925092565b60006020828403121561579157600080fd5b815161503d816148c1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526158128285018b6150c5565b91508382036080850152615826828a6150c5565b915060ff881660a085015283820360c08501526158438288614d3b565b90861660e085015283810361010085015290506153898185614d3b565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b600082601f83011261589757600080fd5b813560206158a761486e836147f7565b82815260059290921b840181019181810190868411156158c657600080fd5b8286015b848110156148b657803583529183019183016158ca565b600082601f8301126158f257600080fd5b8135602061590261486e836147f7565b82815260059290921b8401810191818101908684111561592157600080fd5b8286015b848110156148b657803567ffffffffffffffff8111156159455760008081fd5b6159538986838b0101614a9c565b845250918301918301615925565b60006020828403121561597357600080fd5b813567ffffffffffffffff8082111561598b57600080fd5b9083019060c0828603121561599f57600080fd5b6159a7614785565b82358152602083013560208201526040830135828111156159c757600080fd5b6159d387828601615886565b6040830152506060830135828111156159eb57600080fd5b6159f787828601615886565b606083015250608083013582811115615a0f57600080fd5b615a1b878286016158e1565b60808301525060a083013582811115615a3357600080fd5b615a3f878286016158e1565b60a08301525095945050505050565b61ffff818116838216019080821115613a8657613a86615044565b808202811582820484141761222f5761222f615044565b8181038181111561222f5761222f615044565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615ad157615ad1615a93565b500490565b6bffffffffffffffffffffffff85168152836020820152826040820152608060608201526000615b096080830184614d3b565b9695505050505050565b6bffffffffffffffffffffffff828116828216039080821115613a8657613a86615044565b60006bffffffffffffffffffffffff80841680615b5757615b57615a93565b92169190910492915050565b6bffffffffffffffffffffffff818116838216028082169190828114615b8b57615b8b615044565b505092915050565b8281526040602082015260006135556040830184614d3b565b60008060408385031215615bbf57600080fd5b8251615bca816148f8565b6020939093015192949293505050565b805169ffffffffffffffffffff8116811461484857600080fd5b600080600080600060a08688031215615c0c57600080fd5b615c1586615bda565b9450602086015193506040860151925060608601519150615c3860808701615bda565b90509295509295909350565b6fffffffffffffffffffffffffffffffff818116838216019080821115613a8657613a86615044565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600060408284031215615cae57600080fd5b6040516040810181811067ffffffffffffffff82111715615cd157615cd161472c565b6040528251615cdf816148db565b81526020928301519281019290925250919050565b600060a08284031215615d0657600080fd5b60405160a0810181811067ffffffffffffffff82111715615d2957615d2961472c565b806040525082518152602083015160208201526040830151615d4a816148db565b60408201526060830151615d5d816148db565b60608201526080928301519281019290925250919050565b600181815b80851115615dce57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615db457615db4615044565b80851615615dc157918102915b93841c9390800290615d7a565b509250929050565b600082615de55750600161222f565b81615df25750600061222f565b8160018114615e085760028114615e1257615e2e565b600191505061222f565b60ff841115615e2357615e23615044565b50506001821b61222f565b5060208310610133831016604e8410600b8410161715615e51575081810a61222f565b615e5b8383615d75565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615e8d57615e8d615044565b029392505050565b600061222c8383615dd656fea164736f6c6343000813000a", + Bin: "0x6101806040523480156200001257600080fd5b506040516200668a3803806200668a83398101604081905262000035916200062f565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b91906200062f565b826001600160a01b031663226cf83c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200010091906200062f565b836001600160a01b031663614486af6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016591906200062f565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca91906200062f565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f91906200062f565b866001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029491906200062f565b876001600160a01b031663c5b964e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f9919062000656565b886001600160a01b031663ac4dc59a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000338573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200035e91906200062f565b3380600081620003b55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620003e857620003e8816200056b565b5050506001600160a01b0380891660805287811660a05286811660c05285811660e052848116610100528316610120526025805483919060ff19166001838181111562000439576200043962000679565b0217905550806001600160a01b0316610140816001600160a01b03168152505060c0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200049a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004c091906200068f565b60ff1660a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200052a91906200068f565b60ff16146200054c576040516301f86e1760e41b815260040160405180910390fd5b5050506001600160a01b039095166101605250620006b4945050505050565b336001600160a01b03821603620005c55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620003ac565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200062c57600080fd5b50565b6000602082840312156200064257600080fd5b81516200064f8162000616565b9392505050565b6000602082840312156200066957600080fd5b8151600281106200064f57600080fd5b634e487b7160e01b600052602160045260246000fd5b600060208284031215620006a257600080fd5b815160ff811681146200064f57600080fd5b60805160a05160c05160e05161010051610120516101405161016051615f56620007346000396000818160be01526101910152600050506000505060005050600050506000613b1701526000505060008181610de701528181610ef5015281816110200152818161106a015281816116ec01526131400152615f566000f3fe6080604052600436106100bc5760003560e01c80638da5cb5b11610074578063b1dc65a41161004e578063b1dc65a4146102f6578063e3d0e71214610316578063f2fde38b14610336576100bc565b80638da5cb5b14610265578063a4c0ed3614610290578063afcb95d7146102b0576100bc565b8063349e8cca116100a5578063349e8cca1461018257806379ba5097146101d657806381ff7048146101eb576100bc565b80630870d3a114610103578063181f5a7714610123575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e8080156100fc573d6000f35b3d6000fd5b005b34801561010f57600080fd5b5061010161011e366004614c9d565b610356565b34801561012f57600080fd5b5061016c6040518060400160405280601881526020017f4175746f6d6174696f6e526567697374727920322e332e30000000000000000081525081565b6040516101799190614e19565b60405180910390f35b34801561018e57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610179565b3480156101e257600080fd5b50610101610ccd565b3480156101f757600080fd5b5061024260175460135463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610179565b34801561027157600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166101b1565b34801561029c57600080fd5b506101016102ab366004614e75565b610dcf565b3480156102bc57600080fd5b50601354601454604080516000815260208101939093526c0100000000000000000000000090910463ffffffff1690820152606001610179565b34801561030257600080fd5b50610101610311366004614f16565b6110eb565b34801561032257600080fd5b50610101610331366004614fcd565b6113cc565b34801561034257600080fd5b5061010161035136600461509a565b611406565b61035e61141a565b601f8851111561039a576040517f25d0209c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560ff166000036103d7576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b865188511415806103f657506103ee8660036150e6565b60ff16885111155b1561042d576040517f1d2d1c5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051825114610468576040517fcf54c06a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610472828261149d565b61047c8888611ad5565b604051806101200160405280601460000160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff168152602001600063ffffffff1681526020018660a0015162ffffff16815260200186610120015161ffff1681526020018760ff168152602001601460000160169054906101000a900460ff1615158152602001601460000160179054906101000a900460ff1615158152602001866080015115158152602001866101e0015173ffffffffffffffffffffffffffffffffffffffff16815250601460008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160106101000a81548162ffffff021916908362ffffff16021790555060608201518160000160136101000a81548161ffff021916908361ffff16021790555060808201518160000160156101000a81548160ff021916908360ff16021790555060a08201518160000160166101000a81548160ff02191690831515021790555060c08201518160000160176101000a81548160ff02191690831515021790555060e08201518160000160186101000a81548160ff0219169083151502179055506101008201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050604051806101600160405280866060015173ffffffffffffffffffffffffffffffffffffffff168152602001866000015163ffffffff168152602001866020015163ffffffff1681526020016016600001601c9054906101000a900463ffffffff1663ffffffff16815260200186610100015173ffffffffffffffffffffffffffffffffffffffff168152602001601660010160149054906101000a900463ffffffff1663ffffffff168152602001601660010160189054906101000a900463ffffffff1663ffffffff168152602001866040015163ffffffff16815260200186610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018660c0015163ffffffff1681526020018660e0015163ffffffff16815250601660008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160186101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060a08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101208201518160020160146101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160186101000a81548163ffffffff021916908363ffffffff160217905550905050846101600151601981905550846101800151601a81905550846101a00151601b819055506000601660010160189054906101000a900463ffffffff169050856101e0015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa69190615102565b601780547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000063ffffffff9384160217808255600192601491610b1d9185917401000000000000000000000000000000000000000090041661511b565b92506101000a81548163ffffffff021916908363ffffffff160217905550600086604051602001610b4e9190615189565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018152919052601754909150610bb3904690309074010000000000000000000000000000000000000000900463ffffffff168d8d8d878d8d612196565b6013556000610bc26009612240565b90505b8015610bff57610bec610be4610bdc60018461530f565b600990612250565b600990612263565b5080610bf781615322565b915050610bc5565b5060005b876101c0015151811015610c5657610c43886101c001518281518110610c2b57610c2b615357565b6020026020010151600961228590919063ffffffff16565b5080610c4e81615386565b915050610c03565b506013546017546040517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0592610cb99286927401000000000000000000000000000000000000000090910463ffffffff16908f908f908f9089908f908f906153be565b60405180910390a150505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d53576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610e3e576040517fc8bad78d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208114610e78576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610e8682840184615454565b6000818152600460205260409020549091506601000000000000900463ffffffff90811614610ee1576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600460205260409020600201547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614610f65576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260046020526040902060010154610fa490859070010000000000000000000000000000000090046bffffffffffffffffffffffff1661546d565b600082815260046020908152604080832060010180546bffffffffffffffffffffffff95909516700100000000000000000000000000000000027fffffffff000000000000000000000000ffffffffffffffffffffffffffffffff9095169490941790935573ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168252602190522054611053908590615492565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660009081526021602090815260409182902093909355516bffffffffffffffffffffffff871681529087169183917fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa734891506203910160405180910390a35050505050565b60005a60408051610120810182526014546bffffffffffffffffffffffff8116825263ffffffff6c01000000000000000000000000820416602083015262ffffff7001000000000000000000000000000000008204169282019290925261ffff730100000000000000000000000000000000000000830416606082015260ff75010000000000000000000000000000000000000000008304811660808301527601000000000000000000000000000000000000000000008304811615801560a08401527701000000000000000000000000000000000000000000000084048216151560c0840152780100000000000000000000000000000000000000000000000090930416151560e082015260155473ffffffffffffffffffffffffffffffffffffffff1661010082015291925061124f576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604090205460ff16611298576040517f1099ed7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6013548a35146112d4576040517fdfdcf8e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60808101516112e49060016154a5565b60ff16861415806112f55750858414155b1561132c576040517f0244f71a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61133c8a8a8a8a8a8a8a8a6122a7565b60006113488a8a612510565b905060208b0135600881901c63ffffffff166113658484876125c9565b836020015163ffffffff168163ffffffff1611156113bd57601480547fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c0100000000000000000000000063ffffffff8416021790555b50505050505050505050505050565b6000806000858060200190518101906113e5919061568f565b9250925092506113fb8989898689898888610356565b505050505050505050565b61140e61141a565b611417816131b6565b50565b60005473ffffffffffffffffffffffffffffffffffffffff16331461149b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610d4a565b565b60005b60245481101561155b5760226000602483815481106114c1576114c1615357565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffff00000000000000000000000000000000000000000000000000000000168155600181019190915560020180547fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001690558061155381615386565b9150506114a0565b50611568602460006146f1565b60255460ff1660005b8351811015611acf57600084828151811061158e5761158e615357565b6020026020010151905060008483815181106115ac576115ac615357565b602002602001015190508173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611601573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611625919061583a565b60ff16816060015160ff161415806116b35750806040015173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611687573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ab919061583a565b60ff16600814155b156116ea576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161480156117565750600184600181111561175457611754615857565b145b1561178d576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821615806117c85750604081015173ffffffffffffffffffffffffffffffffffffffff16155b156117ff576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82811660009081526022602052604090205467010000000000000090041615611869576040517f357d0cc400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6024805460018181019092557f7cd332d19b93bcabe3cce7ca0c18a052f57e5fd03b4758a09f30f5ddc4b22ec401805473ffffffffffffffffffffffffffffffffffffffff8086167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216821790925560008181526022602090815260409182902086518154928801518489015160608a015160ff167b01000000000000000000000000000000000000000000000000000000027fffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffff9190981667010000000000000002167fffffffff000000000000000000000000000000000000000000ffffffffffffff62ffffff909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000090951663ffffffff9093169290921793909317929092169190911793909317835560808501519383019390935560a0840151600290920180546bffffffffffffffffffffffff9093167fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009093169290921790915590517fca93cbe727c73163ec538f71be6c0a64877d7f1f6dd35d5ca7cbaef3a3e34ba390611ab2908490600060c08201905063ffffffff835116825262ffffff602084015116602083015273ffffffffffffffffffffffffffffffffffffffff604084015116604083015260ff6060840151166060830152608083015160808301526bffffffffffffffffffffffff60a08401511660a083015292915050565b60405180910390a250508080611ac790615386565b915050611571565b50505050565b60005b600e54811015611b4c57611b39600e8281548110611af857611af8615357565b600091825260209091200154601454600e5473ffffffffffffffffffffffffffffffffffffffff909216916bffffffffffffffffffffffff909116906132ab565b5080611b4481615386565b915050611ad8565b5060255460009060ff16815b600e54811015611cbd57600e8181548110611b7557611b75615357565b6000918252602082200154600d805473ffffffffffffffffffffffffffffffffffffffff9092169550600c929184908110611bb257611bb2615357565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff9081168452838201949094526040928301822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690559286168152600b909252902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556001826001811115611c5457611c54615857565b148015611c99575073ffffffffffffffffffffffffffffffffffffffff83166000908152600b60205260409020546201000090046bffffffffffffffffffffffff1615155b15611cab57611ca9600f84612285565b505b80611cb581615386565b915050611b58565b50611cca600d60006146f1565b611cd6600e60006146f1565b6040805160808101825260008082526020820181905291810182905260608101829052905b855181101561216657600c6000878381518110611d1a57611d1a615357565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff1615611d85576040517f77cea0fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16868281518110611daf57611daf615357565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611e04576040517f815e1d6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806001151581526020018260ff16815250600c6000888481518110611e3557611e35615357565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909316929092171790558451859082908110611edd57611edd615357565b60200260200101519350600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611f4d576040517f58a70a0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152600b60209081526040918290208251608081018452905460ff80821615801584526101008304909116938301939093526bffffffffffffffffffffffff6201000082048116948301949094526e01000000000000000000000000000090049092166060830152909250612008576040517f6a7281ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180835260ff80831660208086019182526014546bffffffffffffffffffffffff9081166060880190815273ffffffffffffffffffffffffffffffffffffffff8a166000908152600b909352604092839020885181549551948a0151925184166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff939094166201000002929092167fffffffffffff000000000000000000000000000000000000000000000000ffff94909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009095169490941717919091169290921791909117905583600181111561214257612142615857565b0361215457612152600f85612263565b505b8061215e81615386565b915050611cfb565b50845161217a90600d90602088019061470f565b50835161218e90600e90602087019061470f565b505050505050565b6000808a8a8a8a8a8a8a8a8a6040516020016121ba99989796959493929190615886565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179b9a5050505050505050505050565b600061224a825490565b92915050565b600061225c83836134b3565b9392505050565b600061225c8373ffffffffffffffffffffffffffffffffffffffff84166134dd565b600061225c8373ffffffffffffffffffffffffffffffffffffffff84166135d7565b600087876040516122b992919061591b565b6040519081900381206122d0918b9060200161592b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201208383019092526000808452908301819052909250906000805b888110156124a75760018587836020811061233c5761233c615357565b61234991901a601b6154a5565b8c8c8581811061235b5761235b615357565b905060200201358b8b8681811061237457612374615357565b90506020020135604051600081526020016040526040516123b1949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156123d3573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff81166000908152600c602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290955093509050612481576040517f0f4c073700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015160080260ff166001901b84019350808061249f90615386565b91505061231f565b50827e01010101010101010101010101010101010101010101010101010101010101841614612502576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050565b6125496040518060c001604052806000815260200160008152602001606081526020016060815260200160608152602001606081525090565b600061255783850185615a1c565b604081015151606082015151919250908114158061257a57508082608001515114155b8061258a5750808260a001515114155b156125c1576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b509392505050565b600082604001515167ffffffffffffffff8111156125e9576125e96147a6565b6040519080825280602002602001820160405280156126b557816020015b6040805161020081018252600060e08201818152610100830182905261012083018290526101408301829052610160830182905261018083018290526101a083018290526101c083018290526101e0830182905282526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816126075790505b50905060006040518060800160405280600061ffff16815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff16815260200160008152509050600085610100015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612753573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127779190615102565b9050600086610100015173ffffffffffffffffffffffffffffffffffffffff166318b8f6136040518163ffffffff1660e01b8152600401602060405180830381865afa1580156127cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ef9190615102565b905060005b866040015151811015612c7f57600460008860400151838151811061281b5761281b615357565b6020908102919091018101518252818101929092526040908101600020815161012081018352815460ff8082161515835261010080830490911615159583019590955263ffffffff620100008204811694830194909452660100000000000081048416606083015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009091048116608083015260018301546fffffffffffffffffffffffffffffffff811660a08401526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08401527c0100000000000000000000000000000000000000000000000000000000900490931660e082015260029091015490911691810191909152855186908390811061293e5761293e615357565b6020026020010151600001819052506129738760400151828151811061296657612966615357565b6020026020010151613626565b85828151811061298557612985615357565b60200260200101516060019060018111156129a2576129a2615857565b908160018111156129b5576129b5615857565b81525050612a19876040015182815181106129d2576129d2615357565b602002602001015184896080015184815181106129f1576129f1615357565b6020026020010151888581518110612a0b57612a0b615357565b60200260200101518c6136d1565b868381518110612a2b57612a2b615357565b6020026020010151602001878481518110612a4857612a48615357565b602002602001015160c0018281525082151515158152505050848181518110612a7357612a73615357565b60200260200101516020015115612aa357600184600001818151612a979190615b09565b61ffff16905250612aa8565b612c6d565b612b0e858281518110612abd57612abd615357565b6020026020010151600001516080015188606001518381518110612ae357612ae3615357565b60200260200101518960a001518481518110612b0157612b01615357565b60200260200101516137f0565b868381518110612b2057612b20615357565b6020026020010151604001878481518110612b3d57612b3d615357565b6020026020010151608001828152508215151515815250505087608001516001612b6791906154a5565b612b759060ff166040615b24565b6103a48860a001518381518110612b8e57612b8e615357565b602002602001015151612ba19190615492565b612bab9190615492565b858281518110612bbd57612bbd615357565b602002602001015160a0018181525050848181518110612bdf57612bdf615357565b602002602001015160a0015184606001818151612bfc9190615492565b9052508451859082908110612c1357612c13615357565b60200260200101516080015186612c2a919061530f565b9550612c6d87604001518281518110612c4557612c45615357565b602002602001015184878481518110612c6057612c60615357565b6020026020010151613a0b565b80612c7781615386565b9150506127f4565b50825161ffff16600003612c965750505050505050565b61c800612ca4366010615b24565b5a612caf908861530f565b612cb99190615492565b612cc39190615492565b83519095506123f090612cda9061ffff1687615b6a565b612ce49190615492565b6040805160808101825260008082526020820181905291810182905260608101829052919650612d1389613b10565b905060005b88604001515181101561304f57868181518110612d3757612d37615357565b6020026020010151602001511561303d57801580612dcf575086612d5c60018361530f565b81518110612d6c57612d6c615357565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff16878281518110612da557612da5615357565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff1614155b15612e0357612e008a888381518110612dea57612dea615357565b6020026020010151600001516101000151613bfa565b92505b6000612f218b6040518061012001604052808b8681518110612e2757612e27615357565b60200260200101516080015181526020018c81526020018a606001518c8781518110612e5557612e55615357565b602002602001015160a001518a612e6c9190615b24565b612e769190615b6a565b81526020018d6000015181526020018d6020015181526020018681526020018b8681518110612ea757612ea7615357565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff168152602001878152602001600115158152508c604001518581518110612ef657612ef6615357565b60200260200101518b8681518110612f1057612f10615357565b602002602001015160000151613d76565b9050806060015187604001818151612f39919061546d565b6bffffffffffffffffffffffff169052506040810151602088018051612f6090839061546d565b6bffffffffffffffffffffffff169052508751889083908110612f8557612f85615357565b60200260200101516040015115158a604001518381518110612fa957612fa9615357565b60200260200101517fad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b83606001518460400151612fe6919061546d565b8b8681518110612ff857612ff8615357565b6020026020010151608001518d8f60800151888151811061301b5761301b615357565b60200260200101516040516130339493929190615b7e565b60405180910390a3505b8061304781615386565b915050612d18565b505050602083810151336000908152600b9092526040909120805460029061308c9084906201000090046bffffffffffffffffffffffff1661546d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508260400151601460000160008282829054906101000a90046bffffffffffffffffffffffff166130ea919061546d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508260400151836020015161312c919061546d565b6bffffffffffffffffffffffff16602160007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546131a89190615492565b909155505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603613235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610d4a565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e01000000000000000000000000000090049091166060820152906134a75760008160600151856133439190615bbb565b905060006133518583615be0565b90508083604001818151613365919061546d565b6bffffffffffffffffffffffff169052506133808582615c0b565b83606001818151613391919061546d565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b60008260000182815481106134ca576134ca615357565b9060005260206000200154905092915050565b600081815260018301602052604081205480156135c657600061350160018361530f565b85549091506000906135159060019061530f565b905081811461357a57600086600001828154811061353557613535615357565b906000526020600020015490508087600001848154811061355857613558615357565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061358b5761358b615c3b565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061224a565b600091505061224a565b5092915050565b600081815260018301602052604081205461361e5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561224a565b50600061224a565b6000818160045b600f8110156136b3577fff00000000000000000000000000000000000000000000000000000000000000821683826020811061366b5761366b615357565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146136a157506000949350505050565b806136ab81615386565b91505061362d565b5081600f1a60018111156136c9576136c9615857565b949350505050565b6000808080856060015160018111156136ec576136ec615857565b03613712576136fe8888888888614072565b61370d576000925090506137e6565b61378a565b60018560600151600181111561372a5761372a615857565b0361375857600061373d898989886141fc565b925090508061375257506000925090506137e6565b5061378a565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516060015163ffffffff1687106137df57877fc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636876040516137cc9190614e19565b60405180910390a26000925090506137e6565b6001925090505b9550959350505050565b601454600090819077010000000000000000000000000000000000000000000000900460ff161561384d576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16770100000000000000000000000000000000000000000000001790556040517f4585e33b00000000000000000000000000000000000000000000000000000000906138c2908590602401614e19565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d16906139959087908790600401615c6a565b60408051808303816000875af11580156139b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139d79190615c83565b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16905590969095509350505050565b600081606001516001811115613a2357613a23615857565b03613a8757600083815260046020526040902060010180547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff851602179055505050565b600181606001516001811115613a9f57613a9f615857565b03613b0b5760c08101805160009081526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055915191517fa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f29190a25b505050565b60008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613b80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ba49190615ccb565b50935050925050600082131580613bba57508042105b80613bea57506000846040015162ffffff16118015613bea5750613bde814261530f565b846040015162ffffff16105b156135d0575050601b5492915050565b60408051608081018252600080825260208083018281528385018381526060850184905273ffffffffffffffffffffffffffffffffffffffff878116855260229093528584208054640100000000810462ffffff1690925263ffffffff82169092527b01000000000000000000000000000000000000000000000000000000810460ff16855285517ffeaf968c00000000000000000000000000000000000000000000000000000000815295519495919484936701000000000000009092049091169163feaf968c9160048083019260a09291908290030181865afa158015613ce7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d0b9190615ccb565b50935050925050600082131580613d2157508042105b80613d5157506000866040015162ffffff16118015613d515750613d45814261530f565b866040015162ffffff16105b15613d655760018301546060850152613d6d565b606084018290525b50505092915050565b604080516080810182526000808252602080830182905292820181905260608201529082015115613def5760008381526023602090815260409182902082518084018452905463ffffffff811680835262ffffff640100000000909204821692840192835260e089018051909401529051915191169101525b6000613dfb8686614409565b60c0840151602082015182519293509091600091613e189161546d565b905082600001516bffffffffffffffffffffffff16826bffffffffffffffffffffffff161015613e9d57819050613e7e87608001518860e0015160600151846bffffffffffffffffffffffff16613e6f9190615b24565b613e799190615b6a565b61464f565b6bffffffffffffffffffffffff16604084015260006060840152613f29565b806bffffffffffffffffffffffff16826bffffffffffffffffffffffff161015613f2957819050613f1583604001516bffffffffffffffffffffffff1688608001518960e0015160600151856bffffffffffffffffffffffff16613f019190615b24565b613f0b9190615b6a565b613e79919061530f565b6bffffffffffffffffffffffff1660608401525b60008681526004602052604090206001018054829190601090613f6f90849070010000000000000000000000000000000090046bffffffffffffffffffffffff16615bbb565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008881526004602052604081206001018054928516935091613fca9084906fffffffffffffffffffffffffffffffff16615d1b565b92506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550806bffffffffffffffffffffffff16602160008960c0015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254614061919061530f565b909155509298975050505050505050565b600080848060200190518101906140899190615d44565b845160e00151815191925063ffffffff908116911610156140e657867f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8866040516140d49190614e19565b60405180910390a260009150506141f3565b8260e0015180156141a657506020810151158015906141a65750602081015161010084015182516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa15801561417f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141a39190615102565b14155b806141b85750805163ffffffff168611155b156141ed57867f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301866040516140d49190614e19565b60019150505b95945050505050565b6000806000848060200190518101906142159190615d9c565b905060008782600001518360200151846040015160405160200161427794939291909384526020840192909252604083015260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016606082015260640190565b6040516020818303038152906040528051906020012090508460e00151801561435257506080820151158015906143525750608082015161010086015160608401516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa15801561432b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061434f9190615102565b14155b80614367575086826060015163ffffffff1610155b156143b157877f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc3018760405161439c9190614e19565b60405180910390a26000935091506144009050565b60008181526008602052604090205460ff16156143f857877f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e88760405161439c9190614e19565b600193509150505b94509492505050565b60408051608081018252600080825260208201819052918101829052606081019190915260008260e001516000015160ff1690506000846060015161ffff1684606001516144579190615b24565b9050836101000151801561446a5750803a105b1561447257503a5b600060128311614483576001614499565b61448e60128461530f565b61449990600a615f3d565b90506000601284106144ac5760016144c2565b6144b784601261530f565b6144c290600a615f3d565b905060008660a001518760400151886020015189600001516144e49190615492565b6144ee9087615b24565b6144f89190615492565b6145029190615b24565b9050614525828860e001516060015161451b9190615b24565b613e6f8584615b24565b6bffffffffffffffffffffffff168652608087015161454890613e799083615b6a565b6bffffffffffffffffffffffff1660408088019190915260e088015101516000906145819062ffffff16683635c9adc5dea00000615b24565b9050600081633b9aca008a60a001518b60e001516020015163ffffffff168c604001518d600001518b6145b49190615b24565b6145be9190615492565b6145c89190615b24565b6145d29190615b24565b6145dc9190615b6a565b6145e69190615492565b9050614609848a60e00151606001516145ff9190615b24565b613e6f8784615b24565b6bffffffffffffffffffffffff166020890152608089015161462f90613e799083615b6a565b6bffffffffffffffffffffffff1660608901525050505050505092915050565b60006bffffffffffffffffffffffff8211156146ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610d4a565b5090565b50805460008255906000526020600020908101906114179190614791565b828054828255906000526020600020908101928215614789579160200282015b8281111561478957825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90911617825560209092019160019091019061472f565b506146ed9291505b5b808211156146ed5760008155600101614792565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610200810167ffffffffffffffff811182821017156147f9576147f96147a6565b60405290565b60405160c0810167ffffffffffffffff811182821017156147f9576147f96147a6565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614869576148696147a6565b604052919050565b600067ffffffffffffffff82111561488b5761488b6147a6565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff8116811461141757600080fd5b80356148c281614895565b919050565b600082601f8301126148d857600080fd5b813560206148ed6148e883614871565b614822565b82815260059290921b8401810191818101908684111561490c57600080fd5b8286015b8481101561493057803561492381614895565b8352918301918301614910565b509695505050505050565b60ff8116811461141757600080fd5b80356148c28161493b565b63ffffffff8116811461141757600080fd5b80356148c281614955565b801515811461141757600080fd5b80356148c281614972565b62ffffff8116811461141757600080fd5b80356148c28161498b565b61ffff8116811461141757600080fd5b80356148c2816149a7565b600061020082840312156149d557600080fd5b6149dd6147d5565b90506149e882614967565b81526149f660208301614967565b6020820152614a0760408301614967565b6040820152614a18606083016148b7565b6060820152614a2960808301614980565b6080820152614a3a60a0830161499c565b60a0820152614a4b60c08301614967565b60c0820152614a5c60e08301614967565b60e0820152610100614a6f8184016148b7565b90820152610120614a818382016149b7565b90820152610140614a938382016148b7565b90820152610160828101359082015261018080830135908201526101a080830135908201526101c08083013567ffffffffffffffff811115614ad457600080fd5b614ae0858286016148c7565b8284015250506101e0614af48184016148b7565b9082015292915050565b803567ffffffffffffffff811681146148c257600080fd5b600082601f830112614b2757600080fd5b813567ffffffffffffffff811115614b4157614b416147a6565b614b7260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614822565b818152846020838601011115614b8757600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff8116811461141757600080fd5b600082601f830112614bcf57600080fd5b81356020614bdf6148e883614871565b82815260c09283028501820192828201919087851115614bfe57600080fd5b8387015b85811015614c905781818a031215614c1a5760008081fd5b614c226147ff565b8135614c2d81614955565b815281860135614c3c8161498b565b81870152604082810135614c4f81614895565b90820152606082810135614c628161493b565b908201526080828101359082015260a080830135614c7f81614ba4565b908201528452928401928101614c02565b5090979650505050505050565b600080600080600080600080610100898b031215614cba57600080fd5b883567ffffffffffffffff80821115614cd257600080fd5b614cde8c838d016148c7565b995060208b0135915080821115614cf457600080fd5b614d008c838d016148c7565b9850614d0e60408c0161494a565b975060608b0135915080821115614d2457600080fd5b614d308c838d016149c2565b9650614d3e60808c01614afe565b955060a08b0135915080821115614d5457600080fd5b614d608c838d01614b16565b945060c08b0135915080821115614d7657600080fd5b614d828c838d016148c7565b935060e08b0135915080821115614d9857600080fd5b50614da58b828c01614bbe565b9150509295985092959890939650565b6000815180845260005b81811015614ddb57602081850181015186830182015201614dbf565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061225c6020830184614db5565b60008083601f840112614e3e57600080fd5b50813567ffffffffffffffff811115614e5657600080fd5b602083019150836020828501011115614e6e57600080fd5b9250929050565b60008060008060608587031215614e8b57600080fd5b8435614e9681614895565b935060208501359250604085013567ffffffffffffffff811115614eb957600080fd5b614ec587828801614e2c565b95989497509550505050565b60008083601f840112614ee357600080fd5b50813567ffffffffffffffff811115614efb57600080fd5b6020830191508360208260051b8501011115614e6e57600080fd5b60008060008060008060008060e0898b031215614f3257600080fd5b606089018a811115614f4357600080fd5b8998503567ffffffffffffffff80821115614f5d57600080fd5b614f698c838d01614e2c565b909950975060808b0135915080821115614f8257600080fd5b614f8e8c838d01614ed1565b909750955060a08b0135915080821115614fa757600080fd5b50614fb48b828c01614ed1565b999c989b50969995989497949560c00135949350505050565b60008060008060008060c08789031215614fe657600080fd5b863567ffffffffffffffff80821115614ffe57600080fd5b61500a8a838b016148c7565b9750602089013591508082111561502057600080fd5b61502c8a838b016148c7565b965061503a60408a0161494a565b9550606089013591508082111561505057600080fd5b61505c8a838b01614b16565b945061506a60808a01614afe565b935060a089013591508082111561508057600080fd5b5061508d89828a01614b16565b9150509295509295509295565b6000602082840312156150ac57600080fd5b813561225c81614895565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff81811683821602908116908181146135d0576135d06150b7565b60006020828403121561511457600080fd5b5051919050565b63ffffffff8181168382160190808211156135d0576135d06150b7565b600081518084526020808501945080840160005b8381101561517e57815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010161514c565b509495945050505050565b602081526151a060208201835163ffffffff169052565b600060208301516151b9604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015180151560a08401525060a083015162ffffff811660c08401525060c083015163ffffffff811660e08401525060e08301516101006152388185018363ffffffff169052565b84015190506101206152618482018373ffffffffffffffffffffffffffffffffffffffff169052565b84015190506101406152788482018361ffff169052565b84015190506101606152a18482018373ffffffffffffffffffffffffffffffffffffffff169052565b840151610180848101919091528401516101a0808501919091528401516101c0808501919091528401516102006101e0808601829052919250906152e9610220860184615138565b95015173ffffffffffffffffffffffffffffffffffffffff169301929092525090919050565b8181038181111561224a5761224a6150b7565b600081615331576153316150b7565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036153b7576153b76150b7565b5060010190565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526153ee8184018a615138565b905082810360808401526154028189615138565b905060ff871660a084015282810360c084015261541f8187614db5565b905067ffffffffffffffff851660e08401528281036101008401526154448185614db5565b9c9b505050505050505050505050565b60006020828403121561546657600080fd5b5035919050565b6bffffffffffffffffffffffff8181168382160190808211156135d0576135d06150b7565b8082018082111561224a5761224a6150b7565b60ff818116838216019081111561224a5761224a6150b7565b80516148c281614955565b80516148c281614895565b80516148c281614972565b80516148c28161498b565b80516148c2816149a7565b600082601f83011261550657600080fd5b815160206155166148e883614871565b82815260059290921b8401810191818101908684111561553557600080fd5b8286015b8481101561493057805161554c81614895565b8352918301918301615539565b600082601f83011261556a57600080fd5b8151602061557a6148e883614871565b82815260059290921b8401810191818101908684111561559957600080fd5b8286015b848110156149305780516155b081614895565b835291830191830161559d565b600082601f8301126155ce57600080fd5b815160206155de6148e883614871565b82815260c092830285018201928282019190878511156155fd57600080fd5b8387015b85811015614c905781818a0312156156195760008081fd5b6156216147ff565b815161562c81614955565b81528186015161563b8161498b565b8187015260408281015161564e81614895565b908201526060828101516156618161493b565b908201526080828101519082015260a08083015161567e81614ba4565b908201528452928401928101615601565b6000806000606084860312156156a457600080fd5b835167ffffffffffffffff808211156156bc57600080fd5b9085019061020082880312156156d157600080fd5b6156d96147d5565b6156e2836154be565b81526156f0602084016154be565b6020820152615701604084016154be565b6040820152615712606084016154c9565b6060820152615723608084016154d4565b608082015261573460a084016154df565b60a082015261574560c084016154be565b60c082015261575660e084016154be565b60e08201526101006157698185016154c9565b9082015261012061577b8482016154ea565b9082015261014061578d8482016154c9565b90820152610160838101519082015261018080840151908201526101a080840151908201526101c080840151838111156157c657600080fd5b6157d28a8287016154f5565b8284015250506101e06157e68185016154c9565b90820152602087015190955091508082111561580157600080fd5b61580d87838801615559565b9350604086015191508082111561582357600080fd5b50615830868287016155bd565b9150509250925092565b60006020828403121561584c57600080fd5b815161225c8161493b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526158cd8285018b615138565b915083820360808501526158e1828a615138565b915060ff881660a085015283820360c08501526158fe8288614db5565b90861660e085015283810361010085015290506154448185614db5565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b600082601f83011261595257600080fd5b813560206159626148e883614871565b82815260059290921b8401810191818101908684111561598157600080fd5b8286015b848110156149305780358352918301918301615985565b600082601f8301126159ad57600080fd5b813560206159bd6148e883614871565b82815260059290921b840181019181810190868411156159dc57600080fd5b8286015b8481101561493057803567ffffffffffffffff811115615a005760008081fd5b615a0e8986838b0101614b16565b8452509183019183016159e0565b600060208284031215615a2e57600080fd5b813567ffffffffffffffff80821115615a4657600080fd5b9083019060c08286031215615a5a57600080fd5b615a626147ff565b8235815260208301356020820152604083013582811115615a8257600080fd5b615a8e87828601615941565b604083015250606083013582811115615aa657600080fd5b615ab287828601615941565b606083015250608083013582811115615aca57600080fd5b615ad68782860161599c565b60808301525060a083013582811115615aee57600080fd5b615afa8782860161599c565b60a08301525095945050505050565b61ffff8181168382160190808211156135d0576135d06150b7565b808202811582820484141761224a5761224a6150b7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615b7957615b79615b3b565b500490565b6bffffffffffffffffffffffff85168152836020820152826040820152608060608201526000615bb16080830184614db5565b9695505050505050565b6bffffffffffffffffffffffff8281168282160390808211156135d0576135d06150b7565b60006bffffffffffffffffffffffff80841680615bff57615bff615b3b565b92169190910492915050565b6bffffffffffffffffffffffff818116838216028082169190828114615c3357615c336150b7565b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8281526040602082015260006136c96040830184614db5565b60008060408385031215615c9657600080fd5b8251615ca181614972565b6020939093015192949293505050565b805169ffffffffffffffffffff811681146148c257600080fd5b600080600080600060a08688031215615ce357600080fd5b615cec86615cb1565b9450602086015193506040860151925060608601519150615d0f60808701615cb1565b90509295509295909350565b6fffffffffffffffffffffffffffffffff8181168382160190808211156135d0576135d06150b7565b600060408284031215615d5657600080fd5b6040516040810181811067ffffffffffffffff82111715615d7957615d796147a6565b6040528251615d8781614955565b81526020928301519281019290925250919050565b600060a08284031215615dae57600080fd5b60405160a0810181811067ffffffffffffffff82111715615dd157615dd16147a6565b806040525082518152602083015160208201526040830151615df281614955565b60408201526060830151615e0581614955565b60608201526080928301519281019290925250919050565b600181815b80851115615e7657817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615e5c57615e5c6150b7565b80851615615e6957918102915b93841c9390800290615e22565b509250929050565b600082615e8d5750600161224a565b81615e9a5750600061224a565b8160018114615eb05760028114615eba57615ed6565b600191505061224a565b60ff841115615ecb57615ecb6150b7565b50506001821b61224a565b5060208310610133831016604e8410600b8410161715615ef9575081810a61224a565b615f038383615e1d565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615f3557615f356150b7565b029392505050565b600061225c8383615e7e56fea164736f6c6343000813000a", } var AutomationRegistryABI = AutomationRegistryMetaData.ABI diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 54925200f81..58100294e06 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -14,7 +14,7 @@ automation_registry_logic_a_wrapper_2_3: ../../contracts/solc/v0.8.19/Automation automation_registry_logic_b_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.bin a6d33dfbbfb0ff253eb59a51f4f6d6d4c22ea5ec95aae52d25d49a312b37a22f automation_registry_logic_b_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_3/AutomationRegistryLogicB2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_3/AutomationRegistryLogicB2_3.bin 2d0f45d2087f6f3c8bfa0a16b26a1c8c1d5c64b89859478c609201535c96eeed automation_registry_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.bin de60f69878e9b32a291a001c91fc8636544c2cfbd9b507c8c1a4873b602bfb62 -automation_registry_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.bin 2f9db5da86183eaf4f78f726458e5a928d37f7c90c4024923847b25186b644c5 +automation_registry_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.bin 68acf720890c89512a43c3468712f5da6c1c9613bc7c462b51599293f0cce9f4 automation_utils_2_1: ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.abi ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.bin 815b17b63f15d26a0274b962eefad98cdee4ec897ead58688bbb8e2470e585f5 automation_utils_2_2: ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.abi ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.bin 8743f6231aaefa3f2a0b2d484258070d506e2d0860690e66890dccc3949edb2e automation_utils_2_3: ../../contracts/solc/v0.8.19/AutomationUtils2_3/AutomationUtils2_3.abi ../../contracts/solc/v0.8.19/AutomationUtils2_3/AutomationUtils2_3.bin 11e2b481dc9a4d936e3443345d45d2cc571164459d214917b42a8054b295393b From 9120bcdb9a7b962dd618a5fe18e7006a41184c81 Mon Sep 17 00:00:00 2001 From: frank zhu Date: Tue, 23 Apr 2024 09:54:07 -0700 Subject: [PATCH 07/77] fix: ci-core workflow post slack conditional (#12930) --- .github/workflows/ci-core.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index 5e9234eb491..394faf71e2f 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -171,8 +171,16 @@ jobs: run: | cat output.txt | gotestloghelper -ci - name: Print Races + id: print-races if: ${{ failure() && matrix.type.cmd == 'go_core_race_tests' && needs.filter.outputs.changes == 'true' }} - run: find race.* | xargs cat + run: | + find race.* | xargs cat > race.txt + if [[ -s race.txt ]]; then + cat race.txt + echo "post_to_slack=true" >> $GITHUB_OUTPUT + else + echo "post_to_slack=false" >> $GITHUB_OUTPUT + fi - name: Print postgres logs if: ${{ always() && needs.filter.outputs.changes == 'true' }} run: docker compose logs postgres | tee ../../../postgres_logs.txt @@ -189,7 +197,7 @@ jobs: ./coverage.txt ./postgres_logs.txt - name: Notify Slack - if: ${{ failure() && matrix.type.cmd == 'go_core_race_tests' && (github.event_name == 'merge_group' || github.event.branch == 'develop') && needs.filter.outputs.changes == 'true' }} + if: ${{ failure() && steps.print-races.outputs.post_to_slack == 'true' && matrix.type.cmd == 'go_core_race_tests' && (github.event_name == 'merge_group' || github.event.branch == 'develop') && needs.filter.outputs.changes == 'true' }} uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 env: SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} From a0f956db9b0d7540db1df0c584bc6feba64f8f32 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Tue, 23 Apr 2024 12:00:15 -0500 Subject: [PATCH 08/77] bump deps (#12927) --- core/scripts/go.mod | 14 +++++++------- core/scripts/go.sum | 28 ++++++++++++++-------------- go.mod | 14 +++++++------- go.sum | 28 ++++++++++++++-------------- integration-tests/go.mod | 14 +++++++------- integration-tests/go.sum | 28 ++++++++++++++-------------- integration-tests/load/go.mod | 14 +++++++------- integration-tests/load/go.sum | 28 ++++++++++++++-------------- 8 files changed, 84 insertions(+), 84 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 9441180e763..5be5d137696 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -109,7 +109,7 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/dominikbraun/graph v0.23.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/dvsekhvalnov/jose2go v1.5.0 // indirect + github.com/dvsekhvalnov/jose2go v1.7.0 // indirect github.com/esote/minmaxheap v1.0.0 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect github.com/fatih/color v1.16.0 // indirect @@ -253,7 +253,7 @@ require ( github.com/scylladb/go-reflectx v1.0.1 // indirect github.com/sethvargo/go-retry v0.2.4 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect - github.com/shirou/gopsutil/v3 v3.23.11 // indirect + github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.10 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 // indirect @@ -292,7 +292,7 @@ require ( github.com/valyala/fastjson v1.4.1 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/x448/float16 v0.8.4 // indirect - github.com/yusufpapurcu/wmi v1.2.3 // indirect + github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/zondax/hid v0.9.1 // indirect github.com/zondax/ledger-go v0.14.1 // indirect go.dedis.ch/fixbuf v1.0.3 // indirect @@ -312,13 +312,13 @@ require ( go.uber.org/ratelimit v0.3.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/arch v0.7.0 // indirect - golang.org/x/crypto v0.21.0 // indirect + golang.org/x/crypto v0.22.0 // indirect golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect golang.org/x/mod v0.15.0 // indirect - golang.org/x/net v0.21.0 // indirect + golang.org/x/net v0.24.0 // indirect golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect + golang.org/x/sys v0.19.0 // indirect + golang.org/x/term v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.18.0 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 1f881b15778..b26bad1299e 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -373,8 +373,8 @@ github.com/dominikbraun/graph v0.23.0/go.mod h1:yOjYyogZLY1LSG9E33JWZJiq5k83Qy2C github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= -github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= +github.com/dvsekhvalnov/jose2go v1.7.0 h1:bnQc8+GMnidJZA8zc6lLEAb4xNrIqHwO+9TzqvtQZPo= +github.com/dvsekhvalnov/jose2go v1.7.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/elastic/go-sysinfo v1.11.1 h1:g9mwl05njS4r69TisC+vwHWTSKywZFYYUu3so3T/Lao= github.com/elastic/go-sysinfo v1.11.1/go.mod h1:6KQb31j0QeWBDF88jIdWSxE8cwoOB9tO4Y4osN7Q70E= @@ -1167,8 +1167,8 @@ github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08O github.com/sethvargo/go-retry v0.2.4/go.mod h1:1afjQuvh7s4gflMObvjLPaWgluLLyhA1wmVZ6KLpICw= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shirou/gopsutil/v3 v3.23.11 h1:i3jP9NjCPUz7FiZKxlMnODZkdSIp2gnzfrvsu9CuWEQ= -github.com/shirou/gopsutil/v3 v3.23.11/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM= +github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE= +github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= @@ -1367,8 +1367,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= -github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= @@ -1479,8 +1479,8 @@ golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1579,8 +1579,8 @@ golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1693,9 +1693,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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1703,8 +1703,8 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX 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.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/go.mod b/go.mod index ff9993618c1..752dd110c49 100644 --- a/go.mod +++ b/go.mod @@ -68,7 +68,7 @@ require ( github.com/robfig/cron/v3 v3.0.1 github.com/rogpeppe/go-internal v1.11.0 github.com/scylladb/go-reflectx v1.0.1 - github.com/shirou/gopsutil/v3 v3.23.11 + github.com/shirou/gopsutil/v3 v3.24.3 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chain-selectors v1.0.10 github.com/smartcontractkit/chainlink-automation v1.0.3 @@ -98,11 +98,11 @@ require ( go.opentelemetry.io/otel v1.24.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.26.0 - golang.org/x/crypto v0.21.0 + golang.org/x/crypto v0.22.0 golang.org/x/exp v0.0.0-20240213143201-ec583247a57a golang.org/x/mod v0.15.0 golang.org/x/sync v0.6.0 - golang.org/x/term v0.18.0 + golang.org/x/term v0.19.0 golang.org/x/text v0.14.0 golang.org/x/time v0.5.0 golang.org/x/tools v0.18.0 @@ -176,7 +176,7 @@ require ( github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/dvsekhvalnov/jose2go v1.5.0 // indirect + github.com/dvsekhvalnov/jose2go v1.7.0 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect @@ -310,7 +310,7 @@ require ( github.com/valyala/fastjson v1.4.1 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/x448/float16 v0.8.4 // indirect - github.com/yusufpapurcu/wmi v1.2.3 // indirect + github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/zondax/hid v0.9.1 // indirect github.com/zondax/ledger-go v0.14.1 // indirect go.dedis.ch/protobuf v1.0.11 // indirect @@ -326,9 +326,9 @@ require ( go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.uber.org/ratelimit v0.3.0 // indirect golang.org/x/arch v0.7.0 // indirect - golang.org/x/net v0.21.0 // indirect + golang.org/x/net v0.24.0 // indirect golang.org/x/oauth2 v0.17.0 // indirect - golang.org/x/sys v0.18.0 // indirect + golang.org/x/sys v0.19.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect google.golang.org/api v0.149.0 // indirect google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405 // indirect diff --git a/go.sum b/go.sum index 1f94c3dfc9f..5f042f2e4c4 100644 --- a/go.sum +++ b/go.sum @@ -356,8 +356,8 @@ github.com/dominikbraun/graph v0.23.0/go.mod h1:yOjYyogZLY1LSG9E33JWZJiq5k83Qy2C github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= -github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= +github.com/dvsekhvalnov/jose2go v1.7.0 h1:bnQc8+GMnidJZA8zc6lLEAb4xNrIqHwO+9TzqvtQZPo= +github.com/dvsekhvalnov/jose2go v1.7.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/elastic/go-sysinfo v1.11.1 h1:g9mwl05njS4r69TisC+vwHWTSKywZFYYUu3so3T/Lao= github.com/elastic/go-sysinfo v1.11.1/go.mod h1:6KQb31j0QeWBDF88jIdWSxE8cwoOB9tO4Y4osN7Q70E= @@ -1162,8 +1162,8 @@ github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08O github.com/sethvargo/go-retry v0.2.4/go.mod h1:1afjQuvh7s4gflMObvjLPaWgluLLyhA1wmVZ6KLpICw= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shirou/gopsutil/v3 v3.23.11 h1:i3jP9NjCPUz7FiZKxlMnODZkdSIp2gnzfrvsu9CuWEQ= -github.com/shirou/gopsutil/v3 v3.23.11/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM= +github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE= +github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= @@ -1362,8 +1362,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= -github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= @@ -1474,8 +1474,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.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1573,8 +1573,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug 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.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1686,9 +1686,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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1697,8 +1697,8 @@ 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.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index e3afe782e95..4f166385c69 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -160,7 +160,7 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/dominikbraun/graph v0.23.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/dvsekhvalnov/jose2go v1.5.0 // indirect + github.com/dvsekhvalnov/jose2go v1.7.0 // indirect github.com/edsrzf/mmap-go v1.1.0 // indirect github.com/emicklei/go-restful/v3 v3.10.2 // indirect github.com/esote/minmaxheap v1.0.0 // indirect @@ -373,7 +373,7 @@ require ( github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect github.com/sercand/kuberesolver/v5 v5.1.1 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect - github.com/shirou/gopsutil/v3 v3.23.12 // indirect + github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.10 // indirect @@ -418,7 +418,7 @@ require ( github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xlab/treeprint v1.1.0 // indirect - github.com/yusufpapurcu/wmi v1.2.3 // indirect + github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/zondax/hid v0.9.1 // indirect github.com/zondax/ledger-go v0.14.1 // indirect go.dedis.ch/fixbuf v1.0.3 // indirect @@ -446,13 +446,13 @@ require ( go.uber.org/ratelimit v0.3.0 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect golang.org/x/arch v0.7.0 // indirect - golang.org/x/crypto v0.21.0 // indirect + golang.org/x/crypto v0.22.0 // indirect golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect golang.org/x/mod v0.15.0 // indirect - golang.org/x/net v0.21.0 // indirect + golang.org/x/net v0.24.0 // indirect golang.org/x/oauth2 v0.17.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect + golang.org/x/sys v0.19.0 // indirect + golang.org/x/term v0.19.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.18.0 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 5a8b091ebcc..65b67170dea 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -457,8 +457,8 @@ github.com/dominikbraun/graph v0.23.0/go.mod h1:yOjYyogZLY1LSG9E33JWZJiq5k83Qy2C github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= -github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= +github.com/dvsekhvalnov/jose2go v1.7.0 h1:bnQc8+GMnidJZA8zc6lLEAb4xNrIqHwO+9TzqvtQZPo= +github.com/dvsekhvalnov/jose2go v1.7.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ= github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= @@ -1493,8 +1493,8 @@ github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08O github.com/sethvargo/go-retry v0.2.4/go.mod h1:1afjQuvh7s4gflMObvjLPaWgluLLyhA1wmVZ6KLpICw= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shirou/gopsutil/v3 v3.23.12 h1:z90NtUkp3bMtmICZKpC4+WaknU1eXtp5vtbQ11DgpE4= -github.com/shirou/gopsutil/v3 v3.23.12/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM= +github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE= +github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= @@ -1715,8 +1715,8 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/gopher-lua v1.1.0 h1:BojcDhfyDWgU2f2TOzYK/g5p2gxMrku8oupLDqlnSqE= github.com/yuin/gopher-lua v1.1.0/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= -github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= -github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= @@ -1853,8 +1853,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/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.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1960,8 +1960,8 @@ 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.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -2091,9 +2091,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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -2103,8 +2103,8 @@ 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.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 95870bad6a2..42e97969260 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -137,7 +137,7 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/dominikbraun/graph v0.23.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/dvsekhvalnov/jose2go v1.5.0 // indirect + github.com/dvsekhvalnov/jose2go v1.7.0 // indirect github.com/edsrzf/mmap-go v1.1.0 // indirect github.com/emicklei/go-restful/v3 v3.10.2 // indirect github.com/esote/minmaxheap v1.0.0 // indirect @@ -361,7 +361,7 @@ require ( github.com/segmentio/ksuid v1.0.4 // indirect github.com/sercand/kuberesolver/v5 v5.1.1 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect - github.com/shirou/gopsutil/v3 v3.23.12 // indirect + github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/shopspring/decimal v1.3.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect @@ -412,7 +412,7 @@ require ( github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xlab/treeprint v1.1.0 // indirect - github.com/yusufpapurcu/wmi v1.2.3 // indirect + github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/zondax/hid v0.9.1 // indirect github.com/zondax/ledger-go v0.14.1 // indirect go.dedis.ch/fixbuf v1.0.3 // indirect @@ -441,14 +441,14 @@ require ( go.uber.org/zap v1.26.0 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect golang.org/x/arch v0.7.0 // indirect - golang.org/x/crypto v0.21.0 // indirect + golang.org/x/crypto v0.22.0 // indirect golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect golang.org/x/mod v0.15.0 // indirect - golang.org/x/net v0.21.0 // indirect + golang.org/x/net v0.24.0 // indirect golang.org/x/oauth2 v0.17.0 // indirect golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect + golang.org/x/sys v0.19.0 // indirect + golang.org/x/term v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.18.0 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 051fdf9cd6e..5572271a58f 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -447,8 +447,8 @@ github.com/dominikbraun/graph v0.23.0/go.mod h1:yOjYyogZLY1LSG9E33JWZJiq5k83Qy2C github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= -github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= +github.com/dvsekhvalnov/jose2go v1.7.0 h1:bnQc8+GMnidJZA8zc6lLEAb4xNrIqHwO+9TzqvtQZPo= +github.com/dvsekhvalnov/jose2go v1.7.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ= github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= @@ -1476,8 +1476,8 @@ github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08O github.com/sethvargo/go-retry v0.2.4/go.mod h1:1afjQuvh7s4gflMObvjLPaWgluLLyhA1wmVZ6KLpICw= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shirou/gopsutil/v3 v3.23.12 h1:z90NtUkp3bMtmICZKpC4+WaknU1eXtp5vtbQ11DgpE4= -github.com/shirou/gopsutil/v3 v3.23.12/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM= +github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE= +github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= @@ -1700,8 +1700,8 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/gopher-lua v1.1.0 h1:BojcDhfyDWgU2f2TOzYK/g5p2gxMrku8oupLDqlnSqE= github.com/yuin/gopher-lua v1.1.0/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= -github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= -github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= @@ -1839,8 +1839,8 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0 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.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1946,8 +1946,8 @@ 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.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -2076,9 +2076,9 @@ 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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -2089,8 +2089,8 @@ 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.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= From 3f4573479c32dedf44f04261f9d5d4905f2542c7 Mon Sep 17 00:00:00 2001 From: Dylan Tinianov Date: Tue, 23 Apr 2024 13:15:45 -0400 Subject: [PATCH 09/77] Configurable Client Errors (#12760) * Implement client errors * Test client errors * Set client errors * changeset * Fix race conditions * Fix config tests * Enable client errors * remove global map * Move errors to NodePool * Rename errors * Update chains-evm.toml * Fix test data * Fix and generate docs * generate testdata * changeset * update changeset * update testdata * generate docs * Update errors.go * remove variable * Refactor ClientErrors * Pass client errors * update client errors * Update config * Fix config * Update config tests * update golden files * Update config-multi-chain-effective.toml * Add regex to toml * Update lovely-jeans-confess.md --- .changeset/lovely-jeans-confess.md | 6 + common/client/node.go | 3 + common/client/node_test.go | 6 + core/chains/evm/client/chain_client.go | 17 +- core/chains/evm/client/client.go | 2 +- core/chains/evm/client/config_builder_test.go | 2 +- core/chains/evm/client/errors.go | 153 +++++++++++------- core/chains/evm/client/errors_test.go | 139 ++++++++++------ core/chains/evm/client/evm_client.go | 5 +- core/chains/evm/client/evm_client_test.go | 2 +- core/chains/evm/client/helpers_test.go | 72 ++++++++- core/chains/evm/client/pool.go | 2 +- core/chains/evm/client/tx_simulator_test.go | 4 +- core/chains/evm/config/chain_scoped.go | 4 + .../evm/config/chain_scoped_client_errors.go | 50 ++++++ .../evm/config/chain_scoped_node_pool.go | 2 + core/chains/evm/config/config.go | 18 +++ core/chains/evm/config/config_test.go | 54 +++++++ core/chains/evm/config/toml/config.go | 65 ++++++++ core/chains/evm/txmgr/broadcaster_test.go | 39 +++-- core/chains/evm/txmgr/builder.go | 7 +- core/chains/evm/txmgr/client.go | 10 +- core/chains/evm/txmgr/confirmer_test.go | 10 +- core/chains/evm/txmgr/nonce_tracker_test.go | 12 +- core/chains/evm/txmgr/resender_test.go | 6 +- core/chains/evm/txmgr/txmgr_test.go | 1 + core/chains/legacyevm/chain.go | 2 +- core/chains/legacyevm/evm_txm.go | 1 + core/cmd/shell_local.go | 3 +- core/config/docs/chains-evm.toml | 32 ++++ core/config/docs/docs_test.go | 1 + core/services/chainlink/config_test.go | 32 ++++ .../chainlink/testdata/config-full.toml | 16 ++ .../promreporter/prom_reporter_test.go | 1 + core/services/vrf/delegate_test.go | 2 +- core/web/resolver/testdata/config-full.toml | 16 ++ docs/CONFIG.md | 104 ++++++++++++ 37 files changed, 735 insertions(+), 166 deletions(-) create mode 100644 .changeset/lovely-jeans-confess.md create mode 100644 core/chains/evm/config/chain_scoped_client_errors.go diff --git a/.changeset/lovely-jeans-confess.md b/.changeset/lovely-jeans-confess.md new file mode 100644 index 00000000000..50fc70c2c14 --- /dev/null +++ b/.changeset/lovely-jeans-confess.md @@ -0,0 +1,6 @@ +--- +"chainlink": minor +--- + +#nops : Enable configurable client error regexes for error classification +#added : New toml configuration options for [EVM.NodePool.Errors] to pass regexes on NonceTooLow, NonceTooHigh, ReplacementTransactionUnderpriced, LimitReached, TransactionAlreadyInMempool, TerminallyUnderpriced, InsufficientEth, TxFeeExceedsCap, L2FeeTooLow, L2FeeTooHigh, L2Full, TransactionAlreadyMined, Fatal, and ServiceUnavailable. diff --git a/common/client/node.go b/common/client/node.go index 61816be21da..6450b086f10 100644 --- a/common/client/node.go +++ b/common/client/node.go @@ -9,6 +9,8 @@ import ( "sync" "time" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config" + "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" @@ -45,6 +47,7 @@ type NodeConfig interface { SyncThreshold() uint32 NodeIsSyncingEnabled() bool FinalizedBlockPollInterval() time.Duration + Errors() config.ClientErrors } type ChainConfig interface { diff --git a/common/client/node_test.go b/common/client/node_test.go index a97f26555a9..85c96145740 100644 --- a/common/client/node_test.go +++ b/common/client/node_test.go @@ -9,6 +9,7 @@ import ( clientMocks "github.com/smartcontractkit/chainlink/v2/common/client/mocks" "github.com/smartcontractkit/chainlink/v2/common/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config" ) type testNodeConfig struct { @@ -18,6 +19,7 @@ type testNodeConfig struct { syncThreshold uint32 nodeIsSyncingEnabled bool finalizedBlockPollInterval time.Duration + errors config.ClientErrors } func (n testNodeConfig) PollFailureThreshold() uint32 { @@ -44,6 +46,10 @@ func (n testNodeConfig) FinalizedBlockPollInterval() time.Duration { return n.finalizedBlockPollInterval } +func (n testNodeConfig) Errors() config.ClientErrors { + return n.errors +} + type testNode struct { *node[types.ID, Head, NodeClient[types.ID, Head]] } diff --git a/core/chains/evm/client/chain_client.go b/core/chains/evm/client/chain_client.go index 52bc1263c75..3ee10a600da 100644 --- a/core/chains/evm/client/chain_client.go +++ b/core/chains/evm/client/chain_client.go @@ -5,6 +5,8 @@ import ( "math/big" "time" + evmconfig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" @@ -38,8 +40,9 @@ type chainClient struct { RPCClient, rpc.BatchElem, ] - logger logger.SugaredLogger - chainType config.ChainType + logger logger.SugaredLogger + chainType config.ChainType + clientErrors evmconfig.ClientErrors } func NewChainClient( @@ -51,6 +54,7 @@ func NewChainClient( sendonlys []commonclient.SendOnlyNode[*big.Int, RPCClient], chainID *big.Int, chainType config.ChainType, + clientErrors evmconfig.ClientErrors, ) Client { multiNode := commonclient.NewMultiNode( lggr, @@ -63,13 +67,14 @@ func NewChainClient( chainType, "EVM", func(tx *types.Transaction, err error) commonclient.SendTxReturnCode { - return ClassifySendError(err, logger.Sugared(logger.Nop()), tx, common.Address{}, chainType.IsL2()) + return ClassifySendError(err, clientErrors, logger.Sugared(logger.Nop()), tx, common.Address{}, chainType.IsL2()) }, 0, // use the default value provided by the implementation ) return &chainClient{ - multiNode: multiNode, - logger: logger.Sugared(lggr), + multiNode: multiNode, + logger: logger.Sugared(lggr), + clientErrors: clientErrors, } } @@ -208,7 +213,7 @@ func (c *chainClient) SendTransaction(ctx context.Context, tx *types.Transaction func (c *chainClient) SendTransactionReturnCode(ctx context.Context, tx *types.Transaction, fromAddress common.Address) (commonclient.SendTxReturnCode, error) { err := c.SendTransaction(ctx, tx) - returnCode := ClassifySendError(err, c.logger, tx, fromAddress, c.IsL2()) + returnCode := ClassifySendError(err, c.clientErrors, c.logger, tx, fromAddress, c.IsL2()) return returnCode, err } diff --git a/core/chains/evm/client/client.go b/core/chains/evm/client/client.go index 2758c9cf0a4..9628c74b9ab 100644 --- a/core/chains/evm/client/client.go +++ b/core/chains/evm/client/client.go @@ -225,7 +225,7 @@ func (client *client) HeaderByHash(ctx context.Context, h common.Hash) (*types.H func (client *client) SendTransactionReturnCode(ctx context.Context, tx *types.Transaction, fromAddress common.Address) (commonclient.SendTxReturnCode, error) { err := client.SendTransaction(ctx, tx) - returnCode := ClassifySendError(err, client.logger, tx, fromAddress, client.pool.ChainType().IsL2()) + returnCode := ClassifySendError(err, nil, client.logger, tx, fromAddress, client.pool.ChainType().IsL2()) return returnCode, err } diff --git a/core/chains/evm/client/config_builder_test.go b/core/chains/evm/client/config_builder_test.go index 431cbc82353..963cb855023 100644 --- a/core/chains/evm/client/config_builder_test.go +++ b/core/chains/evm/client/config_builder_test.go @@ -56,7 +56,7 @@ func TestClientConfigBuilder(t *testing.T) { require.Equal(t, *finalityTagEnabled, chainCfg.FinalityTagEnabled()) // let combiler tell us, when we do not have sufficient data to create evm client - _ = client.NewEvmClient(nodePool, chainCfg, logger.Test(t), big.NewInt(10), nodes) + _ = client.NewEvmClient(nodePool, chainCfg, nil, logger.Test(t), big.NewInt(10), nodes) } func TestNodeConfigs(t *testing.T) { diff --git a/core/chains/evm/client/errors.go b/core/chains/evm/client/errors.go index 37572bc8643..b7e0d9317eb 100644 --- a/core/chains/evm/client/errors.go +++ b/core/chains/evm/client/errors.go @@ -13,6 +13,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" commonclient "github.com/smartcontractkit/chainlink/v2/common/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/label" ) @@ -29,16 +30,11 @@ func (s *SendError) Error() string { // Fatal indicates whether the error should be considered fatal or not // Fatal errors mean that no matter how many times the send is retried, no node // will ever accept it -func (s *SendError) Fatal() bool { - return s != nil && s.fatal -} - -// CauseStr returns the string of the original error -func (s *SendError) CauseStr() string { - if s.err != nil { - return pkgerrors.Cause(s.err).Error() +func (s *SendError) Fatal(configErrors *ClientErrors) bool { + if configErrors != nil && configErrors.ErrIs(s.err, Fatal) { + return true } - return "" + return s != nil && s.fatal } const ( @@ -66,7 +62,26 @@ const ( OutOfCounters ) -type ClientErrors = map[int]*regexp.Regexp +type ClientErrors map[int]*regexp.Regexp + +// ErrIs returns true if err matches any provided error types +func (e *ClientErrors) ErrIs(err error, errorTypes ...int) bool { + if err == nil { + return false + } + for _, errorType := range errorTypes { + if _, ok := (*e)[errorType]; !ok { + return false + } + if (*e)[errorType].String() == "" { + return false + } + if (*e)[errorType].MatchString(pkgerrors.Cause(err).Error()) { + return true + } + } + return false +} // Parity // See: https://github.com/openethereum/openethereum/blob/master/rpc/src/v1/helpers/errors.rs#L420 @@ -235,16 +250,38 @@ var zkEvm = ClientErrors{ var clients = []ClientErrors{parity, geth, arbitrum, metis, substrate, avalanche, nethermind, harmony, besu, erigon, klaytn, celo, zkSync, zkEvm} -func (s *SendError) is(errorType int) bool { +// ClientErrorRegexes returns a map of compiled regexes for each error type +func ClientErrorRegexes(errsRegex config.ClientErrors) *ClientErrors { + if errsRegex == nil { + return &ClientErrors{} + } + return &ClientErrors{ + NonceTooLow: regexp.MustCompile(errsRegex.NonceTooLow()), + NonceTooHigh: regexp.MustCompile(errsRegex.NonceTooHigh()), + ReplacementTransactionUnderpriced: regexp.MustCompile(errsRegex.ReplacementTransactionUnderpriced()), + LimitReached: regexp.MustCompile(errsRegex.LimitReached()), + TransactionAlreadyInMempool: regexp.MustCompile(errsRegex.TransactionAlreadyInMempool()), + TerminallyUnderpriced: regexp.MustCompile(errsRegex.TerminallyUnderpriced()), + InsufficientEth: regexp.MustCompile(errsRegex.InsufficientEth()), + TxFeeExceedsCap: regexp.MustCompile(errsRegex.TxFeeExceedsCap()), + L2FeeTooLow: regexp.MustCompile(errsRegex.L2FeeTooLow()), + L2FeeTooHigh: regexp.MustCompile(errsRegex.L2FeeTooHigh()), + L2Full: regexp.MustCompile(errsRegex.L2Full()), + TransactionAlreadyMined: regexp.MustCompile(errsRegex.TransactionAlreadyMined()), + Fatal: regexp.MustCompile(errsRegex.Fatal()), + ServiceUnavailable: regexp.MustCompile(errsRegex.ServiceUnavailable()), + } +} + +func (s *SendError) is(errorType int, configErrors *ClientErrors) bool { if s == nil || s.err == nil { return false } - str := s.CauseStr() + if configErrors != nil && configErrors.ErrIs(s.err, errorType) { + return true + } for _, client := range clients { - if _, ok := client[errorType]; !ok { - continue - } - if client[errorType].MatchString(str) { + if client.ErrIs(s.err, errorType) { return true } } @@ -252,72 +289,72 @@ func (s *SendError) is(errorType int) bool { } // IsReplacementUnderpriced indicates that a transaction already exists in the mempool with this nonce but a different gas price or payload -func (s *SendError) IsReplacementUnderpriced() bool { - return s.is(ReplacementTransactionUnderpriced) +func (s *SendError) IsReplacementUnderpriced(configErrors *ClientErrors) bool { + return s.is(ReplacementTransactionUnderpriced, configErrors) } -func (s *SendError) IsNonceTooLowError() bool { - return s.is(NonceTooLow) +func (s *SendError) IsNonceTooLowError(configErrors *ClientErrors) bool { + return s.is(NonceTooLow, configErrors) } -func (s *SendError) IsNonceTooHighError() bool { - return s.is(NonceTooHigh) +func (s *SendError) IsNonceTooHighError(configErrors *ClientErrors) bool { + return s.is(NonceTooHigh, configErrors) } // IsTransactionAlreadyMined - Harmony returns this error if the transaction has already been mined -func (s *SendError) IsTransactionAlreadyMined() bool { - return s.is(TransactionAlreadyMined) +func (s *SendError) IsTransactionAlreadyMined(configErrors *ClientErrors) bool { + return s.is(TransactionAlreadyMined, configErrors) } // Geth/parity returns this error if the transaction is already in the node's mempool -func (s *SendError) IsTransactionAlreadyInMempool() bool { - return s.is(TransactionAlreadyInMempool) +func (s *SendError) IsTransactionAlreadyInMempool(configErrors *ClientErrors) bool { + return s.is(TransactionAlreadyInMempool, configErrors) } // IsTerminallyUnderpriced indicates that this transaction is so far underpriced the node won't even accept it in the first place -func (s *SendError) IsTerminallyUnderpriced() bool { - return s.is(TerminallyUnderpriced) +func (s *SendError) IsTerminallyUnderpriced(configErrors *ClientErrors) bool { + return s.is(TerminallyUnderpriced, configErrors) } -func (s *SendError) IsTemporarilyUnderpriced() bool { - return s.is(LimitReached) +func (s *SendError) IsTemporarilyUnderpriced(configErrors *ClientErrors) bool { + return s.is(LimitReached, configErrors) } -func (s *SendError) IsInsufficientEth() bool { - return s.is(InsufficientEth) +func (s *SendError) IsInsufficientEth(configErrors *ClientErrors) bool { + return s.is(InsufficientEth, configErrors) } // IsTxFeeExceedsCap returns true if the transaction and gas price are combined in // some way that makes the total transaction too expensive for the eth node to // accept at all. No amount of retrying at this or higher gas prices can ever // succeed. -func (s *SendError) IsTxFeeExceedsCap() bool { - return s.is(TxFeeExceedsCap) +func (s *SendError) IsTxFeeExceedsCap(configErrors *ClientErrors) bool { + return s.is(TxFeeExceedsCap, configErrors) } // L2FeeTooLow is an l2-specific error returned when total fee is too low -func (s *SendError) L2FeeTooLow() bool { - return s.is(L2FeeTooLow) +func (s *SendError) L2FeeTooLow(configErrors *ClientErrors) bool { + return s.is(L2FeeTooLow, configErrors) } // IsL2FeeTooHigh is an l2-specific error returned when total fee is too high -func (s *SendError) IsL2FeeTooHigh() bool { - return s.is(L2FeeTooHigh) +func (s *SendError) IsL2FeeTooHigh(configErrors *ClientErrors) bool { + return s.is(L2FeeTooHigh, configErrors) } // IsL2Full is an l2-specific error returned when the queue or mempool is full. -func (s *SendError) IsL2Full() bool { - return s.is(L2Full) +func (s *SendError) IsL2Full(configErrors *ClientErrors) bool { + return s.is(L2Full, configErrors) } // IsServiceUnavailable indicates if the error was caused by a service being unavailable -func (s *SendError) IsServiceUnavailable() bool { - return s.is(ServiceUnavailable) +func (s *SendError) IsServiceUnavailable(configErrors *ClientErrors) bool { + return s.is(ServiceUnavailable, configErrors) } // IsOutOfCounters is a zk chain specific error returned if the transaction is too complex to prove on zk circuits -func (s *SendError) IsOutOfCounters() bool { - return s.is(OutOfCounters) +func (s *SendError) IsOutOfCounters(configErrors *ClientErrors) bool { + return s.is(OutOfCounters, configErrors) } // IsTimeout indicates if the error was caused by an exceeded context deadline @@ -369,6 +406,7 @@ func isFatalSendError(err error) bool { return false } str := pkgerrors.Cause(err).Error() + for _, client := range clients { if _, ok := client[Fatal]; !ok { continue @@ -444,23 +482,26 @@ func ExtractRPCError(baseErr error) (*JsonError, error) { return &jErr, nil } -func ClassifySendError(err error, lggr logger.SugaredLogger, tx *types.Transaction, fromAddress common.Address, isL2 bool) commonclient.SendTxReturnCode { +func ClassifySendError(err error, clientErrors config.ClientErrors, lggr logger.SugaredLogger, tx *types.Transaction, fromAddress common.Address, isL2 bool) commonclient.SendTxReturnCode { sendError := NewSendError(err) if sendError == nil { return commonclient.Successful } - if sendError.Fatal() { + + configErrors := ClientErrorRegexes(clientErrors) + + if sendError.Fatal(configErrors) { lggr.Criticalw("Fatal error sending transaction", "err", sendError, "etx", tx) // Attempt is thrown away in this case; we don't need it since it never got accepted by a node return commonclient.Fatal } - if sendError.IsNonceTooLowError() || sendError.IsTransactionAlreadyMined() { + if sendError.IsNonceTooLowError(configErrors) || sendError.IsTransactionAlreadyMined(configErrors) { lggr.Debugw(fmt.Sprintf("Transaction already confirmed for this nonce: %d", tx.Nonce()), "err", sendError, "etx", tx) // Nonce too low indicated that a transaction at this nonce was confirmed already. // Mark it as TransactionAlreadyKnown. return commonclient.TransactionAlreadyKnown } - if sendError.IsReplacementUnderpriced() { + if sendError.IsReplacementUnderpriced(configErrors) { lggr.Errorw(fmt.Sprintf("Replacement transaction underpriced for eth_tx %x. "+ "Please note that using your node's private keys outside of the chainlink node is NOT SUPPORTED and can lead to missed transactions.", tx.Hash()), "gasPrice", tx.GasPrice, "gasTipCap", tx.GasTipCap, "gasFeeCap", tx.GasFeeCap, "err", sendError, "etx", tx) @@ -468,19 +509,19 @@ func ClassifySendError(err error, lggr logger.SugaredLogger, tx *types.Transacti // Assume success and hand off to the next cycle. return commonclient.Successful } - if sendError.IsTransactionAlreadyInMempool() { + if sendError.IsTransactionAlreadyInMempool(configErrors) { lggr.Debugw("Transaction already in mempool", "etx", tx, "err", sendError) return commonclient.Successful } - if sendError.IsTemporarilyUnderpriced() { + if sendError.IsTemporarilyUnderpriced(configErrors) { lggr.Infow("Transaction temporarily underpriced", "err", sendError) return commonclient.Successful } - if sendError.IsTerminallyUnderpriced() { + if sendError.IsTerminallyUnderpriced(configErrors) { lggr.Errorw("Transaction terminally underpriced", "etx", tx, "err", sendError) return commonclient.Underpriced } - if sendError.L2FeeTooLow() || sendError.IsL2FeeTooHigh() || sendError.IsL2Full() { + if sendError.L2FeeTooLow(configErrors) || sendError.IsL2FeeTooHigh(configErrors) || sendError.IsL2Full(configErrors) { if isL2 { lggr.Errorw("Transaction fee out of range", "err", sendError, "etx", tx) return commonclient.FeeOutOfValidRange @@ -488,21 +529,21 @@ func ClassifySendError(err error, lggr logger.SugaredLogger, tx *types.Transacti lggr.Errorw("this error type only handled for L2s", "err", sendError, "etx", tx) return commonclient.Unsupported } - if sendError.IsNonceTooHighError() { + if sendError.IsNonceTooHighError(configErrors) { // This error occurs when the tx nonce is greater than current_nonce + tx_count_in_mempool, // instead of keeping the tx in mempool. This can happen if previous transactions haven't // reached the client yet. The correct thing to do is to mark it as retryable. lggr.Warnw("Transaction has a nonce gap.", "err", sendError, "etx", tx) return commonclient.Retryable } - if sendError.IsInsufficientEth() { + if sendError.IsInsufficientEth(configErrors) { lggr.Criticalw(fmt.Sprintf("Tx %x with type 0x%d was rejected due to insufficient eth: %s\n"+ "ACTION REQUIRED: Chainlink wallet with address 0x%x is OUT OF FUNDS", tx.Hash(), tx.Type(), sendError.Error(), fromAddress, ), "err", sendError, "etx", tx) return commonclient.InsufficientFunds } - if sendError.IsServiceUnavailable() { + if sendError.IsServiceUnavailable(configErrors) { lggr.Errorw(fmt.Sprintf("service unavailable while sending transaction %x", tx.Hash()), "err", sendError, "etx", tx) return commonclient.Retryable } @@ -514,7 +555,7 @@ func ClassifySendError(err error, lggr logger.SugaredLogger, tx *types.Transacti lggr.Errorw(fmt.Sprintf("context was canceled while sending transaction %x", tx.Hash()), "err", sendError, "etx", tx) return commonclient.Retryable } - if sendError.IsTxFeeExceedsCap() { + if sendError.IsTxFeeExceedsCap(configErrors) { lggr.Criticalw(fmt.Sprintf("Sending transaction failed: %s", label.RPCTxFeeCapConfiguredIncorrectlyWarning), "etx", tx, "err", sendError, diff --git a/core/chains/evm/client/errors_test.go b/core/chains/evm/client/errors_test.go index 5d1fa135725..744abb89f60 100644 --- a/core/chains/evm/client/errors_test.go +++ b/core/chains/evm/client/errors_test.go @@ -1,6 +1,7 @@ package client_test import ( + "errors" "testing" pkgerrors "github.com/pkg/errors" @@ -25,9 +26,10 @@ func Test_Eth_Errors(t *testing.T) { var err *evmclient.SendError randomError := evmclient.NewSendErrorS("some old bollocks") - t.Run("IsNonceTooLowError", func(t *testing.T) { - assert.False(t, randomError.IsNonceTooLowError()) + testErrors := evmclient.NewTestClientErrors() + clientErrors := evmclient.ClientErrorRegexes(&testErrors) + t.Run("IsNonceTooLowError", func(t *testing.T) { tests := []errorCase{ {"nonce too low", true, "Geth"}, {"nonce too low: address 0x336394A3219e71D9d9bd18201d34E95C1Bb7122C, tx: 8089 state: 8090", true, "Arbitrum"}, @@ -41,20 +43,20 @@ func Test_Eth_Errors(t *testing.T) { {"call failed: OldNonce", true, "Nethermind"}, {"call failed: OldNonce, Current nonce: 22, nonce of rejected tx: 17", true, "Nethermind"}, {"nonce too low. allowed nonce range: 427 - 447, actual: 426", true, "zkSync"}, + {"client error nonce too low", true, "tomlConfig"}, } for _, test := range tests { t.Run(test.network, func(t *testing.T) { err = evmclient.NewSendErrorS(test.message) - assert.Equal(t, err.IsNonceTooLowError(), test.expect) + assert.Equal(t, err.IsNonceTooLowError(clientErrors), test.expect) err = newSendErrorWrapped(test.message) - assert.Equal(t, err.IsNonceTooLowError(), test.expect) + assert.Equal(t, err.IsNonceTooLowError(clientErrors), test.expect) }) } }) t.Run("IsNonceTooHigh", func(t *testing.T) { - tests := []errorCase{ {"call failed: NonceGap", true, "Nethermind"}, {"call failed: NonceGap, Future nonce. Expected nonce: 10", true, "Nethermind"}, @@ -62,29 +64,31 @@ func Test_Eth_Errors(t *testing.T) { {"nonce too high", true, "Geth"}, {"nonce too high", true, "Erigon"}, {"nonce too high. allowed nonce range: 427 - 477, actual: 527", true, "zkSync"}, + {"client error nonce too high", true, "tomlConfig"}, } for _, test := range tests { err = evmclient.NewSendErrorS(test.message) - assert.Equal(t, err.IsNonceTooHighError(), test.expect) + assert.Equal(t, err.IsNonceTooHighError(clientErrors), test.expect) err = newSendErrorWrapped(test.message) - assert.Equal(t, err.IsNonceTooHighError(), test.expect) + assert.Equal(t, err.IsNonceTooHighError(clientErrors), test.expect) } }) t.Run("IsTransactionAlreadyMined", func(t *testing.T) { - assert.False(t, randomError.IsTransactionAlreadyMined()) + assert.False(t, randomError.IsTransactionAlreadyMined(clientErrors)) tests := []errorCase{ {"transaction already finalized", true, "Harmony"}, + {"client error transaction already mined", true, "tomlConfig"}, } for _, test := range tests { t.Run(test.network, func(t *testing.T) { err = evmclient.NewSendErrorS(test.message) - assert.Equal(t, err.IsTransactionAlreadyMined(), test.expect) + assert.Equal(t, err.IsTransactionAlreadyMined(clientErrors), test.expect) err = newSendErrorWrapped(test.message) - assert.Equal(t, err.IsTransactionAlreadyMined(), test.expect) + assert.Equal(t, err.IsTransactionAlreadyMined(clientErrors), test.expect) }) } }) @@ -100,18 +104,20 @@ func Test_Eth_Errors(t *testing.T) { {"Transaction gas price 100wei is too low. There is another transaction with same nonce in the queue with gas price 150wei. Try increasing the gas price or incrementing the nonce.", true, "Parity"}, {"There are too many transactions in the queue. Your transaction was dropped due to limit. Try increasing the fee.", false, "Parity"}, {"gas price too low", false, "Arbitrum"}, + {"client error replacement underpriced", true, "tomlConfig"}, + {"", false, "tomlConfig"}, } for _, test := range tests { err = evmclient.NewSendErrorS(test.message) - assert.Equal(t, err.IsReplacementUnderpriced(), test.expect) + assert.Equal(t, err.IsReplacementUnderpriced(clientErrors), test.expect) err = newSendErrorWrapped(test.message) - assert.Equal(t, err.IsReplacementUnderpriced(), test.expect) + assert.Equal(t, err.IsReplacementUnderpriced(clientErrors), test.expect) } }) t.Run("IsTransactionAlreadyInMempool", func(t *testing.T) { - assert.False(t, randomError.IsTransactionAlreadyInMempool()) + assert.False(t, randomError.IsTransactionAlreadyInMempool(clientErrors)) tests := []errorCase{ // I have seen this in log output @@ -130,17 +136,18 @@ func Test_Eth_Errors(t *testing.T) { {"known transaction. transaction with hash 0x6013…3053 is already in the system", true, "zkSync"}, // This seems to be an erroneous message from the zkSync client, we'll have to match it anyway {"ErrorObject { code: ServerError(3), message: \\\"known transaction. transaction with hash 0xf016…ad63 is already in the system\\\", data: Some(RawValue(\\\"0x\\\")) }", true, "zkSync"}, + {"client error transaction already in mempool", true, "tomlConfig"}, } for _, test := range tests { err = evmclient.NewSendErrorS(test.message) - assert.Equal(t, err.IsTransactionAlreadyInMempool(), test.expect) + assert.Equal(t, err.IsTransactionAlreadyInMempool(clientErrors), test.expect) err = newSendErrorWrapped(test.message) - assert.Equal(t, err.IsTransactionAlreadyInMempool(), test.expect) + assert.Equal(t, err.IsTransactionAlreadyInMempool(clientErrors), test.expect) } }) t.Run("IsTerminallyUnderpriced", func(t *testing.T) { - assert.False(t, randomError.IsTerminallyUnderpriced()) + assert.False(t, randomError.IsTerminallyUnderpriced(clientErrors)) tests := []errorCase{ {"transaction underpriced", true, "geth"}, @@ -159,13 +166,14 @@ func Test_Eth_Errors(t *testing.T) { {"intrinsic gas too low", true, "Klaytn"}, {"max fee per gas less than block base fee", true, "zkSync"}, {"virtual machine entered unexpected state. please contact developers and provide transaction details that caused this error. Error description: The operator included transaction with an unacceptable gas price", true, "zkSync"}, + {"client error terminally underpriced", true, "tomlConfig"}, } for _, test := range tests { err = evmclient.NewSendErrorS(test.message) - assert.Equal(t, err.IsTerminallyUnderpriced(), test.expect, "expected %q to match %s for client %s", err, "IsTerminallyUnderpriced", test.network) + assert.Equal(t, err.IsTerminallyUnderpriced(clientErrors), test.expect, "expected %q to match %s for client %s", err, "IsTerminallyUnderpriced", test.network) err = newSendErrorWrapped(test.message) - assert.Equal(t, err.IsTerminallyUnderpriced(), test.expect, "expected %q to match %s for client %s", err, "IsTerminallyUnderpriced", test.network) + assert.Equal(t, err.IsTerminallyUnderpriced(clientErrors), test.expect, "expected %q to match %s for client %s", err, "IsTerminallyUnderpriced", test.network) } }) @@ -174,12 +182,13 @@ func Test_Eth_Errors(t *testing.T) { {"There are too many transactions in the queue. Your transaction was dropped due to limit. Try increasing the fee.", true, "Parity"}, {"There are too many transactions in the queue. Your transaction was dropped due to limit. Try increasing the fee.", true, "Parity"}, {"Transaction gas price is too low. It does not satisfy your node's minimal gas price (minimal: 100 got: 50). Try increasing the gas price.", false, "Parity"}, + {"client error transaction underpriced", false, "tomlConfig"}, } for _, test := range tests { err = evmclient.NewSendErrorS(test.message) - assert.Equal(t, err.IsTemporarilyUnderpriced(), test.expect) + assert.Equal(t, err.IsTemporarilyUnderpriced(clientErrors), test.expect) err = newSendErrorWrapped(test.message) - assert.Equal(t, err.IsTemporarilyUnderpriced(), test.expect) + assert.Equal(t, err.IsTemporarilyUnderpriced(clientErrors), test.expect) } }) @@ -204,12 +213,13 @@ func Test_Eth_Errors(t *testing.T) { {"insufficient funds for gas * price + value + gatewayFee", true, "celo"}, {"insufficient balance for transfer", true, "zkSync"}, {"insufficient funds for gas + value. balance: 42719769622667482000, fee: 48098250000000, value: 42719769622667482000", true, "celo"}, + {"client error insufficient eth", true, "tomlConfig"}, } for _, test := range tests { err = evmclient.NewSendErrorS(test.message) - assert.Equal(t, err.IsInsufficientEth(), test.expect) + assert.Equal(t, err.IsInsufficientEth(clientErrors), test.expect) err = newSendErrorWrapped(test.message) - assert.Equal(t, err.IsInsufficientEth(), test.expect) + assert.Equal(t, err.IsInsufficientEth(clientErrors), test.expect) } }) @@ -217,12 +227,13 @@ func Test_Eth_Errors(t *testing.T) { tests := []errorCase{ {"call failed: 503 Service Unavailable: \r\n503 Service Temporarily Unavailable\r\n\r\n

503 Service Temporarily Unavailable

\r\n\r\n\r\n", true, "Nethermind"}, {"call failed: 502 Bad Gateway: \r\n502 Bad Gateway\r\n\r\n

502 Bad Gateway

\r\n
", true, "Arbitrum"}, + {"client error service unavailable", true, "tomlConfig"}, } for _, test := range tests { err = evmclient.NewSendErrorS(test.message) - assert.Equal(t, err.IsServiceUnavailable(), test.expect) + assert.Equal(t, err.IsServiceUnavailable(clientErrors), test.expect) err = newSendErrorWrapped(test.message) - assert.Equal(t, err.IsServiceUnavailable(), test.expect) + assert.Equal(t, err.IsServiceUnavailable(clientErrors), test.expect) } }) @@ -237,68 +248,72 @@ func Test_Eth_Errors(t *testing.T) { {"max fee per gas higher than max priority fee per gas", true, "Klaytn"}, {"tx fee (1.10 of currency celo) exceeds the configured cap (1.00 celo)", true, "celo"}, {"max priority fee per gas higher than max fee per gas", true, "zkSync"}, + {"client error tx fee exceeds cap", true, "tomlConfig"}, } for _, test := range tests { err = evmclient.NewSendErrorS(test.message) - assert.Equal(t, err.IsTxFeeExceedsCap(), test.expect) + assert.Equal(t, err.IsTxFeeExceedsCap(clientErrors), test.expect) err = newSendErrorWrapped(test.message) - assert.Equal(t, err.IsTxFeeExceedsCap(), test.expect) + assert.Equal(t, err.IsTxFeeExceedsCap(clientErrors), test.expect) } - assert.False(t, randomError.IsTxFeeExceedsCap()) + assert.False(t, randomError.IsTxFeeExceedsCap(clientErrors)) // Nil err = evmclient.NewSendError(nil) - assert.False(t, err.IsTxFeeExceedsCap()) + assert.False(t, err.IsTxFeeExceedsCap(clientErrors)) }) t.Run("L2 Fees errors", func(t *testing.T) { err = evmclient.NewSendErrorS("max fee per gas less than block base fee") - assert.False(t, err.IsL2FeeTooHigh()) - assert.True(t, err.L2FeeTooLow()) + assert.False(t, err.IsL2FeeTooHigh(clientErrors)) + assert.True(t, err.L2FeeTooLow(clientErrors)) err = newSendErrorWrapped("max fee per gas less than block base fee") - assert.False(t, err.IsL2FeeTooHigh()) - assert.True(t, err.L2FeeTooLow()) + assert.False(t, err.IsL2FeeTooHigh(clientErrors)) + assert.True(t, err.L2FeeTooLow(clientErrors)) err = evmclient.NewSendErrorS("queue full") - assert.True(t, err.IsL2Full()) + assert.True(t, err.IsL2Full(clientErrors)) err = evmclient.NewSendErrorS("sequencer pending tx pool full, please try again") - assert.True(t, err.IsL2Full()) + assert.True(t, err.IsL2Full(clientErrors)) - assert.False(t, randomError.IsL2FeeTooHigh()) - assert.False(t, randomError.L2FeeTooLow()) + assert.False(t, randomError.IsL2FeeTooHigh(clientErrors)) + assert.False(t, randomError.L2FeeTooLow(clientErrors)) // Nil err = evmclient.NewSendError(nil) - assert.False(t, err.IsL2FeeTooHigh()) - assert.False(t, err.L2FeeTooLow()) + assert.False(t, err.IsL2FeeTooHigh(clientErrors)) + assert.False(t, err.L2FeeTooLow(clientErrors)) }) t.Run("Metis gas price errors", func(t *testing.T) { err := evmclient.NewSendErrorS("primary websocket (wss://ws-mainnet.metis.io) call failed: gas price too low: 18000000000 wei, use at least tx.gasPrice = 19500000000 wei") - assert.True(t, err.L2FeeTooLow()) + assert.True(t, err.L2FeeTooLow(clientErrors)) err = newSendErrorWrapped("primary websocket (wss://ws-mainnet.metis.io) call failed: gas price too low: 18000000000 wei, use at least tx.gasPrice = 19500000000 wei") - assert.True(t, err.L2FeeTooLow()) + assert.True(t, err.L2FeeTooLow(clientErrors)) - assert.False(t, randomError.L2FeeTooLow()) + assert.False(t, randomError.L2FeeTooLow(clientErrors)) // Nil err = evmclient.NewSendError(nil) - assert.False(t, err.L2FeeTooLow()) + assert.False(t, err.L2FeeTooLow(clientErrors)) }) t.Run("moonriver errors", func(t *testing.T) { err := evmclient.NewSendErrorS("primary http (http://***REDACTED***:9933) call failed: submit transaction to pool failed: Pool(Stale)") - assert.True(t, err.IsNonceTooLowError()) - assert.False(t, err.IsTransactionAlreadyInMempool()) - assert.False(t, err.Fatal()) + assert.True(t, err.IsNonceTooLowError(clientErrors)) + assert.False(t, err.IsTransactionAlreadyInMempool(clientErrors)) + assert.False(t, err.Fatal(clientErrors)) err = evmclient.NewSendErrorS("primary http (http://***REDACTED***:9933) call failed: submit transaction to pool failed: Pool(AlreadyImported)") - assert.True(t, err.IsTransactionAlreadyInMempool()) - assert.False(t, err.IsNonceTooLowError()) - assert.False(t, err.Fatal()) + assert.True(t, err.IsTransactionAlreadyInMempool(clientErrors)) + assert.False(t, err.IsNonceTooLowError(clientErrors)) + assert.False(t, err.Fatal(clientErrors)) }) } func Test_Eth_Errors_Fatal(t *testing.T) { t.Parallel() + testErrors := evmclient.NewTestClientErrors() + clientErrors := evmclient.ClientErrorRegexes(&testErrors) + tests := []errorCase{ {"some old bollocks", false, "none"}, @@ -363,12 +378,38 @@ func Test_Eth_Errors_Fatal(t *testing.T) { {"Failed to serialize transaction: max fee per pubdata byte higher than 2^64-1", true, "zkSync"}, {"Failed to serialize transaction: max priority fee per gas higher than 2^64-1", true, "zkSync"}, {"Failed to serialize transaction: oversized data. max: 1000000; actual: 1000000", true, "zkSync"}, + + {"client error fatal", true, "tomlConfig"}, } for _, test := range tests { t.Run(test.message, func(t *testing.T) { err := evmclient.NewSendError(pkgerrors.New(test.message)) - assert.Equal(t, test.expect, err.Fatal()) + assert.Equal(t, test.expect, err.Fatal(clientErrors)) }) } } + +func Test_Config_Errors(t *testing.T) { + testErrors := evmclient.NewTestClientErrors() + clientErrors := evmclient.ClientErrorRegexes(&testErrors) + + t.Run("Client Error Matching", func(t *testing.T) { + assert.True(t, clientErrors.ErrIs(errors.New(testErrors.NonceTooLow()), evmclient.NonceTooLow)) + assert.True(t, clientErrors.ErrIs(errors.New(testErrors.NonceTooHigh()), evmclient.NonceTooHigh)) + assert.True(t, clientErrors.ErrIs(errors.New(testErrors.ReplacementTransactionUnderpriced()), evmclient.ReplacementTransactionUnderpriced)) + assert.True(t, clientErrors.ErrIs(errors.New(testErrors.LimitReached()), evmclient.LimitReached)) + assert.True(t, clientErrors.ErrIs(errors.New(testErrors.TransactionAlreadyInMempool()), evmclient.TransactionAlreadyInMempool)) + assert.True(t, clientErrors.ErrIs(errors.New(testErrors.TerminallyUnderpriced()), evmclient.TerminallyUnderpriced)) + assert.True(t, clientErrors.ErrIs(errors.New(testErrors.InsufficientEth()), evmclient.InsufficientEth)) + assert.True(t, clientErrors.ErrIs(errors.New(testErrors.TxFeeExceedsCap()), evmclient.TxFeeExceedsCap)) + assert.True(t, clientErrors.ErrIs(errors.New(testErrors.L2FeeTooLow()), evmclient.L2FeeTooLow)) + assert.True(t, clientErrors.ErrIs(errors.New(testErrors.L2FeeTooHigh()), evmclient.L2FeeTooHigh)) + assert.True(t, clientErrors.ErrIs(errors.New(testErrors.L2Full()), evmclient.L2Full)) + assert.True(t, clientErrors.ErrIs(errors.New(testErrors.TransactionAlreadyMined()), evmclient.TransactionAlreadyMined)) + assert.True(t, clientErrors.ErrIs(errors.New(testErrors.Fatal()), evmclient.Fatal)) + assert.True(t, clientErrors.ErrIs(errors.New(testErrors.ServiceUnavailable()), evmclient.ServiceUnavailable)) + assert.True(t, clientErrors.ErrIs(errors.New(testErrors.ServiceUnavailable()), evmclient.L2Full, evmclient.ServiceUnavailable)) + assert.False(t, clientErrors.ErrIs(errors.New("some old bollocks"), evmclient.NonceTooLow)) + }) +} diff --git a/core/chains/evm/client/evm_client.go b/core/chains/evm/client/evm_client.go index f60605bc88e..98f7c99bf40 100644 --- a/core/chains/evm/client/evm_client.go +++ b/core/chains/evm/client/evm_client.go @@ -12,7 +12,7 @@ import ( evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ) -func NewEvmClient(cfg evmconfig.NodePool, chainCfg commonclient.ChainConfig, lggr logger.Logger, chainID *big.Int, nodes []*toml.Node) Client { +func NewEvmClient(cfg evmconfig.NodePool, chainCfg commonclient.ChainConfig, clientErrors evmconfig.ClientErrors, lggr logger.Logger, chainID *big.Int, nodes []*toml.Node) Client { var empty url.URL var primaries []commonclient.Node[*big.Int, *evmtypes.Head, RPCClient] var sendonlys []commonclient.SendOnlyNode[*big.Int, RPCClient] @@ -32,6 +32,7 @@ func NewEvmClient(cfg evmconfig.NodePool, chainCfg commonclient.ChainConfig, lgg primaries = append(primaries, primaryNode) } } + return NewChainClient(lggr, cfg.SelectionMode(), cfg.LeaseDuration(), chainCfg.NodeNoNewHeadsThreshold(), - primaries, sendonlys, chainID, chainCfg.ChainType()) + primaries, sendonlys, chainID, chainCfg.ChainType(), clientErrors) } diff --git a/core/chains/evm/client/evm_client_test.go b/core/chains/evm/client/evm_client_test.go index 1317c365d38..ea2eed3b240 100644 --- a/core/chains/evm/client/evm_client_test.go +++ b/core/chains/evm/client/evm_client_test.go @@ -36,6 +36,6 @@ func TestNewEvmClient(t *testing.T) { pollFailureThreshold, pollInterval, syncThreshold, nodeIsSyncingEnabled, noNewHeadsThreshold, finalityDepth, finalityTagEnabled) require.NoError(t, err) - client := client.NewEvmClient(nodePool, chainCfg, logger.Test(t), testutils.FixtureChainID, nodes) + client := client.NewEvmClient(nodePool, chainCfg, nil, logger.Test(t), testutils.FixtureChainID, nodes) require.NotNil(t, client) } diff --git a/core/chains/evm/client/helpers_test.go b/core/chains/evm/client/helpers_test.go index 2a360219046..1db8958443c 100644 --- a/core/chains/evm/client/helpers_test.go +++ b/core/chains/evm/client/helpers_test.go @@ -19,6 +19,65 @@ import ( evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ) +type TestClientErrors struct { + nonceTooLow string + nonceTooHigh string + replacementTransactionUnderpriced string + limitReached string + transactionAlreadyInMempool string + terminallyUnderpriced string + insufficientEth string + txFeeExceedsCap string + l2FeeTooLow string + l2FeeTooHigh string + l2Full string + transactionAlreadyMined string + fatal string + serviceUnavailable string +} + +func NewTestClientErrors() TestClientErrors { + return TestClientErrors{ + nonceTooLow: "client error nonce too low", + nonceTooHigh: "client error nonce too high", + replacementTransactionUnderpriced: "client error replacement underpriced", + limitReached: "client error limit reached", + transactionAlreadyInMempool: "client error transaction already in mempool", + terminallyUnderpriced: "client error terminally underpriced", + insufficientEth: "client error insufficient eth", + txFeeExceedsCap: "client error tx fee exceeds cap", + l2FeeTooLow: "client error l2 fee too low", + l2FeeTooHigh: "client error l2 fee too high", + l2Full: "client error l2 full", + transactionAlreadyMined: "client error transaction already mined", + fatal: "client error fatal", + serviceUnavailable: "client error service unavailable", + } +} + +func (c *TestClientErrors) NonceTooLow() string { return c.nonceTooLow } +func (c *TestClientErrors) NonceTooHigh() string { return c.nonceTooHigh } + +func (c *TestClientErrors) ReplacementTransactionUnderpriced() string { + return c.replacementTransactionUnderpriced +} + +func (c *TestClientErrors) LimitReached() string { return c.limitReached } + +func (c *TestClientErrors) TransactionAlreadyInMempool() string { + return c.transactionAlreadyInMempool +} + +func (c *TestClientErrors) TerminallyUnderpriced() string { return c.terminallyUnderpriced } +func (c *TestClientErrors) InsufficientEth() string { return c.insufficientEth } +func (c *TestClientErrors) TxFeeExceedsCap() string { return c.txFeeExceedsCap } +func (c *TestClientErrors) L2FeeTooLow() string { return c.l2FeeTooLow } +func (c *TestClientErrors) L2FeeTooHigh() string { return c.l2FeeTooHigh } +func (c *TestClientErrors) L2Full() string { return c.l2Full } +func (c *TestClientErrors) TransactionAlreadyMined() string { return c.transactionAlreadyMined } +func (c *TestClientErrors) Fatal() string { return c.fatal } +func (c *TestClientErrors) ServiceUnavailable() string { return c.serviceUnavailable } + type TestNodePoolConfig struct { NodePollFailureThreshold uint32 NodePollInterval time.Duration @@ -27,6 +86,7 @@ type TestNodePoolConfig struct { NodeLeaseDuration time.Duration NodeIsSyncingEnabledVal bool NodeFinalizedBlockPollInterval time.Duration + NodeErrors config.ClientErrors } func (tc TestNodePoolConfig) PollFailureThreshold() uint32 { return tc.NodePollFailureThreshold } @@ -45,6 +105,10 @@ func (tc TestNodePoolConfig) FinalizedBlockPollInterval() time.Duration { return tc.NodeFinalizedBlockPollInterval } +func (tc TestNodePoolConfig) Errors() config.ClientErrors { + return tc.NodeErrors +} + func NewClientWithTestNode(t *testing.T, nodePoolCfg config.NodePool, noNewHeadsThreshold time.Duration, rpcUrl string, rpcHTTPURL *url.URL, sendonlyRPCURLs []url.URL, id int32, chainID *big.Int) (*client, error) { parsed, err := url.ParseRequestURI(rpcUrl) if err != nil { @@ -119,7 +183,8 @@ func NewChainClientWithTestNode( } var chainType commonconfig.ChainType - c := NewChainClient(lggr, nodeCfg.SelectionMode(), leaseDuration, noNewHeadsThreshold, primaries, sendonlys, chainID, chainType) + clientErrors := NewTestClientErrors() + c := NewChainClient(lggr, nodeCfg.SelectionMode(), leaseDuration, noNewHeadsThreshold, primaries, sendonlys, chainID, chainType, &clientErrors) t.Cleanup(c.Close) return c, nil } @@ -135,7 +200,7 @@ func NewChainClientWithEmptyNode( lggr := logger.Test(t) var chainType commonconfig.ChainType - c := NewChainClient(lggr, selectionMode, leaseDuration, noNewHeadsThreshold, nil, nil, chainID, chainType) + c := NewChainClient(lggr, selectionMode, leaseDuration, noNewHeadsThreshold, nil, nil, chainID, chainType, nil) t.Cleanup(c.Close) return c } @@ -161,7 +226,8 @@ func NewChainClientWithMockedRpc( n := commonclient.NewNode[*big.Int, *evmtypes.Head, RPCClient]( cfg, clientMocks.ChainConfig{NoNewHeadsThresholdVal: noNewHeadsThreshold}, lggr, *parsed, nil, "eth-primary-node-0", 1, chainID, 1, rpc, "EVM") primaries := []commonclient.Node[*big.Int, *evmtypes.Head, RPCClient]{n} - c := NewChainClient(lggr, selectionMode, leaseDuration, noNewHeadsThreshold, primaries, nil, chainID, chainType) + clientErrors := NewTestClientErrors() + c := NewChainClient(lggr, selectionMode, leaseDuration, noNewHeadsThreshold, primaries, nil, chainID, chainType, &clientErrors) t.Cleanup(c.Close) return c } diff --git a/core/chains/evm/client/pool.go b/core/chains/evm/client/pool.go index 891fd8c9226..dcaf2a6b543 100644 --- a/core/chains/evm/client/pool.go +++ b/core/chains/evm/client/pool.go @@ -404,7 +404,7 @@ func (p *Pool) SendTransaction(ctx context.Context, tx *types.Transaction) error err := NewSendError(n.SendTransaction(sendCtx, tx)) p.logger.Debugw("Sendonly node sent transaction", "name", n.String(), "tx", tx, "err", err) - if err == nil || err.IsNonceTooLowError() || err.IsTransactionAlreadyMined() || err.IsTransactionAlreadyInMempool() { + if err == nil || err.IsNonceTooLowError(nil) || err.IsTransactionAlreadyMined(nil) || err.IsTransactionAlreadyInMempool(nil) { // Nonce too low or transaction known errors are expected since // the primary SendTransaction may well have succeeded already return diff --git a/core/chains/evm/client/tx_simulator_test.go b/core/chains/evm/client/tx_simulator_test.go index 4e270d401bf..b31b8541abe 100644 --- a/core/chains/evm/client/tx_simulator_test.go +++ b/core/chains/evm/client/tx_simulator_test.go @@ -78,7 +78,7 @@ func TestSimulateTx_Default(t *testing.T) { Data: []byte("0x00"), } sendErr := client.SimulateTransaction(ctx, ethClient, logger.TestSugared(t), "", msg) - require.Equal(t, true, sendErr.IsOutOfCounters()) + require.Equal(t, true, sendErr.IsOutOfCounters(nil)) }) t.Run("returns without error if simulation returns non-OOC error", func(t *testing.T) { @@ -108,6 +108,6 @@ func TestSimulateTx_Default(t *testing.T) { Data: []byte("0x00"), } sendErr := client.SimulateTransaction(ctx, ethClient, logger.TestSugared(t), "", msg) - require.Equal(t, false, sendErr.IsOutOfCounters()) + require.Equal(t, false, sendErr.IsOutOfCounters(nil)) }) } diff --git a/core/chains/evm/config/chain_scoped.go b/core/chains/evm/config/chain_scoped.go index 292582ddbc7..8f94fef09f4 100644 --- a/core/chains/evm/config/chain_scoped.go +++ b/core/chains/evm/config/chain_scoped.go @@ -143,6 +143,10 @@ func (e *EVMConfig) NodePool() NodePool { return &NodePoolConfig{C: e.C.NodePool} } +func (e *EVMConfig) ClientErrors() ClientErrors { + return &clientErrorsConfig{c: e.C.NodePool.Errors} +} + func (e *EVMConfig) NodeNoNewHeadsThreshold() time.Duration { return e.C.NoNewHeadsThreshold.Duration() } diff --git a/core/chains/evm/config/chain_scoped_client_errors.go b/core/chains/evm/config/chain_scoped_client_errors.go new file mode 100644 index 00000000000..53bb04846d2 --- /dev/null +++ b/core/chains/evm/config/chain_scoped_client_errors.go @@ -0,0 +1,50 @@ +package config + +import ( + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" +) + +func derefOrDefault(s *string) string { + if s == nil { + return "" + } + + return *s +} + +type clientErrorsConfig struct { + c toml.ClientErrors +} + +func (c *clientErrorsConfig) NonceTooLow() string { return derefOrDefault(c.c.NonceTooLow) } +func (c *clientErrorsConfig) NonceTooHigh() string { return derefOrDefault(c.c.NonceTooHigh) } + +func (c *clientErrorsConfig) ReplacementTransactionUnderpriced() string { + return derefOrDefault(c.c.ReplacementTransactionUnderpriced) +} + +func (c *clientErrorsConfig) LimitReached() string { return derefOrDefault(c.c.LimitReached) } + +func (c *clientErrorsConfig) TransactionAlreadyInMempool() string { + return derefOrDefault(c.c.TransactionAlreadyInMempool) +} + +func (c *clientErrorsConfig) TerminallyUnderpriced() string { + return derefOrDefault(c.c.TerminallyUnderpriced) +} + +func (c *clientErrorsConfig) InsufficientEth() string { return derefOrDefault(c.c.InsufficientEth) } +func (c *clientErrorsConfig) TxFeeExceedsCap() string { return derefOrDefault(c.c.TxFeeExceedsCap) } +func (c *clientErrorsConfig) L2FeeTooLow() string { return derefOrDefault(c.c.L2FeeTooLow) } +func (c *clientErrorsConfig) L2FeeTooHigh() string { return derefOrDefault(c.c.L2FeeTooHigh) } +func (c *clientErrorsConfig) L2Full() string { return derefOrDefault(c.c.L2Full) } + +func (c *clientErrorsConfig) TransactionAlreadyMined() string { + return derefOrDefault(c.c.TransactionAlreadyMined) +} + +func (c *clientErrorsConfig) Fatal() string { return derefOrDefault(c.c.Fatal) } + +func (c *clientErrorsConfig) ServiceUnavailable() string { + return derefOrDefault(c.c.ServiceUnavailable) +} diff --git a/core/chains/evm/config/chain_scoped_node_pool.go b/core/chains/evm/config/chain_scoped_node_pool.go index 6874b412f7f..7f071e5506f 100644 --- a/core/chains/evm/config/chain_scoped_node_pool.go +++ b/core/chains/evm/config/chain_scoped_node_pool.go @@ -37,3 +37,5 @@ func (n *NodePoolConfig) NodeIsSyncingEnabled() bool { func (n *NodePoolConfig) FinalizedBlockPollInterval() time.Duration { return n.C.FinalizedBlockPollInterval.Duration() } + +func (n *NodePoolConfig) Errors() ClientErrors { return &clientErrorsConfig{c: n.C.Errors} } diff --git a/core/chains/evm/config/config.go b/core/chains/evm/config/config.go index 7295b29b096..34de754de21 100644 --- a/core/chains/evm/config/config.go +++ b/core/chains/evm/config/config.go @@ -76,6 +76,23 @@ type BalanceMonitor interface { Enabled() bool } +type ClientErrors interface { + NonceTooLow() string + NonceTooHigh() string + ReplacementTransactionUnderpriced() string + LimitReached() string + TransactionAlreadyInMempool() string + TerminallyUnderpriced() string + InsufficientEth() string + TxFeeExceedsCap() string + L2FeeTooLow() string + L2FeeTooHigh() string + L2Full() string + TransactionAlreadyMined() string + Fatal() string + ServiceUnavailable() string +} + type Transactions interface { ForwardersEnabled() bool ReaperInterval() time.Duration @@ -141,6 +158,7 @@ type NodePool interface { LeaseDuration() time.Duration NodeIsSyncingEnabled() bool FinalizedBlockPollInterval() time.Duration + Errors() ClientErrors } // TODO BCF-2509 does the chainscopedconfig really need the entire app config? diff --git a/core/chains/evm/config/config_test.go b/core/chains/evm/config/config_test.go index 6fa491051c5..e1c7a9f48cc 100644 --- a/core/chains/evm/config/config_test.go +++ b/core/chains/evm/config/config_test.go @@ -478,4 +478,58 @@ func TestNodePoolConfig(t *testing.T) { require.Equal(t, false, cfg.EVM().NodePool().NodeIsSyncingEnabled()) } +func TestClientErrorsConfig(t *testing.T) { + t.Parallel() + + t.Run("EVM().NodePool().Errors()", func(t *testing.T) { + clientErrorsOverrides := func(c *chainlink.Config, s *chainlink.Secrets) { + id := ubig.New(big.NewInt(rand.Int63())) + c.EVM[0] = &toml.EVMConfig{ + ChainID: id, + Chain: toml.Defaults(id, &toml.Chain{ + NodePool: toml.NodePool{ + Errors: toml.ClientErrors{ + NonceTooLow: ptr[string]("client error nonce too low"), + NonceTooHigh: ptr[string]("client error nonce too high"), + ReplacementTransactionUnderpriced: ptr[string]("client error replacement underpriced"), + LimitReached: ptr[string]("client error limit reached"), + TransactionAlreadyInMempool: ptr[string]("client error transaction already in mempool"), + TerminallyUnderpriced: ptr[string]("client error terminally underpriced"), + InsufficientEth: ptr[string]("client error insufficient eth"), + TxFeeExceedsCap: ptr[string]("client error tx fee exceeds cap"), + L2FeeTooLow: ptr[string]("client error l2 fee too low"), + L2FeeTooHigh: ptr[string]("client error l2 fee too high"), + L2Full: ptr[string]("client error l2 full"), + TransactionAlreadyMined: ptr[string]("client error transaction already mined"), + Fatal: ptr[string]("client error fatal"), + ServiceUnavailable: ptr[string]("client error service unavailable"), + }, + }, + }), + } + } + + gcfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { + clientErrorsOverrides(c, s) + }) + cfg := evmtest.NewChainScopedConfig(t, gcfg) + + errors := cfg.EVM().NodePool().Errors() + assert.Equal(t, "client error nonce too low", errors.NonceTooLow()) + assert.Equal(t, "client error nonce too high", errors.NonceTooHigh()) + assert.Equal(t, "client error replacement underpriced", errors.ReplacementTransactionUnderpriced()) + assert.Equal(t, "client error limit reached", errors.LimitReached()) + assert.Equal(t, "client error transaction already in mempool", errors.TransactionAlreadyInMempool()) + assert.Equal(t, "client error terminally underpriced", errors.TerminallyUnderpriced()) + assert.Equal(t, "client error insufficient eth", errors.InsufficientEth()) + assert.Equal(t, "client error tx fee exceeds cap", errors.TxFeeExceedsCap()) + assert.Equal(t, "client error l2 fee too low", errors.L2FeeTooLow()) + assert.Equal(t, "client error l2 fee too high", errors.L2FeeTooHigh()) + assert.Equal(t, "client error l2 full", errors.L2Full()) + assert.Equal(t, "client error transaction already mined", errors.TransactionAlreadyMined()) + assert.Equal(t, "client error fatal", errors.Fatal()) + assert.Equal(t, "client error service unavailable", errors.ServiceUnavailable()) + }) +} + func ptr[T any](t T) *T { return &t } diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index 0f647034162..1b1baf41094 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -702,6 +702,69 @@ func (t *HeadTracker) setFrom(f *HeadTracker) { } } +type ClientErrors struct { + NonceTooLow *string `toml:",omitempty"` + NonceTooHigh *string `toml:",omitempty"` + ReplacementTransactionUnderpriced *string `toml:",omitempty"` + LimitReached *string `toml:",omitempty"` + TransactionAlreadyInMempool *string `toml:",omitempty"` + TerminallyUnderpriced *string `toml:",omitempty"` + InsufficientEth *string `toml:",omitempty"` + TxFeeExceedsCap *string `toml:",omitempty"` + L2FeeTooLow *string `toml:",omitempty"` + L2FeeTooHigh *string `toml:",omitempty"` + L2Full *string `toml:",omitempty"` + TransactionAlreadyMined *string `toml:",omitempty"` + Fatal *string `toml:",omitempty"` + ServiceUnavailable *string `toml:",omitempty"` +} + +func (r *ClientErrors) setFrom(f *ClientErrors) bool { + if v := f.NonceTooLow; v != nil { + r.NonceTooLow = v + } + if v := f.NonceTooHigh; v != nil { + r.NonceTooHigh = v + } + if v := f.ReplacementTransactionUnderpriced; v != nil { + r.ReplacementTransactionUnderpriced = v + } + if v := f.LimitReached; v != nil { + r.LimitReached = v + } + if v := f.TransactionAlreadyInMempool; v != nil { + r.TransactionAlreadyInMempool = v + } + if v := f.TerminallyUnderpriced; v != nil { + r.TerminallyUnderpriced = v + } + if v := f.InsufficientEth; v != nil { + r.InsufficientEth = v + } + if v := f.TxFeeExceedsCap; v != nil { + r.TxFeeExceedsCap = v + } + if v := f.L2FeeTooLow; v != nil { + r.L2FeeTooLow = v + } + if v := f.L2FeeTooHigh; v != nil { + r.L2FeeTooHigh = v + } + if v := f.L2Full; v != nil { + r.L2Full = v + } + if v := f.TransactionAlreadyMined; v != nil { + r.TransactionAlreadyMined = v + } + if v := f.Fatal; v != nil { + r.Fatal = v + } + if v := f.ServiceUnavailable; v != nil { + r.ServiceUnavailable = v + } + return true +} + type NodePool struct { PollFailureThreshold *uint32 PollInterval *commonconfig.Duration @@ -710,6 +773,7 @@ type NodePool struct { LeaseDuration *commonconfig.Duration NodeIsSyncingEnabled *bool FinalizedBlockPollInterval *commonconfig.Duration + Errors ClientErrors `toml:",omitempty"` } func (p *NodePool) setFrom(f *NodePool) { @@ -734,6 +798,7 @@ func (p *NodePool) setFrom(f *NodePool) { if v := f.FinalizedBlockPollInterval; v != nil { p.FinalizedBlockPollInterval = v } + p.Errors.setFrom(&f.Errors) } type OCR struct { diff --git a/core/chains/evm/txmgr/broadcaster_test.go b/core/chains/evm/txmgr/broadcaster_test.go index 9ab8a808a88..4e19a2ec7da 100644 --- a/core/chains/evm/txmgr/broadcaster_test.go +++ b/core/chains/evm/txmgr/broadcaster_test.go @@ -69,7 +69,7 @@ func NewTestEthBroadcaster( return gas.NewFixedPriceEstimator(config.EVM().GasEstimator(), nil, ge.BlockHistory(), lggr, nil) }, ge.EIP1559DynamicFees(), ge) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, keyStore, estimator) - ethBroadcaster := txmgrcommon.NewBroadcaster(txStore, txmgr.NewEvmTxmClient(ethClient), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(config.EVM().GasEstimator()), config.EVM().Transactions(), gconfig.Database().Listener(), keyStore, txBuilder, nonceTracker, lggr, checkerFactory, nonceAutoSync) + ethBroadcaster := txmgrcommon.NewBroadcaster(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(config.EVM().GasEstimator()), config.EVM().Transactions(), gconfig.Database().Listener(), keyStore, txBuilder, nonceTracker, lggr, checkerFactory, nonceAutoSync) // Mark instance as test ethBroadcaster.XXXTestDisableUnstartedTxAutoProcessing() @@ -86,7 +86,7 @@ func TestEthBroadcaster_Lifecycle(t *testing.T) { cltest.MustInsertRandomKeyReturningState(t, ethKeyStore) estimator := gasmocks.NewEvmFeeEstimator(t) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), evmcfg.EVM().GasEstimator(), ethKeyStore, estimator) - txmClient := txmgr.NewEvmTxmClient(ethClient) + txmClient := txmgr.NewEvmTxmClient(ethClient, nil) ethClient.On("PendingNonceAt", mock.Anything, mock.Anything).Return(uint64(0), nil) eb := txmgr.NewEvmBroadcaster( txStore, @@ -145,7 +145,7 @@ func TestEthBroadcaster_LoadNextSequenceMapFailure_StartupSuccess(t *testing.T) estimator := gasmocks.NewEvmFeeEstimator(t) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), evmcfg.EVM().GasEstimator(), ethKeyStore, estimator) ethClient.On("PendingNonceAt", mock.Anything, mock.Anything).Return(uint64(0), errors.New("Getting on-chain nonce failed")) - txmClient := txmgr.NewEvmTxmClient(ethClient) + txmClient := txmgr.NewEvmTxmClient(ethClient, nil) eb := txmgr.NewEvmBroadcaster( txStore, txmClient, @@ -182,9 +182,8 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Success(t *testing.T) { ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(uint64(0), nil).Once() ethClient.On("PendingNonceAt", mock.Anything, otherAddress).Return(uint64(0), nil).Once() lggr := logger.Test(t) - nonceTracker := txmgr.NewNonceTracker(lggr, txStore, txmgr.NewEvmTxmClient(ethClient)) + nonceTracker := txmgr.NewNonceTracker(lggr, txStore, txmgr.NewEvmTxmClient(ethClient, nil)) eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, cfg, evmcfg, checkerFactory, false, nonceTracker) - toAddress := gethCommon.HexToAddress("0x6C03DDA95a2AEd917EeCc6eddD4b9D16E6380411") timeNow := time.Now() @@ -383,7 +382,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Success(t *testing.T) { }) evmcfg = evmtest.NewChainScopedConfig(t, cfg) ethClient.On("PendingNonceAt", mock.Anything, otherAddress).Return(uint64(1), nil).Once() - nonceTracker = txmgr.NewNonceTracker(lggr, txStore, txmgr.NewEvmTxmClient(ethClient)) + nonceTracker = txmgr.NewNonceTracker(lggr, txStore, txmgr.NewEvmTxmClient(ethClient, nil)) eb = NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, cfg, evmcfg, checkerFactory, false, nonceTracker) t.Run("sends transactions with type 0x2 in EIP-1559 mode", func(t *testing.T) { @@ -533,7 +532,7 @@ func TestEthBroadcaster_TransmitChecking(t *testing.T) { evmcfg := evmtest.NewChainScopedConfig(t, cfg) checkerFactory := &testCheckerFactory{} ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(uint64(0), nil).Once() - nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient)) + nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient, nil)) eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, cfg, evmcfg, checkerFactory, false, nonceTracker) checker := txmgr.TransmitCheckerSpec{ @@ -625,7 +624,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_OptimisticLockingOnEthTx(t *testi <-chBlock }).Once() ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(uint64(0), nil) - txmClient := txmgr.NewEvmTxmClient(ethClient) + txmClient := txmgr.NewEvmTxmClient(ethClient, nil) eb := txmgr.NewEvmBroadcaster( txStore, txmClient, @@ -682,7 +681,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Success_WithMultiplier(t *testing ethClient := evmtest.NewEthClientMockWithDefaultChain(t) ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(uint64(0), nil).Once() - nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient)) + nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient, nil)) eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, cfg, evmcfg, &testCheckerFactory{}, false, nonceTracker) ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *gethTypes.Transaction) bool { @@ -764,7 +763,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) { ethClient := evmtest.NewEthClientMockWithDefaultChain(t) ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(uint64(0), nil).Once() - nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient)) + nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient, nil)) eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, cfg, evmcfg, &testCheckerFactory{}, false, nonceTracker) // Crashed right after we commit the database transaction that saved @@ -803,7 +802,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) { ethClient := evmtest.NewEthClientMockWithDefaultChain(t) ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(uint64(0), nil).Once() - nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient)) + nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient, nil)) eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, cfg, evmcfg, &testCheckerFactory{}, false, nonceTracker) // Crashed right after we commit the database transaction that saved the nonce to the eth_tx @@ -840,7 +839,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) { ethClient := evmtest.NewEthClientMockWithDefaultChain(t) ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(uint64(0), nil).Once() - nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient)) + nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient, nil)) eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, cfg, evmcfg, &testCheckerFactory{}, false, nonceTracker) // Crashed right after we commit the database transaction that saved the nonce to the eth_tx @@ -876,7 +875,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) { ethClient := evmtest.NewEthClientMockWithDefaultChain(t) ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(uint64(0), nil).Once() - nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient)) + nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient, nil)) eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, cfg, evmcfg, &testCheckerFactory{}, false, nonceTracker) // Crashed right after we commit the database transaction that saved the nonce to the eth_tx @@ -914,7 +913,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) { ethClient := evmtest.NewEthClientMockWithDefaultChain(t) ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(uint64(0), nil).Once() - nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient)) + nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient, nil)) eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, cfg, evmcfg, &testCheckerFactory{}, false, nonceTracker) // Crashed right after we commit the database transaction that saved the nonce to the eth_tx @@ -956,7 +955,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) { ethClient := evmtest.NewEthClientMockWithDefaultChain(t) ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(uint64(0), nil).Once() - nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient)) + nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(ethClient, nil)) eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, cfg, evmcfg, &testCheckerFactory{}, false, nonceTracker) // Crashed right after we commit the database transaction that saved the nonce to the eth_tx @@ -1021,7 +1020,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { ethClient := evmtest.NewEthClientMockWithDefaultChain(t) ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(uint64(0), nil).Once() lggr := logger.Test(t) - txmClient := txmgr.NewEvmTxmClient(ethClient) + txmClient := txmgr.NewEvmTxmClient(ethClient, nil) nonceTracker := txmgr.NewNonceTracker(lggr, txStore, txmClient) eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, cfg, evmcfg, &testCheckerFactory{}, false, nonceTracker) ctx := testutils.Context(t) @@ -1667,7 +1666,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_KeystoreErrors(t *testing.T) { kst.On("EnabledAddressesForChain", mock.Anything, &cltest.FixtureChainID).Return(addresses, nil).Once() ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(uint64(0), nil).Once() lggr := logger.Test(t) - nonceTracker := txmgr.NewNonceTracker(lggr, txStore, txmgr.NewEvmTxmClient(ethClient)) + nonceTracker := txmgr.NewNonceTracker(lggr, txStore, txmgr.NewEvmTxmClient(ethClient, nil)) eb := NewTestEthBroadcaster(t, txStore, ethClient, kst, cfg, evmcfg, &testCheckerFactory{}, false, nonceTracker) ctx := testutils.Context(t) _, err := nonceTracker.GetNextSequence(ctx, fromAddress) @@ -1716,7 +1715,7 @@ func TestEthBroadcaster_Trigger(t *testing.T) { ethKeyStore := cltest.NewKeyStore(t, db).Eth() ethClient := evmtest.NewEthClientMockWithDefaultChain(t) lggr := logger.Test(t) - nonceTracker := txmgr.NewNonceTracker(lggr, txStore, txmgr.NewEvmTxmClient(ethClient)) + nonceTracker := txmgr.NewNonceTracker(lggr, txStore, txmgr.NewEvmTxmClient(ethClient, nil)) eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, cfg, evmcfg, &testCheckerFactory{}, false, nonceTracker) eb.Trigger(testutils.NewAddress()) @@ -1754,7 +1753,7 @@ func TestEthBroadcaster_SyncNonce(t *testing.T) { addresses := []gethCommon.Address{fromAddress} kst.On("EnabledAddressesForChain", mock.Anything, &cltest.FixtureChainID).Return(addresses, nil).Once() ethClient.On("PendingNonceAt", mock.Anything, fromAddress).Return(uint64(0), nil).Once() - txmClient := txmgr.NewEvmTxmClient(ethClient) + txmClient := txmgr.NewEvmTxmClient(ethClient, nil) eb := txmgr.NewEvmBroadcaster(txStore, txmClient, evmTxmCfg, txmgr.NewEvmTxmFeeConfig(ge), evmcfg.EVM().Transactions(), cfg.Database().Listener(), kst, txBuilder, lggr, checkerFactory, false) err := eb.Start(ctx) assert.NoError(t, err) @@ -1788,7 +1787,7 @@ func TestEthBroadcaster_NonceTracker_InProgressTx(t *testing.T) { // Tx with nonce 0 in DB will set local nonce map to value to 1 mustInsertInProgressEthTxWithAttempt(t, txStore, evmtypes.Nonce(inProgressTxNonce), fromAddress) - nonceTracker := txmgr.NewNonceTracker(lggr, txStore, txmgr.NewEvmTxmClient(ethClient)) + nonceTracker := txmgr.NewNonceTracker(lggr, txStore, txmgr.NewEvmTxmClient(ethClient, nil)) eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, cfg, evmcfg, checkerFactory, false, nonceTracker) // Check the local nonce map was set to 1 higher than in-progress tx nonce diff --git a/core/chains/evm/txmgr/builder.go b/core/chains/evm/txmgr/builder.go index b345f48a671..f13efb2b258 100644 --- a/core/chains/evm/txmgr/builder.go +++ b/core/chains/evm/txmgr/builder.go @@ -26,6 +26,7 @@ func NewTxm( chainConfig ChainConfig, fCfg FeeConfig, txConfig config.Transactions, + clientErrors config.ClientErrors, dbConfig DatabaseConfig, listenerConfig ListenerConfig, client evmclient.Client, @@ -47,9 +48,9 @@ func NewTxm( // create tx attempt builder txAttemptBuilder := NewEvmTxAttemptBuilder(*client.ConfiguredChainID(), fCfg, keyStore, estimator) txStore := NewTxStore(sqlxDB, lggr) - txmCfg := NewEvmTxmConfig(chainConfig) // wrap Evm specific config - feeCfg := NewEvmTxmFeeConfig(fCfg) // wrap Evm specific config - txmClient := NewEvmTxmClient(client) // wrap Evm specific client + txmCfg := NewEvmTxmConfig(chainConfig) // wrap Evm specific config + feeCfg := NewEvmTxmFeeConfig(fCfg) // wrap Evm specific config + txmClient := NewEvmTxmClient(client, clientErrors) // wrap Evm specific client chainID := txmClient.ConfiguredChainID() evmBroadcaster := NewEvmBroadcaster(txStore, txmClient, txmCfg, feeCfg, txConfig, listenerConfig, keyStore, txAttemptBuilder, lggr, checker, chainConfig.NonceAutoSync()) evmTracker := NewEvmTracker(txStore, keyStore, chainID, lggr) diff --git a/core/chains/evm/txmgr/client.go b/core/chains/evm/txmgr/client.go index 89375e2d017..8ba3c841289 100644 --- a/core/chains/evm/txmgr/client.go +++ b/core/chains/evm/txmgr/client.go @@ -18,6 +18,7 @@ import ( commonclient "github.com/smartcontractkit/chainlink/v2/common/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + evmconfig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ) @@ -25,11 +26,12 @@ import ( var _ TxmClient = (*evmTxmClient)(nil) type evmTxmClient struct { - client client.Client + client client.Client + clientErrors evmconfig.ClientErrors } -func NewEvmTxmClient(c client.Client) *evmTxmClient { - return &evmTxmClient{client: c} +func NewEvmTxmClient(c client.Client, clientErrors evmconfig.ClientErrors) *evmTxmClient { + return &evmTxmClient{client: c, clientErrors: clientErrors} } func (c *evmTxmClient) PendingSequenceAt(ctx context.Context, addr common.Address) (evmtypes.Nonce, error) { @@ -84,7 +86,7 @@ func (c *evmTxmClient) BatchSendTransactions( return } sendErr := reqs[i].Error - codes[i] = client.ClassifySendError(sendErr, lggr, tx, attempts[i].Tx.FromAddress, c.client.IsL2()) + codes[i] = client.ClassifySendError(sendErr, c.clientErrors, lggr, tx, attempts[i].Tx.FromAddress, c.client.IsL2()) txErrs[i] = sendErr }(index) } diff --git a/core/chains/evm/txmgr/confirmer_test.go b/core/chains/evm/txmgr/confirmer_test.go index 88c7dfc0a53..44449b7a44f 100644 --- a/core/chains/evm/txmgr/confirmer_test.go +++ b/core/chains/evm/txmgr/confirmer_test.go @@ -129,7 +129,7 @@ func TestEthConfirmer_Lifecycle(t *testing.T) { ge := config.EVM().GasEstimator() feeEstimator := gas.NewEvmFeeEstimator(lggr, newEst, ge.EIP1559DynamicFees(), ge) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, ethKeyStore, feeEstimator) - ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(ge), config.EVM().Transactions(), gconfig.Database(), ethKeyStore, txBuilder, lggr) + ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(ge), config.EVM().Transactions(), gconfig.Database(), ethKeyStore, txBuilder, lggr) ctx := testutils.Context(t) // Can't close unstarted instance @@ -1652,7 +1652,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing addresses := []gethCommon.Address{fromAddress} kst.On("EnabledAddressesForChain", mock.Anything, &cltest.FixtureChainID).Return(addresses, nil).Maybe() // Create confirmer with necessary state - ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient), ccfg.EVM(), txmgr.NewEvmTxmFeeConfig(ccfg.EVM().GasEstimator()), ccfg.EVM().Transactions(), cfg.Database(), kst, txBuilder, lggr) + ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), ccfg.EVM(), txmgr.NewEvmTxmFeeConfig(ccfg.EVM().GasEstimator()), ccfg.EVM().Transactions(), cfg.Database(), kst, txBuilder, lggr) servicetest.Run(t, ec) currentHead := int64(30) oldEnough := int64(15) @@ -1699,7 +1699,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, kst, feeEstimator) addresses := []gethCommon.Address{fromAddress} kst.On("EnabledAddressesForChain", mock.Anything, &cltest.FixtureChainID).Return(addresses, nil).Maybe() - ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient), ccfg.EVM(), txmgr.NewEvmTxmFeeConfig(ccfg.EVM().GasEstimator()), ccfg.EVM().Transactions(), cfg.Database(), kst, txBuilder, lggr) + ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), ccfg.EVM(), txmgr.NewEvmTxmFeeConfig(ccfg.EVM().GasEstimator()), ccfg.EVM().Transactions(), cfg.Database(), kst, txBuilder, lggr) servicetest.Run(t, ec) currentHead := int64(30) oldEnough := int64(15) @@ -1879,7 +1879,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) { var attempt1_2 txmgr.TxAttempt ethClient = evmtest.NewEthClientMockWithDefaultChain(t) - ec.XXXTestSetClient(txmgr.NewEvmTxmClient(ethClient)) + ec.XXXTestSetClient(txmgr.NewEvmTxmClient(ethClient, nil)) t.Run("creates new attempt with higher gas price if transaction has an attempt older than threshold", func(t *testing.T) { expectedBumpedGasPrice := big.NewInt(20000000000) @@ -3134,7 +3134,7 @@ func newEthConfirmer(t testing.TB, txStore txmgr.EvmTxStore, ethClient client.Cl return gas.NewFixedPriceEstimator(ge, nil, ge.BlockHistory(), lggr, nil) }, ge.EIP1559DynamicFees(), ge) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, ks, estimator) - ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(ge), config.EVM().Transactions(), gconfig.Database(), ks, txBuilder, lggr) + ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(ge), config.EVM().Transactions(), gconfig.Database(), ks, txBuilder, lggr) ec.SetResumeCallback(fn) servicetest.Run(t, ec) return ec diff --git a/core/chains/evm/txmgr/nonce_tracker_test.go b/core/chains/evm/txmgr/nonce_tracker_test.go index 38059b82335..c6af58ab7ac 100644 --- a/core/chains/evm/txmgr/nonce_tracker_test.go +++ b/core/chains/evm/txmgr/nonce_tracker_test.go @@ -33,7 +33,7 @@ func TestNonceTracker_LoadSequenceMap(t *testing.T) { client := clientmock.NewClient(t) client.On("ConfiguredChainID").Return(chainID) - nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(client)) + nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(client, nil)) addr1 := common.HexToAddress("0xd5e099c71b797516c10ed0f0d895f429c2781142") addr2 := common.HexToAddress("0xd5e099c71b797516c10ed0f0d895f429c2781140") @@ -85,7 +85,7 @@ func TestNonceTracker_syncOnChain(t *testing.T) { client := clientmock.NewClient(t) client.On("ConfiguredChainID").Return(chainID) - nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(client)) + nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(client, nil)) addr := common.HexToAddress("0xd5e099c71b797516c10ed0f0d895f429c2781142") @@ -142,7 +142,7 @@ func TestNonceTracker_SyncSequence(t *testing.T) { client := clientmock.NewClient(t) client.On("ConfiguredChainID").Return(chainID) - nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(client)) + nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(client, nil)) addr := common.HexToAddress("0xd5e099c71b797516c10ed0f0d895f429c2781142") enabledAddresses := []common.Address{addr} @@ -189,7 +189,7 @@ func TestNonceTracker_GetNextSequence(t *testing.T) { client := clientmock.NewClient(t) client.On("ConfiguredChainID").Return(chainID) - nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(client)) + nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(client, nil)) addr := common.HexToAddress("0xd5e099c71b797516c10ed0f0d895f429c2781142") @@ -241,7 +241,7 @@ func TestNonceTracker_GenerateNextSequence(t *testing.T) { client := clientmock.NewClient(t) client.On("ConfiguredChainID").Return(chainID) - nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(client)) + nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(client, nil)) addr := common.HexToAddress("0xd5e099c71b797516c10ed0f0d895f429c2781142") enabledAddresses := []common.Address{addr} @@ -271,7 +271,7 @@ func Test_SetNonceAfterInit(t *testing.T) { client := clientmock.NewClient(t) client.On("ConfiguredChainID").Return(chainID) - nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(client)) + nonceTracker := txmgr.NewNonceTracker(logger.Test(t), txStore, txmgr.NewEvmTxmClient(client, nil)) addr := common.HexToAddress("0xd5e099c71b797516c10ed0f0d895f429c2781142") enabledAddresses := []common.Address{addr} diff --git a/core/chains/evm/txmgr/resender_test.go b/core/chains/evm/txmgr/resender_test.go index 8df5344f57c..331e39d6ccf 100644 --- a/core/chains/evm/txmgr/resender_test.go +++ b/core/chains/evm/txmgr/resender_test.go @@ -64,7 +64,7 @@ func Test_EthResender_resendUnconfirmed(t *testing.T) { addr3TxesRawHex = append(addr3TxesRawHex, hexutil.Encode(etx.TxAttempts[0].SignedRawTx)) } - er := txmgr.NewEvmResender(lggr, txStore, txmgr.NewEvmTxmClient(ethClient), txmgr.NewEvmTracker(txStore, ethKeyStore, big.NewInt(0), lggr), ethKeyStore, 100*time.Millisecond, ccfg.EVM(), ccfg.EVM().Transactions()) + er := txmgr.NewEvmResender(lggr, txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTracker(txStore, ethKeyStore, big.NewInt(0), lggr), ethKeyStore, 100*time.Millisecond, ccfg.EVM(), ccfg.EVM().Transactions()) var resentHex = make(map[string]struct{}) ethClient.On("BatchCallContextAll", mock.Anything, mock.MatchedBy(func(elems []rpc.BatchElem) bool { @@ -119,7 +119,7 @@ func Test_EthResender_alertUnconfirmed(t *testing.T) { txStore := cltest.NewTestTxStore(t, db) originalBroadcastAt := time.Unix(1616509100, 0) - er := txmgr.NewEvmResender(lggr, txStore, txmgr.NewEvmTxmClient(ethClient), txmgr.NewEvmTracker(txStore, ethKeyStore, big.NewInt(0), lggr), ethKeyStore, 100*time.Millisecond, ccfg.EVM(), ccfg.EVM().Transactions()) + er := txmgr.NewEvmResender(lggr, txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTracker(txStore, ethKeyStore, big.NewInt(0), lggr), ethKeyStore, 100*time.Millisecond, ccfg.EVM(), ccfg.EVM().Transactions()) t.Run("alerts only once for unconfirmed transaction attempt within the unconfirmedTxAlertDelay duration", func(t *testing.T) { _ = cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, int64(1), fromAddress, originalBroadcastAt) @@ -156,7 +156,7 @@ func Test_EthResender_Start(t *testing.T) { ctx := testutils.Context(t) ethClient := evmtest.NewEthClientMockWithDefaultChain(t) - er := txmgr.NewEvmResender(lggr, txStore, txmgr.NewEvmTxmClient(ethClient), txmgr.NewEvmTracker(txStore, ethKeyStore, big.NewInt(0), lggr), ethKeyStore, 100*time.Millisecond, ccfg.EVM(), ccfg.EVM().Transactions()) + er := txmgr.NewEvmResender(lggr, txStore, txmgr.NewEvmTxmClient(ethClient, nil), txmgr.NewEvmTracker(txStore, ethKeyStore, big.NewInt(0), lggr), ethKeyStore, 100*time.Millisecond, ccfg.EVM(), ccfg.EVM().Transactions()) originalBroadcastAt := time.Unix(1616509100, 0) etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 0, fromAddress, originalBroadcastAt) diff --git a/core/chains/evm/txmgr/txmgr_test.go b/core/chains/evm/txmgr/txmgr_test.go index b76c9255b2b..aac9d89c490 100644 --- a/core/chains/evm/txmgr/txmgr_test.go +++ b/core/chains/evm/txmgr/txmgr_test.go @@ -73,6 +73,7 @@ func makeTestEvmTxm( ccfg, fcfg, txConfig, + nil, dbConfig, listenerConfig, ethClient, diff --git a/core/chains/legacyevm/chain.go b/core/chains/legacyevm/chain.go index 00a235f391b..920532518ab 100644 --- a/core/chains/legacyevm/chain.go +++ b/core/chains/legacyevm/chain.go @@ -218,7 +218,7 @@ func newChain(ctx context.Context, cfg *evmconfig.ChainScoped, nodes []*toml.Nod if !opts.AppConfig.EVMRPCEnabled() { client = evmclient.NewNullClient(chainID, l) } else if opts.GenEthClient == nil { - client = evmclient.NewEvmClient(cfg.EVM().NodePool(), cfg.EVM(), l, chainID, nodes) + client = evmclient.NewEvmClient(cfg.EVM().NodePool(), cfg.EVM(), cfg.EVM().NodePool().Errors(), l, chainID, nodes) } else { client = opts.GenEthClient(chainID) } diff --git a/core/chains/legacyevm/evm_txm.go b/core/chains/legacyevm/evm_txm.go index c4959b78a47..6b2d1262ce8 100644 --- a/core/chains/legacyevm/evm_txm.go +++ b/core/chains/legacyevm/evm_txm.go @@ -58,6 +58,7 @@ func newEvmTxm( cfg, txmgr.NewEvmTxmFeeConfig(cfg.GasEstimator()), cfg.Transactions(), + cfg.NodePool().Errors(), databaseConfig, listenerConfig, client, diff --git a/core/cmd/shell_local.go b/core/cmd/shell_local.go index 8e29dada9a5..a61390a4886 100644 --- a/core/cmd/shell_local.go +++ b/core/cmd/shell_local.go @@ -636,7 +636,8 @@ func (s *Shell) RebroadcastTransactions(c *cli.Context) (err error) { txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), chain.Config().EVM().GasEstimator(), keyStore.Eth(), nil) cfg := txmgr.NewEvmTxmConfig(chain.Config().EVM()) feeCfg := txmgr.NewEvmTxmFeeConfig(chain.Config().EVM().GasEstimator()) - ec := txmgr.NewEvmConfirmer(orm, txmgr.NewEvmTxmClient(ethClient), cfg, feeCfg, chain.Config().EVM().Transactions(), app.GetConfig().Database(), keyStore.Eth(), txBuilder, chain.Logger()) + ec := txmgr.NewEvmConfirmer(orm, txmgr.NewEvmTxmClient(ethClient, chain.Config().EVM().NodePool().Errors()), + cfg, feeCfg, chain.Config().EVM().Transactions(), app.GetConfig().Database(), keyStore.Eth(), txBuilder, chain.Logger()) totalNonces := endingNonce - beginningNonce + 1 nonces := make([]evmtypes.Nonce, totalNonces) for i := int64(0); i < totalNonces; i++ { diff --git a/core/config/docs/chains-evm.toml b/core/config/docs/chains-evm.toml index dd63edaf694..fdcb72a3da0 100644 --- a/core/config/docs/chains-evm.toml +++ b/core/config/docs/chains-evm.toml @@ -352,6 +352,38 @@ NodeIsSyncingEnabled = false # Default # # Set to 0 to disable. FinalizedBlockPollInterval = '5s' # Default + +# Errors enable the node to provide custom regex patterns to match against error messages from RPCs. +[EVM.NodePool.Errors] +# NonceTooLow is a regex pattern to match against nonce too low errors. +NonceTooLow = '(: |^)nonce too low' # Example +# NonceTooHigh is a regex pattern to match against nonce too high errors. +NonceTooHigh = '(: |^)nonce too high' # Example +# ReplacementTransactionUnderpriced is a regex pattern to match against replacement transaction underpriced errors. +ReplacementTransactionUnderpriced = '(: |^)replacement transaction underpriced' # Example +# LimitReached is a regex pattern to match against limit reached errors. +LimitReached = '(: |^)limit reached' # Example +# TransactionAlreadyInMempool is a regex pattern to match against transaction already in mempool errors. +TransactionAlreadyInMempool = '(: |^)transaction already in mempool' # Example +# TerminallyUnderpriced is a regex pattern to match against terminally underpriced errors. +TerminallyUnderpriced = '(: |^)terminally underpriced' # Example +# InsufficientEth is a regex pattern to match against insufficient eth errors. +InsufficientEth = '(: |^)insufficeint eth' # Example +# TxFeeExceedsCap is a regex pattern to match against tx fee exceeds cap errors. +TxFeeExceedsCap = '(: |^)tx fee exceeds cap' # Example +# L2FeeTooLow is a regex pattern to match against l2 fee too low errors. +L2FeeTooLow = '(: |^)l2 fee too low' # Example +# L2FeeTooHigh is a regex pattern to match against l2 fee too high errors. +L2FeeTooHigh = '(: |^)l2 fee too high' # Example +# L2Full is a regex pattern to match against l2 full errors. +L2Full = '(: |^)l2 full' # Example +# TransactionAlreadyMined is a regex pattern to match against transaction already mined errors. +TransactionAlreadyMined = '(: |^)transaction already mined' # Example +# Fatal is a regex pattern to match against fatal errors. +Fatal = '(: |^)fatal' # Example +# ServiceUnavailable is a regex pattern to match against service unavailable errors. +ServiceUnavailable = '(: |^)service unavailable' # Example + [EVM.OCR] # ContractConfirmations sets `OCR.ContractConfirmations` for this EVM chain. ContractConfirmations = 4 # Default diff --git a/core/config/docs/docs_test.go b/core/config/docs/docs_test.go index 35a78762e64..8c6429fd0df 100644 --- a/core/config/docs/docs_test.go +++ b/core/config/docs/docs_test.go @@ -84,6 +84,7 @@ func TestDoc(t *testing.T) { require.Empty(t, docDefaults.ChainWriter.ForwarderAddress) docDefaults.ChainWriter.FromAddress = nil docDefaults.ChainWriter.ForwarderAddress = nil + docDefaults.NodePool.Errors = evmcfg.ClientErrors{} assertTOML(t, fallbackDefaults, docDefaults) }) diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 27e5c9317fa..d02948fd07b 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -583,6 +583,22 @@ func TestConfig_Marshal(t *testing.T) { LeaseDuration: &zeroSeconds, NodeIsSyncingEnabled: ptr(true), FinalizedBlockPollInterval: &second, + Errors: evmcfg.ClientErrors{ + NonceTooLow: ptr[string]("(: |^)nonce too low"), + NonceTooHigh: ptr[string]("(: |^)nonce too high"), + ReplacementTransactionUnderpriced: ptr[string]("(: |^)replacement transaction underpriced"), + LimitReached: ptr[string]("(: |^)limit reached"), + TransactionAlreadyInMempool: ptr[string]("(: |^)transaction already in mempool"), + TerminallyUnderpriced: ptr[string]("(: |^)terminally underpriced"), + InsufficientEth: ptr[string]("(: |^)insufficient eth"), + TxFeeExceedsCap: ptr[string]("(: |^)tx fee exceeds cap"), + L2FeeTooLow: ptr[string]("(: |^)l2 fee too low"), + L2FeeTooHigh: ptr[string]("(: |^)l2 fee too high"), + L2Full: ptr[string]("(: |^)l2 full"), + TransactionAlreadyMined: ptr[string]("(: |^)transaction already mined"), + Fatal: ptr[string]("(: |^)fatal"), + ServiceUnavailable: ptr[string]("(: |^)service unavailable"), + }, }, OCR: evmcfg.OCR{ ContractConfirmations: ptr[uint16](11), @@ -1025,6 +1041,22 @@ LeaseDuration = '0s' NodeIsSyncingEnabled = true FinalizedBlockPollInterval = '1s' +[EVM.NodePool.Errors] +NonceTooLow = '(: |^)nonce too low' +NonceTooHigh = '(: |^)nonce too high' +ReplacementTransactionUnderpriced = '(: |^)replacement transaction underpriced' +LimitReached = '(: |^)limit reached' +TransactionAlreadyInMempool = '(: |^)transaction already in mempool' +TerminallyUnderpriced = '(: |^)terminally underpriced' +InsufficientEth = '(: |^)insufficient eth' +TxFeeExceedsCap = '(: |^)tx fee exceeds cap' +L2FeeTooLow = '(: |^)l2 fee too low' +L2FeeTooHigh = '(: |^)l2 fee too high' +L2Full = '(: |^)l2 full' +TransactionAlreadyMined = '(: |^)transaction already mined' +Fatal = '(: |^)fatal' +ServiceUnavailable = '(: |^)service unavailable' + [EVM.OCR] ContractConfirmations = 11 ContractTransmitterTransmitTimeout = '1m0s' diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index 76c4aa0cade..8a016149e59 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -344,6 +344,22 @@ LeaseDuration = '0s' NodeIsSyncingEnabled = true FinalizedBlockPollInterval = '1s' +[EVM.NodePool.Errors] +NonceTooLow = '(: |^)nonce too low' +NonceTooHigh = '(: |^)nonce too high' +ReplacementTransactionUnderpriced = '(: |^)replacement transaction underpriced' +LimitReached = '(: |^)limit reached' +TransactionAlreadyInMempool = '(: |^)transaction already in mempool' +TerminallyUnderpriced = '(: |^)terminally underpriced' +InsufficientEth = '(: |^)insufficient eth' +TxFeeExceedsCap = '(: |^)tx fee exceeds cap' +L2FeeTooLow = '(: |^)l2 fee too low' +L2FeeTooHigh = '(: |^)l2 fee too high' +L2Full = '(: |^)l2 full' +TransactionAlreadyMined = '(: |^)transaction already mined' +Fatal = '(: |^)fatal' +ServiceUnavailable = '(: |^)service unavailable' + [EVM.OCR] ContractConfirmations = 11 ContractTransmitterTransmitTimeout = '1m0s' diff --git a/core/services/promreporter/prom_reporter_test.go b/core/services/promreporter/prom_reporter_test.go index 635b5b83c47..bb09b86df95 100644 --- a/core/services/promreporter/prom_reporter_test.go +++ b/core/services/promreporter/prom_reporter_test.go @@ -53,6 +53,7 @@ func newLegacyChainContainer(t *testing.T, db *sqlx.DB) legacyevm.LegacyChainCon evmConfig, evmConfig.GasEstimator(), evmConfig.Transactions(), + nil, dbConfig, dbConfig.Listener(), ethClient, diff --git a/core/services/vrf/delegate_test.go b/core/services/vrf/delegate_test.go index 6df91cef717..a3962977257 100644 --- a/core/services/vrf/delegate_test.go +++ b/core/services/vrf/delegate_test.go @@ -83,7 +83,7 @@ func buildVrfUni(t *testing.T, db *sqlx.DB, cfg chainlink.GeneralConfig) vrfUniv btORM := bridges.NewORM(db) ks := keystore.NewInMemory(db, utils.FastScryptParams, lggr) _, dbConfig, evmConfig := txmgr.MakeTestConfigs(t) - txm, err := txmgr.NewTxm(db, db, evmConfig, evmConfig.GasEstimator(), evmConfig.Transactions(), dbConfig, dbConfig.Listener(), ec, logger.TestLogger(t), nil, ks.Eth(), nil) + txm, err := txmgr.NewTxm(db, db, evmConfig, evmConfig.GasEstimator(), evmConfig.Transactions(), nil, dbConfig, dbConfig.Listener(), ec, logger.TestLogger(t), nil, ks.Eth(), nil) orm := headtracker.NewORM(*testutils.FixtureChainID, db) require.NoError(t, orm.IdempotentInsertHead(testutils.Context(t), cltest.Head(51))) jrm := job.NewORM(db, prm, btORM, ks, lggr, cfg.Database()) diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index 4eb2fce6c47..69d56974130 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -343,6 +343,22 @@ LeaseDuration = '0s' NodeIsSyncingEnabled = false FinalizedBlockPollInterval = '5s' +[EVM.NodePool.Errors] +NonceTooLow = '(: |^)nonce too low' +NonceTooHigh = '(: |^)nonce too high' +ReplacementTransactionUnderpriced = '(: |^)replacement transaction underpriced' +LimitReached = '(: |^)limit reached' +TransactionAlreadyInMempool = '(: |^)transaction already in mempool' +TerminallyUnderpriced = '(: |^)terminally underpriced' +InsufficientEth = '(: |^)infufficient Eth' +TxFeeExceedsCap = '(: |^)tx fee exceeds cap' +L2FeeTooLow = '(: |^)l2 fee too low' +L2FeeTooHigh = '(: |^)l2 fee too high' +L2Full = '(: |^)l2 full' +TransactionAlreadyMined = '(: |^)transaction already mined' +Fatal = '(: |^)fatal' +ServiceUnavailable = '(: |^)service unavailable' + [EVM.OCR] ContractConfirmations = 11 ContractTransmitterTransmitTimeout = '1m0s' diff --git a/docs/CONFIG.md b/docs/CONFIG.md index c33dcb6ffb8..fcf251f2702 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -7244,6 +7244,110 @@ reported based on latest block and finality depth. Set to 0 to disable. +## EVM.NodePool.Errors +```toml +[EVM.NodePool.Errors] +NonceTooLow = '(: |^)nonce too low' # Example +NonceTooHigh = '(: |^)nonce too high' # Example +ReplacementTransactionUnderpriced = '(: |^)replacement transaction underpriced' # Example +LimitReached = '(: |^)limit reached' # Example +TransactionAlreadyInMempool = '(: |^)transaction already in mempool' # Example +TerminallyUnderpriced = '(: |^)terminally underpriced' # Example +InsufficientEth = '(: |^)insufficeint eth' # Example +TxFeeExceedsCap = '(: |^)tx fee exceeds cap' # Example +L2FeeTooLow = '(: |^)l2 fee too low' # Example +L2FeeTooHigh = '(: |^)l2 fee too high' # Example +L2Full = '(: |^)l2 full' # Example +TransactionAlreadyMined = '(: |^)transaction already mined' # Example +Fatal = '(: |^)fatal' # Example +ServiceUnavailable = '(: |^)service unavailable' # Example +``` +Errors enable the node to provide custom regex patterns to match against error messages from RPCs. + +### NonceTooLow +```toml +NonceTooLow = '(: |^)nonce too low' # Example +``` +NonceTooLow is a regex pattern to match against nonce too low errors. + +### NonceTooHigh +```toml +NonceTooHigh = '(: |^)nonce too high' # Example +``` +NonceTooHigh is a regex pattern to match against nonce too high errors. + +### ReplacementTransactionUnderpriced +```toml +ReplacementTransactionUnderpriced = '(: |^)replacement transaction underpriced' # Example +``` +ReplacementTransactionUnderpriced is a regex pattern to match against replacement transaction underpriced errors. + +### LimitReached +```toml +LimitReached = '(: |^)limit reached' # Example +``` +LimitReached is a regex pattern to match against limit reached errors. + +### TransactionAlreadyInMempool +```toml +TransactionAlreadyInMempool = '(: |^)transaction already in mempool' # Example +``` +TransactionAlreadyInMempool is a regex pattern to match against transaction already in mempool errors. + +### TerminallyUnderpriced +```toml +TerminallyUnderpriced = '(: |^)terminally underpriced' # Example +``` +TerminallyUnderpriced is a regex pattern to match against terminally underpriced errors. + +### InsufficientEth +```toml +InsufficientEth = '(: |^)insufficeint eth' # Example +``` +InsufficientEth is a regex pattern to match against insufficient eth errors. + +### TxFeeExceedsCap +```toml +TxFeeExceedsCap = '(: |^)tx fee exceeds cap' # Example +``` +TxFeeExceedsCap is a regex pattern to match against tx fee exceeds cap errors. + +### L2FeeTooLow +```toml +L2FeeTooLow = '(: |^)l2 fee too low' # Example +``` +L2FeeTooLow is a regex pattern to match against l2 fee too low errors. + +### L2FeeTooHigh +```toml +L2FeeTooHigh = '(: |^)l2 fee too high' # Example +``` +L2FeeTooHigh is a regex pattern to match against l2 fee too high errors. + +### L2Full +```toml +L2Full = '(: |^)l2 full' # Example +``` +L2Full is a regex pattern to match against l2 full errors. + +### TransactionAlreadyMined +```toml +TransactionAlreadyMined = '(: |^)transaction already mined' # Example +``` +TransactionAlreadyMined is a regex pattern to match against transaction already mined errors. + +### Fatal +```toml +Fatal = '(: |^)fatal' # Example +``` +Fatal is a regex pattern to match against fatal errors. + +### ServiceUnavailable +```toml +ServiceUnavailable = '(: |^)service unavailable' # Example +``` +ServiceUnavailable is a regex pattern to match against service unavailable errors. + ## EVM.OCR ```toml [EVM.OCR] From dc769e88f4b71c460138f3acc66867528ca421c1 Mon Sep 17 00:00:00 2001 From: frank zhu Date: Tue, 23 Apr 2024 11:04:08 -0700 Subject: [PATCH 10/77] fix: edit semvar to patch instead of removed for a changeset file (#12931) --- .changeset/new-forks-grab.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/new-forks-grab.md b/.changeset/new-forks-grab.md index cb078beb29b..350b5baafb0 100644 --- a/.changeset/new-forks-grab.md +++ b/.changeset/new-forks-grab.md @@ -1,5 +1,5 @@ --- -"chainlink": removed +"chainlink": patch --- Drop unused queryTimeout config from TXM strategy #internal From ea3fd85400357198d8c97878822d6ca3d4101561 Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Tue, 23 Apr 2024 11:16:06 -0700 Subject: [PATCH 11/77] fix: remove dry-run npm publish step name (#12933) --- .github/workflows/solidity.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/solidity.yml b/.github/workflows/solidity.yml index 62b0966b358..a128316b99e 100644 --- a/.github/workflows/solidity.yml +++ b/.github/workflows/solidity.yml @@ -212,7 +212,7 @@ jobs: echo "Bumping version to ${{ needs.tag-check.outputs.pre-release-version }}" pnpm version ${{ needs.tag-check.outputs.pre-release-version }} --no-git-tag-version --no-commit-hooks --no-git-checks - - name: Publish to NPM (Dry Run) + - name: Publish to NPM (beta) uses: smartcontractkit/.github/actions/ci-publish-npm@e1c9d45fc66369d6be5d3863c65af1750797a7f5 # ci-publish-npm@0.3.0 with: npm-token: ${{ secrets.NPM_TOKEN }} @@ -254,7 +254,7 @@ jobs: exit 1 fi - - name: Publish to NPM (Dry Run) + - name: Publish to NPM (latest) uses: smartcontractkit/.github/actions/ci-publish-npm@e1c9d45fc66369d6be5d3863c65af1750797a7f5 # ci-publish-npm@0.3.0 with: npm-token: ${{ secrets.NPM_TOKEN }} From 12170e850198483b6463a911b5ccd5b1af95ea67 Mon Sep 17 00:00:00 2001 From: chainchad <96362174+chainchad@users.noreply.github.com> Date: Tue, 23 Apr 2024 16:17:58 -0400 Subject: [PATCH 12/77] Remove trunk CRIB restarts (#12935) --- .github/workflows/build-publish-develop.yml | 38 --------------------- 1 file changed, 38 deletions(-) diff --git a/.github/workflows/build-publish-develop.yml b/.github/workflows/build-publish-develop.yml index 1df1720d714..99bb999538f 100644 --- a/.github/workflows/build-publish-develop.yml +++ b/.github/workflows/build-publish-develop.yml @@ -56,44 +56,6 @@ jobs: dockerhub_password: ${{ secrets.DOCKERHUB_READONLY_PASSWORD }} git-commit-sha: ${{ steps.git-ref.outputs.checked-out || github.sha }} - - name: Setup GAP - # Don't run for plugins. - if: matrix.image.name == '' - uses: smartcontractkit/.github/actions/setup-gap@1bc7ce34fa81fffcb4a6eb0e4e12e59d94d0fc8f # setup-gap@0.2.0 - with: - aws-region: ${{ secrets.AWS_REGION }} - aws-role-arn: ${{ secrets.AWS_OIDC_CRIB_ROLE_ARN_SAND }} - api-gateway-host: ${{ secrets.AWS_API_GW_HOST_K8S_SAND }} - use-k8s: "true" - k8s-cluster-name: ${{ secrets.AWS_EKS_CLUSTER_NAME_SAND }} - use-private-ecr-registry: true - ecr-private-registry: ${{ secrets.AWS_ACCOUNT_ID_PROD }} - metrics-job-name: push-chainlink-develop ${{ matrix.image.name }} - gc-host: ${{ secrets.GRAFANA_INTERNAL_HOST }} - gc-basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - gc-org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - - # A mutable image tag is used for these CRIBs and it was just built/published - # from this workflow. The deployment has an `imagePullPolicy: Always` set, so - # we need to restart the deployments to pick up the new image. - - name: Restart K8s Deployments for CRIBs - # Don't run for plugins. - if: matrix.image.name == '' - shell: bash - run: | - set -euo pipefail - # Removes the "smartcontractkit/" (org name) prefix. - REPO_NAME_ONLY="${GITHUB_REPOSITORY##*/}" - K8S_NAMESPACE="crib-${REPO_NAME_ONLY}-develop" - - deployment_node_names=$(kubectl --namespace "${K8S_NAMESPACE}" \ - get deployments \ - -l "app=${K8S_NAMESPACE}" \ - -o custom-columns=:metadata.name --no-headers) - - echo "Restarting deployments: $deployment_node_names" - kubectl rollout restart deployment $deployment_node_names --namespace "${K8S_NAMESPACE}" - - name: Collect Metrics if: always() id: collect-gha-metrics From 293c9f81bc28f04a7d8d0676b0e2716bc26faab7 Mon Sep 17 00:00:00 2001 From: Sneha Agnihotri <180277+snehaagni@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:14:24 -0700 Subject: [PATCH 13/77] @chainlink.contracts release v1.1.0 (#12728) * Update CHANGELOG and package version for contracts * remove unreleased section Signed-off-by: Sneha Agnihotri --------- Signed-off-by: Sneha Agnihotri --- contracts/.changeset/afraid-seahorses-yell.md | 5 -- contracts/.changeset/afraid-years-fix.md | 5 -- contracts/.changeset/clever-kings-smell.md | 11 --- contracts/.changeset/curly-guests-add.md | 5 -- contracts/.changeset/early-hairs-wonder.md | 5 -- contracts/.changeset/eight-peas-glow.md | 5 -- contracts/.changeset/famous-feet-rescue.md | 5 -- contracts/.changeset/fast-maps-rush.md | 5 -- .../.changeset/fluffy-peaches-provide.md | 5 -- contracts/.changeset/forty-ways-ring.md | 5 -- contracts/.changeset/fresh-zoos-marry.md | 5 -- contracts/.changeset/happy-books-taste.md | 5 -- contracts/.changeset/heavy-lions-pull.md | 5 -- contracts/.changeset/lazy-sheep-invite.md | 5 -- contracts/.changeset/loud-donuts-work.md | 5 -- contracts/.changeset/lucky-bananas-kneel.md | 5 -- contracts/.changeset/lucky-eels-kiss.md | 5 -- contracts/.changeset/many-onions-run.md | 5 -- contracts/.changeset/modern-horses-destroy.md | 5 -- contracts/.changeset/nine-comics-bathe.md | 5 -- contracts/.changeset/odd-experts-jump.md | 5 -- contracts/.changeset/pretty-cups-tickle.md | 5 -- contracts/.changeset/quick-vans-retire.md | 5 -- contracts/.changeset/quiet-cars-taste.md | 5 -- contracts/.changeset/six-donuts-reply.md | 5 -- contracts/.changeset/smooth-spiders-beam.md | 5 -- contracts/.changeset/strange-actors-do.md | 5 -- contracts/.changeset/tasty-rings-bow.md | 5 -- contracts/.changeset/three-spoons-clean.md | 5 -- contracts/.changeset/tricky-pigs-shout.md | 5 -- contracts/.changeset/weak-kangaroos-heal.md | 5 -- contracts/.changeset/wise-shrimps-perform.md | 5 -- contracts/.changeset/young-crabs-sing.md | 5 -- contracts/.changeset/young-insects-punch.md | 5 -- contracts/CHANGELOG.md | 82 ++++++++++++++++++- contracts/package.json | 2 +- 36 files changed, 81 insertions(+), 179 deletions(-) delete mode 100644 contracts/.changeset/afraid-seahorses-yell.md delete mode 100644 contracts/.changeset/afraid-years-fix.md delete mode 100644 contracts/.changeset/clever-kings-smell.md delete mode 100644 contracts/.changeset/curly-guests-add.md delete mode 100644 contracts/.changeset/early-hairs-wonder.md delete mode 100644 contracts/.changeset/eight-peas-glow.md delete mode 100644 contracts/.changeset/famous-feet-rescue.md delete mode 100644 contracts/.changeset/fast-maps-rush.md delete mode 100644 contracts/.changeset/fluffy-peaches-provide.md delete mode 100644 contracts/.changeset/forty-ways-ring.md delete mode 100644 contracts/.changeset/fresh-zoos-marry.md delete mode 100644 contracts/.changeset/happy-books-taste.md delete mode 100644 contracts/.changeset/heavy-lions-pull.md delete mode 100644 contracts/.changeset/lazy-sheep-invite.md delete mode 100644 contracts/.changeset/loud-donuts-work.md delete mode 100644 contracts/.changeset/lucky-bananas-kneel.md delete mode 100644 contracts/.changeset/lucky-eels-kiss.md delete mode 100644 contracts/.changeset/many-onions-run.md delete mode 100644 contracts/.changeset/modern-horses-destroy.md delete mode 100644 contracts/.changeset/nine-comics-bathe.md delete mode 100644 contracts/.changeset/odd-experts-jump.md delete mode 100644 contracts/.changeset/pretty-cups-tickle.md delete mode 100644 contracts/.changeset/quick-vans-retire.md delete mode 100644 contracts/.changeset/quiet-cars-taste.md delete mode 100644 contracts/.changeset/six-donuts-reply.md delete mode 100644 contracts/.changeset/smooth-spiders-beam.md delete mode 100644 contracts/.changeset/strange-actors-do.md delete mode 100644 contracts/.changeset/tasty-rings-bow.md delete mode 100644 contracts/.changeset/three-spoons-clean.md delete mode 100644 contracts/.changeset/tricky-pigs-shout.md delete mode 100644 contracts/.changeset/weak-kangaroos-heal.md delete mode 100644 contracts/.changeset/wise-shrimps-perform.md delete mode 100644 contracts/.changeset/young-crabs-sing.md delete mode 100644 contracts/.changeset/young-insects-punch.md diff --git a/contracts/.changeset/afraid-seahorses-yell.md b/contracts/.changeset/afraid-seahorses-yell.md deleted file mode 100644 index 2d45c33320d..00000000000 --- a/contracts/.changeset/afraid-seahorses-yell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": minor ---- - -Chainlink Functions contracts v1.3.0 diff --git a/contracts/.changeset/afraid-years-fix.md b/contracts/.changeset/afraid-years-fix.md deleted file mode 100644 index 7048f562312..00000000000 --- a/contracts/.changeset/afraid-years-fix.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -upgraded transmission to 0.8.19 diff --git a/contracts/.changeset/clever-kings-smell.md b/contracts/.changeset/clever-kings-smell.md deleted file mode 100644 index eee8eddf53a..00000000000 --- a/contracts/.changeset/clever-kings-smell.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"@chainlink/contracts": minor ---- - -- Misc VRF V2+ contract changes - - Reuse struct RequestCommitmentV2Plus from VRFTypes - - Fix interface name IVRFCoordinatorV2PlusFulfill in BatchVRFCoordinatorV2Plus to avoid confusion with IVRFCoordinatorV2Plus.sol - - Remove unused errors - - Rename variables for readability - - Fix comments - - Minor gas optimisation (++i) diff --git a/contracts/.changeset/curly-guests-add.md b/contracts/.changeset/curly-guests-add.md deleted file mode 100644 index 1bf40fbeab6..00000000000 --- a/contracts/.changeset/curly-guests-add.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": minor ---- - -improve foundry tests diff --git a/contracts/.changeset/early-hairs-wonder.md b/contracts/.changeset/early-hairs-wonder.md deleted file mode 100644 index 808c89f8451..00000000000 --- a/contracts/.changeset/early-hairs-wonder.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -fix bug in auto2.3 withdrawERC20Fees diff --git a/contracts/.changeset/eight-peas-glow.md b/contracts/.changeset/eight-peas-glow.md deleted file mode 100644 index 03c0498abe2..00000000000 --- a/contracts/.changeset/eight-peas-glow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": minor ---- - -VRFV2PlusWrapper config refactor diff --git a/contracts/.changeset/famous-feet-rescue.md b/contracts/.changeset/famous-feet-rescue.md deleted file mode 100644 index d955046ceb9..00000000000 --- a/contracts/.changeset/famous-feet-rescue.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -fix withdraw LINK bug in auto 2.3 diff --git a/contracts/.changeset/fast-maps-rush.md b/contracts/.changeset/fast-maps-rush.md deleted file mode 100644 index a9a25116758..00000000000 --- a/contracts/.changeset/fast-maps-rush.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": minor ---- - -pay deactivated transmitters in offchain settlement diff --git a/contracts/.changeset/fluffy-peaches-provide.md b/contracts/.changeset/fluffy-peaches-provide.md deleted file mode 100644 index cf6f001ac2e..00000000000 --- a/contracts/.changeset/fluffy-peaches-provide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -added logic C contract to automation 2.3 diff --git a/contracts/.changeset/forty-ways-ring.md b/contracts/.changeset/forty-ways-ring.md deleted file mode 100644 index 620d2ca1d84..00000000000 --- a/contracts/.changeset/forty-ways-ring.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -upgrade solc version to 0.8.19 for vrf v2.5 contracts diff --git a/contracts/.changeset/fresh-zoos-marry.md b/contracts/.changeset/fresh-zoos-marry.md deleted file mode 100644 index 32af56e63ac..00000000000 --- a/contracts/.changeset/fresh-zoos-marry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -enable gas tests for auto 2.3 diff --git a/contracts/.changeset/happy-books-taste.md b/contracts/.changeset/happy-books-taste.md deleted file mode 100644 index 4b758a65a2e..00000000000 --- a/contracts/.changeset/happy-books-taste.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -billing overrides diff --git a/contracts/.changeset/heavy-lions-pull.md b/contracts/.changeset/heavy-lions-pull.md deleted file mode 100644 index 236c4ad033e..00000000000 --- a/contracts/.changeset/heavy-lions-pull.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": minor ---- - -Update type and version name for VRFv2+ Wrapper diff --git a/contracts/.changeset/lazy-sheep-invite.md b/contracts/.changeset/lazy-sheep-invite.md deleted file mode 100644 index 77f42295232..00000000000 --- a/contracts/.changeset/lazy-sheep-invite.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": minor ---- - -implement offchain settlement for NOPs payment diff --git a/contracts/.changeset/loud-donuts-work.md b/contracts/.changeset/loud-donuts-work.md deleted file mode 100644 index e177af6fb3e..00000000000 --- a/contracts/.changeset/loud-donuts-work.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -rm hh coverage diff --git a/contracts/.changeset/lucky-bananas-kneel.md b/contracts/.changeset/lucky-bananas-kneel.md deleted file mode 100644 index 2c2b8d5b321..00000000000 --- a/contracts/.changeset/lucky-bananas-kneel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -mv vrf foundry tests diff --git a/contracts/.changeset/lucky-eels-kiss.md b/contracts/.changeset/lucky-eels-kiss.md deleted file mode 100644 index 2279cb107b9..00000000000 --- a/contracts/.changeset/lucky-eels-kiss.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -VRFV2PlusWrapper contract: subID param added to the constructor, removed migrate() method diff --git a/contracts/.changeset/many-onions-run.md b/contracts/.changeset/many-onions-run.md deleted file mode 100644 index 6c186c9d99c..00000000000 --- a/contracts/.changeset/many-onions-run.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -safeTransfer and cleanups diff --git a/contracts/.changeset/modern-horses-destroy.md b/contracts/.changeset/modern-horses-destroy.md deleted file mode 100644 index 32e58da8ff3..00000000000 --- a/contracts/.changeset/modern-horses-destroy.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -fix solhint issues in automation folder diff --git a/contracts/.changeset/nine-comics-bathe.md b/contracts/.changeset/nine-comics-bathe.md deleted file mode 100644 index 7d8573cd784..00000000000 --- a/contracts/.changeset/nine-comics-bathe.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": minor ---- - -Removed 0.6 and 0.7 Solidity source code diff --git a/contracts/.changeset/odd-experts-jump.md b/contracts/.changeset/odd-experts-jump.md deleted file mode 100644 index d82c762477c..00000000000 --- a/contracts/.changeset/odd-experts-jump.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -address TODOs and docs for 2.3 diff --git a/contracts/.changeset/pretty-cups-tickle.md b/contracts/.changeset/pretty-cups-tickle.md deleted file mode 100644 index a7c5625a4e1..00000000000 --- a/contracts/.changeset/pretty-cups-tickle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -auto 2.3 foundry test refactor diff --git a/contracts/.changeset/quick-vans-retire.md b/contracts/.changeset/quick-vans-retire.md deleted file mode 100644 index ad0e6859957..00000000000 --- a/contracts/.changeset/quick-vans-retire.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": minor ---- - -introduce native billing support to automation registry v2.3 diff --git a/contracts/.changeset/quiet-cars-taste.md b/contracts/.changeset/quiet-cars-taste.md deleted file mode 100644 index f59f3e6d05c..00000000000 --- a/contracts/.changeset/quiet-cars-taste.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -more auto 2.3 tests diff --git a/contracts/.changeset/six-donuts-reply.md b/contracts/.changeset/six-donuts-reply.md deleted file mode 100644 index a9da93964be..00000000000 --- a/contracts/.changeset/six-donuts-reply.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -small gas fix diff --git a/contracts/.changeset/smooth-spiders-beam.md b/contracts/.changeset/smooth-spiders-beam.md deleted file mode 100644 index edf804c910b..00000000000 --- a/contracts/.changeset/smooth-spiders-beam.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -change auto 2.3 flat fees from link to USD diff --git a/contracts/.changeset/strange-actors-do.md b/contracts/.changeset/strange-actors-do.md deleted file mode 100644 index 644e30f2a09..00000000000 --- a/contracts/.changeset/strange-actors-do.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -Set LINK native feed in VRFV2PlusWrapper to immutable diff --git a/contracts/.changeset/tasty-rings-bow.md b/contracts/.changeset/tasty-rings-bow.md deleted file mode 100644 index 828050c6eeb..00000000000 --- a/contracts/.changeset/tasty-rings-bow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -add billing override test diff --git a/contracts/.changeset/three-spoons-clean.md b/contracts/.changeset/three-spoons-clean.md deleted file mode 100644 index f822a9cb274..00000000000 --- a/contracts/.changeset/three-spoons-clean.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -use common interface for v2.3 diff --git a/contracts/.changeset/tricky-pigs-shout.md b/contracts/.changeset/tricky-pigs-shout.md deleted file mode 100644 index 095fc06701c..00000000000 --- a/contracts/.changeset/tricky-pigs-shout.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": minor ---- - -bug fixes in s_reserveAmount accounting diff --git a/contracts/.changeset/weak-kangaroos-heal.md b/contracts/.changeset/weak-kangaroos-heal.md deleted file mode 100644 index 0cba92dd998..00000000000 --- a/contracts/.changeset/weak-kangaroos-heal.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -bump solhint and address issues, remove unused imports diff --git a/contracts/.changeset/wise-shrimps-perform.md b/contracts/.changeset/wise-shrimps-perform.md deleted file mode 100644 index b623b1432d3..00000000000 --- a/contracts/.changeset/wise-shrimps-perform.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -support native payment diff --git a/contracts/.changeset/young-crabs-sing.md b/contracts/.changeset/young-crabs-sing.md deleted file mode 100644 index c0593d869b6..00000000000 --- a/contracts/.changeset/young-crabs-sing.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": minor ---- - -removed 0.4 and 0.5 contracts diff --git a/contracts/.changeset/young-insects-punch.md b/contracts/.changeset/young-insects-punch.md deleted file mode 100644 index 47d01926978..00000000000 --- a/contracts/.changeset/young-insects-punch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@chainlink/contracts": patch ---- - -increase num optimizations to 500 for v2.5 coordinator diff --git a/contracts/CHANGELOG.md b/contracts/CHANGELOG.md index 1740f95d205..667a5ad2529 100644 --- a/contracts/CHANGELOG.md +++ b/contracts/CHANGELOG.md @@ -1,8 +1,86 @@ # @chainlink/contracts CHANGELOG.md -## Unreleased +## 1.1.0 + +### Minor Changes + +- [#12481](https://github.com/smartcontractkit/chainlink/pull/12481) [`daa90db289`](https://github.com/smartcontractkit/chainlink/commit/daa90db289f84829a607b41792f7d231871a5462) Thanks [@justinkaseman](https://github.com/justinkaseman)! - Chainlink Functions contracts v1.3.0 + +- [#12489](https://github.com/smartcontractkit/chainlink/pull/12489) [`3a49094db2`](https://github.com/smartcontractkit/chainlink/commit/3a49094db25036e1948818e4030fca11be748914) Thanks [@kidambisrinivas](https://github.com/kidambisrinivas)! - - Misc VRF V2+ contract changes + + - Reuse struct RequestCommitmentV2Plus from VRFTypes + - Fix interface name IVRFCoordinatorV2PlusFulfill in BatchVRFCoordinatorV2Plus to avoid confusion with IVRFCoordinatorV2Plus.sol + - Remove unused errors + - Rename variables for readability + - Fix comments + - Minor gas optimisation (++i) + +- [#12522](https://github.com/smartcontractkit/chainlink/pull/12522) [`886201638e`](https://github.com/smartcontractkit/chainlink/commit/886201638e14dc478ae7104b4a5aed9ac8af5bba) Thanks [@FelixFan1992](https://github.com/FelixFan1992)! - improve foundry tests + +- [#12581](https://github.com/smartcontractkit/chainlink/pull/12581) [`6fcc73983e`](https://github.com/smartcontractkit/chainlink/commit/6fcc73983e5b782bb4ac577cb33093bf80e3a582) Thanks [@kidambisrinivas](https://github.com/kidambisrinivas)! - VRFV2PlusWrapper config refactor + +- [#12547](https://github.com/smartcontractkit/chainlink/pull/12547) [`8162f7b101`](https://github.com/smartcontractkit/chainlink/commit/8162f7b1012dd669e51bbb4038a6d5df29906267) Thanks [@FelixFan1992](https://github.com/FelixFan1992)! - pay deactivated transmitters in offchain settlement + +- [#12466](https://github.com/smartcontractkit/chainlink/pull/12466) [`f9d02e3192`](https://github.com/smartcontractkit/chainlink/commit/f9d02e3192f1a35fda05ca69a50f986c9149748f) Thanks [@vreff](https://github.com/vreff)! - Update type and version name for VRFv2+ Wrapper + +- [#12469](https://github.com/smartcontractkit/chainlink/pull/12469) [`1370133b72`](https://github.com/smartcontractkit/chainlink/commit/1370133b722ab97650b15c6aeab72bb494790b63) Thanks [@FelixFan1992](https://github.com/FelixFan1992)! - implement offchain settlement for NOPs payment + +- [#12578](https://github.com/smartcontractkit/chainlink/pull/12578) [`ffd492295f`](https://github.com/smartcontractkit/chainlink/commit/ffd492295f03de8c3b946a003dacbded731d7899) Thanks [@RensR](https://github.com/RensR)! - Removed 0.6 and 0.7 Solidity source code + +- [#12418](https://github.com/smartcontractkit/chainlink/pull/12418) [`22114fb20a`](https://github.com/smartcontractkit/chainlink/commit/22114fb20a67e2263ffb6d445530559f02423809) Thanks [@RyanRHall](https://github.com/RyanRHall)! - introduce native billing support to automation registry v2.3 + +- [#12583](https://github.com/smartcontractkit/chainlink/pull/12583) [`50724c3bb1`](https://github.com/smartcontractkit/chainlink/commit/50724c3bb1fb959f85d361bc0615f58cc16e4fc9) Thanks [@FelixFan1992](https://github.com/FelixFan1992)! - bug fixes in s_reserveAmount accounting + +- [#12569](https://github.com/smartcontractkit/chainlink/pull/12569) [`98ef65add8`](https://github.com/smartcontractkit/chainlink/commit/98ef65add85dc4c22333bf413fa7b593c501212d) Thanks [@RensR](https://github.com/RensR)! - removed 0.4 and 0.5 contracts + +### Patch Changes + +- [#12612](https://github.com/smartcontractkit/chainlink/pull/12612) [`d44abe3769`](https://github.com/smartcontractkit/chainlink/commit/d44abe37693d6995377fa1329e433e7fba26885d) Thanks [@RensR](https://github.com/RensR)! - upgraded transmission to 0.8.19 + +- [#12582](https://github.com/smartcontractkit/chainlink/pull/12582) [`684afa4e1f`](https://github.com/smartcontractkit/chainlink/commit/684afa4e1fcb2cad292cbc3b97ebeda3e3ef7bc8) Thanks [@RyanRHall](https://github.com/RyanRHall)! - fix bug in auto2.3 withdrawERC20Fees + +- [#12591](https://github.com/smartcontractkit/chainlink/pull/12591) [`b3086d0ec2`](https://github.com/smartcontractkit/chainlink/commit/b3086d0ec2565badaafdbb9c26e30caeb6fb41c9) Thanks [@RyanRHall](https://github.com/RyanRHall)! - fix withdraw LINK bug in auto 2.3 + +- [#12497](https://github.com/smartcontractkit/chainlink/pull/12497) [`3ca3494450`](https://github.com/smartcontractkit/chainlink/commit/3ca34944507b01b7d4511d8ea8aff402c0a7bb85) Thanks [@RyanRHall](https://github.com/RyanRHall)! - added logic C contract to automation 2.3 + +- [#12479](https://github.com/smartcontractkit/chainlink/pull/12479) [`93762ccbd8`](https://github.com/smartcontractkit/chainlink/commit/93762ccbd868b9e227abf3220afb9ad22ba41b92) Thanks [@jinhoonbang](https://github.com/jinhoonbang)! - upgrade solc version to 0.8.19 for vrf v2.5 contracts + +- [#12619](https://github.com/smartcontractkit/chainlink/pull/12619) [`6531e34865`](https://github.com/smartcontractkit/chainlink/commit/6531e348659e2b7048b25183eadddbcb10426741) Thanks [@RyanRHall](https://github.com/RyanRHall)! - enable gas tests for auto 2.3 + +- [#12536](https://github.com/smartcontractkit/chainlink/pull/12536) [`87b0d8f309`](https://github.com/smartcontractkit/chainlink/commit/87b0d8f3091e3276cd049d3a852ab63e4d6bda5b) Thanks [@shileiwill](https://github.com/shileiwill)! - billing overrides + +- [#12614](https://github.com/smartcontractkit/chainlink/pull/12614) [`93ff878b2d`](https://github.com/smartcontractkit/chainlink/commit/93ff878b2d88f6e928cdb6a8a830fb8ee100bddd) Thanks [@RensR](https://github.com/RensR)! - rm hh coverage + +- [#12613](https://github.com/smartcontractkit/chainlink/pull/12613) [`dd333e977f`](https://github.com/smartcontractkit/chainlink/commit/dd333e977f0c39509250a2bd40295da279726496) Thanks [@RensR](https://github.com/RensR)! - mv vrf foundry tests + +- [#12529](https://github.com/smartcontractkit/chainlink/pull/12529) [`84913bfcfc`](https://github.com/smartcontractkit/chainlink/commit/84913bfcfcfcf6f93fb359814208a32e3e659d23) Thanks [@ibrajer](https://github.com/ibrajer)! - VRFV2PlusWrapper contract: subID param added to the constructor, removed migrate() method + +- [#12555](https://github.com/smartcontractkit/chainlink/pull/12555) [`cda84cb1b7`](https://github.com/smartcontractkit/chainlink/commit/cda84cb1b7582379ac140b3a88da6179275dbefb) Thanks [@shileiwill](https://github.com/shileiwill)! - safeTransfer and cleanups + +- [#12640](https://github.com/smartcontractkit/chainlink/pull/12640) [`76e507e849`](https://github.com/smartcontractkit/chainlink/commit/76e507e8490933318e5b36cf103d6157f9fa2f34) Thanks [@RensR](https://github.com/RensR)! - fix solhint issues in automation folder + +- [#12553](https://github.com/smartcontractkit/chainlink/pull/12553) [`4892376917`](https://github.com/smartcontractkit/chainlink/commit/4892376917a16253165dc761f8efec41da32ec9c) Thanks [@RyanRHall](https://github.com/RyanRHall)! - address TODOs and docs for 2.3 + +- [#12499](https://github.com/smartcontractkit/chainlink/pull/12499) [`1a36386481`](https://github.com/smartcontractkit/chainlink/commit/1a363864816a3e7821d5a5844f13be360f0ecb58) Thanks [@RyanRHall](https://github.com/RyanRHall)! - auto 2.3 foundry test refactor + +- [#12661](https://github.com/smartcontractkit/chainlink/pull/12661) [`3b02047754`](https://github.com/smartcontractkit/chainlink/commit/3b020477548c17ed786036494ccc733107ca4152) Thanks [@RyanRHall](https://github.com/RyanRHall)! - more auto 2.3 tests + +- [#12598](https://github.com/smartcontractkit/chainlink/pull/12598) [`e753637e01`](https://github.com/smartcontractkit/chainlink/commit/e753637e01fabb8ea3760eb14204124c8d3b88e1) Thanks [@RyanRHall](https://github.com/RyanRHall)! - small gas fix + +- [#12540](https://github.com/smartcontractkit/chainlink/pull/12540) [`17c037678d`](https://github.com/smartcontractkit/chainlink/commit/17c037678d05c88f28a28a3ac760c742f549d5ec) Thanks [@RyanRHall](https://github.com/RyanRHall)! - change auto 2.3 flat fees from link to USD + +- [#12592](https://github.com/smartcontractkit/chainlink/pull/12592) [`b512ef5a7d`](https://github.com/smartcontractkit/chainlink/commit/b512ef5a7d1bc87d0cbd5357c5c47cc0dcb75e0b) Thanks [@ibrajer](https://github.com/ibrajer)! - Set LINK native feed in VRFV2PlusWrapper to immutable + +- [#12577](https://github.com/smartcontractkit/chainlink/pull/12577) [`cf00183f62`](https://github.com/smartcontractkit/chainlink/commit/cf00183f6295fe95979b460f89bcc65f22237fd4) Thanks [@shileiwill](https://github.com/shileiwill)! - add billing override test + +- [#12443](https://github.com/smartcontractkit/chainlink/pull/12443) [`e604a73d7b`](https://github.com/smartcontractkit/chainlink/commit/e604a73d7b21c5f053631d9c8afeb0eaf7203310) Thanks [@shileiwill](https://github.com/shileiwill)! - use common interface for v2.3 + +- [#12565](https://github.com/smartcontractkit/chainlink/pull/12565) [`b673505a91`](https://github.com/smartcontractkit/chainlink/commit/b673505a91719d42ff1a60623f1cfea26d186e56) Thanks [@RensR](https://github.com/RensR)! - bump solhint and address issues, remove unused imports + +- [#12477](https://github.com/smartcontractkit/chainlink/pull/12477) [`b2576475fc`](https://github.com/smartcontractkit/chainlink/commit/b2576475fc5c8ac037fc569fddc56e9d515ae7ca) Thanks [@shileiwill](https://github.com/shileiwill)! - support native payment + +- [#12531](https://github.com/smartcontractkit/chainlink/pull/12531) [`88e010d604`](https://github.com/smartcontractkit/chainlink/commit/88e010d604682c54c4f99e0a0916f94c0d13ece6) Thanks [@jinhoonbang](https://github.com/jinhoonbang)! - increase num optimizations to 500 for v2.5 coordinator -... ## 1.0.0 - 2024-03-25 diff --git a/contracts/package.json b/contracts/package.json index 3c17ded05a9..0e0be43647d 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -1,6 +1,6 @@ { "name": "@chainlink/contracts", - "version": "1.0.0", + "version": "1.1.0", "description": "Chainlink smart contracts", "author": "Chainlink devs", "license": "MIT", From ea1aa8d9a9f3fee4ec905f17a7386114a5d4f0fc Mon Sep 17 00:00:00 2001 From: chainchad <96362174+chainchad@users.noreply.github.com> Date: Tue, 23 Apr 2024 19:35:45 -0400 Subject: [PATCH 14/77] Support devspace local-dev profile for CRIB (#12938) * Support devspace local-dev profile for CRIB * Remove testing section in README --- charts/chainlink-cluster/.gitignore | 4 + charts/chainlink-cluster/Chart.lock | 2 +- charts/chainlink-cluster/Chart.yaml | 2 +- charts/chainlink-cluster/README.md | 156 ++++++++++++++++-- .../templates/chainlink-cm.yaml | 18 +- .../values-profiles/README.md | 3 + .../values-profiles/values-dev.yaml.example | 95 +++++++++++ charts/chainlink-cluster/values.yaml | 24 ++- crib/devspace.yaml | 48 +++++- 9 files changed, 322 insertions(+), 30 deletions(-) create mode 100644 charts/chainlink-cluster/values-profiles/README.md create mode 100644 charts/chainlink-cluster/values-profiles/values-dev.yaml.example diff --git a/charts/chainlink-cluster/.gitignore b/charts/chainlink-cluster/.gitignore index 3ee791f740a..9e704020530 100644 --- a/charts/chainlink-cluster/.gitignore +++ b/charts/chainlink-cluster/.gitignore @@ -1,3 +1,7 @@ # Helm charts/ requirements.lock +.rendered +values-profiles/* +!values-profiles/values-dev.yaml.example +!values-profiles/README.md \ No newline at end of file diff --git a/charts/chainlink-cluster/Chart.lock b/charts/chainlink-cluster/Chart.lock index 38e7f09705e..11ebdfdf691 100644 --- a/charts/chainlink-cluster/Chart.lock +++ b/charts/chainlink-cluster/Chart.lock @@ -12,4 +12,4 @@ dependencies: repository: https://grafana.github.io/helm-charts version: 7.3.2 digest: sha256:37722063f68689c42ac1d6549ddfae4756370c1659b8ac1c0d7da8916c6fad3d -generated: "2024-02-27T11:04:29.920915-06:00" +generated: "2024-04-23T17:49:50.347667-04:00" diff --git a/charts/chainlink-cluster/Chart.yaml b/charts/chainlink-cluster/Chart.yaml index fa45ea9bd77..d8d3dd98b22 100644 --- a/charts/chainlink-cluster/Chart.yaml +++ b/charts/chainlink-cluster/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v2 name: chainlink-cluster description: Chainlink nodes cluster -version: 0.4.0 +version: 0.4.2 appVersion: "2.6.0" dependencies: - name: mockserver diff --git a/charts/chainlink-cluster/README.md b/charts/chainlink-cluster/README.md index b76d55090dd..403ab9b876a 100644 --- a/charts/chainlink-cluster/README.md +++ b/charts/chainlink-cluster/README.md @@ -1,44 +1,174 @@ # Chainlink cluster Example CL nodes cluster for system level tests +Install `kubefwd` (no nixpkg for it yet, planned) + +```sh +brew install txn2/tap/kubefwd +``` + +If you want to build images you need [docker](https://docs.docker.com/engine/install/) service running + +Enter the shell (from the root project dir) + +```sh +nix develop +``` # Develop -## Install from release -Note: The setup below doesn't work at the moment. -Add the repository +## New cluster + +We are using [devspace](https://www.devspace.sh/docs/getting-started/installation?x0=3) + +Configure the cluster, see `deployments.app.helm.values` and [values.yaml](./values.yaml) comments for more details +Set up your K8s access + +```sh +export DEVSPACE_IMAGE="..." +./setup.sh ${my-personal-namespace-name-crib} ``` -helm repo add chainlink-cluster https://raw.githubusercontent.com/smartcontractkit/chainlink/helm-release/ -helm repo update + +Create a .env file based on the .env.sample file + +```sh +cp .env.sample .env +# Fill in the required values in .env ``` -Set default namespace +Build and deploy the current state of your repository +```sh +devspace deploy ``` -kubectl create ns cl-cluster -kubectl config set-context --current --namespace cl-cluster + +Default `ttl` is `72h`, use `ttl` command to update if you need more time + +Valid values are `1h`, `2m`, `3s`, etc. Go time format is invalid `1h2m3s` + +```sh +devspace run ttl ${namespace} 120h +``` + +If you want to deploy an image tag that is already available in ECR, use: + +```sh +devspace deploy --override-image-tag "" ``` -Install +If you want to deploy an image tag from a public ECR repo, use: +```sh +export DEVSPACE_IMAGE=public.ecr.aws/chainlink/chainlink +devspace deploy --override-image-tag 2.9.0 ``` + +To apply custom TOML configuration specific for your nodes, create a `values-dev.yaml` file in the `./values-profiles` directory. Start by copying the example file: + +```sh +cp values-profiles/values-dev.yaml.example values-profiles/values-dev.yaml + +``` + +Then customize the values-dev.yaml file as needed. To use this configuration during deployment, pass the --profile local-dev flag: + +```sh +devspace deploy --profile local-dev +``` + +Forward ports to check UI or run tests + +```sh +devspace run connect ${my-personal-namespace-name-crib} +``` + +List ingress hostnames + +```sh +devspace run ingress-hosts +``` + +Destroy the cluster + +```sh +devspace purge +``` + +## Running load tests + +Check this [doc](../../integration-tests/load/ocr/README.md) + +If you used `devspace dev ...` always use `devspace reset pods` to switch the pods back + +# Helm + +If you would like to use `helm` directly, please uncomment data in `values.yaml` + +## Install from local files + +```sh helm install -f values.yaml cl-cluster . ``` +Forward all apps (in another terminal) + +```sh +sudo kubefwd svc -n cl-cluster +``` + +Then you can connect and run your tests + +## Install from release + +Add the repository + +```sh +helm repo add chainlink-cluster https://raw.githubusercontent.com/smartcontractkit/chainlink/helm-release/ +helm repo update +``` + +Set default namespace + +```sh +kubectl create ns cl-cluster +kubectl config set-context --current --namespace cl-cluster +``` + ## Create a new release -Note: The setup below doesn't work at the moment. Bump version in `Chart.yml` add your changes and add `helm_release` label to any PR to trigger a release ## Helm Test -``` +```sh helm test cl-cluster ``` ## Uninstall -``` +```sh helm uninstall cl-cluster -``` \ No newline at end of file +``` + +# Grafana dashboard + +We are using [Grabana](https://github.com/K-Phoen/grabana) lib to create dashboards programmatically + +You can also select dashboard platform in `INFRA_PLATFORM` either `kubernetes` or `docker` + +```sh +export LOKI_TENANT_ID=promtail +export LOKI_URL=... +export GRAFANA_URL=... +export GRAFANA_TOKEN=... +export PROMETHEUS_DATA_SOURCE_NAME=Thanos +export LOKI_DATA_SOURCE_NAME=Loki +export INFRA_PLATFORM=kubernetes +export GRAFANA_FOLDER=CRIB +export DASHBOARD_NAME=Core-Cluster-Load + +devspace run dashboard_deploy +``` + +Open Grafana folder `DashboardCoreDebug` and find dashboard `ChainlinkClusterDebug` diff --git a/charts/chainlink-cluster/templates/chainlink-cm.yaml b/charts/chainlink-cluster/templates/chainlink-cm.yaml index 9a99e2a5128..bd0c911331c 100644 --- a/charts/chainlink-cluster/templates/chainlink-cm.yaml +++ b/charts/chainlink-cluster/templates/chainlink-cm.yaml @@ -16,9 +16,11 @@ data: CREATE EXTENSION pg_stat_statements; default.toml: | - {{ if (hasKey $cfg "toml") }} - {{ $cfg.toml | nindent 4 }} - {{ else }} + {{- if (hasKey $cfg "toml") }} + {{ $cfg.toml | nindent 4 }} + {{- else if and (hasKey $.Values.chainlink.global "toml") $.Values.chainlink.global.toml }} + {{ $.Values.chainlink.global.toml | nindent 4 }} + {{- else }} RootDir = './clroot' [Log] JSONConsole = true @@ -57,12 +59,14 @@ data: {{- end }} [WebServer.TLS] HTTPSPort = 0 - {{ end }} + {{- end }} overrides.toml: | - {{ if (hasKey $cfg "overridesToml") }} - {{ $cfg.overridesToml | nindent 4 }} + {{- if (hasKey $cfg "overridesToml") }} + {{- $cfg.overridesToml | nindent 4 }} + {{- else if and (hasKey $.Values.chainlink.global "overridesToml") $.Values.chainlink.global.overridesToml }} + {{- $.Values.chainlink.global.overridesToml | nindent 4 }} {{ else }} - {{ end }} + {{- end }} secrets.toml: | {{ if (hasKey $cfg "secretsToml") }} {{ $cfg.secretsToml | nindent 4 }} diff --git a/charts/chainlink-cluster/values-profiles/README.md b/charts/chainlink-cluster/values-profiles/README.md new file mode 100644 index 00000000000..7f5b6df4904 --- /dev/null +++ b/charts/chainlink-cluster/values-profiles/README.md @@ -0,0 +1,3 @@ +# values-profiles + +Store helm values files for different [DevSpace profiles](https://www.devspace.sh/docs/configuration/profiles/) here. The convention is to make the yaml file name in here match the DevSpace profile name. diff --git a/charts/chainlink-cluster/values-profiles/values-dev.yaml.example b/charts/chainlink-cluster/values-profiles/values-dev.yaml.example new file mode 100644 index 00000000000..99151149182 --- /dev/null +++ b/charts/chainlink-cluster/values-profiles/values-dev.yaml.example @@ -0,0 +1,95 @@ +# Disable geth if using existing testnets. +geth: + enabled: false +chainlink: + global: + toml: |- + RootDir = './clroot' + [Log] + JSONConsole = true + Level = 'debug' + [WebServer] + AllowOrigins = '*' + SecureCookies = false + SessionTimeout = '999h0m0s' + [Feature] + FeedsManager = true + LogPoller = true + UICSAKeys = true + [OCR] + Enabled = true + DefaultTransactionQueueDepth = 0 + [P2P] + [P2P.V2] + Enabled = true + ListenAddresses = ['0.0.0.0:6690'] + AnnounceAddresses = ['0.0.0.0:6690'] + DeltaDial = '500ms' + DeltaReconcile = '5s' + [[EVM]] + # Avax Fuji Testnet + ChainID = "43113" + MinContractPayment = '0' + AutoCreateKey = true + FinalityDepth = 1 + [[EVM.Nodes]] + Name = 'avax-fuji-testnet-official' + WSURL = 'wss://api.avax-test.network/ext/bc/C/ws' + HTTPURL = 'https://api.avax-test.network/ext/bc/C/rpc' + [[EVM]] + # BSC Testnet + ChainID = "97" + MinContractPayment = '0' + AutoCreateKey = true + FinalityDepth = 1 + [[EVM.Nodes]] + Name = 'bsc-testnet-official' + HTTPURL = 'https://data-seed-prebsc-1-s.bnbchain.org:8545' + WSURL = 'wss://data-seed-prebsc-1-s1.binance.org:8545/' + [WebServer.TLS] + HTTPSPort = 0 + + overridesToml: |- + [Feature] + LogPoller = true + + [Log] + Level = 'debug' + JSONConsole = true + + [Log.File] + MaxSize = '0b' + + [WebServer] + AllowOrigins = '*' + HTTPPort = 6688 + SecureCookies = false + HTTPWriteTimeout = '1m' + + [WebServer.RateLimit] + Authenticated = 2000 + Unauthenticated = 1000 + + [WebServer.TLS] + HTTPSPort = 0 + + [Database] + MaxIdleConns = 50 + MaxOpenConns = 50 + MigrateOnStartup = true + + [OCR2] + Enabled = true + DefaultTransactionQueueDepth = 0 + + [OCR] + Enabled = false + DefaultTransactionQueueDepth = 0 + + [P2P] + [P2P.V2] + Enabled = true + ListenAddresses = ['0.0.0.0:6690'] + AnnounceAddresses = ['0.0.0.0:6690'] + DeltaDial = '500ms' + DeltaReconcile = '5s' \ No newline at end of file diff --git a/charts/chainlink-cluster/values.yaml b/charts/chainlink-cluster/values.yaml index ed497a65ff9..d6315f488fd 100644 --- a/charts/chainlink-cluster/values.yaml +++ b/charts/chainlink-cluster/values.yaml @@ -11,6 +11,23 @@ # version: stable chainlink: enabled: true + global: + # `toml` is initially set to null. Uncomment and modify the following example as needed. + # Example configuration parameters for all Chainlink nodes. Can be overridden by individual node configurations and via `overridesToml`. + # toml: |- + # [Log] + # Level = 'info' + # [WebServer] + # HTTPPort = 6688 + toml: null + # `overridesToml` is initially set to null. Uncomment and modify the following example as needed. + # Example configuration parameters that override the main configuration. + # overridesToml: |- + # [Log] + # Level = 'debug' + # [WebServer] + # HTTPPort = 6690 + overridesToml: null podSecurityContext: fsGroup: 14933 securityContext: @@ -73,13 +90,6 @@ chainlink: - name: node-4 - name: node-5 - name: node-6 - resources: - requests: - cpu: 350m - memory: 1024Mi - limits: - cpu: 350m - memory: 1024Mi # each CL node have a dedicated PostgreSQL 11.15 # use StatefulSet by setting: diff --git a/crib/devspace.yaml b/crib/devspace.yaml index ca12e1ed205..cc82c6a464c 100644 --- a/crib/devspace.yaml +++ b/crib/devspace.yaml @@ -107,6 +107,42 @@ deployments: fsGroup: 999 chainlink: + global: + overridesToml: |- + [Feature] + LogPoller = true + [Log] + Level = 'debug' + JSONConsole = true + [Log.File] + MaxSize = '0b' + [WebServer] + AllowOrigins = '*' + HTTPPort = 6688 + SecureCookies = false + HTTPWriteTimeout = '1m' + [WebServer.RateLimit] + Authenticated = 2000 + Unauthenticated = 1000 + [WebServer.TLS] + HTTPSPort = 0 + [Database] + MaxIdleConns = 50 + MaxOpenConns = 50 + MigrateOnStartup = true + [OCR2] + Enabled = true + DefaultTransactionQueueDepth = 0 + [OCR] + Enabled = false + DefaultTransactionQueueDepth = 0 + [P2P] + [P2P.V2] + Enabled = true + ListenAddresses = ['0.0.0.0:6690'] + AnnounceAddresses = ['0.0.0.0:6690'] + DeltaDial = '500ms' + DeltaReconcile = '5s' securityContext: capabilities: drop: @@ -118,7 +154,7 @@ deployments: web_port: 6688 p2p_port: 6690 # extraEnvVars: - # "CL_MEDIAN_CMD": "chainlink-feeds" + # "CL_MEDIAN_CMD": "chainlink-feeds" nodes: - name: node-1 image: ${runtime.images.app} @@ -385,3 +421,13 @@ deployments: nodeSelector: tolerations: affinity: +profiles: + - name: local-dev + patches: + # Remove the global overridesToml field. + # This will be configured via a values file. + - op: remove + path: deployments.app.helm.values.chainlink.global.overridesToml + - op: add + path: deployments.app.helm.valuesFiles + value: ["../charts/chainlink-cluster/values-profiles/values-dev.yaml"] From a1f140759fec7c27f7d9aef4bb441b81a80f8b76 Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Tue, 23 Apr 2024 17:24:53 -0700 Subject: [PATCH 15/77] chore: bump ci-publish-npm to v0.4.0 (#12937) --- .github/workflows/solidity.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/solidity.yml b/.github/workflows/solidity.yml index a128316b99e..5940313fc65 100644 --- a/.github/workflows/solidity.yml +++ b/.github/workflows/solidity.yml @@ -213,7 +213,7 @@ jobs: pnpm version ${{ needs.tag-check.outputs.pre-release-version }} --no-git-tag-version --no-commit-hooks --no-git-checks - name: Publish to NPM (beta) - uses: smartcontractkit/.github/actions/ci-publish-npm@e1c9d45fc66369d6be5d3863c65af1750797a7f5 # ci-publish-npm@0.3.0 + uses: smartcontractkit/.github/actions/ci-publish-npm@4b0ab756abcb1760cb82e1e87b94ff431905bffc # ci-publish-npm@0.4.0 with: npm-token: ${{ secrets.NPM_TOKEN }} create-github-release: false @@ -255,7 +255,7 @@ jobs: fi - name: Publish to NPM (latest) - uses: smartcontractkit/.github/actions/ci-publish-npm@e1c9d45fc66369d6be5d3863c65af1750797a7f5 # ci-publish-npm@0.3.0 + uses: smartcontractkit/.github/actions/ci-publish-npm@4b0ab756abcb1760cb82e1e87b94ff431905bffc # ci-publish-npm@0.4.0 with: npm-token: ${{ secrets.NPM_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }} From 44bc2e45c9e56168e6a75eb9d0414d2b438b9969 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Tue, 23 Apr 2024 20:07:41 -0500 Subject: [PATCH 16/77] core/config/docs: mark EVM.NodePool.Errors ADVANCED (#12936) --- core/config/docs/chains-evm.toml | 1 + docs/CONFIG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/core/config/docs/chains-evm.toml b/core/config/docs/chains-evm.toml index fdcb72a3da0..49c42bc04fb 100644 --- a/core/config/docs/chains-evm.toml +++ b/core/config/docs/chains-evm.toml @@ -353,6 +353,7 @@ NodeIsSyncingEnabled = false # Default # Set to 0 to disable. FinalizedBlockPollInterval = '5s' # Default +# **ADVANCED** # Errors enable the node to provide custom regex patterns to match against error messages from RPCs. [EVM.NodePool.Errors] # NonceTooLow is a regex pattern to match against nonce too low errors. diff --git a/docs/CONFIG.md b/docs/CONFIG.md index fcf251f2702..0596fcdd84d 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -7245,6 +7245,7 @@ reported based on latest block and finality depth. Set to 0 to disable. ## EVM.NodePool.Errors +:warning: **_ADVANCED_**: _Do not change these settings unless you know what you are doing._ ```toml [EVM.NodePool.Errors] NonceTooLow = '(: |^)nonce too low' # Example From 18a9fc83754f5da77916d64addb8f2209e33608a Mon Sep 17 00:00:00 2001 From: jinhoonbang Date: Wed, 24 Apr 2024 00:05:32 -0700 Subject: [PATCH 17/77] add receive() function to v2plus wrapper consumer (#12943) * set test coordinator default to false in v2 deployment super script * add receive() function to wrapper consumer example for vrf v2 plus * prettier --- .../VRFV2PlusWrapperConsumerExample.sol | 6 + .../vrfv2plus_wrapper_consumer_example.go | 148 +++++++++++++++++- ...rapper-dependency-versions-do-not-edit.txt | 2 +- .../vrfv2/testnet/v2scripts/super_scripts.go | 2 +- core/scripts/vrfv2plus/testnet/main.go | 8 +- 5 files changed, 161 insertions(+), 5 deletions(-) diff --git a/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusWrapperConsumerExample.sol b/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusWrapperConsumerExample.sol index 5025a300c28..62e6ed2da1e 100644 --- a/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusWrapperConsumerExample.sol +++ b/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusWrapperConsumerExample.sol @@ -77,4 +77,10 @@ contract VRFV2PlusWrapperConsumerExample is VRFV2PlusWrapperConsumerBase, Confir // solhint-disable-next-line gas-custom-errors require(success, "withdrawNative failed"); } + + event Received(address, uint256); + + receive() external payable { + emit Received(msg.sender, msg.value); + } } diff --git a/core/gethwrappers/generated/vrfv2plus_wrapper_consumer_example/vrfv2plus_wrapper_consumer_example.go b/core/gethwrappers/generated/vrfv2plus_wrapper_consumer_example/vrfv2plus_wrapper_consumer_example.go index 4a4370bdf5e..c92a6496d3f 100644 --- a/core/gethwrappers/generated/vrfv2plus_wrapper_consumer_example/vrfv2plus_wrapper_consumer_example.go +++ b/core/gethwrappers/generated/vrfv2plus_wrapper_consumer_example/vrfv2plus_wrapper_consumer_example.go @@ -31,8 +31,8 @@ var ( ) var VRFV2PlusWrapperConsumerExampleMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfV2Wrapper\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyVRFWrapperCanFulfill\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"}],\"name\":\"WrappedRequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"}],\"name\":\"WrapperRequestMade\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkToken\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_requestId\",\"type\":\"uint256\"}],\"name\":\"getRequestStatus\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"fulfilled\",\"type\":\"bool\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_vrfV2PlusWrapper\",\"outputs\":[{\"internalType\":\"contractIVRFV2PlusWrapper\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"}],\"name\":\"makeRequest\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"}],\"name\":\"makeRequestNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requests\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"fulfilled\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"native\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLink\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60c06040523480156200001157600080fd5b5060405162001672380380620016728339810160408190526200003491620001f5565b33806000836000819050806001600160a01b0316631c4695f46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200007d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000a39190620001f5565b6001600160a01b0390811660805290811660a052831690506200010d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620001405762000140816200014a565b5050505062000227565b336001600160a01b03821603620001a45760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000104565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200020857600080fd5b81516001600160a01b03811681146200022057600080fd5b9392505050565b60805160a0516113ed62000285600039600081816101aa0152818161047b01528181610ab001528181610b5b01528181610c0501528181610cf30152610d62015260008181610242015281816106220152610b1f01526113ed6000f3fe608060405234801561001057600080fd5b50600436106100df5760003560e01c806384276d811161008c578063a168fa8911610066578063a168fa89146101cc578063d8a4676f1461021e578063e76d516814610240578063f2fde38b1461026657600080fd5b806384276d81146101535780638da5cb5b146101665780639ed0868d146101a557600080fd5b80631fe543e3116100bd5780631fe543e31461012357806379ba5097146101385780637a8042bd1461014057600080fd5b80630c09b832146100e457806312065fe01461010a5780631e1a349914610110575b600080fd5b6100f76100f2366004611088565b610279565b6040519081526020015b60405180910390f35b476100f7565b6100f761011e366004611088565b6103b4565b610136610131366004611103565b610479565b005b61013661051b565b61013661014e3660046111eb565b610618565b6101366101613660046111eb565b610715565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610101565b6101807f000000000000000000000000000000000000000000000000000000000000000081565b6102016101da3660046111eb565b600260205260009081526040902080546001820154600390920154909160ff908116911683565b604080519384529115156020840152151590820152606001610101565b61023161022c3660046111eb565b6107e7565b6040516101019392919061123f565b7f0000000000000000000000000000000000000000000000000000000000000000610180565b610136610274366004611269565b610907565b600061028361091b565b600061029f60405180602001604052806000151581525061099e565b905060006102af86868685610a5a565b604080516080810182528281526000602080830182815284518381528083018652848601908152606085018490528784526002808452959093208451815590516001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055915180519699509496509194909361033c93850192019061100f565b5060609190910151600390910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905560405181815283907f5f56b4c20db9f5b294cbf6f681368de4a992a27e2de2ee702dcf2cbbfa791ec49060200160405180910390a250509392505050565b60006103be61091b565b60006103da60405180602001604052806001151581525061099e565b905060006103ea86868685610c9d565b60408051608081018252828152600060208083018281528451838152808301865284860190815260016060860181905288855260028085529690942085518155915193820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001694151594909417909355915180519699509496509194909361033c93850192019061100f565b7f00000000000000000000000000000000000000000000000000000000000000003373ffffffffffffffffffffffffffffffffffffffff82161461050c576040517f8ba9316e00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff821660248201526044015b60405180910390fd5b6105168383610e03565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461059c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610503565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61062061091b565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb61067b60005473ffffffffffffffffffffffffffffffffffffffff1690565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602481018490526044016020604051808303816000875af11580156106ed573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071191906112a6565b5050565b61071d61091b565b6000805460405173ffffffffffffffffffffffffffffffffffffffff9091169083908381818185875af1925050503d8060008114610777576040519150601f19603f3d011682016040523d82523d6000602084013e61077c565b606091505b5050905080610711576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f77697468647261774e6174697665206661696c656400000000000000000000006044820152606401610503565b6000818152600260205260408120548190606090610861576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e640000000000000000000000000000006044820152606401610503565b6000848152600260208181526040808420815160808101835281548152600182015460ff16151581850152938101805483518186028101860185528181529294938601938301828280156108d457602002820191906000526020600020905b8154815260200190600101908083116108c0575b50505091835250506003919091015460ff1615156020918201528151908201516040909201519097919650945092505050565b61090f61091b565b61091881610f1a565b50565b60005473ffffffffffffffffffffffffffffffffffffffff16331461099c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610503565b565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa826040516024016109d791511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b6040517f27e5c50a00000000000000000000000000000000000000000000000000000000815263ffffffff808616600483015283166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906327e5c50a90604401602060405180830381865afa158015610af7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1b91906112c8565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634000aea07f00000000000000000000000000000000000000000000000000000000000000008389898989604051602001610b929493929190611345565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401610bbf93929190611382565b6020604051808303816000875af1158015610bde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0291906112a6565b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663fc2a88c36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9291906112c8565b915094509492505050565b6040517f13c34b7f00000000000000000000000000000000000000000000000000000000815263ffffffff808616600483015283166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906313c34b7f90604401602060405180830381865afa158015610d3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5e91906112c8565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639cfc058e82888888886040518663ffffffff1660e01b8152600401610dc09493929190611345565b60206040518083038185885af1158015610dde573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610c9291906112c8565b600082815260026020526040902054610e78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e640000000000000000000000000000006044820152606401610503565b6000828152600260208181526040909220600181810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690911790558351610ecb9391909201919084019061100f565b50600082815260026020526040908190205490517f6c84e12b4c188e61f1b4727024a5cf05c025fa58467e5eedf763c0744c89da7b91610f0e91859185916113b7565b60405180910390a15050565b3373ffffffffffffffffffffffffffffffffffffffff821603610f99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610503565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b82805482825590600052602060002090810192821561104a579160200282015b8281111561104a57825182559160200191906001019061102f565b5061105692915061105a565b5090565b5b80821115611056576000815560010161105b565b803563ffffffff8116811461108357600080fd5b919050565b60008060006060848603121561109d57600080fd5b6110a68461106f565b9250602084013561ffff811681146110bd57600080fd5b91506110cb6040850161106f565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806040838503121561111657600080fd5b8235915060208084013567ffffffffffffffff8082111561113657600080fd5b818601915086601f83011261114a57600080fd5b81358181111561115c5761115c6110d4565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110858211171561119f5761119f6110d4565b6040529182528482019250838101850191898311156111bd57600080fd5b938501935b828510156111db578435845293850193928501926111c2565b8096505050505050509250929050565b6000602082840312156111fd57600080fd5b5035919050565b600081518084526020808501945080840160005b8381101561123457815187529582019590820190600101611218565b509495945050505050565b83815282151560208201526060604082015260006112606060830184611204565b95945050505050565b60006020828403121561127b57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461129f57600080fd5b9392505050565b6000602082840312156112b857600080fd5b8151801515811461129f57600080fd5b6000602082840312156112da57600080fd5b5051919050565b6000815180845260005b81811015611307576020818501810151868301820152016112eb565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600063ffffffff808716835261ffff861660208401528085166040840152506080606083015261137860808301846112e1565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815282602082015260606040820152600061126060608301846112e1565b8381526060602082015260006113d06060830185611204565b905082604083015294935050505056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfV2Wrapper\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyVRFWrapperCanFulfill\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"Received\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"}],\"name\":\"WrappedRequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"}],\"name\":\"WrapperRequestMade\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkToken\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_requestId\",\"type\":\"uint256\"}],\"name\":\"getRequestStatus\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"fulfilled\",\"type\":\"bool\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_vrfV2PlusWrapper\",\"outputs\":[{\"internalType\":\"contractIVRFV2PlusWrapper\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"}],\"name\":\"makeRequest\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"}],\"name\":\"makeRequestNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requests\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"fulfilled\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"native\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLink\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x60c06040523480156200001157600080fd5b5060405162001751380380620017518339810160408190526200003491620001f5565b33806000836000819050806001600160a01b0316631c4695f46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200007d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000a39190620001f5565b6001600160a01b0390811660805290811660a052831690506200010d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620001405762000140816200014a565b5050505062000227565b336001600160a01b03821603620001a45760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000104565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200020857600080fd5b81516001600160a01b03811681146200022057600080fd5b9392505050565b60805160a0516114cc62000285600039600081816102550152818161055a01528181610b8f01528181610c3a01528181610ce401528181610dd20152610e41015260008181610314015281816107010152610bfe01526114cc6000f3fe6080604052600436106100d65760003560e01c806384276d811161007f578063a168fa8911610059578063a168fa8914610277578063d8a4676f146102d6578063e76d516814610305578063f2fde38b1461033857600080fd5b806384276d81146101d75780638da5cb5b146101f75780639ed0868d1461024357600080fd5b80631fe543e3116100b05780631fe543e31461018057806379ba5097146101a25780637a8042bd146101b757600080fd5b80630c09b8321461011a57806312065fe01461014d5780631e1a34991461016057600080fd5b3661011557604080513381523460208201527f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f88525874910160405180910390a1005b600080fd5b34801561012657600080fd5b5061013a610135366004611167565b610358565b6040519081526020015b60405180910390f35b34801561015957600080fd5b504761013a565b34801561016c57600080fd5b5061013a61017b366004611167565b610493565b34801561018c57600080fd5b506101a061019b3660046111e2565b610558565b005b3480156101ae57600080fd5b506101a06105fa565b3480156101c357600080fd5b506101a06101d23660046112ca565b6106f7565b3480156101e357600080fd5b506101a06101f23660046112ca565b6107f4565b34801561020357600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610144565b34801561024f57600080fd5b5061021e7f000000000000000000000000000000000000000000000000000000000000000081565b34801561028357600080fd5b506102b96102923660046112ca565b600260205260009081526040902080546001820154600390920154909160ff908116911683565b604080519384529115156020840152151590820152606001610144565b3480156102e257600080fd5b506102f66102f13660046112ca565b6108c6565b6040516101449392919061131e565b34801561031157600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061021e565b34801561034457600080fd5b506101a0610353366004611348565b6109e6565b60006103626109fa565b600061037e604051806020016040528060001515815250610a7d565b9050600061038e86868685610b39565b604080516080810182528281526000602080830182815284518381528083018652848601908152606085018490528784526002808452959093208451815590516001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055915180519699509496509194909361041b9385019201906110ee565b5060609190910151600390910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905560405181815283907f5f56b4c20db9f5b294cbf6f681368de4a992a27e2de2ee702dcf2cbbfa791ec49060200160405180910390a250509392505050565b600061049d6109fa565b60006104b9604051806020016040528060011515815250610a7d565b905060006104c986868685610d7c565b60408051608081018252828152600060208083018281528451838152808301865284860190815260016060860181905288855260028085529690942085518155915193820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001694151594909417909355915180519699509496509194909361041b9385019201906110ee565b7f00000000000000000000000000000000000000000000000000000000000000003373ffffffffffffffffffffffffffffffffffffffff8216146105eb576040517f8ba9316e00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff821660248201526044015b60405180910390fd5b6105f58383610ee2565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461067b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016105e2565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6106ff6109fa565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb61075a60005473ffffffffffffffffffffffffffffffffffffffff1690565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602481018490526044016020604051808303816000875af11580156107cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107f09190611385565b5050565b6107fc6109fa565b6000805460405173ffffffffffffffffffffffffffffffffffffffff9091169083908381818185875af1925050503d8060008114610856576040519150601f19603f3d011682016040523d82523d6000602084013e61085b565b606091505b50509050806107f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f77697468647261774e6174697665206661696c6564000000000000000000000060448201526064016105e2565b6000818152600260205260408120548190606090610940576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e6400000000000000000000000000000060448201526064016105e2565b6000848152600260208181526040808420815160808101835281548152600182015460ff16151581850152938101805483518186028101860185528181529294938601938301828280156109b357602002820191906000526020600020905b81548152602001906001019080831161099f575b50505091835250506003919091015460ff1615156020918201528151908201516040909201519097919650945092505050565b6109ee6109fa565b6109f781610ff9565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016105e2565b565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401610ab691511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b6040517f27e5c50a00000000000000000000000000000000000000000000000000000000815263ffffffff808616600483015283166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906327e5c50a90604401602060405180830381865afa158015610bd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bfa91906113a7565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634000aea07f00000000000000000000000000000000000000000000000000000000000000008389898989604051602001610c719493929190611424565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401610c9e93929190611461565b6020604051808303816000875af1158015610cbd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce19190611385565b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663fc2a88c36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7191906113a7565b915094509492505050565b6040517f13c34b7f00000000000000000000000000000000000000000000000000000000815263ffffffff808616600483015283166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906313c34b7f90604401602060405180830381865afa158015610e19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e3d91906113a7565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639cfc058e82888888886040518663ffffffff1660e01b8152600401610e9f9493929190611424565b60206040518083038185885af1158015610ebd573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610d7191906113a7565b600082815260026020526040902054610f57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e6400000000000000000000000000000060448201526064016105e2565b6000828152600260208181526040909220600181810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690911790558351610faa939190920191908401906110ee565b50600082815260026020526040908190205490517f6c84e12b4c188e61f1b4727024a5cf05c025fa58467e5eedf763c0744c89da7b91610fed9185918591611496565b60405180910390a15050565b3373ffffffffffffffffffffffffffffffffffffffff821603611078576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016105e2565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215611129579160200282015b8281111561112957825182559160200191906001019061110e565b50611135929150611139565b5090565b5b80821115611135576000815560010161113a565b803563ffffffff8116811461116257600080fd5b919050565b60008060006060848603121561117c57600080fd5b6111858461114e565b9250602084013561ffff8116811461119c57600080fd5b91506111aa6040850161114e565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080604083850312156111f557600080fd5b8235915060208084013567ffffffffffffffff8082111561121557600080fd5b818601915086601f83011261122957600080fd5b81358181111561123b5761123b6111b3565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110858211171561127e5761127e6111b3565b60405291825284820192508381018501918983111561129c57600080fd5b938501935b828510156112ba578435845293850193928501926112a1565b8096505050505050509250929050565b6000602082840312156112dc57600080fd5b5035919050565b600081518084526020808501945080840160005b83811015611313578151875295820195908201906001016112f7565b509495945050505050565b838152821515602082015260606040820152600061133f60608301846112e3565b95945050505050565b60006020828403121561135a57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461137e57600080fd5b9392505050565b60006020828403121561139757600080fd5b8151801515811461137e57600080fd5b6000602082840312156113b957600080fd5b5051919050565b6000815180845260005b818110156113e6576020818501810151868301820152016113ca565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600063ffffffff808716835261ffff861660208401528085166040840152506080606083015261145760808301846113c0565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815282602082015260606040820152600061133f60608301846113c0565b8381526060602082015260006114af60608301856112e3565b905082604083015294935050505056fea164736f6c6343000813000a", } var VRFV2PlusWrapperConsumerExampleABI = VRFV2PlusWrapperConsumerExampleMetaData.ABI @@ -405,6 +405,18 @@ func (_VRFV2PlusWrapperConsumerExample *VRFV2PlusWrapperConsumerExampleTransacto return _VRFV2PlusWrapperConsumerExample.Contract.WithdrawNative(&_VRFV2PlusWrapperConsumerExample.TransactOpts, amount) } +func (_VRFV2PlusWrapperConsumerExample *VRFV2PlusWrapperConsumerExampleTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFV2PlusWrapperConsumerExample.contract.RawTransact(opts, nil) +} + +func (_VRFV2PlusWrapperConsumerExample *VRFV2PlusWrapperConsumerExampleSession) Receive() (*types.Transaction, error) { + return _VRFV2PlusWrapperConsumerExample.Contract.Receive(&_VRFV2PlusWrapperConsumerExample.TransactOpts) +} + +func (_VRFV2PlusWrapperConsumerExample *VRFV2PlusWrapperConsumerExampleTransactorSession) Receive() (*types.Transaction, error) { + return _VRFV2PlusWrapperConsumerExample.Contract.Receive(&_VRFV2PlusWrapperConsumerExample.TransactOpts) +} + type VRFV2PlusWrapperConsumerExampleOwnershipTransferRequestedIterator struct { Event *VRFV2PlusWrapperConsumerExampleOwnershipTransferRequested @@ -677,6 +689,124 @@ func (_VRFV2PlusWrapperConsumerExample *VRFV2PlusWrapperConsumerExampleFilterer) return event, nil } +type VRFV2PlusWrapperConsumerExampleReceivedIterator struct { + Event *VRFV2PlusWrapperConsumerExampleReceived + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFV2PlusWrapperConsumerExampleReceivedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFV2PlusWrapperConsumerExampleReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFV2PlusWrapperConsumerExampleReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFV2PlusWrapperConsumerExampleReceivedIterator) Error() error { + return it.fail +} + +func (it *VRFV2PlusWrapperConsumerExampleReceivedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFV2PlusWrapperConsumerExampleReceived struct { + Arg0 common.Address + Arg1 *big.Int + Raw types.Log +} + +func (_VRFV2PlusWrapperConsumerExample *VRFV2PlusWrapperConsumerExampleFilterer) FilterReceived(opts *bind.FilterOpts) (*VRFV2PlusWrapperConsumerExampleReceivedIterator, error) { + + logs, sub, err := _VRFV2PlusWrapperConsumerExample.contract.FilterLogs(opts, "Received") + if err != nil { + return nil, err + } + return &VRFV2PlusWrapperConsumerExampleReceivedIterator{contract: _VRFV2PlusWrapperConsumerExample.contract, event: "Received", logs: logs, sub: sub}, nil +} + +func (_VRFV2PlusWrapperConsumerExample *VRFV2PlusWrapperConsumerExampleFilterer) WatchReceived(opts *bind.WatchOpts, sink chan<- *VRFV2PlusWrapperConsumerExampleReceived) (event.Subscription, error) { + + logs, sub, err := _VRFV2PlusWrapperConsumerExample.contract.WatchLogs(opts, "Received") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFV2PlusWrapperConsumerExampleReceived) + if err := _VRFV2PlusWrapperConsumerExample.contract.UnpackLog(event, "Received", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFV2PlusWrapperConsumerExample *VRFV2PlusWrapperConsumerExampleFilterer) ParseReceived(log types.Log) (*VRFV2PlusWrapperConsumerExampleReceived, error) { + event := new(VRFV2PlusWrapperConsumerExampleReceived) + if err := _VRFV2PlusWrapperConsumerExample.contract.UnpackLog(event, "Received", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type VRFV2PlusWrapperConsumerExampleWrappedRequestFulfilledIterator struct { Event *VRFV2PlusWrapperConsumerExampleWrappedRequestFulfilled @@ -941,6 +1071,8 @@ func (_VRFV2PlusWrapperConsumerExample *VRFV2PlusWrapperConsumerExample) ParseLo return _VRFV2PlusWrapperConsumerExample.ParseOwnershipTransferRequested(log) case _VRFV2PlusWrapperConsumerExample.abi.Events["OwnershipTransferred"].ID: return _VRFV2PlusWrapperConsumerExample.ParseOwnershipTransferred(log) + case _VRFV2PlusWrapperConsumerExample.abi.Events["Received"].ID: + return _VRFV2PlusWrapperConsumerExample.ParseReceived(log) case _VRFV2PlusWrapperConsumerExample.abi.Events["WrappedRequestFulfilled"].ID: return _VRFV2PlusWrapperConsumerExample.ParseWrappedRequestFulfilled(log) case _VRFV2PlusWrapperConsumerExample.abi.Events["WrapperRequestMade"].ID: @@ -959,6 +1091,10 @@ func (VRFV2PlusWrapperConsumerExampleOwnershipTransferred) Topic() common.Hash { return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") } +func (VRFV2PlusWrapperConsumerExampleReceived) Topic() common.Hash { + return common.HexToHash("0x88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f88525874") +} + func (VRFV2PlusWrapperConsumerExampleWrappedRequestFulfilled) Topic() common.Hash { return common.HexToHash("0x6c84e12b4c188e61f1b4727024a5cf05c025fa58467e5eedf763c0744c89da7b") } @@ -1002,6 +1138,8 @@ type VRFV2PlusWrapperConsumerExampleInterface interface { WithdrawNative(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) + Receive(opts *bind.TransactOpts) (*types.Transaction, error) + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFV2PlusWrapperConsumerExampleOwnershipTransferRequestedIterator, error) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFV2PlusWrapperConsumerExampleOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) @@ -1014,6 +1152,12 @@ type VRFV2PlusWrapperConsumerExampleInterface interface { ParseOwnershipTransferred(log types.Log) (*VRFV2PlusWrapperConsumerExampleOwnershipTransferred, error) + FilterReceived(opts *bind.FilterOpts) (*VRFV2PlusWrapperConsumerExampleReceivedIterator, error) + + WatchReceived(opts *bind.WatchOpts, sink chan<- *VRFV2PlusWrapperConsumerExampleReceived) (event.Subscription, error) + + ParseReceived(log types.Log) (*VRFV2PlusWrapperConsumerExampleReceived, error) + FilterWrappedRequestFulfilled(opts *bind.FilterOpts) (*VRFV2PlusWrapperConsumerExampleWrappedRequestFulfilledIterator, error) WatchWrappedRequestFulfilled(opts *bind.WatchOpts, sink chan<- *VRFV2PlusWrapperConsumerExampleWrappedRequestFulfilled) (event.Subscription, error) diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 58100294e06..6af70fd8f03 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -112,5 +112,5 @@ vrfv2plus_consumer_example: ../../contracts/solc/v0.8.19/VRFV2PlusConsumerExampl vrfv2plus_malicious_migrator: ../../contracts/solc/v0.8.19/VRFV2PlusMaliciousMigrator/VRFV2PlusMaliciousMigrator.abi ../../contracts/solc/v0.8.19/VRFV2PlusMaliciousMigrator/VRFV2PlusMaliciousMigrator.bin 5dff20621fe6ed3bed75fe4b65381b0d4b1f6286ee3571553dbeb57213b53416 vrfv2plus_reverting_example: ../../contracts/solc/v0.8.19/VRFV2PlusRevertingExample/VRFV2PlusRevertingExample.abi ../../contracts/solc/v0.8.19/VRFV2PlusRevertingExample/VRFV2PlusRevertingExample.bin 82860e6ed846eaa4a5127b96c8ce4e444138412e9ed0605cfdecb6995436b3af vrfv2plus_wrapper: ../../contracts/solc/v0.8.19/VRFV2PlusWrapper/VRFV2PlusWrapper.abi ../../contracts/solc/v0.8.19/VRFV2PlusWrapper/VRFV2PlusWrapper.bin 3c98547449e5ce5ba7a858efa48052407247771c4f6f59f883a9ba38018ef634 -vrfv2plus_wrapper_consumer_example: ../../contracts/solc/v0.8.19/VRFV2PlusWrapperConsumerExample/VRFV2PlusWrapperConsumerExample.abi ../../contracts/solc/v0.8.19/VRFV2PlusWrapperConsumerExample/VRFV2PlusWrapperConsumerExample.bin 7554bc93b2a60361cdd5611f7802de58deba6257a84d11545993f4aa37bdff02 +vrfv2plus_wrapper_consumer_example: ../../contracts/solc/v0.8.19/VRFV2PlusWrapperConsumerExample/VRFV2PlusWrapperConsumerExample.abi ../../contracts/solc/v0.8.19/VRFV2PlusWrapperConsumerExample/VRFV2PlusWrapperConsumerExample.bin aeb0c681fa264f90971f65cba1e8d41064948070b217c8204a80ac95e1fa2294 vrfv2plus_wrapper_load_test_consumer: ../../contracts/solc/v0.8.19/VRFV2PlusWrapperLoadTestConsumer/VRFV2PlusWrapperLoadTestConsumer.abi ../../contracts/solc/v0.8.19/VRFV2PlusWrapperLoadTestConsumer/VRFV2PlusWrapperLoadTestConsumer.bin 824cf74f968382efdcbbbc866eef884c13d59295b1f07b6646727ed4c0686c86 diff --git a/core/scripts/vrfv2/testnet/v2scripts/super_scripts.go b/core/scripts/vrfv2/testnet/v2scripts/super_scripts.go index b4d29af3aee..f392a35f246 100644 --- a/core/scripts/vrfv2/testnet/v2scripts/super_scripts.go +++ b/core/scripts/vrfv2/testnet/v2scripts/super_scripts.go @@ -63,7 +63,7 @@ func DeployUniverseViaCLI(e helpers.Environment) { bhsJobRunTimeout := flag.String("bhs-job-run-timeout", "1m", "") deployVRFOwner := deployCmd.Bool("deploy-vrf-owner", true, "whether to deploy VRF owner contracts") - useTestCoordinator := deployCmd.Bool("use-test-coordinator", true, "whether to use test coordinator") + useTestCoordinator := deployCmd.Bool("use-test-coordinator", false, "whether to use test coordinator") simulationBlock := deployCmd.String("simulation-block", "pending", "simulation block can be 'pending' or 'latest'") // optional flags diff --git a/core/scripts/vrfv2plus/testnet/main.go b/core/scripts/vrfv2plus/testnet/main.go index 56d6855d54e..c2e6a710858 100644 --- a/core/scripts/vrfv2plus/testnet/main.go +++ b/core/scripts/vrfv2plus/testnet/main.go @@ -1269,13 +1269,19 @@ func main() { cbGasLimit := cmd.Uint("cb-gas-limit", 100_000, "request callback gas limit") confirmations := cmd.Uint("request-confirmations", 3, "request confirmations") numWords := cmd.Uint("num-words", 1, "num words to request") + nativePayment := cmd.Bool("native-payment", false, "whether to use native payment or not") helpers.ParseArgs(cmd, os.Args[2:], "consumer-address") consumer, err := vrfv2plus_wrapper_consumer_example.NewVRFV2PlusWrapperConsumerExample( common.HexToAddress(*consumerAddress), e.Ec) helpers.PanicErr(err) - tx, err := consumer.MakeRequest(e.Owner, uint32(*cbGasLimit), uint16(*confirmations), uint32(*numWords)) + var tx *types.Transaction + if *nativePayment { + tx, err = consumer.MakeRequestNative(e.Owner, uint32(*cbGasLimit), uint16(*confirmations), uint32(*numWords)) + } else { + tx, err = consumer.MakeRequest(e.Owner, uint32(*cbGasLimit), uint16(*confirmations), uint32(*numWords)) + } helpers.PanicErr(err) helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID) case "wrapper-consumer-request-status": From 9ab33475def21c77a788f5c29bcf2eae05ebf3f5 Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Wed, 24 Apr 2024 10:35:40 +0200 Subject: [PATCH 18/77] Show E2E test coverage of chainlink node binary (#12835) * Get E2E test coverage of chainlink node binary * Fix * Fix lint * Add step to upload go coverage folder * Fix * debug * Fix * Fix lint * Debug * Fix * Fix * Show coverage in github workflow console * Fix lint * Cleanup * Add docs * Do not fail if no coverage dir was found * Update show_coverage.go to merge nodes coverage for each test * Cleanup * Update gha * Create NodeCoverageHelper and generate total coverage for all tests * Update covdata artifact name * Fix * Remove unnecessary build step * Update README * Fix * Update readme * Fix * Fixes * Remove ls step from workflow * Fix action version and tag * Bump CTF * Bump CTF --- .../actions/build-chainlink-image/action.yml | 3 +- .github/workflows/integration-tests.yml | 77 ++++++++- .gitignore | 1 + GNUmakefile | 4 + core/chainlink.Dockerfile | 14 +- integration-tests/docker/README.md | 26 +++ .../docker/node_coverage_helper.go | 162 ++++++++++++++++++ .../docker/test_env/cl_node_cluster.go | 69 ++++++++ integration-tests/docker/test_env/test_env.go | 96 ++++++++++- .../docker/test_env/test_env_builder.go | 3 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- integration-tests/load/vrfv2/vrfv2_test.go | 4 +- .../load/vrfv2plus/vrfv2plus_test.go | 4 +- integration-tests/scripts/show_coverage.go | 78 +++++++++ integration-tests/smoke/vrfv2_test.go | 8 +- integration-tests/smoke/vrfv2plus_test.go | 14 +- 19 files changed, 545 insertions(+), 30 deletions(-) create mode 100644 integration-tests/docker/node_coverage_helper.go create mode 100644 integration-tests/scripts/show_coverage.go diff --git a/.github/actions/build-chainlink-image/action.yml b/.github/actions/build-chainlink-image/action.yml index f75bd68a87e..bd5ffe6403d 100644 --- a/.github/actions/build-chainlink-image/action.yml +++ b/.github/actions/build-chainlink-image/action.yml @@ -33,7 +33,7 @@ runs: AWS_ROLE_TO_ASSUME: ${{ inputs.AWS_ROLE_TO_ASSUME }} - name: Build Image if: steps.check-image.outputs.exists != 'true' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@519851800779323566b7b7c22cc21bff95dbb639 # v2.3.14 with: cl_repo: smartcontractkit/chainlink cl_ref: ${{ inputs.git_commit_sha }} @@ -41,6 +41,7 @@ runs: push_tag: ${{ env.CHAINLINK_IMAGE }}:${{ inputs.git_commit_sha }}${{ inputs.tag_suffix }} QA_AWS_REGION: ${{ inputs.AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ inputs.AWS_ROLE_TO_ASSUME }} + GO_COVER_FLAG: true dep_evm_sha: ${{ inputs.dep_evm_sha }} - name: Print Chainlink Image Built shell: sh diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 98d67a8b2d3..3ba0f2976ec 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -372,7 +372,7 @@ jobs: ## Run this step when changes that require tests to be run are made - name: Run Tests if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@519851800779323566b7b7c22cc21bff95dbb639 with: test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage test_download_vendor_packages_command: cd ./integration-tests && go mod download @@ -392,6 +392,16 @@ jobs: QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: "" should_tidy: "false" + go_coverage_src_dir: /var/tmp/go-coverage + go_coverage_dest_dir: ${{ github.workspace }}/.covdata + + - name: Upload Coverage Data + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + with: + name: cl-node-coverage-data-${{ matrix.product.name }} + path: .covdata + retention-days: 1 + - name: Print failed test summary if: always() uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/show-test-summary@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11 @@ -464,7 +474,7 @@ jobs: ## Run this step when changes that require tests to be run are made - name: Run Tests if: needs.changes.outputs.src == 'true' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@519851800779323566b7b7c22cc21bff95dbb639 # v2.3.11 with: test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage test_download_vendor_packages_command: cd ./integration-tests && go mod download @@ -484,6 +494,15 @@ jobs: QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: "" should_tidy: "false" + go_coverage_src_dir: /var/tmp/go-coverage + go_coverage_dest_dir: ${{ github.workspace }}/.covdata + + - name: Upload Coverage Data + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + with: + name: cl-node-coverage-data-${{ matrix.product.name }} + path: .covdata + retention-days: 1 eth-smoke-tests-matrix: if: ${{ !contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests') }} @@ -666,7 +685,7 @@ jobs: ## Run this step when changes that require tests to be run are made - name: Run Tests if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@519851800779323566b7b7c22cc21bff95dbb639 with: test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage test_download_vendor_packages_command: cd ./integration-tests && go mod download @@ -686,6 +705,16 @@ jobs: QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: "" should_tidy: "false" + go_coverage_src_dir: /var/tmp/go-coverage + go_coverage_dest_dir: ${{ github.workspace }}/.covdata + + - name: Upload Coverage Data + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + with: + name: cl-node-coverage-data-${{ matrix.product.name }}-${{ matrix.product.tag_suffix }} + path: .covdata + retention-days: 1 + # Run this step when changes that do not need the test to run are made - name: Run Setup if: needs.changes.outputs.src == 'false' @@ -778,6 +807,26 @@ jobs: this-job-name: Clean up integration environment deployments continue-on-error: true + show-coverage: + name: Show Chainlink Node Go Coverage + if: always() + needs: [cleanup] + runs-on: ubuntu-latest + steps: + - name: Checkout the repo + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + with: + repository: smartcontractkit/chainlink + ref: ${{ inputs.cl_ref || github.event.pull_request.head.sha || github.event.merge_group.head_sha }} + - name: Download All Artifacts + uses: actions/download-artifact@9c19ed7fe5d278cd354c7dfd5d3b88589c7e2395 # v4.1.6 + with: + path: cl-node-coverage-data + pattern: cl-node-coverage-data-* + merge-multiple: true + - name: Show Coverage + run: go run ./integration-tests/scripts/show_coverage.go "${{ github.workspace }}/cl-node-coverage-data/*/merged" + # Run the setup if the matrix finishes but this time save the cache if we have a cache hit miss # this will also only run if both of the matrix jobs pass eth-smoke-go-mod-cache: @@ -850,7 +899,7 @@ jobs: upgradeImage: ${{ env.UPGRADE_IMAGE }} upgradeVersion: ${{ env.UPGRADE_VERSION }} - name: Run Migration Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@519851800779323566b7b7c22cc21bff95dbb639 # v2.3.11 with: test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json ./migration 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage test_download_vendor_packages_command: cd ./integration-tests && go mod download @@ -868,6 +917,15 @@ jobs: QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + go_coverage_src_dir: /var/tmp/go-coverage + go_coverage_dest_dir: ${{ github.workspace }}/.covdata + - name: Upload Coverage Data + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + with: + name: cl-node-coverage-data-migration-tests + path: .covdata + retention-days: 1 + - name: Collect Metrics if: always() id: collect-gha-metrics @@ -1150,7 +1208,7 @@ jobs: echo "BASE64_CONFIG_OVERRIDE=$BASE64_CONFIG_OVERRIDE" >> $GITHUB_ENV - name: Run Tests if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@519851800779323566b7b7c22cc21bff95dbb639 # v2.3.11 with: test_command_to_run: export ENV_JOB_IMAGE=${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-solana-tests:${{ needs.get_solana_sha.outputs.sha }} && make test_smoke cl_repo: ${{ env.CHAINLINK_IMAGE }} @@ -1168,4 +1226,13 @@ jobs: QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: "" run_setup: false + go_coverage_src_dir: /var/tmp/go-coverage + go_coverage_dest_dir: ${{ github.workspace }}/.covdata + + - name: Upload Coverage Data + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + with: + name: cl-node-coverage-data-solana-tests + path: .covdata + retention-days: 1 diff --git a/.gitignore b/.gitignore index 0a938ff9123..b286c329292 100644 --- a/.gitignore +++ b/.gitignore @@ -51,6 +51,7 @@ output.txt race.* golangci-lint-output.txt /golangci-lint/ +.covdata # DB state ./db/ diff --git a/GNUmakefile b/GNUmakefile index c5a0dfc6c21..524786585e9 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -45,6 +45,10 @@ docs: ## Install and run pkgsite to view Go docs install-chainlink: operator-ui ## Install the chainlink binary. go install $(GOFLAGS) . +.PHONY: install-chainlink-cover +install-chainlink-cover: operator-ui ## Install the chainlink binary with cover flag. + go install -cover $(GOFLAGS) . + .PHONY: chainlink chainlink: ## Build the chainlink binary. go build $(GOFLAGS) . diff --git a/core/chainlink.Dockerfile b/core/chainlink.Dockerfile index 4aa447b5ddd..48f6da73612 100644 --- a/core/chainlink.Dockerfile +++ b/core/chainlink.Dockerfile @@ -12,12 +12,19 @@ RUN go mod download # Env vars needed for chainlink build ARG COMMIT_SHA +# Build chainlink bin with cover flag https://go.dev/doc/build-cover#FAQ +ARG GO_COVER_FLAG=false + COPY . . RUN apt-get update && apt-get install -y jq # Build the golang binary -RUN make install-chainlink +RUN if [ "$GO_COVER_FLAG" = "true" ]; then \ + make install-chainlink-cover; \ + else \ + make install-chainlink; \ + fi # Link LOOP Plugin source dirs with simple names RUN go list -m -f "{{.Dir}}" github.com/smartcontractkit/chainlink-feeds | xargs -I % ln -s % /chainlink-feeds @@ -68,6 +75,11 @@ WORKDIR /home/${CHAINLINK_USER} ENV XDG_CACHE_HOME /home/${CHAINLINK_USER}/.cache RUN mkdir -p ${XDG_CACHE_HOME} +# Set up env and dir for go coverage profiling https://go.dev/doc/build-cover#FAQ +ARG GO_COVER_DIR="/var/tmp/go-coverage" +ENV GOCOVERDIR=${GO_COVER_DIR} +RUN mkdir -p $GO_COVER_DIR + EXPOSE 6688 ENTRYPOINT ["chainlink"] diff --git a/integration-tests/docker/README.md b/integration-tests/docker/README.md index 7df481832e6..c558f3bca8a 100644 --- a/integration-tests/docker/README.md +++ b/integration-tests/docker/README.md @@ -20,3 +20,29 @@ cd ./integration-tests/docker/cmd go run test_env.go start-env cl-cluster ``` + +## Obtaining Test Coverage for Chainlink Node + +To acquire test coverage data for end-to-end (E2E) tests on the Chainlink Node, follow these steps: + +1. Build Chainlink Node docker image with the cover flag. + + First, build the Chainlink Node Docker image with the `GO_COVER_FLAG` argument set to `true`. This enables the coverage flag in the build process. Here’s how you can do it: + ``` + docker buildx build --platform linux/arm64 . -t localhost/chainlink-local:develop -f ./core/chainlink.Dockerfile --build-arg GO_COVER_FLAG=true + ``` + Make sure to replace localhost/chainlink-local:develop with the appropriate repository and tag. + +2. Configure and Run E2E Tests + Next, configure the E2E tests to generate an HTML coverage report. You need to modify the `overrides.toml` file as shown below to include the show_html_coverage_report setting under the `[Logging]` section: + + ``` + [Logging] + show_html_coverage_report=true + ``` + +After the tests are complete, the coverage report will be generated in HTML format. Example: `~/Downloads/go-coverage/TestOCRv2Basic_plugins-chain-reader/coverage.html` +``` + log.go:43: 16:29:46.73 INF Chainlink node coverage html report saved filePath=~/Downloads/go-coverage/TestOCRv2Basic_plugins-chain-reader/coverage.html +``` + diff --git a/integration-tests/docker/node_coverage_helper.go b/integration-tests/docker/node_coverage_helper.go new file mode 100644 index 00000000000..52531bd35cf --- /dev/null +++ b/integration-tests/docker/node_coverage_helper.go @@ -0,0 +1,162 @@ +package docker + +import ( + "context" + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" + "sync" + + "github.com/pkg/errors" + tc "github.com/testcontainers/testcontainers-go" +) + +type NodeCoverageHelper struct { + Nodes []tc.Container + GoCoverSrcDir string // Path to the source directory on the chainlink image with go coverage data + NodeCoverageDirs []string // Paths to individual node coverage directories + CoverageDir string // Path to the base directory with all coverage + MergedDir string // Path to the directory where all coverage will be merged + ChainlinkDir string // Path to the root chainlink directory +} + +func NewNodeCoverageHelper(ctx context.Context, nodes []tc.Container, chainlinkDir, coverageDir string) (*NodeCoverageHelper, error) { + coverSrcDir := os.Getenv("GO_COVERAGE_SRC_DIR") + if coverSrcDir == "" { + coverSrcDir = "/var/tmp/go-coverage" // Default path + } + + helper := &NodeCoverageHelper{ + Nodes: nodes, + GoCoverSrcDir: coverSrcDir, + CoverageDir: coverageDir, + MergedDir: filepath.Join(coverageDir, "merged"), + ChainlinkDir: chainlinkDir, + } + + if err := os.MkdirAll(coverageDir, 0755); err != nil { + return nil, errors.Wrap(err, "failed to create base directory for node coverage") + } + + // Copy coverage data from nodes + if err := helper.copyCoverageFromNodes(ctx); err != nil { + return nil, errors.Wrap(err, "failed to copy coverage from nodes during initialization") + } + + // Merge the coverage data + if err := helper.mergeCoverage(); err != nil { + return nil, errors.Wrap(err, "failed to merge coverage data") + } + + return helper, nil +} + +func (c *NodeCoverageHelper) SaveMergedHTMLReport() (string, error) { + // Generate the textual coverage report + txtCommand := exec.Command("go", "tool", "covdata", "textfmt", "-i=.", "-o=cov.txt") + txtCommand.Dir = c.MergedDir + if txtOutput, err := txtCommand.CombinedOutput(); err != nil { + return "", errors.Wrapf(err, "failed to generate textual coverage report: %s", string(txtOutput)) + } + + // Generate the HTML coverage report + htmlFilePath := filepath.Join(c.CoverageDir, "coverage.html") + // #nosec G204 + htmlCommand := exec.Command("go", "tool", "cover", "-html="+filepath.Join(c.MergedDir, "cov.txt"), "-o="+htmlFilePath) + htmlCommand.Dir = c.ChainlinkDir + if htmlOutput, err := htmlCommand.CombinedOutput(); err != nil { + return "", errors.Wrapf(err, "failed to generate HTML coverage report: %s", string(htmlOutput)) + } + + return htmlFilePath, nil +} + +func (c *NodeCoverageHelper) SaveMergedCoveragePercentage() (string, error) { + filePath := filepath.Join(c.CoverageDir, "percentage.txt") + + // Calculate coverage percentage from the merged data + percentCmd := exec.Command("go", "tool", "covdata", "percent", "-i=.") + percentCmd.Dir = c.MergedDir // Ensure the command runs in the directory with the merged data + output, err := percentCmd.CombinedOutput() + if err != nil { + return "", fmt.Errorf("failed to get merged coverage percentage report: %w, output: %s", err, string(output)) + } + + // Save the cmd output to a file + if err := os.WriteFile(filePath, output, 0600); err != nil { + return "", errors.Wrap(err, "failed to write coverage percentage to file") + } + + return filePath, nil +} + +func (c *NodeCoverageHelper) mergeCoverage() error { + if err := os.MkdirAll(c.MergedDir, 0755); err != nil { + return fmt.Errorf("failed to create merged directory: %w", err) + } + + // Merge the coverage data from all chainlink nodes + dirInput := strings.Join(c.NodeCoverageDirs, ",") + // #nosec G204 + mergeCmd := exec.Command("go", "tool", "covdata", "merge", "-o", c.MergedDir, "-i="+dirInput) + mergeCmd.Dir = filepath.Dir(c.MergedDir) + output, err := mergeCmd.CombinedOutput() + if err != nil { + return fmt.Errorf("error executing merge command: %w, output: %s", err, string(output)) + } + + // Remove the coverage dirs after merging + for _, dir := range c.NodeCoverageDirs { + if err := os.RemoveAll(dir); err != nil { + return fmt.Errorf("failed to remove directory %s: %w", dir, err) + } + } + c.NodeCoverageDirs = []string{} // Reset the coverage paths after merging + + return nil +} + +func (c *NodeCoverageHelper) copyCoverageFromNodes(ctx context.Context) error { + var wg sync.WaitGroup + errorsChan := make(chan error, len(c.Nodes)) + + for i, node := range c.Nodes { + wg.Add(1) + go func(n tc.Container, id int) { + defer wg.Done() + finalDestPath := filepath.Join(c.CoverageDir, fmt.Sprintf("node_%d", id)) + if err := os.MkdirAll(finalDestPath, 0755); err != nil { + errorsChan <- fmt.Errorf("failed to create directory for node %d: %w", id, err) + return + } + err := copyFolderFromContainerUsingDockerCP(ctx, n.GetContainerID(), c.GoCoverSrcDir, finalDestPath) + if err != nil { + errorsChan <- fmt.Errorf("failed to copy folder from container for node %d: %w", id, err) + return + } + finalDestPath = filepath.Join(finalDestPath, "go-coverage") // Assuming path structure /var/tmp/go-coverage/TestName/node_X/go-coverage + c.NodeCoverageDirs = append(c.NodeCoverageDirs, finalDestPath) + }(node, i) + } + + wg.Wait() + close(errorsChan) + + for err := range errorsChan { + if err != nil { + return err + } + } + + return nil +} +func copyFolderFromContainerUsingDockerCP(ctx context.Context, containerID, srcPath, destPath string) error { + source := fmt.Sprintf("%s:%s", containerID, srcPath) + cmd := exec.CommandContext(ctx, "docker", "cp", source, destPath) + if output, err := cmd.CombinedOutput(); err != nil { + return errors.Wrapf(err, "docker cp command failed: %s, output: %s", cmd, string(output)) + } + return nil +} diff --git a/integration-tests/docker/test_env/cl_node_cluster.go b/integration-tests/docker/test_env/cl_node_cluster.go index 08122b5744d..679e5393811 100644 --- a/integration-tests/docker/test_env/cl_node_cluster.go +++ b/integration-tests/docker/test_env/cl_node_cluster.go @@ -1,9 +1,16 @@ package test_env import ( + "context" "fmt" + "os" + "os/exec" + "path/filepath" + "sync" + "time" "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" "golang.org/x/sync/errgroup" "github.com/smartcontractkit/chainlink/integration-tests/client" @@ -36,6 +43,25 @@ func (c *ClCluster) Start() error { return eg.Wait() } +func (c *ClCluster) Stop() error { + eg := &errgroup.Group{} + nodes := c.Nodes + timeout := time.Minute * 1 + + for i := 0; i < len(nodes); i++ { + nodeIndex := i + eg.Go(func() error { + err := nodes[nodeIndex].Container.Stop(context.Background(), &timeout) + if err != nil { + return err + } + return nil + }) + } + + return eg.Wait() +} + func (c *ClCluster) NodeAPIs() []*client.ChainlinkClient { clients := make([]*client.ChainlinkClient, 0) for _, c := range c.Nodes { @@ -68,3 +94,46 @@ func (c *ClCluster) NodeCSAKeys() ([]string, error) { } return keys, nil } + +func (c *ClCluster) CopyFolderFromNodes(ctx context.Context, srcPath, destPath string) error { + var wg sync.WaitGroup + errors := make(chan error, len(c.Nodes)) + + for i, node := range c.Nodes { + wg.Add(1) + go func(n *ClNode, id int) { + defer wg.Done() + // Create a unique subdirectory for each node based on an identifier + finalDestPath := filepath.Join(destPath, fmt.Sprintf("node_%d", id)) + if err := os.MkdirAll(finalDestPath, 0755); err != nil { + errors <- fmt.Errorf("failed to create directory for node %d: %w", id, err) + return + } + err := copyFolderFromContainerUsingDockerCP(ctx, n.Container.GetContainerID(), srcPath, finalDestPath) + if err != nil { + errors <- fmt.Errorf("failed to copy folder for node %d: %w", id, err) + return + } + }(node, i) + } + + wg.Wait() + close(errors) + + for err := range errors { + if err != nil { + return err + } + } + + return nil +} + +func copyFolderFromContainerUsingDockerCP(ctx context.Context, containerID, srcPath, destPath string) error { + source := fmt.Sprintf("%s:%s", containerID, srcPath) + cmd := exec.CommandContext(ctx, "docker", "cp", source, destPath) + if output, err := cmd.CombinedOutput(); err != nil { + return errors.Wrapf(err, "docker cp command failed: %s, output: %s", cmd, string(output)) + } + return nil +} diff --git a/integration-tests/docker/test_env/test_env.go b/integration-tests/docker/test_env/test_env.go index d54f51eeea1..fc0ba355556 100644 --- a/integration-tests/docker/test_env/test_env.go +++ b/integration-tests/docker/test_env/test_env.go @@ -1,9 +1,14 @@ package test_env import ( + "context" "encoding/json" "fmt" "math/big" + "os" + "path/filepath" + "runtime" + "strings" "testing" "github.com/ethereum/go-ethereum/accounts/keystore" @@ -23,6 +28,7 @@ import ( actions_seth "github.com/smartcontractkit/chainlink/integration-tests/actions/seth" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" + d "github.com/smartcontractkit/chainlink/integration-tests/docker" core_testconfig "github.com/smartcontractkit/chainlink/integration-tests/testconfig" ) @@ -198,8 +204,12 @@ func (te *CLClusterTestEnv) Terminate() error { return nil } +type CleanupOpts struct { + TestName string +} + // Cleanup cleans the environment up after it's done being used, mainly for returning funds when on live networks and logs. -func (te *CLClusterTestEnv) Cleanup() error { +func (te *CLClusterTestEnv) Cleanup(opts CleanupOpts) error { te.l.Info().Msg("Cleaning up test environment") runIdErr := runid.RemoveLocalRunId(te.TestConfig.GetLoggingConfig().RunId) @@ -228,6 +238,11 @@ func (te *CLClusterTestEnv) Cleanup() error { } } + err := te.handleNodeCoverageReports(opts.TestName) + if err != nil { + te.l.Error().Err(err).Msg("Error handling node coverage reports") + } + // close EVMClient connections for _, evmClient := range te.evmClients { err := evmClient.Close() @@ -241,6 +256,85 @@ func (te *CLClusterTestEnv) Cleanup() error { return nil } +// handleNodeCoverageReports handles the coverage reports for the chainlink nodes +func (te *CLClusterTestEnv) handleNodeCoverageReports(testName string) error { + testName = strings.ReplaceAll(testName, "/", "_") + showHTMLCoverageReport := te.TestConfig.GetLoggingConfig().ShowHTMLCoverageReport != nil && *te.TestConfig.GetLoggingConfig().ShowHTMLCoverageReport + isCI := os.Getenv("CI") != "" + + te.l.Info(). + Bool("showCoverageReportFlag", showHTMLCoverageReport). + Bool("isCI", isCI). + Bool("show", showHTMLCoverageReport || isCI). + Msg("Checking if coverage report should be shown") + + var covHelper *d.NodeCoverageHelper + + if showHTMLCoverageReport || isCI { + // Stop all nodes in the chainlink cluster. + // This is needed to get go coverage profile from the node containers https://go.dev/doc/build-cover#FAQ + err := te.ClCluster.Stop() + if err != nil { + return err + } + + clDir, err := getChainlinkDir() + if err != nil { + return err + } + + var coverageRootDir string + if os.Getenv("GO_COVERAGE_DEST_DIR") != "" { + coverageRootDir = filepath.Join(os.Getenv("GO_COVERAGE_DEST_DIR"), testName) + } else { + coverageRootDir = filepath.Join(clDir, ".covdata", testName) + } + + var containers []tc.Container + for _, node := range te.ClCluster.Nodes { + containers = append(containers, node.Container) + } + + covHelper, err = d.NewNodeCoverageHelper(context.Background(), containers, clDir, coverageRootDir) + if err != nil { + return err + } + } + + // Show html coverage report when flag is set (local runs) + if showHTMLCoverageReport { + path, err := covHelper.SaveMergedHTMLReport() + if err != nil { + return err + } + te.l.Info().Str("testName", testName).Str("filePath", path).Msg("Chainlink node coverage html report saved") + } + + // Save percentage coverage report when running in CI + if isCI { + // Save coverage percentage to a file to show in the CI + path, err := covHelper.SaveMergedCoveragePercentage() + if err != nil { + te.l.Error().Err(err).Str("testName", testName).Msg("Failed to save coverage percentage for test") + } else { + te.l.Info().Str("testName", testName).Str("filePath", path).Msg("Chainlink node coverage percentage report saved") + } + } + + return nil +} + +// getChainlinkDir returns the path to the chainlink directory +func getChainlinkDir() (string, error) { + _, filename, _, ok := runtime.Caller(1) + if !ok { + return "", fmt.Errorf("cannot determine the path of the calling file") + } + dir := filepath.Dir(filename) + chainlinkDir := filepath.Clean(filepath.Join(dir, "../../..")) + return chainlinkDir, nil +} + func (te *CLClusterTestEnv) logWhetherAllContainersAreRunning() { for _, node := range te.ClCluster.Nodes { if node.Container == nil { diff --git a/integration-tests/docker/test_env/test_env_builder.go b/integration-tests/docker/test_env/test_env_builder.go index b9406bf16aa..c2aa07c8fa9 100644 --- a/integration-tests/docker/test_env/test_env_builder.go +++ b/integration-tests/docker/test_env/test_env_builder.go @@ -258,7 +258,8 @@ func (b *CLTestEnvBuilder) Build() (*CLClusterTestEnv, error) { switch b.cleanUpType { case CleanUpTypeStandard: b.t.Cleanup(func() { - if err := b.te.Cleanup(); err != nil { + // Cleanup test environment + if err := b.te.Cleanup(CleanupOpts{TestName: b.t.Name()}); err != nil { b.l.Error().Err(err).Msg("Error cleaning up test environment") } }) diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 4f166385c69..327e5e69d94 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -26,7 +26,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.3 github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9 - github.com/smartcontractkit/chainlink-testing-framework v1.28.3 + github.com/smartcontractkit/chainlink-testing-framework v1.28.4 github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 65b67170dea..577ae3f2a0d 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1529,8 +1529,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba5 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58/go.mod h1:oV5gIuSKrPEcjQ6uB6smBsm5kXHxyydVLNyAs4V9CoQ= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595 h1:y6ks0HsSOhPUueOmTcoxDQ50RCS1XINlRDTemZyHjFw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595/go.mod h1:vV6WfnVIbK5Q1JsIru4YcTG0T1uRpLJm6t2BgCnCSsg= -github.com/smartcontractkit/chainlink-testing-framework v1.28.3 h1:rZ622PUSE9jJvI2g1SNNcMJedXyMzq9XJ8SbV2j9TvA= -github.com/smartcontractkit/chainlink-testing-framework v1.28.3/go.mod h1:jN+HgXbriq6fKRlIqLw9F3I81aYImV6kBJkIfz0mdIA= +github.com/smartcontractkit/chainlink-testing-framework v1.28.4 h1:/OOPH76VFQlG5HEXrXgBVDv1fjuasQzMV1EyeaaXWzM= +github.com/smartcontractkit/chainlink-testing-framework v1.28.4/go.mod h1:jN+HgXbriq6fKRlIqLw9F3I81aYImV6kBJkIfz0mdIA= github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 h1:LQmRsrzzaYYN3wEU1l5tWiccznhvbyGnu2N+wHSXZAo= github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772/go.mod h1:Kn1Hape05UzFZ7bOUnm3GVsHzP0TNrVmpfXYNHdqGGs= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 42e97969260..eaf0332af63 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -17,7 +17,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.3 github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9 - github.com/smartcontractkit/chainlink-testing-framework v1.28.3 + github.com/smartcontractkit/chainlink-testing-framework v1.28.4 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 5572271a58f..631336409b3 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1512,8 +1512,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba5 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58/go.mod h1:oV5gIuSKrPEcjQ6uB6smBsm5kXHxyydVLNyAs4V9CoQ= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595 h1:y6ks0HsSOhPUueOmTcoxDQ50RCS1XINlRDTemZyHjFw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595/go.mod h1:vV6WfnVIbK5Q1JsIru4YcTG0T1uRpLJm6t2BgCnCSsg= -github.com/smartcontractkit/chainlink-testing-framework v1.28.3 h1:rZ622PUSE9jJvI2g1SNNcMJedXyMzq9XJ8SbV2j9TvA= -github.com/smartcontractkit/chainlink-testing-framework v1.28.3/go.mod h1:jN+HgXbriq6fKRlIqLw9F3I81aYImV6kBJkIfz0mdIA= +github.com/smartcontractkit/chainlink-testing-framework v1.28.4 h1:/OOPH76VFQlG5HEXrXgBVDv1fjuasQzMV1EyeaaXWzM= +github.com/smartcontractkit/chainlink-testing-framework v1.28.4/go.mod h1:jN+HgXbriq6fKRlIqLw9F3I81aYImV6kBJkIfz0mdIA= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240227164431-18a7065e23ea h1:ZdLmNAfKRjH8AYUvjiiDGUgiWQfq/7iNpxyTkvjx/ko= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240227164431-18a7065e23ea/go.mod h1:gCKC9w6XpNk6jm+XIk2psrkkfxhi421N9NSiFceXW88= github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 h1:LQmRsrzzaYYN3wEU1l5tWiccznhvbyGnu2N+wHSXZAo= diff --git a/integration-tests/load/vrfv2/vrfv2_test.go b/integration-tests/load/vrfv2/vrfv2_test.go index e420d66ec8c..ca41dd40ea9 100644 --- a/integration-tests/load/vrfv2/vrfv2_test.go +++ b/integration-tests/load/vrfv2/vrfv2_test.go @@ -86,7 +86,7 @@ func TestVRFV2Performance(t *testing.T) { } } if !*vrfv2Config.General.UseExistingEnv { - if err := testEnv.Cleanup(); err != nil { + if err := testEnv.Cleanup(test_env.CleanupOpts{}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } @@ -230,7 +230,7 @@ func TestVRFV2BHSPerformance(t *testing.T) { } } if !*vrfv2Config.General.UseExistingEnv { - if err := testEnv.Cleanup(); err != nil { + if err := testEnv.Cleanup(test_env.CleanupOpts{}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } diff --git a/integration-tests/load/vrfv2plus/vrfv2plus_test.go b/integration-tests/load/vrfv2plus/vrfv2plus_test.go index d461b4cde20..e24b2ff17d8 100644 --- a/integration-tests/load/vrfv2plus/vrfv2plus_test.go +++ b/integration-tests/load/vrfv2plus/vrfv2plus_test.go @@ -86,7 +86,7 @@ func TestVRFV2PlusPerformance(t *testing.T) { } } if !*testConfig.VRFv2Plus.General.UseExistingEnv { - if err := testEnv.Cleanup(); err != nil { + if err := testEnv.Cleanup(test_env.CleanupOpts{}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } @@ -229,7 +229,7 @@ func TestVRFV2PlusBHSPerformance(t *testing.T) { } } if !*testConfig.VRFv2Plus.General.UseExistingEnv { - if err := testEnv.Cleanup(); err != nil { + if err := testEnv.Cleanup(test_env.CleanupOpts{}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } diff --git a/integration-tests/scripts/show_coverage.go b/integration-tests/scripts/show_coverage.go new file mode 100644 index 00000000000..0491ec744a2 --- /dev/null +++ b/integration-tests/scripts/show_coverage.go @@ -0,0 +1,78 @@ +package main + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" +) + +// main manages the process of combining coverage data for all tests +func main() { + // Check if the user has provided an argument + if len(os.Args) < 2 { + fmt.Println("Usage: go run script.go ") + os.Exit(1) + } + + // First argument after the program name is the search pattern + searchPattern := os.Args[1] + + // Glob pattern to find all 'merged' directories in artifact folders + dirs, err := filepath.Glob(searchPattern) + if err != nil { + fmt.Printf("Failed to find directories: %v\n", err) + os.Exit(1) + } + + if len(dirs) == 0 { + fmt.Println("No directories found.") + return + } + + fmt.Printf("Found directories with test coverage data: %v\n", dirs) + + // Join the directory paths for input + dirInput := strings.Join(dirs, ",") + + // Ensure the merged directory exists + mergedDir := filepath.Join(".covdata", "merged") + if err := os.MkdirAll(mergedDir, 0755); err != nil { + fmt.Printf("Failed to create merged directory %s: %v\n", mergedDir, err) + os.Exit(1) + } + + // Merge the coverage data from all chainlink nodes + mergeCmd := exec.Command("go", "tool", "covdata", "merge", "-o", mergedDir, "-i="+dirInput) + fmt.Printf("Merging coverage data for all tests:\n%s\n", mergeCmd.String()) + output, err := mergeCmd.CombinedOutput() + if err != nil { + fmt.Printf("Error executing merge command: %v, output: %s\n", err, output) + os.Exit(1) + } + + // Calculate coverage percentage in the merged directory + coverageCmd := exec.Command("go", "tool", "covdata", "percent", "-i=.") + coverageCmd.Dir = mergedDir + fmt.Printf("Calculate total coverage for on all tests: %s\n", coverageCmd.String()) + coverageOutput, err := coverageCmd.CombinedOutput() + if err != nil { + fmt.Printf("Error calculating coverage percentage: %v\n", err) + os.Exit(1) + } + + // Save the coverage percentage to a file + filePath, err := filepath.Abs(filepath.Join(mergedDir, "percentage.txt")) + if err != nil { + fmt.Printf("Error obtaining absolute path: %s\n", err) + os.Exit(1) + } + if err := os.WriteFile(filePath, coverageOutput, 0600); err != nil { + fmt.Printf("Failed to write coverage percentage to file: %v\n", err) + os.Exit(1) + } + fmt.Printf("Total coverage for all tests saved to %s\n", filePath) + + fmt.Printf("Total coverage for all tests:\n%s\n", string(coverageOutput)) +} diff --git a/integration-tests/smoke/vrfv2_test.go b/integration-tests/smoke/vrfv2_test.go index 77fe49f422d..62c5dc84fe6 100644 --- a/integration-tests/smoke/vrfv2_test.go +++ b/integration-tests/smoke/vrfv2_test.go @@ -63,7 +63,7 @@ func TestVRFv2Basic(t *testing.T) { } } if !*vrfv2Config.General.UseExistingEnv { - if err := testEnv.Cleanup(); err != nil { + if err := testEnv.Cleanup(test_env.CleanupOpts{}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } @@ -556,7 +556,7 @@ func TestVRFv2MultipleSendingKeys(t *testing.T) { } } if !*vrfv2Config.General.UseExistingEnv { - if err := testEnv.Cleanup(); err != nil { + if err := testEnv.Cleanup(test_env.CleanupOpts{}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } @@ -664,7 +664,7 @@ func TestVRFOwner(t *testing.T) { } } if !*vrfv2Config.General.UseExistingEnv { - if err := testEnv.Cleanup(); err != nil { + if err := testEnv.Cleanup(test_env.CleanupOpts{}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } @@ -807,7 +807,7 @@ func TestVRFV2WithBHS(t *testing.T) { } } if !*vrfv2Config.General.UseExistingEnv { - if err := testEnv.Cleanup(); err != nil { + if err := testEnv.Cleanup(test_env.CleanupOpts{}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } diff --git a/integration-tests/smoke/vrfv2plus_test.go b/integration-tests/smoke/vrfv2plus_test.go index 36fc9d5268d..c535e77ef62 100644 --- a/integration-tests/smoke/vrfv2plus_test.go +++ b/integration-tests/smoke/vrfv2plus_test.go @@ -64,7 +64,7 @@ func TestVRFv2Plus(t *testing.T) { } } if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(); err != nil { + if err := env.Cleanup(test_env.CleanupOpts{}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } @@ -719,7 +719,7 @@ func TestVRFv2PlusMultipleSendingKeys(t *testing.T) { } } if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(); err != nil { + if err := env.Cleanup(test_env.CleanupOpts{}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } @@ -826,7 +826,7 @@ func TestVRFv2PlusMigration(t *testing.T) { } } if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(); err != nil { + if err := env.Cleanup(test_env.CleanupOpts{}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } @@ -1249,7 +1249,7 @@ func TestVRFV2PlusWithBHS(t *testing.T) { } } if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(); err != nil { + if err := env.Cleanup(test_env.CleanupOpts{}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } @@ -1470,7 +1470,7 @@ func TestVRFV2PlusWithBHF(t *testing.T) { } } if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(); err != nil { + if err := env.Cleanup(test_env.CleanupOpts{}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } @@ -1618,7 +1618,7 @@ func TestVRFv2PlusReplayAfterTimeout(t *testing.T) { } } if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(); err != nil { + if err := env.Cleanup(test_env.CleanupOpts{}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } @@ -1817,7 +1817,7 @@ func TestVRFv2PlusPendingBlockSimulationAndZeroConfirmationDelays(t *testing.T) } } if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(); err != nil { + if err := env.Cleanup(test_env.CleanupOpts{}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } From f78f0b5f796fb52781084a1136a11cb091d21704 Mon Sep 17 00:00:00 2001 From: Tate Date: Wed, 24 Apr 2024 08:18:15 -0600 Subject: [PATCH 19/77] Remove usages of docker container names for urls (#12929) We change names on retries but do not update the container names in the requestor so it was not a stable way to get the urls. We already have other stable ways to get the urls so just use those. --- integration-tests/docker/test_env/cl_node.go | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/integration-tests/docker/test_env/cl_node.go b/integration-tests/docker/test_env/cl_node.go index 7eee9231b17..8bb83cc8ee4 100644 --- a/integration-tests/docker/test_env/cl_node.go +++ b/integration-tests/docker/test_env/cl_node.go @@ -308,7 +308,7 @@ func (n *ClNode) containerStartOrRestart(restartDb bool) error { // If the node secrets TOML is not set, generate it with the default template nodeSecretsToml, err := templates.NodeSecretsTemplate{ PgDbName: n.PostgresDb.DbName, - PgHost: n.PostgresDb.ContainerName, + PgHost: strings.Split(n.PostgresDb.InternalURL.Host, ":")[0], PgPort: n.PostgresDb.InternalPort, PgPassword: n.PostgresDb.Password, CustomSecrets: n.NodeSecretsConfigTOML, @@ -339,14 +339,6 @@ func (n *ClNode) containerStartOrRestart(restartDb bool) error { return fmt.Errorf("%s err: %w", ErrStartCLNodeContainer, err) } - // retries can change the container name which affects urls used later - // so update to use the name that actually started - n.ContainerName, err = container.Name(context.Background()) - if err != nil { - return err - } - n.ContainerName = strings.Replace(n.ContainerName, "/", "", -1) - clEndpoint, err := test_env.GetEndpoint(testcontext.Get(n.t), container, "http") if err != nil { return err @@ -374,7 +366,7 @@ func (n *ClNode) containerStartOrRestart(restartDb bool) error { if err != nil { return fmt.Errorf("%s err: %w", ErrConnectNodeClient, err) } - clClient.Config.InternalIP = n.ContainerName + n.Container = container n.API = clClient From 0f28e363920a5d07587ed3b3db028ef232b88b6b Mon Sep 17 00:00:00 2001 From: Radek Scheibinger Date: Wed, 24 Apr 2024 16:34:47 +0200 Subject: [PATCH 20/77] Validate if all required env vars are supplied. (#12879) * Decouple crib config from cl-cluster helm chart * Validate required env vars Validate if all required env vars are supplied * explain how to fix missing vars * add info about example --- crib/devspace.yaml | 2 ++ crib/scripts/check_env_vars.sh | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100755 crib/scripts/check_env_vars.sh diff --git a/crib/devspace.yaml b/crib/devspace.yaml index cc82c6a464c..9c2895e9ac6 100644 --- a/crib/devspace.yaml +++ b/crib/devspace.yaml @@ -73,6 +73,8 @@ images: MACOS_SDK_DIR=$(pwd)/tools/bin/MacOSX12.3.sdk IMAGE=$image ./tools/bin/goreleaser_wrapper release --snapshot --clean --config .goreleaser.devspace.yaml docker push $image hooks: + - command: ./scripts/check_env_vars.sh + events: [ "before:deploy:app" ] - wait: running: true terminatedWithCode: 0 diff --git a/crib/scripts/check_env_vars.sh b/crib/scripts/check_env_vars.sh new file mode 100755 index 00000000000..f26f78e7470 --- /dev/null +++ b/crib/scripts/check_env_vars.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# List of required environment variables +required_vars=( + "DEVSPACE_IMAGE" + "DEVSPACE_INGRESS_CIDRS" + "DEVSPACE_INGRESS_BASE_DOMAIN" + "DEVSPACE_INGRESS_CERT_ARN" + "DEVSPACE_K8S_POD_WAIT_TIMEOUT" + "NS_TTL" + ) + +missing_vars=0 # Counter for missing variables + +# Check each variable +for var in "${required_vars[@]}"; do + if [ -z "${!var}" ]; then # If variable is unset or empty + echo "Error: Environment variable $var is not set." + missing_vars=$((missing_vars + 1)) + fi +done + +# Exit with an error if any variables were missing +if [ $missing_vars -ne 0 ]; then + echo "Total missing environment variables: $missing_vars" + echo "To fix it, add missing variables in the \"crib/.env\" file." + echo "you can find example of the .env config in the \"crib/.env.example\"" + exit 1 +else + echo "All required environment variables are set." +fi \ No newline at end of file From 5276e02da9245b2b43f49cde89295d0757b5a07c Mon Sep 17 00:00:00 2001 From: Cedric Date: Wed, 24 Apr 2024 15:44:53 +0100 Subject: [PATCH 21/77] [chore] Bump chainlink-common/pkg/capabilities (#12946) --- core/capabilities/registry_test.go | 6 ++++++ core/capabilities/targets/write_target.go | 1 + core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- core/services/workflows/engine_test.go | 6 ++++++ go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 11 files changed, 25 insertions(+), 12 deletions(-) diff --git a/core/capabilities/registry_test.go b/core/capabilities/registry_test.go index 3bed31a957a..ccff0a5360e 100644 --- a/core/capabilities/registry_test.go +++ b/core/capabilities/registry_test.go @@ -42,6 +42,7 @@ func TestRegistry(t *testing.T) { capabilities.CapabilityTypeAction, "capability-1-description", "v1.0.0", + nil, ) require.NoError(t, err) @@ -70,6 +71,7 @@ func TestRegistry_NoDuplicateIDs(t *testing.T) { capabilities.CapabilityTypeAction, "capability-1-description", "v1.0.0", + nil, ) require.NoError(t, err) @@ -82,6 +84,7 @@ func TestRegistry_NoDuplicateIDs(t *testing.T) { capabilities.CapabilityTypeConsensus, "capability-2-description", "v1.0.0", + nil, ) require.NoError(t, err) c2 := &mockCapability{CapabilityInfo: ci} @@ -106,6 +109,7 @@ func TestRegistry_ChecksExecutionAPIByType(t *testing.T) { capabilities.CapabilityTypeAction, "capability-1-description", "v1.0.0", + nil, ) require.NoError(t, err) @@ -126,6 +130,7 @@ func TestRegistry_ChecksExecutionAPIByType(t *testing.T) { capabilities.CapabilityTypeTarget, "capability-1-description", "v1.0.0", + nil, ) require.NoError(t, err) @@ -159,6 +164,7 @@ func TestRegistry_ChecksExecutionAPIByType(t *testing.T) { capabilities.CapabilityTypeConsensus, "capability-1-description", "v1.0.0", + nil, ) require.NoError(t, err) diff --git a/core/capabilities/targets/write_target.go b/core/capabilities/targets/write_target.go index 47f1048211e..3349e05003e 100644 --- a/core/capabilities/targets/write_target.go +++ b/core/capabilities/targets/write_target.go @@ -63,6 +63,7 @@ func NewEvmWrite(chain legacyevm.Chain, lggr logger.Logger) *EvmWrite { capabilities.CapabilityTypeTarget, "Write target.", "v1.0.0", + nil, ) return &EvmWrite{ diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 5be5d137696..9788679dd98 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -21,7 +21,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink-automation v1.0.3 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c diff --git a/core/scripts/go.sum b/core/scripts/go.sum index b26bad1299e..45ef18e49ca 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1185,8 +1185,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfsE3+8OEzT3Q0Z9au0z1BPWs= github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9 h1:elDIBChe7ByPNvCyrSjMLTPKrgY+sKgzzlWe2p3wokY= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 h1:54hM3/SrOM166it2K35hGb5K7gQ49/Op0aHp9WkqpqU= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 h1:MvaNzuaQh1vX4CAYLM8qFd99cf0ZF1JNwtDZtLU7WvU= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= diff --git a/core/services/workflows/engine_test.go b/core/services/workflows/engine_test.go index 7bb6cd00c1c..448ff13ec79 100644 --- a/core/services/workflows/engine_test.go +++ b/core/services/workflows/engine_test.go @@ -136,6 +136,7 @@ func TestEngineWithHardcodedWorkflow(t *testing.T) { capabilities.CapabilityTypeTarget, "a write capability targeting ethereum sepolia testnet", "v1.0.0", + nil, ), func(req capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) { m := req.Inputs.Underlying["report"].(*values.Map) @@ -219,6 +220,7 @@ func mockTrigger(t *testing.T) (capabilities.TriggerCapability, capabilities.Cap capabilities.CapabilityTypeTrigger, "issues a trigger when a mercury report is received.", "v1.0.0", + nil, ), ch: make(chan capabilities.CapabilityResponse, 10), } @@ -242,6 +244,7 @@ func mockFailingConsensus() *mockCapability { capabilities.CapabilityTypeConsensus, "an ocr3 consensus capability", "v3.0.0", + nil, ), func(req capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) { return capabilities.CapabilityResponse{}, errors.New("fatal consensus error") @@ -256,6 +259,7 @@ func mockConsensus() *mockCapability { capabilities.CapabilityTypeConsensus, "an ocr3 consensus capability", "v3.0.0", + nil, ), func(req capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) { obs := req.Inputs.Underlying["observations"] @@ -282,6 +286,7 @@ func mockTarget() *mockCapability { capabilities.CapabilityTypeTarget, "a write capability targeting polygon mumbai testnet", "v1.0.0", + nil, ), func(req capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) { m := req.Inputs.Underlying["report"].(*values.Map) @@ -383,6 +388,7 @@ func mockAction() (*mockCapability, values.Value) { capabilities.CapabilityTypeAction, "a read chain action", "v1.0.0", + nil, ), func(req capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) { diff --git a/go.mod b/go.mod index 752dd110c49..b357e57eac5 100644 --- a/go.mod +++ b/go.mod @@ -72,7 +72,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chain-selectors v1.0.10 github.com/smartcontractkit/chainlink-automation v1.0.3 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab diff --git a/go.sum b/go.sum index 5f042f2e4c4..664ddd5efe0 100644 --- a/go.sum +++ b/go.sum @@ -1180,8 +1180,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfsE3+8OEzT3Q0Z9au0z1BPWs= github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9 h1:elDIBChe7ByPNvCyrSjMLTPKrgY+sKgzzlWe2p3wokY= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 h1:54hM3/SrOM166it2K35hGb5K7gQ49/Op0aHp9WkqpqU= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 h1:MvaNzuaQh1vX4CAYLM8qFd99cf0ZF1JNwtDZtLU7WvU= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 327e5e69d94..d07e68c9f7a 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -25,7 +25,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.3 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 github.com/smartcontractkit/chainlink-testing-framework v1.28.4 github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 577ae3f2a0d..efef8224d85 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1517,8 +1517,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfsE3+8OEzT3Q0Z9au0z1BPWs= github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9 h1:elDIBChe7ByPNvCyrSjMLTPKrgY+sKgzzlWe2p3wokY= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 h1:54hM3/SrOM166it2K35hGb5K7gQ49/Op0aHp9WkqpqU= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 h1:MvaNzuaQh1vX4CAYLM8qFd99cf0ZF1JNwtDZtLU7WvU= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index eaf0332af63..a7a37ab1e0e 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.30.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.3 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 github.com/smartcontractkit/chainlink-testing-framework v1.28.4 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 631336409b3..d50656bfed5 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1500,8 +1500,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfsE3+8OEzT3Q0Z9au0z1BPWs= github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9 h1:elDIBChe7ByPNvCyrSjMLTPKrgY+sKgzzlWe2p3wokY= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240419205832-845fa69af8d9/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 h1:54hM3/SrOM166it2K35hGb5K7gQ49/Op0aHp9WkqpqU= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 h1:MvaNzuaQh1vX4CAYLM8qFd99cf0ZF1JNwtDZtLU7WvU= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= From 0f23216f5d4da07084255f79a808ba591c9b860d Mon Sep 17 00:00:00 2001 From: Ilja Pavlovs Date: Wed, 24 Apr 2024 19:13:51 +0300 Subject: [PATCH 22/77] VRF-824: add reorg test for VRF v2 and v2 Plus (#12939) * VRF-824: add reorg test for VRF v2 Plus * VRF-824: fixing lint * VRF-824: cleaning up * VRF-824: fixing test * VRF-824: fixing test * VRF-824: fixing test * VRF-824: adding vrfv2 test for reorg * VRF-824: fixing lint * VRF-824: migrating to resty for raw rpc call --- .github/workflows/integration-tests.yml | 4 +- integration-tests/actions/actions.go | 102 ++++++++ .../actions/vrf/vrfv2/contract_steps.go | 10 +- .../actions/vrf/vrfv2plus/contract_steps.go | 8 +- integration-tests/load/vrfv2/gun.go | 2 +- integration-tests/load/vrfv2plus/gun.go | 2 +- integration-tests/smoke/vrfv2_test.go | 227 +++++++++++++++- integration-tests/smoke/vrfv2plus_test.go | 245 ++++++++++++++++-- 8 files changed, 558 insertions(+), 42 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 3ba0f2976ec..1f3e093cfdc 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -563,12 +563,12 @@ jobs: pyroscope_env: ci-smoke-vrf-evm-simulated - name: vrfv2 id: vrfv2 - nodes: 4 + nodes: 5 os: ubuntu-latest pyroscope_env: ci-smoke-vrf2-evm-simulated - name: vrfv2plus id: vrfv2plus - nodes: 7 + nodes: 8 os: ubuntu-latest pyroscope_env: ci-smoke-vrf2plus-evm-simulated - name: forwarder_ocr diff --git a/integration-tests/actions/actions.go b/integration-tests/actions/actions.go index f5c91b63527..ee4309c3613 100644 --- a/integration-tests/actions/actions.go +++ b/integration-tests/actions/actions.go @@ -8,14 +8,18 @@ import ( "errors" "fmt" "math/big" + "os" "strings" "sync" "testing" "time" "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + "github.com/go-resty/resty/v2" + "github.com/rs/zerolog" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/keystore" @@ -33,6 +37,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" ) // ContractDeploymentInterval After how many contract actions to wait before starting any more @@ -562,3 +567,100 @@ func WaitForBlockNumberToBe( } } } + +// todo - move to EVMClient +func RewindSimulatedChainToBlockNumber( + ctx context.Context, + evmClient blockchain.EVMClient, + rpcURL string, + rewindChainToBlockNumber uint64, + l zerolog.Logger, +) (uint64, error) { + latestBlockNumberBeforeReorg, err := evmClient.LatestBlockNumber(ctx) + if err != nil { + return 0, fmt.Errorf("error getting latest block number: %w", err) + } + + l.Info(). + Str("RPC URL", rpcURL). + Uint64("Latest Block Number before Reorg", latestBlockNumberBeforeReorg). + Uint64("Rewind Chain to Block Number", rewindChainToBlockNumber). + Msg("Performing Reorg on chain by rewinding chain to specific block number") + + _, err = NewRPCRawClient(rpcURL).SetHeadForSimulatedChain(rewindChainToBlockNumber) + + if err != nil { + return 0, fmt.Errorf("error making reorg: %w", err) + } + + err = evmClient.WaitForEvents() + if err != nil { + return 0, fmt.Errorf("error waiting for events: %w", err) + } + + latestBlockNumberAfterReorg, err := evmClient.LatestBlockNumber(ctx) + if err != nil { + return 0, fmt.Errorf("error getting latest block number: %w", err) + } + + l.Info(). + Uint64("Block Number", latestBlockNumberAfterReorg). + Msg("Latest Block Number after Reorg") + return latestBlockNumberAfterReorg, nil +} + +func GetRPCUrl(env *test_env.CLClusterTestEnv, chainID int64) (string, error) { + provider, err := env.GetRpcProvider(chainID) + if err != nil { + return "", err + } + return provider.PublicHttpUrls()[0], nil +} + +// RPCRawClient +// created separate client since method evmClient.RawJsonRPCCall fails on "invalid argument 0: json: cannot unmarshal non-string into Go value of type hexutil.Uint64" +type RPCRawClient struct { + resty *resty.Client +} + +func NewRPCRawClient(url string) *RPCRawClient { + isDebug := os.Getenv("DEBUG_RESTY") == "true" + restyClient := resty.New().SetDebug(isDebug).SetBaseURL(url) + return &RPCRawClient{ + resty: restyClient, + } +} + +func (g *RPCRawClient) SetHeadForSimulatedChain(setHeadToBlockNumber uint64) (JsonRPCResponse, error) { + var responseObject JsonRPCResponse + postBody, _ := json.Marshal(map[string]any{ + "jsonrpc": "2.0", + "id": 1, + "method": "debug_setHead", + "params": []string{hexutil.EncodeUint64(setHeadToBlockNumber)}, + }) + resp, err := g.resty.R(). + SetHeader("Content-Type", "application/json"). + SetBody(postBody). + SetResult(&responseObject). + Post("") + + if err != nil { + return JsonRPCResponse{}, fmt.Errorf("error making API request: %w", err) + } + statusCode := resp.StatusCode() + if statusCode != 200 && statusCode != 201 { + return JsonRPCResponse{}, fmt.Errorf("error invoking debug_setHead method, received unexpected status code %d: %s", statusCode, resp.String()) + } + if responseObject.Error != "" { + return JsonRPCResponse{}, fmt.Errorf("received non-empty error field: %v", responseObject.Error) + } + return responseObject, nil +} + +type JsonRPCResponse struct { + Version string `json:"jsonrpc"` + Id int `json:"id"` + Result string `json:"result,omitempty"` + Error string `json:"error,omitempty"` +} diff --git a/integration-tests/actions/vrf/vrfv2/contract_steps.go b/integration-tests/actions/vrf/vrfv2/contract_steps.go index fef780b695b..7c1ee634f98 100644 --- a/integration-tests/actions/vrf/vrfv2/contract_steps.go +++ b/integration-tests/actions/vrf/vrfv2/contract_steps.go @@ -506,7 +506,7 @@ func RequestRandomnessAndWaitForFulfillment( randomnessRequestCountPerRequest uint16, randomnessRequestCountPerRequestDeviation uint16, randomWordsFulfilledEventTimeout time.Duration, -) (*contracts.CoordinatorRandomWordsFulfilled, error) { +) (*contracts.CoordinatorRandomWordsRequested, *contracts.CoordinatorRandomWordsFulfilled, error) { randomWordsRequestedEvent, err := RequestRandomness( l, consumer, @@ -520,18 +520,18 @@ func RequestRandomnessAndWaitForFulfillment( randomnessRequestCountPerRequestDeviation, ) if err != nil { - return nil, err + return nil, nil, err } - fulfillmentEvents, err := WaitRandomWordsFulfilledEvent( + randomWordsFulfilledEvent, err := WaitRandomWordsFulfilledEvent( coordinator, randomWordsRequestedEvent.RequestId, randomWordsFulfilledEventTimeout, l, ) if err != nil { - return nil, err + return nil, nil, err } - return fulfillmentEvents, nil + return randomWordsRequestedEvent, randomWordsFulfilledEvent, nil } func RequestRandomness( diff --git a/integration-tests/actions/vrf/vrfv2plus/contract_steps.go b/integration-tests/actions/vrf/vrfv2plus/contract_steps.go index 143b1e2cd9b..26532e9b8e8 100644 --- a/integration-tests/actions/vrf/vrfv2plus/contract_steps.go +++ b/integration-tests/actions/vrf/vrfv2plus/contract_steps.go @@ -376,7 +376,7 @@ func RequestRandomnessAndWaitForFulfillment( isNativeBilling bool, config *vrfv2plus_config.General, l zerolog.Logger, -) (*contracts.CoordinatorRandomWordsFulfilled, error) { +) (*contracts.CoordinatorRandomWordsRequested, *contracts.CoordinatorRandomWordsFulfilled, error) { randomWordsRequestedEvent, err := RequestRandomness( consumer, coordinator, @@ -387,7 +387,7 @@ func RequestRandomnessAndWaitForFulfillment( l, ) if err != nil { - return nil, err + return nil, nil, err } randomWordsFulfilledEvent, err := WaitRandomWordsFulfilledEvent( @@ -399,9 +399,9 @@ func RequestRandomnessAndWaitForFulfillment( l, ) if err != nil { - return nil, err + return nil, nil, err } - return randomWordsFulfilledEvent, nil + return randomWordsRequestedEvent, randomWordsFulfilledEvent, nil } diff --git a/integration-tests/load/vrfv2/gun.go b/integration-tests/load/vrfv2/gun.go index 71d3113e60f..d15ee18d451 100644 --- a/integration-tests/load/vrfv2/gun.go +++ b/integration-tests/load/vrfv2/gun.go @@ -87,7 +87,7 @@ func (m *SingleHashGun) Call(_ *wasp.Generator) *wasp.Response { vrfv2Config := m.testConfig.General //randomly increase/decrease randomness request count per TX randomnessRequestCountPerRequest := deviateValue(*vrfv2Config.RandomnessRequestCountPerRequest, *vrfv2Config.RandomnessRequestCountPerRequestDeviation) - _, err := vrfv2.RequestRandomnessAndWaitForFulfillment( + _, _, err := vrfv2.RequestRandomnessAndWaitForFulfillment( m.logger, //the same consumer is used for all requests and in all subs m.contracts.VRFV2Consumers[0], diff --git a/integration-tests/load/vrfv2plus/gun.go b/integration-tests/load/vrfv2plus/gun.go index 8a99392fa57..6879fbe32dc 100644 --- a/integration-tests/load/vrfv2plus/gun.go +++ b/integration-tests/load/vrfv2plus/gun.go @@ -99,7 +99,7 @@ func (m *SingleHashGun) Call(_ *wasp.Generator) *wasp.Response { //randomly increase/decrease randomness request count per TX reqCount := deviateValue(*m.testConfig.General.RandomnessRequestCountPerRequest, *m.testConfig.General.RandomnessRequestCountPerRequestDeviation) m.testConfig.General.RandomnessRequestCountPerRequest = &reqCount - _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillment( + _, _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillment( //the same consumer is used for all requests and in all subs m.contracts.VRFV2PlusConsumer[0], m.contracts.CoordinatorV2Plus, diff --git a/integration-tests/smoke/vrfv2_test.go b/integration-tests/smoke/vrfv2_test.go index 62c5dc84fe6..4dd23bce26f 100644 --- a/integration-tests/smoke/vrfv2_test.go +++ b/integration-tests/smoke/vrfv2_test.go @@ -63,7 +63,7 @@ func TestVRFv2Basic(t *testing.T) { } } if !*vrfv2Config.General.UseExistingEnv { - if err := testEnv.Cleanup(test_env.CleanupOpts{}); err != nil { + if err := testEnv.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } @@ -104,7 +104,7 @@ func TestVRFv2Basic(t *testing.T) { subBalanceBeforeRequest := subscription.Balance // test and assert - randomWordsFulfilledEvent, err := vrfv2.RequestRandomnessAndWaitForFulfillment( + _, randomWordsFulfilledEvent, err := vrfv2.RequestRandomnessAndWaitForFulfillment( l, consumers[0], vrfContracts.CoordinatorV2, @@ -137,6 +137,54 @@ func TestVRFv2Basic(t *testing.T) { } }) + t.Run("VRF Node waits block confirmation number specified by the consumer in the rand request before sending fulfilment on-chain", func(t *testing.T) { + configCopy := config.MustCopy().(tc.TestConfig) + testConfig := configCopy.VRFv2.General + + consumers, subIDs, err := vrfv2.SetupNewConsumersAndSubs( + testEnv, + chainID, + vrfContracts.CoordinatorV2, + configCopy, + vrfContracts.LinkToken, + 1, + 1, + l, + ) + require.NoError(t, err, "error setting up new consumers and subs") + subID := subIDs[0] + subscription, err := vrfContracts.CoordinatorV2.GetSubscription(testcontext.Get(t), subID) + require.NoError(t, err, "error getting subscription information") + vrfcommon.LogSubDetails(l, subscription, strconv.FormatUint(subID, 10), vrfContracts.CoordinatorV2) + subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDs...) + + expectedBlockNumberWait := uint16(10) + testConfig.MinimumConfirmations = ptr.Ptr[uint16](expectedBlockNumberWait) + randomWordsRequestedEvent, randomWordsFulfilledEvent, err := vrfv2.RequestRandomnessAndWaitForFulfillment( + l, + consumers[0], + vrfContracts.CoordinatorV2, + subID, + vrfKey, + *testConfig.MinimumConfirmations, + *testConfig.CallbackGasLimit, + *testConfig.NumberOfWords, + *testConfig.RandomnessRequestCountPerRequest, + *testConfig.RandomnessRequestCountPerRequestDeviation, + testConfig.RandomWordsFulfilledEventTimeout.Duration, + ) + require.NoError(t, err, "error requesting randomness and waiting for fulfilment") + + // check that VRF node waited at least the number of blocks specified by the consumer in the rand request min confs field + blockNumberWait := randomWordsRequestedEvent.Raw.BlockNumber - randomWordsFulfilledEvent.Raw.BlockNumber + require.GreaterOrEqual(t, blockNumberWait, uint64(expectedBlockNumberWait)) + + status, err := consumers[0].GetRequestStatus(testcontext.Get(t), randomWordsFulfilledEvent.RequestId) + require.NoError(t, err, "error getting rand request status") + require.True(t, status.Fulfilled) + l.Info().Bool("Fulfilment Status", status.Fulfilled).Msg("Random Words Request Fulfilment Status") + }) + t.Run("CL Node VRF Job Runs", func(t *testing.T) { configCopy := config.MustCopy().(tc.TestConfig) consumers, subIDsForJobRuns, err := vrfv2.SetupNewConsumersAndSubs( @@ -161,7 +209,7 @@ func TestVRFv2Basic(t *testing.T) { require.NoError(t, err, "error reading job runs") // test and assert - _, err = vrfv2.RequestRandomnessAndWaitForFulfillment( + _, _, err = vrfv2.RequestRandomnessAndWaitForFulfillment( l, consumers[0], vrfContracts.CoordinatorV2, @@ -281,7 +329,7 @@ func TestVRFv2Basic(t *testing.T) { vrfcommon.LogSubDetails(l, subscription, strconv.FormatUint(subIDForOracleWithdraw, 10), vrfContracts.CoordinatorV2) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDsForOracleWithDraw...) - fulfilledEventLink, err := vrfv2.RequestRandomnessAndWaitForFulfillment( + _, fulfilledEventLink, err := vrfv2.RequestRandomnessAndWaitForFulfillment( l, consumers[0], vrfContracts.CoordinatorV2, @@ -436,7 +484,7 @@ func TestVRFv2Basic(t *testing.T) { // Request randomness - should fail due to underfunded subscription randomWordsFulfilledEventTimeout := 5 * time.Second - _, err = vrfv2.RequestRandomnessAndWaitForFulfillment( + _, _, err = vrfv2.RequestRandomnessAndWaitForFulfillment( l, consumers[0], vrfContracts.CoordinatorV2, @@ -556,7 +604,7 @@ func TestVRFv2MultipleSendingKeys(t *testing.T) { } } if !*vrfv2Config.General.UseExistingEnv { - if err := testEnv.Cleanup(test_env.CleanupOpts{}); err != nil { + if err := testEnv.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } @@ -602,7 +650,7 @@ func TestVRFv2MultipleSendingKeys(t *testing.T) { var fulfillmentTxFromAddresses []string for i := 0; i < newEnvConfig.NumberOfTxKeysToCreate+1; i++ { - randomWordsFulfilledEvent, err := vrfv2.RequestRandomnessAndWaitForFulfillment( + _, randomWordsFulfilledEvent, err := vrfv2.RequestRandomnessAndWaitForFulfillment( l, consumers[0], vrfContracts.CoordinatorV2, @@ -664,7 +712,7 @@ func TestVRFOwner(t *testing.T) { } } if !*vrfv2Config.General.UseExistingEnv { - if err := testEnv.Cleanup(test_env.CleanupOpts{}); err != nil { + if err := testEnv.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } @@ -807,7 +855,7 @@ func TestVRFV2WithBHS(t *testing.T) { } } if !*vrfv2Config.General.UseExistingEnv { - if err := testEnv.Cleanup(test_env.CleanupOpts{}); err != nil { + if err := testEnv.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } @@ -984,3 +1032,164 @@ func TestVRFV2WithBHS(t *testing.T) { require.Equal(t, 0, randomWordsRequestedEvent.Raw.BlockHash.Cmp(randRequestBlockHash)) }) } + +func TestVRFV2NodeReorg(t *testing.T) { + t.Parallel() + var ( + env *test_env.CLClusterTestEnv + vrfContracts *vrfcommon.VRFContracts + subIDsForCancellingAfterTest []uint64 + defaultWalletAddress string + vrfKey *vrfcommon.VRFKeyData + ) + l := logging.GetTestLogger(t) + + config, err := tc.GetConfig("Smoke", tc.VRFv2) + require.NoError(t, err, "Error getting config") + vrfv2Config := config.VRFv2 + chainID := networks.MustGetSelectedNetworkConfig(config.GetNetworkConfig())[0].ChainID + + cleanupFn := func() { + evmClient, err := env.GetEVMClient(chainID) + require.NoError(t, err, "Getting EVM client shouldn't fail") + + if evmClient.NetworkSimulated() { + l.Info(). + Str("Network Name", evmClient.GetNetworkName()). + Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") + } else { + if *vrfv2Config.General.CancelSubsAfterTestRun { + //cancel subs and return funds to sub owner + vrfv2.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, defaultWalletAddress, subIDsForCancellingAfterTest, l) + } + } + if !*vrfv2Config.General.UseExistingEnv { + if err := env.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { + l.Error().Err(err).Msg("Error cleaning up test environment") + } + } + } + newEnvConfig := vrfcommon.NewEnvConfig{ + NodesToCreate: []vrfcommon.VRFNodeType{vrfcommon.VRF}, + NumberOfTxKeysToCreate: 0, + UseVRFOwner: false, + UseTestCoordinator: false, + } + + env, vrfContracts, vrfKey, _, err = vrfv2.SetupVRFV2Universe(testcontext.Get(t), t, config, chainID, cleanupFn, newEnvConfig, l) + require.NoError(t, err, "Error setting up VRFv2 universe") + + evmClient, err := env.GetEVMClient(chainID) + require.NoError(t, err, "Getting EVM client shouldn't fail") + defaultWalletAddress = evmClient.GetDefaultWallet().Address() + + consumers, subIDs, err := vrfv2.SetupNewConsumersAndSubs( + env, + chainID, + vrfContracts.CoordinatorV2, + config, + vrfContracts.LinkToken, + 1, + 1, + l, + ) + require.NoError(t, err, "error setting up new consumers and subs") + subID := subIDs[0] + subscription, err := vrfContracts.CoordinatorV2.GetSubscription(testcontext.Get(t), subID) + require.NoError(t, err, "error getting subscription information") + vrfcommon.LogSubDetails(l, subscription, strconv.FormatUint(subID, 10), vrfContracts.CoordinatorV2) + subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDs...) + + t.Run("Reorg on fulfillment", func(t *testing.T) { + configCopy := config.MustCopy().(tc.TestConfig) + configCopy.VRFv2.General.MinimumConfirmations = ptr.Ptr[uint16](10) + + //1. request randomness and wait for fulfillment for blockhash from Reorged Fork + randomWordsRequestedEvent, randomWordsFulfilledEventOnReorgedFork, err := vrfv2.RequestRandomnessAndWaitForFulfillment( + l, + consumers[0], + vrfContracts.CoordinatorV2, + subID, + vrfKey, + *configCopy.VRFv2.General.MinimumConfirmations, + *configCopy.VRFv2.General.CallbackGasLimit, + *configCopy.VRFv2.General.NumberOfWords, + *configCopy.VRFv2.General.RandomnessRequestCountPerRequest, + *configCopy.VRFv2.General.RandomnessRequestCountPerRequestDeviation, + configCopy.VRFv2.General.RandomWordsFulfilledEventTimeout.Duration, + ) + require.NoError(t, err) + + // rewind chain to block number after the request was made, but before the request was fulfilled + rewindChainToBlock := randomWordsRequestedEvent.Raw.BlockNumber + 1 + + rpcUrl, err := actions.GetRPCUrl(env, chainID) + require.NoError(t, err, "error getting rpc url") + + //2. rewind chain by n number of blocks - basically, mimicking reorg scenario + latestBlockNumberAfterReorg, err := actions.RewindSimulatedChainToBlockNumber(testcontext.Get(t), evmClient, rpcUrl, rewindChainToBlock, l) + require.NoError(t, err, fmt.Sprintf("error rewinding chain to block number %d", rewindChainToBlock)) + + //3.1 ensure that chain is reorged and latest block number is greater than the block number when request was made + require.Greater(t, latestBlockNumberAfterReorg, randomWordsRequestedEvent.Raw.BlockNumber) + + //3.2 ensure that chain is reorged and latest block number is less than the block number when fulfilment was performed + require.Less(t, latestBlockNumberAfterReorg, randomWordsFulfilledEventOnReorgedFork.Raw.BlockNumber) + + //4. wait for the fulfillment which VRF Node will generate for Canonical chain + _, err = vrfv2.WaitRandomWordsFulfilledEvent( + vrfContracts.CoordinatorV2, + randomWordsRequestedEvent.RequestId, + configCopy.VRFv2.General.RandomWordsFulfilledEventTimeout.Duration, + l, + ) + + require.NoError(t, err, "error waiting for randomness fulfilled event") + }) + + t.Run("Reorg on rand request", func(t *testing.T) { + configCopy := config.MustCopy().(tc.TestConfig) + //1. set minimum confirmations to higher value so that we can be sure that request won't be fulfilled before reorg + configCopy.VRFv2.General.MinimumConfirmations = ptr.Ptr[uint16](6) + + //2. request randomness + randomWordsRequestedEvent, err := vrfv2.RequestRandomness( + l, + consumers[0], + vrfContracts.CoordinatorV2, + subID, + vrfKey, + *configCopy.VRFv2.General.MinimumConfirmations, + *configCopy.VRFv2.General.CallbackGasLimit, + *configCopy.VRFv2.General.NumberOfWords, + *configCopy.VRFv2.General.RandomnessRequestCountPerRequest, + *configCopy.VRFv2.General.RandomnessRequestCountPerRequestDeviation, + ) + require.NoError(t, err) + + // rewind chain to block number before the randomness request was made + rewindChainToBlockNumber := randomWordsRequestedEvent.Raw.BlockNumber - 3 + + rpcUrl, err := actions.GetRPCUrl(env, chainID) + require.NoError(t, err, "error getting rpc url") + + //3. rewind chain by n number of blocks - basically, mimicking reorg scenario + latestBlockNumberAfterReorg, err := actions.RewindSimulatedChainToBlockNumber(testcontext.Get(t), evmClient, rpcUrl, rewindChainToBlockNumber, l) + require.NoError(t, err, fmt.Sprintf("error rewinding chain to block number %d", rewindChainToBlockNumber)) + + //4. ensure that chain is reorged and latest block number is less than the block number when request was made + require.Less(t, latestBlockNumberAfterReorg, randomWordsRequestedEvent.Raw.BlockNumber) + + //5. ensure that rand request is not fulfilled for the request which was made on reorged fork + // For context - when performing debug_setHead on geth simulated chain and therefore rewinding chain to a previous block, + //then tx that was mined after reorg will not appear in canonical chain contrary to real world scenario + //Hence, we only verify that VRF node will not generate fulfillment for the reorged fork request + _, err = vrfContracts.CoordinatorV2.WaitForRandomWordsFulfilledEvent( + contracts.RandomWordsFulfilledEventFilter{ + RequestIds: []*big.Int{randomWordsRequestedEvent.RequestId}, + Timeout: time.Second * 10, + }, + ) + require.Error(t, err, "fulfillment should not be generated for the request which was made on reorged fork on Simulated Chain") + }) +} diff --git a/integration-tests/smoke/vrfv2plus_test.go b/integration-tests/smoke/vrfv2plus_test.go index c535e77ef62..ae190e060ee 100644 --- a/integration-tests/smoke/vrfv2plus_test.go +++ b/integration-tests/smoke/vrfv2plus_test.go @@ -19,6 +19,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/networks" "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" + "github.com/smartcontractkit/chainlink/integration-tests/actions" vrfcommon "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/common" "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/vrfv2plus" "github.com/smartcontractkit/chainlink/integration-tests/client" @@ -26,7 +27,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/blockhash_store" - "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" it_utils "github.com/smartcontractkit/chainlink/integration-tests/utils" @@ -64,7 +64,7 @@ func TestVRFv2Plus(t *testing.T) { } } if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(test_env.CleanupOpts{}); err != nil { + if err := env.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } @@ -106,7 +106,7 @@ func TestVRFv2Plus(t *testing.T) { subBalanceBeforeRequest := subscription.Balance // test and assert - randomWordsFulfilledEvent, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment( + _, randomWordsFulfilledEvent, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment( consumers[0], vrfContracts.CoordinatorV2Plus, vrfKey, @@ -163,7 +163,7 @@ func TestVRFv2Plus(t *testing.T) { subNativeTokenBalanceBeforeRequest := subscription.NativeBalance // test and assert - randomWordsFulfilledEvent, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment( + _, randomWordsFulfilledEvent, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment( consumers[0], vrfContracts.CoordinatorV2Plus, vrfKey, @@ -193,6 +193,52 @@ func TestVRFv2Plus(t *testing.T) { require.Equal(t, 1, w.Cmp(big.NewInt(0)), "Expected the VRF job give an answer bigger than 0") } }) + + t.Run("VRF Node waits block confirmation number specified by the consumer in the rand request before sending fulfilment on-chain", func(t *testing.T) { + configCopy := config.MustCopy().(tc.TestConfig) + testConfig := configCopy.VRFv2Plus.General + var isNativeBilling = true + + consumers, subIDs, err := vrfv2plus.SetupNewConsumersAndSubs( + env, + chainID, + vrfContracts.CoordinatorV2Plus, + configCopy, + vrfContracts.LinkToken, + 1, + 1, + l, + ) + require.NoError(t, err, "error setting up new consumers and subs") + subID := subIDs[0] + subscription, err := vrfContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) + require.NoError(t, err, "error getting subscription information") + vrfcommon.LogSubDetails(l, subscription, subID.String(), vrfContracts.CoordinatorV2Plus) + subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDs...) + + expectedBlockNumberWait := uint16(10) + testConfig.MinimumConfirmations = ptr.Ptr[uint16](expectedBlockNumberWait) + randomWordsRequestedEvent, randomWordsFulfilledEvent, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment( + consumers[0], + vrfContracts.CoordinatorV2Plus, + vrfKey, + subID, + isNativeBilling, + testConfig, + l, + ) + require.NoError(t, err, "error requesting randomness and waiting for fulfilment") + + // check that VRF node waited at least the number of blocks specified by the consumer in the rand request min confs field + blockNumberWait := randomWordsRequestedEvent.Raw.BlockNumber - randomWordsFulfilledEvent.Raw.BlockNumber + require.GreaterOrEqual(t, blockNumberWait, uint64(expectedBlockNumberWait)) + + status, err := consumers[0].GetRequestStatus(testcontext.Get(t), randomWordsFulfilledEvent.RequestId) + require.NoError(t, err, "error getting rand request status") + require.True(t, status.Fulfilled) + l.Info().Bool("Fulfilment Status", status.Fulfilled).Msg("Random Words Request Fulfilment Status") + }) + t.Run("CL Node VRF Job Runs", func(t *testing.T) { configCopy := config.MustCopy().(tc.TestConfig) var isNativeBilling = false @@ -217,7 +263,7 @@ func TestVRFv2Plus(t *testing.T) { require.NoError(t, err, "error reading job runs") // test and assert - _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillment( + _, _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillment( consumers[0], vrfContracts.CoordinatorV2Plus, vrfKey, @@ -482,7 +528,7 @@ func TestVRFv2Plus(t *testing.T) { require.False(t, pendingRequestsExist, "Pending requests should not exist") configCopy.VRFv2Plus.General.RandomWordsFulfilledEventTimeout = ptr.Ptr(blockchain.StrDuration{Duration: 5 * time.Second}) - _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillment( + _, _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillment( consumers[0], vrfContracts.CoordinatorV2Plus, vrfKey, @@ -494,7 +540,7 @@ func TestVRFv2Plus(t *testing.T) { require.Error(t, err, "error should occur for waiting for fulfilment due to low sub balance") - _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillment( + _, _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillment( consumers[0], vrfContracts.CoordinatorV2Plus, vrfKey, @@ -622,7 +668,7 @@ func TestVRFv2Plus(t *testing.T) { vrfcommon.LogSubDetails(l, subscription, subID.String(), vrfContracts.CoordinatorV2Plus) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDs...) - fulfilledEventLink, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment( + _, fulfilledEventLink, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment( consumers[0], vrfContracts.CoordinatorV2Plus, vrfKey, @@ -633,7 +679,7 @@ func TestVRFv2Plus(t *testing.T) { ) require.NoError(t, err) - fulfilledEventNative, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment( + _, fulfilledEventNative, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment( consumers[0], vrfContracts.CoordinatorV2Plus, vrfKey, @@ -719,7 +765,7 @@ func TestVRFv2PlusMultipleSendingKeys(t *testing.T) { } } if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(test_env.CleanupOpts{}); err != nil { + if err := env.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } @@ -766,7 +812,7 @@ func TestVRFv2PlusMultipleSendingKeys(t *testing.T) { var fulfillmentTxFromAddresses []string for i := 0; i < newEnvConfig.NumberOfTxKeysToCreate+1; i++ { - randomWordsFulfilledEvent, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment( + _, randomWordsFulfilledEvent, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment( consumers[0], vrfContracts.CoordinatorV2Plus, vrfKey, @@ -826,7 +872,7 @@ func TestVRFv2PlusMigration(t *testing.T) { } } if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(test_env.CleanupOpts{}); err != nil { + if err := env.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } @@ -1002,7 +1048,7 @@ func TestVRFv2PlusMigration(t *testing.T) { require.Equal(t, 0, expectedEthTotalBalanceForOldCoordinator.Cmp(oldCoordinatorEthTotalBalanceAfterMigration)) //Verify rand requests fulfills with Link Token billing - _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillment( + _, _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillment( consumers[0], newCoordinator, vrfKey, @@ -1014,7 +1060,7 @@ func TestVRFv2PlusMigration(t *testing.T) { require.NoError(t, err, "error requesting randomness and waiting for fulfilment") //Verify rand requests fulfills with Native Token billing - _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillment( + _, _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillment( consumers[1], newCoordinator, vrfKey, @@ -1249,7 +1295,7 @@ func TestVRFV2PlusWithBHS(t *testing.T) { } } if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(test_env.CleanupOpts{}); err != nil { + if err := env.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } @@ -1470,7 +1516,7 @@ func TestVRFV2PlusWithBHF(t *testing.T) { } } if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(test_env.CleanupOpts{}); err != nil { + if err := env.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } @@ -1618,7 +1664,7 @@ func TestVRFv2PlusReplayAfterTimeout(t *testing.T) { } } if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(test_env.CleanupOpts{}); err != nil { + if err := env.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } @@ -1694,7 +1740,7 @@ func TestVRFv2PlusReplayAfterTimeout(t *testing.T) { 1, ) require.NoError(t, err, "error creating funded sub in replay test") - randomWordsFulfilledEvent, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment( + _, randomWordsFulfilledEvent, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment( consumers[1], vrfContracts.CoordinatorV2Plus, vrfKey, @@ -1817,7 +1863,7 @@ func TestVRFv2PlusPendingBlockSimulationAndZeroConfirmationDelays(t *testing.T) } } if !*vrfv2PlusConfig.General.UseExistingEnv { - if err := env.Cleanup(test_env.CleanupOpts{}); err != nil { + if err := env.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { l.Error().Err(err).Msg("Error cleaning up test environment") } } @@ -1862,7 +1908,7 @@ func TestVRFv2PlusPendingBlockSimulationAndZeroConfirmationDelays(t *testing.T) l.Info().Uint16("minimumConfirmationDelay", *config.VRFv2Plus.General.MinimumConfirmations).Msg("Minimum Confirmation Delay") // test and assert - randomWordsFulfilledEvent, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment( + _, randomWordsFulfilledEvent, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment( consumers[0], vrfContracts.CoordinatorV2Plus, vrfKey, @@ -1878,3 +1924,162 @@ func TestVRFv2PlusPendingBlockSimulationAndZeroConfirmationDelays(t *testing.T) require.True(t, status.Fulfilled) l.Info().Bool("Fulfilment Status", status.Fulfilled).Msg("Random Words Request Fulfilment Status") } + +func TestVRFv2PlusNodeReorg(t *testing.T) { + t.Parallel() + var ( + env *test_env.CLClusterTestEnv + vrfContracts *vrfcommon.VRFContracts + subIDsForCancellingAfterTest []*big.Int + defaultWalletAddress string + vrfKey *vrfcommon.VRFKeyData + ) + l := logging.GetTestLogger(t) + + config, err := tc.GetConfig("Smoke", tc.VRFv2Plus) + require.NoError(t, err, "Error getting config") + vrfv2PlusConfig := config.VRFv2Plus + chainID := networks.MustGetSelectedNetworkConfig(config.GetNetworkConfig())[0].ChainID + + cleanupFn := func() { + evmClient, err := env.GetEVMClient(chainID) + require.NoError(t, err, "Getting EVM client shouldn't fail") + + if evmClient.NetworkSimulated() { + l.Info(). + Str("Network Name", evmClient.GetNetworkName()). + Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") + } else { + if *vrfv2PlusConfig.General.CancelSubsAfterTestRun { + //cancel subs and return funds to sub owner + vrfv2plus.CancelSubsAndReturnFunds(testcontext.Get(t), vrfContracts, defaultWalletAddress, subIDsForCancellingAfterTest, l) + } + } + if !*vrfv2PlusConfig.General.UseExistingEnv { + if err := env.Cleanup(test_env.CleanupOpts{TestName: t.Name()}); err != nil { + l.Error().Err(err).Msg("Error cleaning up test environment") + } + } + } + newEnvConfig := vrfcommon.NewEnvConfig{ + NodesToCreate: []vrfcommon.VRFNodeType{vrfcommon.VRF}, + NumberOfTxKeysToCreate: 0, + UseVRFOwner: false, + UseTestCoordinator: false, + } + + env, vrfContracts, vrfKey, _, err = vrfv2plus.SetupVRFV2PlusUniverse(testcontext.Get(t), t, config, chainID, cleanupFn, newEnvConfig, l) + require.NoError(t, err, "Error setting up VRFv2Plus universe") + + evmClient, err := env.GetEVMClient(chainID) + require.NoError(t, err, "Getting EVM client shouldn't fail") + defaultWalletAddress = evmClient.GetDefaultWallet().Address() + + var isNativeBilling = true + + consumers, subIDs, err := vrfv2plus.SetupNewConsumersAndSubs( + env, + chainID, + vrfContracts.CoordinatorV2Plus, + config, + vrfContracts.LinkToken, + 1, + 1, + l, + ) + require.NoError(t, err, "error setting up new consumers and subs") + subID := subIDs[0] + subscription, err := vrfContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) + require.NoError(t, err, "error getting subscription information") + vrfcommon.LogSubDetails(l, subscription, subID.String(), vrfContracts.CoordinatorV2Plus) + subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDs...) + + t.Run("Reorg on fulfillment", func(t *testing.T) { + configCopy := config.MustCopy().(tc.TestConfig) + configCopy.VRFv2Plus.General.MinimumConfirmations = ptr.Ptr[uint16](10) + + //1. request randomness and wait for fulfillment for blockhash from Reorged Fork + randomWordsRequestedEvent, randomWordsFulfilledEventOnReorgedFork, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment( + consumers[0], + vrfContracts.CoordinatorV2Plus, + vrfKey, + subID, + isNativeBilling, + configCopy.VRFv2Plus.General, + l, + ) + require.NoError(t, err) + + // rewind chain to block number after the request was made, but before the request was fulfilled + rewindChainToBlock := randomWordsRequestedEvent.Raw.BlockNumber + 1 + + rpcUrl, err := actions.GetRPCUrl(env, chainID) + require.NoError(t, err, "error getting rpc url") + + //2. rewind chain by n number of blocks - basically, mimicking reorg scenario + latestBlockNumberAfterReorg, err := actions.RewindSimulatedChainToBlockNumber(testcontext.Get(t), evmClient, rpcUrl, rewindChainToBlock, l) + require.NoError(t, err, fmt.Sprintf("error rewinding chain to block number %d", rewindChainToBlock)) + + //3.1 ensure that chain is reorged and latest block number is greater than the block number when request was made + require.Greater(t, latestBlockNumberAfterReorg, randomWordsRequestedEvent.Raw.BlockNumber) + + //3.2 ensure that chain is reorged and latest block number is less than the block number when fulfilment was performed + require.Less(t, latestBlockNumberAfterReorg, randomWordsFulfilledEventOnReorgedFork.Raw.BlockNumber) + + //4. wait for the fulfillment which VRF Node will generate for Canonical chain + _, err = vrfv2plus.WaitRandomWordsFulfilledEvent( + vrfContracts.CoordinatorV2Plus, + randomWordsRequestedEvent.RequestId, + subID, + isNativeBilling, + configCopy.VRFv2Plus.General.RandomWordsFulfilledEventTimeout.Duration, + l, + ) + require.NoError(t, err, "error waiting for randomness fulfilled event") + }) + + t.Run("Reorg on rand request", func(t *testing.T) { + configCopy := config.MustCopy().(tc.TestConfig) + //1. set minimum confirmations to higher value so that we can be sure that request won't be fulfilled before reorg + configCopy.VRFv2Plus.General.MinimumConfirmations = ptr.Ptr[uint16](6) + + //2. request randomness + randomWordsRequestedEvent, err := vrfv2plus.RequestRandomness( + consumers[0], + vrfContracts.CoordinatorV2Plus, + vrfKey, + subID, + isNativeBilling, + configCopy.VRFv2Plus.General, + l, + ) + require.NoError(t, err) + + // rewind chain to block number before the randomness request was made + rewindChainToBlockNumber := randomWordsRequestedEvent.Raw.BlockNumber - 3 + + rpcUrl, err := actions.GetRPCUrl(env, chainID) + require.NoError(t, err, "error getting rpc url") + + //3. rewind chain by n number of blocks - basically, mimicking reorg scenario + latestBlockNumberAfterReorg, err := actions.RewindSimulatedChainToBlockNumber(testcontext.Get(t), evmClient, rpcUrl, rewindChainToBlockNumber, l) + require.NoError(t, err, fmt.Sprintf("error rewinding chain to block number %d", rewindChainToBlockNumber)) + + //4. ensure that chain is reorged and latest block number is less than the block number when request was made + require.Less(t, latestBlockNumberAfterReorg, randomWordsRequestedEvent.Raw.BlockNumber) + + //5. ensure that rand request is not fulfilled for the request which was made on reorged fork + // For context - when performing debug_setHead on geth simulated chain and therefore rewinding chain to a previous block, + //then tx that was mined after reorg will not appear in canonical chain contrary to real world scenario + //Hence, we only verify that VRF node will not generate fulfillment for the reorged fork request + _, err = vrfContracts.CoordinatorV2Plus.WaitForRandomWordsFulfilledEvent( + contracts.RandomWordsFulfilledEventFilter{ + RequestIds: []*big.Int{randomWordsRequestedEvent.RequestId}, + SubIDs: []*big.Int{subID}, + Timeout: time.Second * 10, + }, + ) + require.Error(t, err, "fulfillment should not be generated for the request which was made on reorged fork on Simulated Chain") + }) + +} From 758ffd6da097adac1f49ceded5e0998cdcb98a29 Mon Sep 17 00:00:00 2001 From: frank zhu Date: Wed, 24 Apr 2024 09:38:51 -0700 Subject: [PATCH 23/77] fix: add changeset semvar value check (#12947) * fix: add changeset semvar value check * add #internal tag --- .changeset/pretty-kangaroos-tell.md | 5 +++++ .github/scripts/check-changeset-tags.sh | 8 ++++++++ 2 files changed, 13 insertions(+) create mode 100644 .changeset/pretty-kangaroos-tell.md diff --git a/.changeset/pretty-kangaroos-tell.md b/.changeset/pretty-kangaroos-tell.md new file mode 100644 index 00000000000..946869b1ca0 --- /dev/null +++ b/.changeset/pretty-kangaroos-tell.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Add check for valid semvar value for changeset file #internal diff --git a/.github/scripts/check-changeset-tags.sh b/.github/scripts/check-changeset-tags.sh index 579661fe704..f82c16d5769 100755 --- a/.github/scripts/check-changeset-tags.sh +++ b/.github/scripts/check-changeset-tags.sh @@ -29,6 +29,14 @@ if [[ ! -f "$CHANGESET_FILE_PATH" ]]; then exit 1 fi +changeset_content=$(sed -n '/^---$/,/^---$/{ /^---$/!p; }' $CHANGESET_FILE_PATH) +semvar_value=$(echo "$changeset_content" | awk -F": " '/"chainlink"/ {print $2}') + +if [[ "$semvar_value" != "major" && "$semvar_value" != "minor" && "$semvar_value" != "patch" ]]; then + echo "Invalid changeset semvar value for 'chainlink'. Must be 'major', 'minor', or 'patch'." + exit 1 +fi + while IFS= read -r line; do for tag in "${tags_list[@]}"; do if [[ "$line" == *"$tag"* ]]; then From 78dd3e026a81cb656b99ac62ce552369573ca736 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Wed, 24 Apr 2024 15:45:08 -0500 Subject: [PATCH 24/77] use sqlutil instead of pg.QOpts/Q/Queryer (#12456) * use sqlutil instead of pg.QOpts * changeset --- .changeset/fuzzy-pans-destroy.md | 5 + core/bridges/orm_test.go | 2 +- core/chains/evm/log/helpers_test.go | 13 +- core/chains/evm/log/integration_test.go | 8 +- core/chains/evm/logpoller/observability.go | 4 +- core/chains/evm/logpoller/orm.go | 208 ++- core/chains/evm/logpoller/query.go | 2 +- core/chains/evm/txmgr/broadcaster_test.go | 2 +- core/chains/evm/txmgr/builder.go | 9 +- core/chains/evm/txmgr/evm_tx_store.go | 52 +- core/chains/evm/txmgr/txmgr_test.go | 1 - core/chains/legacyevm/chain.go | 20 +- core/chains/legacyevm/chain_test.go | 3 +- core/chains/legacyevm/evm_txm.go | 8 +- core/cmd/eth_keys_commands_test.go | 4 +- core/cmd/evm_transaction_commands_test.go | 10 +- core/cmd/jobs_commands_test.go | 7 +- core/cmd/shell.go | 24 +- core/cmd/shell_local.go | 14 +- core/cmd/shell_local_test.go | 12 +- core/cmd/shell_remote_test.go | 13 +- core/internal/cltest/cltest.go | 54 +- core/internal/cltest/factories.go | 16 +- core/internal/cltest/job_factories.go | 23 +- core/internal/features/features_test.go | 19 +- .../features/ocr2/features_ocr2_test.go | 10 +- core/internal/mocks/application.go | 22 - core/internal/testutils/evmtest/evmtest.go | 7 +- core/internal/testutils/pgtest/pgtest.go | 25 +- core/internal/testutils/testutils.go | 3 +- core/scripts/gateway/run_gateway.go | 2 +- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- core/services/chainlink/application.go | 73 +- .../relayer_chain_interoperators_test.go | 13 +- core/services/chainlink/relayer_factory.go | 19 +- core/services/cron/cron_test.go | 4 +- core/services/directrequest/delegate.go | 33 +- core/services/directrequest/delegate_test.go | 7 +- core/services/feeds/mocks/orm.go | 1323 +++++++---------- core/services/feeds/mocks/service.go | 221 ++- core/services/feeds/orm.go | 247 +-- core/services/feeds/orm_test.go | 380 ++--- core/services/feeds/service.go | 299 ++-- core/services/feeds/service_test.go | 1057 +++++++------ core/services/fluxmonitorv2/delegate.go | 13 +- core/services/fluxmonitorv2/flux_monitor.go | 18 +- .../fluxmonitorv2/flux_monitor_test.go | 1 + .../fluxmonitorv2/integrations_test.go | 30 +- core/services/fluxmonitorv2/orm_test.go | 4 +- core/services/functions/listener_test.go | 4 +- core/services/gateway/delegate.go | 13 +- core/services/gateway/gateway_test.go | 12 +- core/services/gateway/handler_factory.go | 13 +- .../handlers/functions/handler.functions.go | 9 +- .../functions/handler.functions_test.go | 4 +- .../gateway_integration_test.go | 2 +- core/services/job/common.go | 3 - core/services/job/helpers_test.go | 3 +- core/services/job/job_orm_test.go | 311 ++-- .../job/job_pipeline_orm_integration_test.go | 6 +- core/services/job/kv_orm.go | 14 +- core/services/job/kv_orm_test.go | 9 +- core/services/job/mocks/orm.go | 458 +++--- core/services/job/mocks/spawner.go | 53 +- core/services/job/orm.go | 787 +++++----- core/services/job/orm_test.go | 8 +- core/services/job/runner_integration_test.go | 84 +- core/services/job/spawner.go | 56 +- core/services/job/spawner_test.go | 56 +- core/services/keeper/delegate.go | 19 +- core/services/keeper/helpers_test.go | 4 + core/services/keeper/integration_test.go | 8 +- .../registry_synchronizer_helper_test.go | 2 +- .../registry_synchronizer_process_logs.go | 3 + .../keeper/registry_synchronizer_sync.go | 6 +- core/services/keeper/upkeep_executer_test.go | 2 +- core/services/keystore/eth_test.go | 6 +- core/services/llo/delegate.go | 16 +- core/services/ocr/contract_tracker.go | 5 +- core/services/ocr/contract_tracker_test.go | 10 +- core/services/ocr/database.go | 7 +- core/services/ocr/database_test.go | 4 +- core/services/ocr/delegate.go | 15 +- core/services/ocr/helpers_internal_test.go | 7 +- .../ocr/mocks/ocr_contract_tracker_db.go | 31 +- core/services/ocr2/database.go | 39 +- core/services/ocr2/database_test.go | 36 +- core/services/ocr2/delegate.go | 63 +- .../ocr2/plugins/dkg/persistence/db.go | 19 +- .../ocr2/plugins/dkg/persistence/db_test.go | 2 +- core/services/ocr2/plugins/dkg/plugin.go | 8 +- .../generic/pipeline_runner_adapter_test.go | 4 +- core/services/ocr2/plugins/ocr2keeper/util.go | 13 +- core/services/ocrbootstrap/database.go | 11 +- core/services/ocrbootstrap/database_test.go | 8 +- core/services/ocrbootstrap/delegate.go | 13 +- .../services/ocrcommon/discoverer_database.go | 13 +- .../ocrcommon/discoverer_database_test.go | 2 +- core/services/ocrcommon/peer_wrapper.go | 13 +- core/services/ocrcommon/peer_wrapper_test.go | 14 +- core/services/pg/connection.go | 5 + core/services/pg/lease_lock.go | 9 +- core/services/pg/q.go | 384 ----- core/services/pg/q_test.go | 85 -- core/services/pg/sqlx.go | 24 +- core/services/pg/transaction.go | 95 -- core/services/pg/utils.go | 50 - core/services/pipeline/helpers_test.go | 3 +- core/services/pipeline/mocks/orm.go | 18 +- core/services/pipeline/orm.go | 69 +- core/services/pipeline/orm_test.go | 49 +- core/services/pipeline/runner.go | 2 +- core/services/pipeline/runner_test.go | 19 +- core/services/pipeline/task.bridge_test.go | 54 +- core/services/pipeline/task.http_test.go | 2 +- core/services/pipeline/test_helpers_test.go | 3 +- core/services/promreporter/prom_reporter.go | 10 +- .../promreporter/prom_reporter_test.go | 7 +- core/services/relay/evm/evm.go | 18 +- core/services/relay/evm/evm_test.go | 23 +- .../evm/mercury/wsrpc/pb/mercury_wsrpc.pb.go | 1 - core/services/relay/evm/ocr2keeper.go | 5 +- core/services/relay/evm/ocr2vrf.go | 6 +- core/services/versioning/orm.go | 14 +- core/services/versioning/orm_test.go | 7 +- core/services/vrf/delegate_test.go | 10 +- core/services/vrf/v1/integration_test.go | 28 +- core/services/vrf/v1/listener_v1.go | 9 +- .../vrf/v2/integration_helpers_test.go | 6 +- .../vrf/v2/integration_v2_plus_test.go | 24 +- .../v2/integration_v2_reverted_txns_test.go | 2 +- core/services/vrf/v2/integration_v2_test.go | 22 +- core/services/vrf/vrftesthelpers/helpers.go | 6 +- core/services/webhook/authorizer.go | 12 +- core/services/webhook/authorizer_test.go | 3 +- .../webhook/external_initiator_manager.go | 44 +- .../external_initiator_manager_test.go | 17 +- .../mocks/external_initiator_manager.go | 18 +- core/services/webhook/validate.go | 6 +- core/services/webhook/validate_test.go | 15 +- core/sessions/ldapauth/sync.go | 38 +- core/sessions/localauth/reaper.go | 16 +- core/sessions/localauth/reaper_test.go | 2 +- core/store/migrate/migrate.go | 39 +- core/store/migrate/migrate_test.go | 27 +- .../migrations/0054_remove_legacy_pipeline.go | 10 +- core/web/bridge_types_controller.go | 2 +- core/web/eth_keys_controller_test.go | 3 +- core/web/evm_transactions_controller_test.go | 8 +- core/web/evm_transfer_controller_test.go | 15 +- core/web/evm_tx_attempts_controller_test.go | 2 +- .../external_initiators_controller_test.go | 2 +- core/web/jobs_controller.go | 10 +- core/web/jobs_controller_test.go | 46 +- core/web/loader/feeds_manager.go | 4 +- core/web/loader/feeds_manager_chain_config.go | 4 +- core/web/loader/job.go | 8 +- core/web/loader/job_proposal.go | 4 +- core/web/loader/job_proposal_spec.go | 4 +- core/web/loader/job_run.go | 4 +- core/web/loader/job_spec_errors.go | 3 +- core/web/loader/loader_test.go | 16 +- ...ipeline_job_spec_errors_controller_test.go | 3 +- core/web/pipeline_runs_controller.go | 11 +- core/web/pipeline_runs_controller_test.go | 12 +- core/web/resolver/bridge_test.go | 4 +- .../feeds_manager_chain_config_test.go | 14 +- core/web/resolver/feeds_manager_test.go | 16 +- core/web/resolver/job.go | 4 +- core/web/resolver/job_error_test.go | 14 +- core/web/resolver/job_proposal_spec_test.go | 20 +- core/web/resolver/job_proposal_test.go | 7 +- core/web/resolver/job_run_test.go | 12 +- core/web/resolver/job_test.go | 36 +- core/web/resolver/mutation.go | 26 +- core/web/resolver/query.go | 14 +- core/web/resolver/spec_test.go | 29 +- core/web/sessions_controller_test.go | 26 +- go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 185 files changed, 3795 insertions(+), 4580 deletions(-) create mode 100644 .changeset/fuzzy-pans-destroy.md delete mode 100644 core/services/pg/q.go delete mode 100644 core/services/pg/q_test.go delete mode 100644 core/services/pg/transaction.go delete mode 100644 core/services/pg/utils.go diff --git a/.changeset/fuzzy-pans-destroy.md b/.changeset/fuzzy-pans-destroy.md new file mode 100644 index 00000000000..3cff19f8d8a --- /dev/null +++ b/.changeset/fuzzy-pans-destroy.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +Use sqlutil instead of pg.Opts/Q/Queryer #internal diff --git a/core/bridges/orm_test.go b/core/bridges/orm_test.go index 85e8b9ecdef..b85b6be00dd 100644 --- a/core/bridges/orm_test.go +++ b/core/bridges/orm_test.go @@ -144,7 +144,7 @@ func TestORM_TestCachedResponse(t *testing.T) { orm := bridges.NewORM(db) trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns()) - specID, err := trORM.CreateSpec(ctx, nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) + specID, err := trORM.CreateSpec(ctx, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) require.NoError(t, err) _, err = orm.GetCachedResponse(ctx, "dot", specID, 1*time.Second) diff --git a/core/chains/evm/log/helpers_test.go b/core/chains/evm/log/helpers_test.go index 0d725b8594b..13aeb8d2338 100644 --- a/core/chains/evm/log/helpers_test.go +++ b/core/chains/evm/log/helpers_test.go @@ -110,7 +110,7 @@ func newBroadcasterHelperWithEthClient(t *testing.T, ethClient evmclient.Client, m[r.Chain().ID().String()] = r.Chain() } legacyChains := legacyevm.NewLegacyChains(m, cc.AppConfig().EVMConfigs()) - pipelineHelper := cltest.NewJobPipelineV2(t, globalConfig.WebServer(), globalConfig.JobPipeline(), globalConfig.Database(), legacyChains, db, kst, nil, nil) + pipelineHelper := cltest.NewJobPipelineV2(t, globalConfig.WebServer(), globalConfig.JobPipeline(), legacyChains, db, kst, nil, nil) return &broadcasterHelper{ t: t, @@ -263,7 +263,7 @@ func (helper *broadcasterHelper) newLogListenerWithJob(name string) *simpleLogLi PipelineSpec: &pipeline.Spec{}, ExternalJobID: uuid.New(), } - err := helper.pipelineHelper.Jrm.CreateJob(jb) + err := helper.pipelineHelper.Jrm.CreateJob(testutils.Context(t), jb) require.NoError(t, err) var rec received @@ -288,7 +288,7 @@ func (listener *simpleLogListener) HandleLog(ctx context.Context, lb log.Broadca listener.received.logs = append(listener.received.logs, lb.RawLog()) listener.received.broadcasts = append(listener.received.broadcasts, lb) - consumed := listener.handleLogBroadcast(lb) + consumed := listener.handleLogBroadcast(ctx, lb) if !consumed { listener.received.uniqueLogs = append(listener.received.uniqueLogs, lb.RawLog()) @@ -321,9 +321,8 @@ func (listener *simpleLogListener) requireAllReceived(t *testing.T, expectedStat }, testutils.WaitTimeout(t), time.Second, "len(received.uniqueLogs): %v is not equal len(expectedState.uniqueLogs): %v", len(received.getUniqueLogs()), len(expectedState.getUniqueLogs())) } -func (listener *simpleLogListener) handleLogBroadcast(lb log.Broadcast) bool { +func (listener *simpleLogListener) handleLogBroadcast(ctx context.Context, lb log.Broadcast) bool { t := listener.t - ctx := testutils.Context(t) consumed, err := listener.WasAlreadyConsumed(ctx, lb) if !assert.NoError(t, err) { return false @@ -354,8 +353,8 @@ type mockListener struct { jobID int32 } -func (l *mockListener) JobID() int32 { return l.jobID } -func (l *mockListener) HandleLog(log.Broadcast) {} +func (l *mockListener) JobID() int32 { return l.jobID } +func (l *mockListener) HandleLog(context.Context, log.Broadcast) {} type mockEthClientExpectedCalls struct { SubscribeFilterLogs int diff --git a/core/chains/evm/log/integration_test.go b/core/chains/evm/log/integration_test.go index fd6b375d80a..e34533b3cfb 100644 --- a/core/chains/evm/log/integration_test.go +++ b/core/chains/evm/log/integration_test.go @@ -250,7 +250,6 @@ func TestBroadcaster_ReplaysLogs(t *testing.T) { func TestBroadcaster_BackfillUnconsumedAfterCrash(t *testing.T) { contract1 := newMockContract(t) contract2 := newMockContract(t) - ctx := testutils.Context(t) blocks := cltest.NewBlocks(t, 10) const ( @@ -267,6 +266,7 @@ func TestBroadcaster_BackfillUnconsumedAfterCrash(t *testing.T) { helper := newBroadcasterHelper(t, 0, 1, logs, func(c *chainlink.Config, s *chainlink.Secrets) { c.EVM[0].FinalityDepth = ptr[uint32](confs) }) + ctx := testutils.Context(t) orm := log.NewORM(helper.db, cltest.FixtureChainID) listener := helper.newLogListenerWithJob("one") @@ -292,6 +292,7 @@ func TestBroadcaster_BackfillUnconsumedAfterCrash(t *testing.T) { helper := newBroadcasterHelper(t, 2, 1, logs, func(c *chainlink.Config, s *chainlink.Secrets) { c.EVM[0].FinalityDepth = ptr[uint32](confs) }) + ctx := testutils.Context(t) orm := log.NewORM(helper.db, cltest.FixtureChainID) contract1.On("ParseLog", log1).Return(flux_aggregator_wrapper.FluxAggregatorNewRound{}, nil) contract2.On("ParseLog", log2).Return(flux_aggregator_wrapper.FluxAggregatorAnswerUpdated{}, nil) @@ -318,6 +319,7 @@ func TestBroadcaster_BackfillUnconsumedAfterCrash(t *testing.T) { helper := newBroadcasterHelper(t, 4, 1, logs, func(c *chainlink.Config, s *chainlink.Secrets) { c.EVM[0].FinalityDepth = ptr[uint32](confs) }) + ctx := testutils.Context(t) orm := log.NewORM(helper.db, cltest.FixtureChainID) listener := helper.newLogListenerWithJob("one") @@ -342,6 +344,7 @@ func TestBroadcaster_BackfillUnconsumedAfterCrash(t *testing.T) { helper := newBroadcasterHelper(t, 7, 1, logs[1:], func(c *chainlink.Config, s *chainlink.Secrets) { c.EVM[0].FinalityDepth = ptr[uint32](confs) }) + ctx := testutils.Context(t) orm := log.NewORM(helper.db, cltest.FixtureChainID) listener := helper.newLogListenerWithJob("one") listener2 := helper.newLogListenerWithJob("two") @@ -377,8 +380,9 @@ func (helper *broadcasterHelper) simulateHeads(t *testing.T, listener, listener2 <-headsDone + ctx := testutils.Context(t) require.Eventually(t, func() bool { - blockNum, err := orm.GetPendingMinBlock(testutils.Context(t)) + blockNum, err := orm.GetPendingMinBlock(ctx) if !assert.NoError(t, err) { return false } diff --git a/core/chains/evm/logpoller/observability.go b/core/chains/evm/logpoller/observability.go index 07a0f58ce78..14dec5274ad 100644 --- a/core/chains/evm/logpoller/observability.go +++ b/core/chains/evm/logpoller/observability.go @@ -76,9 +76,9 @@ type ObservedORM struct { // NewObservedORM creates an observed version of log poller's ORM created by NewORM // Please see ObservedLogPoller for more details on how latencies are measured -func NewObservedORM(chainID *big.Int, db sqlutil.DataSource, lggr logger.Logger) *ObservedORM { +func NewObservedORM(chainID *big.Int, ds sqlutil.DataSource, lggr logger.Logger) *ObservedORM { return &ObservedORM{ - ORM: NewORM(chainID, db, lggr), + ORM: NewORM(chainID, ds, lggr), queryDuration: lpQueryDuration, datasetSize: lpQueryDataSets, logsInserted: lpLogsInserted, diff --git a/core/chains/evm/logpoller/orm.go b/core/chains/evm/logpoller/orm.go index ebba3cffc08..838a38c8ebb 100644 --- a/core/chains/evm/logpoller/orm.go +++ b/core/chains/evm/logpoller/orm.go @@ -59,32 +59,32 @@ type ORM interface { SelectLogsDataWordBetween(ctx context.Context, address common.Address, eventSig common.Hash, wordIndexMin int, wordIndexMax int, wordValue common.Hash, confs Confirmations) ([]Log, error) } -type DbORM struct { +type DSORM struct { chainID *big.Int - db sqlutil.DataSource + ds sqlutil.DataSource lggr logger.Logger } -var _ ORM = &DbORM{} +var _ ORM = &DSORM{} -// NewORM creates an DbORM scoped to chainID. -func NewORM(chainID *big.Int, db sqlutil.DataSource, lggr logger.Logger) *DbORM { - return &DbORM{ +// NewORM creates an DSORM scoped to chainID. +func NewORM(chainID *big.Int, ds sqlutil.DataSource, lggr logger.Logger) *DSORM { + return &DSORM{ chainID: chainID, - db: db, + ds: ds, lggr: lggr, } } -func (o *DbORM) Transaction(ctx context.Context, fn func(*DbORM) error) (err error) { - return sqlutil.Transact(ctx, o.new, o.db, nil, fn) +func (o *DSORM) Transact(ctx context.Context, fn func(*DSORM) error) (err error) { + return sqlutil.Transact(ctx, o.new, o.ds, nil, fn) } -// new returns a NewORM like o, but backed by q. -func (o *DbORM) new(q sqlutil.DataSource) *DbORM { return NewORM(o.chainID, q, o.lggr) } +// new returns a NewORM like o, but backed by ds. +func (o *DSORM) new(ds sqlutil.DataSource) *DSORM { return NewORM(o.chainID, ds, o.lggr) } // InsertBlock is idempotent to support replays. -func (o *DbORM) InsertBlock(ctx context.Context, blockHash common.Hash, blockNumber int64, blockTimestamp time.Time, finalizedBlock int64) error { +func (o *DSORM) InsertBlock(ctx context.Context, blockHash common.Hash, blockNumber int64, blockTimestamp time.Time, finalizedBlock int64) error { args, err := newQueryArgs(o.chainID). withCustomHashArg("block_hash", blockHash). withCustomArg("block_number", blockNumber). @@ -98,12 +98,7 @@ func (o *DbORM) InsertBlock(ctx context.Context, blockHash common.Hash, blockNum (evm_chain_id, block_hash, block_number, block_timestamp, finalized_block_number, created_at) VALUES (:evm_chain_id, :block_hash, :block_number, :block_timestamp, :finalized_block_number, NOW()) ON CONFLICT DO NOTHING` - query, sqlArgs, err := o.db.BindNamed(query, args) - if err != nil { - return err - } - - _, err = o.db.ExecContext(ctx, query, sqlArgs...) + _, err = o.ds.NamedExecContext(ctx, query, args) return err } @@ -111,7 +106,7 @@ func (o *DbORM) InsertBlock(ctx context.Context, blockHash common.Hash, blockNum // // Each address/event pair must have a unique job id, so it may be removed when the job is deleted. // If a second job tries to overwrite the same pair, this should fail. -func (o *DbORM) InsertFilter(ctx context.Context, filter Filter) (err error) { +func (o *DSORM) InsertFilter(ctx context.Context, filter Filter) (err error) { topicArrays := []types.HashArray{filter.Topic2, filter.Topic3, filter.Topic4} args, err := newQueryArgs(o.chainID). withCustomArg("name", filter.Name). @@ -148,18 +143,13 @@ func (o *DbORM) InsertFilter(ctx context.Context, filter Filter) (err error) { topicsColumns.String(), topicsSql.String()) - query, sqlArgs, err := o.db.BindNamed(query, args) - if err != nil { - return err - } - - _, err = o.db.ExecContext(ctx, query, sqlArgs...) + _, err = o.ds.NamedExecContext(ctx, query, args) return err } // DeleteFilter removes all events,address pairs associated with the Filter -func (o *DbORM) DeleteFilter(ctx context.Context, name string) error { - _, err := o.db.ExecContext(ctx, +func (o *DSORM) DeleteFilter(ctx context.Context, name string) error { + _, err := o.ds.ExecContext(ctx, `DELETE FROM evm.log_poller_filters WHERE name = $1 AND evm_chain_id = $2`, name, ubig.New(o.chainID)) return err @@ -167,7 +157,7 @@ func (o *DbORM) DeleteFilter(ctx context.Context, name string) error { } // LoadFilters returns all filters for this chain -func (o *DbORM) LoadFilters(ctx context.Context) (map[string]Filter, error) { +func (o *DSORM) LoadFilters(ctx context.Context) (map[string]Filter, error) { query := `SELECT name, ARRAY_AGG(DISTINCT address)::BYTEA[] AS addresses, ARRAY_AGG(DISTINCT event)::BYTEA[] AS event_sigs, @@ -180,7 +170,7 @@ func (o *DbORM) LoadFilters(ctx context.Context) (map[string]Filter, error) { FROM evm.log_poller_filters WHERE evm_chain_id = $1 GROUP BY name` var rows []Filter - err := o.db.SelectContext(ctx, &rows, query, ubig.New(o.chainID)) + err := o.ds.SelectContext(ctx, &rows, query, ubig.New(o.chainID)) filters := make(map[string]Filter) for _, filter := range rows { filters[filter.Name] = filter @@ -188,31 +178,31 @@ func (o *DbORM) LoadFilters(ctx context.Context) (map[string]Filter, error) { return filters, err } -func (o *DbORM) SelectBlockByHash(ctx context.Context, hash common.Hash) (*LogPollerBlock, error) { +func (o *DSORM) SelectBlockByHash(ctx context.Context, hash common.Hash) (*LogPollerBlock, error) { var b LogPollerBlock - if err := o.db.GetContext(ctx, &b, `SELECT * FROM evm.log_poller_blocks WHERE block_hash = $1 AND evm_chain_id = $2`, hash.Bytes(), ubig.New(o.chainID)); err != nil { + if err := o.ds.GetContext(ctx, &b, `SELECT * FROM evm.log_poller_blocks WHERE block_hash = $1 AND evm_chain_id = $2`, hash.Bytes(), ubig.New(o.chainID)); err != nil { return nil, err } return &b, nil } -func (o *DbORM) SelectBlockByNumber(ctx context.Context, n int64) (*LogPollerBlock, error) { +func (o *DSORM) SelectBlockByNumber(ctx context.Context, n int64) (*LogPollerBlock, error) { var b LogPollerBlock - if err := o.db.GetContext(ctx, &b, `SELECT * FROM evm.log_poller_blocks WHERE block_number = $1 AND evm_chain_id = $2`, n, ubig.New(o.chainID)); err != nil { + if err := o.ds.GetContext(ctx, &b, `SELECT * FROM evm.log_poller_blocks WHERE block_number = $1 AND evm_chain_id = $2`, n, ubig.New(o.chainID)); err != nil { return nil, err } return &b, nil } -func (o *DbORM) SelectLatestBlock(ctx context.Context) (*LogPollerBlock, error) { +func (o *DSORM) SelectLatestBlock(ctx context.Context) (*LogPollerBlock, error) { var b LogPollerBlock - if err := o.db.GetContext(ctx, &b, `SELECT * FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1`, ubig.New(o.chainID)); err != nil { + if err := o.ds.GetContext(ctx, &b, `SELECT * FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1`, ubig.New(o.chainID)); err != nil { return nil, err } return &b, nil } -func (o *DbORM) SelectLatestLogByEventSigWithConfs(ctx context.Context, eventSig common.Hash, address common.Address, confs Confirmations) (*Log, error) { +func (o *DSORM) SelectLatestLogByEventSigWithConfs(ctx context.Context, eventSig common.Hash, address common.Address, confs Confirmations) (*Log, error) { args, err := newQueryArgsForEvent(o.chainID, address, eventSig). withConfs(confs). toArgs() @@ -228,11 +218,11 @@ func (o *DbORM) SelectLatestLogByEventSigWithConfs(ctx context.Context, eventSig ORDER BY (block_number, log_index) DESC LIMIT 1`, nestedBlockNumberQuery(confs)) var l Log - query, sqlArgs, err := o.db.BindNamed(query, args) + query, sqlArgs, err := o.ds.BindNamed(query, args) if err != nil { return nil, err } - if err = o.db.GetContext(ctx, &l, query, sqlArgs...); err != nil { + if err = o.ds.GetContext(ctx, &l, query, sqlArgs...); err != nil { return nil, err } return &l, nil @@ -240,9 +230,9 @@ func (o *DbORM) SelectLatestLogByEventSigWithConfs(ctx context.Context, eventSig // DeleteBlocksBefore delete blocks before and including end. When limit is set, it will delete at most limit blocks. // Otherwise, it will delete all blocks at once. -func (o *DbORM) DeleteBlocksBefore(ctx context.Context, end int64, limit int64) (int64, error) { +func (o *DSORM) DeleteBlocksBefore(ctx context.Context, end int64, limit int64) (int64, error) { if limit > 0 { - result, err := o.db.ExecContext(ctx, + result, err := o.ds.ExecContext(ctx, `DELETE FROM evm.log_poller_blocks WHERE block_number IN ( SELECT block_number FROM evm.log_poller_blocks @@ -257,7 +247,7 @@ func (o *DbORM) DeleteBlocksBefore(ctx context.Context, end int64, limit int64) } return result.RowsAffected() } - result, err := o.db.ExecContext(ctx, `DELETE FROM evm.log_poller_blocks + result, err := o.ds.ExecContext(ctx, `DELETE FROM evm.log_poller_blocks WHERE block_number <= $1 AND evm_chain_id = $2`, end, ubig.New(o.chainID)) if err != nil { return 0, err @@ -265,16 +255,16 @@ func (o *DbORM) DeleteBlocksBefore(ctx context.Context, end int64, limit int64) return result.RowsAffected() } -func (o *DbORM) DeleteLogsAndBlocksAfter(ctx context.Context, start int64) error { +func (o *DSORM) DeleteLogsAndBlocksAfter(ctx context.Context, start int64) error { // These deletes are bounded by reorg depth, so they are // fast and should not slow down the log readers. - return o.Transaction(ctx, func(orm *DbORM) error { + return o.Transact(ctx, func(orm *DSORM) error { // Applying upper bound filter is critical for Postgres performance (especially for evm.logs table) // because it allows the planner to properly estimate the number of rows to be scanned. // If not applied, these queries can become very slow. After some critical number // of logs, Postgres will try to scan all the logs in the index by block_number. // Latency without upper bound filter can be orders of magnitude higher for large number of logs. - _, err := o.db.ExecContext(ctx, `DELETE FROM evm.log_poller_blocks + _, err := o.ds.ExecContext(ctx, `DELETE FROM evm.log_poller_blocks WHERE evm_chain_id = $1 AND block_number >= $2 AND block_number <= (SELECT MAX(block_number) @@ -286,7 +276,7 @@ func (o *DbORM) DeleteLogsAndBlocksAfter(ctx context.Context, start int64) error return err } - _, err = o.db.ExecContext(ctx, `DELETE FROM evm.logs + _, err = o.ds.ExecContext(ctx, `DELETE FROM evm.logs WHERE evm_chain_id = $1 AND block_number >= $2 AND block_number <= (SELECT MAX(block_number) FROM evm.logs WHERE evm_chain_id = $1)`, @@ -307,11 +297,11 @@ type Exp struct { ShouldDelete bool } -func (o *DbORM) DeleteExpiredLogs(ctx context.Context, limit int64) (int64, error) { +func (o *DSORM) DeleteExpiredLogs(ctx context.Context, limit int64) (int64, error) { var err error var result sql.Result if limit > 0 { - result, err = o.db.ExecContext(ctx, ` + result, err = o.ds.ExecContext(ctx, ` DELETE FROM evm.logs WHERE (evm_chain_id, address, event_sig, block_number) IN ( SELECT l.evm_chain_id, l.address, l.event_sig, l.block_number @@ -327,7 +317,7 @@ func (o *DbORM) DeleteExpiredLogs(ctx context.Context, limit int64) (int64, erro LIMIT $2 )`, ubig.New(o.chainID), limit) } else { - result, err = o.db.ExecContext(ctx, `WITH r AS + result, err = o.ds.ExecContext(ctx, `WITH r AS ( SELECT address, event, MAX(retention) AS retention FROM evm.log_poller_filters WHERE evm_chain_id=$1 GROUP BY evm_chain_id,address, event HAVING NOT 0 = ANY(ARRAY_AGG(retention)) @@ -344,16 +334,16 @@ func (o *DbORM) DeleteExpiredLogs(ctx context.Context, limit int64) (int64, erro } // InsertLogs is idempotent to support replays. -func (o *DbORM) InsertLogs(ctx context.Context, logs []Log) error { +func (o *DSORM) InsertLogs(ctx context.Context, logs []Log) error { if err := o.validateLogs(logs); err != nil { return err } - return o.Transaction(ctx, func(orm *DbORM) error { - return orm.insertLogsWithinTx(ctx, logs, orm.db) + return o.Transact(ctx, func(orm *DSORM) error { + return orm.insertLogsWithinTx(ctx, logs, orm.ds) }) } -func (o *DbORM) InsertLogsWithBlock(ctx context.Context, logs []Log, block LogPollerBlock) error { +func (o *DSORM) InsertLogsWithBlock(ctx context.Context, logs []Log, block LogPollerBlock) error { // Optimization, don't open TX when there is only a block to be persisted if len(logs) == 0 { return o.InsertBlock(ctx, block.BlockHash, block.BlockNumber, block.BlockTimestamp, block.FinalizedBlockNumber) @@ -364,16 +354,16 @@ func (o *DbORM) InsertLogsWithBlock(ctx context.Context, logs []Log, block LogPo } // Block and logs goes with the same TX to ensure atomicity - return o.Transaction(ctx, func(orm *DbORM) error { + return o.Transact(ctx, func(orm *DSORM) error { err := orm.InsertBlock(ctx, block.BlockHash, block.BlockNumber, block.BlockTimestamp, block.FinalizedBlockNumber) if err != nil { return err } - return orm.insertLogsWithinTx(ctx, logs, orm.db) + return orm.insertLogsWithinTx(ctx, logs, orm.ds) }) } -func (o *DbORM) insertLogsWithinTx(ctx context.Context, logs []Log, tx sqlutil.DataSource) error { +func (o *DSORM) insertLogsWithinTx(ctx context.Context, logs []Log, tx sqlutil.DataSource) error { batchInsertSize := 4000 for i := 0; i < len(logs); i += batchInsertSize { start, end := i, i+batchInsertSize @@ -387,12 +377,10 @@ func (o *DbORM) insertLogsWithinTx(ctx context.Context, logs []Log, tx sqlutil.D (:evm_chain_id, :log_index, :block_hash, :block_number, :block_timestamp, :address, :event_sig, :topics, :tx_hash, :data, NOW()) ON CONFLICT DO NOTHING` - query, sqlArgs, err := o.db.BindNamed(query, logs[start:end]) + _, err := o.ds.NamedExecContext(ctx, query, logs[start:end]) if err != nil { return err } - - _, err = tx.ExecContext(ctx, query, sqlArgs...) if err != nil { if pkgerrors.Is(err, context.DeadlineExceeded) && batchInsertSize > 500 { // In case of DB timeouts, try to insert again with a smaller batch upto a limit @@ -406,7 +394,7 @@ func (o *DbORM) insertLogsWithinTx(ctx context.Context, logs []Log, tx sqlutil.D return nil } -func (o *DbORM) validateLogs(logs []Log) error { +func (o *DSORM) validateLogs(logs []Log) error { for _, log := range logs { if o.chainID.Cmp(log.EvmChainId.ToInt()) != 0 { return pkgerrors.Errorf("invalid chainID in log got %v want %v", log.EvmChainId.ToInt(), o.chainID) @@ -415,7 +403,7 @@ func (o *DbORM) validateLogs(logs []Log) error { return nil } -func (o *DbORM) SelectLogsByBlockRange(ctx context.Context, start, end int64) ([]Log, error) { +func (o *DSORM) SelectLogsByBlockRange(ctx context.Context, start, end int64) ([]Log, error) { args, err := newQueryArgs(o.chainID). withStartBlock(start). withEndBlock(end). @@ -431,12 +419,12 @@ func (o *DbORM) SelectLogsByBlockRange(ctx context.Context, start, end int64) ([ ORDER BY (block_number, log_index)` var logs []Log - query, sqlArgs, err := o.db.BindNamed(query, args) + query, sqlArgs, err := o.ds.BindNamed(query, args) if err != nil { return nil, err } - err = o.db.SelectContext(ctx, &logs, query, sqlArgs...) + err = o.ds.SelectContext(ctx, &logs, query, sqlArgs...) if err != nil { return nil, err } @@ -444,7 +432,7 @@ func (o *DbORM) SelectLogsByBlockRange(ctx context.Context, start, end int64) ([ } // SelectLogs finds the logs in a given block range. -func (o *DbORM) SelectLogs(ctx context.Context, start, end int64, address common.Address, eventSig common.Hash) ([]Log, error) { +func (o *DSORM) SelectLogs(ctx context.Context, start, end int64, address common.Address, eventSig common.Hash) ([]Log, error) { args, err := newQueryArgsForEvent(o.chainID, address, eventSig). withStartBlock(start). withEndBlock(end). @@ -462,12 +450,12 @@ func (o *DbORM) SelectLogs(ctx context.Context, start, end int64, address common ORDER BY (block_number, log_index)` var logs []Log - query, sqlArgs, err := o.db.BindNamed(query, args) + query, sqlArgs, err := o.ds.BindNamed(query, args) if err != nil { return nil, err } - err = o.db.SelectContext(ctx, &logs, query, sqlArgs...) + err = o.ds.SelectContext(ctx, &logs, query, sqlArgs...) if err != nil { return nil, err } @@ -475,7 +463,7 @@ func (o *DbORM) SelectLogs(ctx context.Context, start, end int64, address common } // SelectLogsCreatedAfter finds logs created after some timestamp. -func (o *DbORM) SelectLogsCreatedAfter(ctx context.Context, address common.Address, eventSig common.Hash, after time.Time, confs Confirmations) ([]Log, error) { +func (o *DSORM) SelectLogsCreatedAfter(ctx context.Context, address common.Address, eventSig common.Hash, after time.Time, confs Confirmations) ([]Log, error) { args, err := newQueryArgsForEvent(o.chainID, address, eventSig). withBlockTimestampAfter(after). withConfs(confs). @@ -494,12 +482,12 @@ func (o *DbORM) SelectLogsCreatedAfter(ctx context.Context, address common.Addre ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) var logs []Log - query, sqlArgs, err := o.db.BindNamed(query, args) + query, sqlArgs, err := o.ds.BindNamed(query, args) if err != nil { return nil, err } - if err = o.db.SelectContext(ctx, &logs, query, sqlArgs...); err != nil { + if err = o.ds.SelectContext(ctx, &logs, query, sqlArgs...); err != nil { return nil, err } return logs, nil @@ -507,7 +495,7 @@ func (o *DbORM) SelectLogsCreatedAfter(ctx context.Context, address common.Addre // SelectLogsWithSigs finds the logs in the given block range with the given event signatures // emitted from the given address. -func (o *DbORM) SelectLogsWithSigs(ctx context.Context, start, end int64, address common.Address, eventSigs []common.Hash) (logs []Log, err error) { +func (o *DSORM) SelectLogsWithSigs(ctx context.Context, start, end int64, address common.Address, eventSigs []common.Hash) (logs []Log, err error) { args, err := newQueryArgs(o.chainID). withAddress(address). withEventSigArray(eventSigs). @@ -525,19 +513,19 @@ func (o *DbORM) SelectLogsWithSigs(ctx context.Context, start, end int64, addres AND block_number BETWEEN :start_block AND :end_block ORDER BY (block_number, log_index)` - query, sqlArgs, err := o.db.BindNamed(query, args) + query, sqlArgs, err := o.ds.BindNamed(query, args) if err != nil { return nil, err } - err = o.db.SelectContext(ctx, &logs, query, sqlArgs...) + err = o.ds.SelectContext(ctx, &logs, query, sqlArgs...) if pkgerrors.Is(err, sql.ErrNoRows) { return nil, nil } return logs, err } -func (o *DbORM) GetBlocksRange(ctx context.Context, start int64, end int64) ([]LogPollerBlock, error) { +func (o *DSORM) GetBlocksRange(ctx context.Context, start int64, end int64) ([]LogPollerBlock, error) { args, err := newQueryArgs(o.chainID). withStartBlock(start). withEndBlock(end). @@ -553,12 +541,12 @@ func (o *DbORM) GetBlocksRange(ctx context.Context, start int64, end int64) ([]L ORDER BY block_number ASC` var blocks []LogPollerBlock - query, sqlArgs, err := o.db.BindNamed(query, args) + query, sqlArgs, err := o.ds.BindNamed(query, args) if err != nil { return nil, err } - err = o.db.SelectContext(ctx, &blocks, query, sqlArgs...) + err = o.ds.SelectContext(ctx, &blocks, query, sqlArgs...) if err != nil { return nil, err } @@ -566,7 +554,7 @@ func (o *DbORM) GetBlocksRange(ctx context.Context, start int64, end int64) ([]L } // SelectLatestLogEventSigsAddrsWithConfs finds the latest log by (address, event) combination that matches a list of Addresses and list of events -func (o *DbORM) SelectLatestLogEventSigsAddrsWithConfs(ctx context.Context, fromBlock int64, addresses []common.Address, eventSigs []common.Hash, confs Confirmations) ([]Log, error) { +func (o *DSORM) SelectLatestLogEventSigsAddrsWithConfs(ctx context.Context, fromBlock int64, addresses []common.Address, eventSigs []common.Hash, confs Confirmations) ([]Log, error) { args, err := newQueryArgs(o.chainID). withAddressArray(addresses). withEventSigArray(eventSigs). @@ -590,19 +578,19 @@ func (o *DbORM) SelectLatestLogEventSigsAddrsWithConfs(ctx context.Context, from ORDER BY block_number ASC`, nestedBlockNumberQuery(confs)) var logs []Log - query, sqlArgs, err := o.db.BindNamed(query, args) + query, sqlArgs, err := o.ds.BindNamed(query, args) if err != nil { return nil, err } - if err = o.db.SelectContext(ctx, &logs, query, sqlArgs...); err != nil { + if err = o.ds.SelectContext(ctx, &logs, query, sqlArgs...); err != nil { return nil, pkgerrors.Wrap(err, "failed to execute query") } return logs, nil } // SelectLatestBlockByEventSigsAddrsWithConfs finds the latest block number that matches a list of Addresses and list of events. It returns 0 if there is no matching block -func (o *DbORM) SelectLatestBlockByEventSigsAddrsWithConfs(ctx context.Context, fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs Confirmations) (int64, error) { +func (o *DSORM) SelectLatestBlockByEventSigsAddrsWithConfs(ctx context.Context, fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs Confirmations) (int64, error) { args, err := newQueryArgs(o.chainID). withEventSigArray(eventSigs). withAddressArray(addresses). @@ -621,18 +609,18 @@ func (o *DbORM) SelectLatestBlockByEventSigsAddrsWithConfs(ctx context.Context, AND block_number <= %s`, nestedBlockNumberQuery(confs)) var blockNumber int64 - query, sqlArgs, err := o.db.BindNamed(query, args) + query, sqlArgs, err := o.ds.BindNamed(query, args) if err != nil { return 0, err } - if err = o.db.GetContext(ctx, &blockNumber, query, sqlArgs...); err != nil { + if err = o.ds.GetContext(ctx, &blockNumber, query, sqlArgs...); err != nil { return 0, err } return blockNumber, nil } -func (o *DbORM) SelectLogsDataWordRange(ctx context.Context, address common.Address, eventSig common.Hash, wordIndex int, wordValueMin, wordValueMax common.Hash, confs Confirmations) ([]Log, error) { +func (o *DSORM) SelectLogsDataWordRange(ctx context.Context, address common.Address, eventSig common.Hash, wordIndex int, wordValueMin, wordValueMax common.Hash, confs Confirmations) ([]Log, error) { args, err := newQueryArgsForEvent(o.chainID, address, eventSig). withWordIndex(wordIndex). withWordValueMin(wordValueMin). @@ -653,18 +641,18 @@ func (o *DbORM) SelectLogsDataWordRange(ctx context.Context, address common.Addr ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) var logs []Log - query, sqlArgs, err := o.db.BindNamed(query, args) + query, sqlArgs, err := o.ds.BindNamed(query, args) if err != nil { return nil, err } - if err := o.db.SelectContext(ctx, &logs, query, sqlArgs...); err != nil { + if err := o.ds.SelectContext(ctx, &logs, query, sqlArgs...); err != nil { return nil, err } return logs, nil } -func (o *DbORM) SelectLogsDataWordGreaterThan(ctx context.Context, address common.Address, eventSig common.Hash, wordIndex int, wordValueMin common.Hash, confs Confirmations) ([]Log, error) { +func (o *DSORM) SelectLogsDataWordGreaterThan(ctx context.Context, address common.Address, eventSig common.Hash, wordIndex int, wordValueMin common.Hash, confs Confirmations) ([]Log, error) { args, err := newQueryArgsForEvent(o.chainID, address, eventSig). withWordIndex(wordIndex). withWordValueMin(wordValueMin). @@ -684,18 +672,18 @@ func (o *DbORM) SelectLogsDataWordGreaterThan(ctx context.Context, address commo ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) var logs []Log - query, sqlArgs, err := o.db.BindNamed(query, args) + query, sqlArgs, err := o.ds.BindNamed(query, args) if err != nil { return nil, err } - if err := o.db.SelectContext(ctx, &logs, query, sqlArgs...); err != nil { + if err := o.ds.SelectContext(ctx, &logs, query, sqlArgs...); err != nil { return nil, err } return logs, nil } -func (o *DbORM) SelectLogsDataWordBetween(ctx context.Context, address common.Address, eventSig common.Hash, wordIndexMin int, wordIndexMax int, wordValue common.Hash, confs Confirmations) ([]Log, error) { +func (o *DSORM) SelectLogsDataWordBetween(ctx context.Context, address common.Address, eventSig common.Hash, wordIndexMin int, wordIndexMax int, wordValue common.Hash, confs Confirmations) ([]Log, error) { args, err := newQueryArgsForEvent(o.chainID, address, eventSig). withWordIndexMin(wordIndexMin). withWordIndexMax(wordIndexMax). @@ -716,18 +704,18 @@ func (o *DbORM) SelectLogsDataWordBetween(ctx context.Context, address common.Ad ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) var logs []Log - query, sqlArgs, err := o.db.BindNamed(query, args) + query, sqlArgs, err := o.ds.BindNamed(query, args) if err != nil { return nil, err } - if err := o.db.SelectContext(ctx, &logs, query, sqlArgs...); err != nil { + if err := o.ds.SelectContext(ctx, &logs, query, sqlArgs...); err != nil { return nil, err } return logs, nil } -func (o *DbORM) SelectIndexedLogsTopicGreaterThan(ctx context.Context, address common.Address, eventSig common.Hash, topicIndex int, topicValueMin common.Hash, confs Confirmations) ([]Log, error) { +func (o *DSORM) SelectIndexedLogsTopicGreaterThan(ctx context.Context, address common.Address, eventSig common.Hash, topicIndex int, topicValueMin common.Hash, confs Confirmations) ([]Log, error) { args, err := newQueryArgsForEvent(o.chainID, address, eventSig). withTopicIndex(topicIndex). withTopicValueMin(topicValueMin). @@ -747,18 +735,18 @@ func (o *DbORM) SelectIndexedLogsTopicGreaterThan(ctx context.Context, address c ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) var logs []Log - query, sqlArgs, err := o.db.BindNamed(query, args) + query, sqlArgs, err := o.ds.BindNamed(query, args) if err != nil { return nil, err } - if err := o.db.SelectContext(ctx, &logs, query, sqlArgs...); err != nil { + if err := o.ds.SelectContext(ctx, &logs, query, sqlArgs...); err != nil { return nil, err } return logs, nil } -func (o *DbORM) SelectIndexedLogsTopicRange(ctx context.Context, address common.Address, eventSig common.Hash, topicIndex int, topicValueMin, topicValueMax common.Hash, confs Confirmations) ([]Log, error) { +func (o *DSORM) SelectIndexedLogsTopicRange(ctx context.Context, address common.Address, eventSig common.Hash, topicIndex int, topicValueMin, topicValueMax common.Hash, confs Confirmations) ([]Log, error) { args, err := newQueryArgsForEvent(o.chainID, address, eventSig). withTopicIndex(topicIndex). withTopicValueMin(topicValueMin). @@ -780,18 +768,18 @@ func (o *DbORM) SelectIndexedLogsTopicRange(ctx context.Context, address common. ORDER BY (evm.logs.block_number, evm.logs.log_index)`, nestedBlockNumberQuery(confs)) var logs []Log - query, sqlArgs, err := o.db.BindNamed(query, args) + query, sqlArgs, err := o.ds.BindNamed(query, args) if err != nil { return nil, err } - if err := o.db.SelectContext(ctx, &logs, query, sqlArgs...); err != nil { + if err := o.ds.SelectContext(ctx, &logs, query, sqlArgs...); err != nil { return nil, err } return logs, nil } -func (o *DbORM) SelectIndexedLogs(ctx context.Context, address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, confs Confirmations) ([]Log, error) { +func (o *DSORM) SelectIndexedLogs(ctx context.Context, address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, confs Confirmations) ([]Log, error) { args, err := newQueryArgsForEvent(o.chainID, address, eventSig). withTopicIndex(topicIndex). withTopicValues(topicValues). @@ -811,19 +799,19 @@ func (o *DbORM) SelectIndexedLogs(ctx context.Context, address common.Address, e ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) var logs []Log - query, sqlArgs, err := o.db.BindNamed(query, args) + query, sqlArgs, err := o.ds.BindNamed(query, args) if err != nil { return nil, err } - if err := o.db.SelectContext(ctx, &logs, query, sqlArgs...); err != nil { + if err := o.ds.SelectContext(ctx, &logs, query, sqlArgs...); err != nil { return nil, err } return logs, nil } // SelectIndexedLogsByBlockRange finds the indexed logs in a given block range. -func (o *DbORM) SelectIndexedLogsByBlockRange(ctx context.Context, start, end int64, address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash) ([]Log, error) { +func (o *DSORM) SelectIndexedLogsByBlockRange(ctx context.Context, start, end int64, address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash) ([]Log, error) { args, err := newQueryArgsForEvent(o.chainID, address, eventSig). withTopicIndex(topicIndex). withTopicValues(topicValues). @@ -844,19 +832,19 @@ func (o *DbORM) SelectIndexedLogsByBlockRange(ctx context.Context, start, end in ORDER BY (block_number, log_index)` var logs []Log - query, sqlArgs, err := o.db.BindNamed(query, args) + query, sqlArgs, err := o.ds.BindNamed(query, args) if err != nil { return nil, err } - err = o.db.SelectContext(ctx, &logs, query, sqlArgs...) + err = o.ds.SelectContext(ctx, &logs, query, sqlArgs...) if err != nil { return nil, err } return logs, nil } -func (o *DbORM) SelectIndexedLogsCreatedAfter(ctx context.Context, address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, after time.Time, confs Confirmations) ([]Log, error) { +func (o *DSORM) SelectIndexedLogsCreatedAfter(ctx context.Context, address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, after time.Time, confs Confirmations) ([]Log, error) { args, err := newQueryArgsForEvent(o.chainID, address, eventSig). withBlockTimestampAfter(after). withConfs(confs). @@ -878,18 +866,18 @@ func (o *DbORM) SelectIndexedLogsCreatedAfter(ctx context.Context, address commo ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) var logs []Log - query, sqlArgs, err := o.db.BindNamed(query, args) + query, sqlArgs, err := o.ds.BindNamed(query, args) if err != nil { return nil, err } - if err := o.db.SelectContext(ctx, &logs, query, sqlArgs...); err != nil { + if err := o.ds.SelectContext(ctx, &logs, query, sqlArgs...); err != nil { return nil, err } return logs, nil } -func (o *DbORM) SelectIndexedLogsByTxHash(ctx context.Context, address common.Address, eventSig common.Hash, txHash common.Hash) ([]Log, error) { +func (o *DSORM) SelectIndexedLogsByTxHash(ctx context.Context, address common.Address, eventSig common.Hash, txHash common.Hash) ([]Log, error) { args, err := newQueryArgs(o.chainID). withTxHash(txHash). withAddress(address). @@ -907,12 +895,12 @@ func (o *DbORM) SelectIndexedLogsByTxHash(ctx context.Context, address common.Ad ORDER BY (block_number, log_index)` var logs []Log - query, sqlArgs, err := o.db.BindNamed(query, args) + query, sqlArgs, err := o.ds.BindNamed(query, args) if err != nil { return nil, err } - err = o.db.SelectContext(ctx, &logs, query, sqlArgs...) + err = o.ds.SelectContext(ctx, &logs, query, sqlArgs...) if err != nil { return nil, err } @@ -920,7 +908,7 @@ func (o *DbORM) SelectIndexedLogsByTxHash(ctx context.Context, address common.Ad } // SelectIndexedLogsWithSigsExcluding query's for logs that have signature A and exclude logs that have a corresponding signature B, matching is done based on the topic index both logs should be inside the block range and have the minimum number of confirmations -func (o *DbORM) SelectIndexedLogsWithSigsExcluding(ctx context.Context, sigA, sigB common.Hash, topicIndex int, address common.Address, startBlock, endBlock int64, confs Confirmations) ([]Log, error) { +func (o *DSORM) SelectIndexedLogsWithSigsExcluding(ctx context.Context, sigA, sigB common.Hash, topicIndex int, address common.Address, startBlock, endBlock int64, confs Confirmations) ([]Log, error) { args, err := newQueryArgs(o.chainID). withAddress(address). withTopicIndex(topicIndex). @@ -955,12 +943,12 @@ func (o *DbORM) SelectIndexedLogsWithSigsExcluding(ctx context.Context, sigA, si ORDER BY block_number,log_index ASC`, nestedQuery, nestedQuery) var logs []Log - query, sqlArgs, err := o.db.BindNamed(query, args) + query, sqlArgs, err := o.ds.BindNamed(query, args) if err != nil { return nil, err } - if err := o.db.SelectContext(ctx, &logs, query, sqlArgs...); err != nil { + if err := o.ds.SelectContext(ctx, &logs, query, sqlArgs...); err != nil { return nil, err } return logs, nil diff --git a/core/chains/evm/logpoller/query.go b/core/chains/evm/logpoller/query.go index 6aabe59045d..f9d2c45bce1 100644 --- a/core/chains/evm/logpoller/query.go +++ b/core/chains/evm/logpoller/query.go @@ -24,7 +24,7 @@ func concatBytes[T bytesProducer](byteSlice []T) [][]byte { return output } -// queryArgs is a helper for building the arguments to a postgres query created by DbORM +// queryArgs is a helper for building the arguments to a postgres query created by DSORM // Besides the convenience methods, it also keeps track of arguments validation and sanitization. type queryArgs struct { args map[string]interface{} diff --git a/core/chains/evm/txmgr/broadcaster_test.go b/core/chains/evm/txmgr/broadcaster_test.go index 4e19a2ec7da..20c069a46d6 100644 --- a/core/chains/evm/txmgr/broadcaster_test.go +++ b/core/chains/evm/txmgr/broadcaster_test.go @@ -1112,7 +1112,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) { } t.Run("with erroring callback bails out", func(t *testing.T) { - require.NoError(t, txStore.InsertTx(ctx, &etx)) + require.NoError(t, txStore.InsertTx(testutils.Context(t), &etx)) fn := func(ctx context.Context, id uuid.UUID, result interface{}, err error) error { return errors.New("something exploded in the callback") } diff --git a/core/chains/evm/txmgr/builder.go b/core/chains/evm/txmgr/builder.go index f13efb2b258..0671f49bb74 100644 --- a/core/chains/evm/txmgr/builder.go +++ b/core/chains/evm/txmgr/builder.go @@ -4,8 +4,6 @@ import ( "math/big" "time" - "github.com/jmoiron/sqlx" - "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink/v2/common/txmgr" @@ -21,8 +19,7 @@ import ( // NewTxm constructs the necessary dependencies for the EvmTxm (broadcaster, confirmer, etc) and returns a new EvmTxManager func NewTxm( - sqlxDB *sqlx.DB, - db sqlutil.DataSource, + ds sqlutil.DataSource, chainConfig ChainConfig, fCfg FeeConfig, txConfig config.Transactions, @@ -40,14 +37,14 @@ func NewTxm( var fwdMgr FwdMgr if txConfig.ForwardersEnabled() { - fwdMgr = forwarders.NewFwdMgr(db, client, logPoller, lggr, chainConfig) + fwdMgr = forwarders.NewFwdMgr(ds, client, logPoller, lggr, chainConfig) } else { lggr.Info("EvmForwarderManager: Disabled") } checker := &CheckerFactory{Client: client} // create tx attempt builder txAttemptBuilder := NewEvmTxAttemptBuilder(*client.ConfiguredChainID(), fCfg, keyStore, estimator) - txStore := NewTxStore(sqlxDB, lggr) + txStore := NewTxStore(ds, lggr) txmCfg := NewEvmTxmConfig(chainConfig) // wrap Evm specific config feeCfg := NewEvmTxmFeeConfig(fCfg) // wrap Evm specific config txmClient := NewEvmTxmClient(client, clientErrors) // wrap Evm specific client diff --git a/core/chains/evm/txmgr/evm_tx_store.go b/core/chains/evm/txmgr/evm_tx_store.go index c8e664e8cfe..dedba07b594 100644 --- a/core/chains/evm/txmgr/evm_tx_store.go +++ b/core/chains/evm/txmgr/evm_tx_store.go @@ -115,7 +115,7 @@ func DbReceiptToEvmReceipt(receipt *dbReceipt) *evmtypes.Receipt { // Directly maps to onchain receipt schema. type rawOnchainReceipt = evmtypes.Receipt -func (o *evmTxStore) Transaction(ctx context.Context, readOnly bool, fn func(*evmTxStore) error) (err error) { +func (o *evmTxStore) Transact(ctx context.Context, readOnly bool, fn func(*evmTxStore) error) (err error) { opts := &sqlutil.TxOptions{TxOptions: sql.TxOptions{ReadOnly: readOnly}} return sqlutil.Transact(ctx, o.new, o.q, opts, fn) } @@ -509,7 +509,7 @@ func (o *evmTxStore) FindTxAttemptsByTxIDs(ctx context.Context, ids []int64) ([] func (o *evmTxStore) FindTxByHash(ctx context.Context, hash common.Hash) (*Tx, error) { var dbEtx DbEthTx - err := o.Transaction(ctx, true, func(orm *evmTxStore) error { + err := o.Transact(ctx, true, func(orm *evmTxStore) error { sql := `SELECT evm.txes.* FROM evm.txes WHERE id IN (SELECT DISTINCT eth_tx_id FROM evm.tx_attempts WHERE hash = $1)` if err := orm.q.GetContext(ctx, &dbEtx, sql, hash); err != nil { return pkgerrors.Wrapf(err, "failed to find eth_tx with hash %d", hash) @@ -575,7 +575,7 @@ func (o *evmTxStore) GetFatalTransactions(ctx context.Context) (txes []*Tx, err var cancel context.CancelFunc ctx, cancel = o.mergeContexts(ctx) defer cancel() - err = o.Transaction(ctx, true, func(orm *evmTxStore) error { + err = o.Transact(ctx, true, func(orm *evmTxStore) error { stmt := `SELECT * FROM evm.txes WHERE state = 'fatal_error'` var dbEtxs []DbEthTx if err = orm.q.SelectContext(ctx, &dbEtxs, stmt); err != nil { @@ -595,7 +595,7 @@ func (o *evmTxStore) GetFatalTransactions(ctx context.Context) (txes []*Tx, err // FindTxWithAttempts finds the Tx with its attempts and receipts preloaded func (o *evmTxStore) FindTxWithAttempts(ctx context.Context, etxID int64) (etx Tx, err error) { - err = o.Transaction(ctx, true, func(orm *evmTxStore) error { + err = o.Transact(ctx, true, func(orm *evmTxStore) error { var dbEtx DbEthTx if err = orm.q.GetContext(ctx, &dbEtx, `SELECT * FROM evm.txes WHERE id = $1 ORDER BY created_at ASC, id ASC`, etxID); err != nil { return pkgerrors.Wrapf(err, "failed to find evm.tx with id %d", etxID) @@ -614,7 +614,7 @@ func (o *evmTxStore) FindTxWithAttempts(ctx context.Context, etxID int64) (etx T func (o *evmTxStore) FindTxAttemptConfirmedByTxIDs(ctx context.Context, ids []int64) ([]TxAttempt, error) { var txAttempts []TxAttempt - err := o.Transaction(ctx, true, func(orm *evmTxStore) error { + err := o.Transact(ctx, true, func(orm *evmTxStore) error { var dbAttempts []DbEthTxAttempt if err := orm.q.SelectContext(ctx, &dbAttempts, `SELECT eta.* FROM evm.tx_attempts eta @@ -806,7 +806,7 @@ func (o *evmTxStore) FindTxAttemptsRequiringReceiptFetch(ctx context.Context, ch var cancel context.CancelFunc ctx, cancel = o.mergeContexts(ctx) defer cancel() - err = o.Transaction(ctx, true, func(orm *evmTxStore) error { + err = o.Transact(ctx, true, func(orm *evmTxStore) error { var dbAttempts []DbEthTxAttempt err = orm.q.SelectContext(ctx, &dbAttempts, ` SELECT evm.tx_attempts.* FROM evm.tx_attempts @@ -963,7 +963,7 @@ func (o *evmTxStore) GetInProgressTxAttempts(ctx context.Context, address common var cancel context.CancelFunc ctx, cancel = o.mergeContexts(ctx) defer cancel() - err = o.Transaction(ctx, true, func(orm *evmTxStore) error { + err = o.Transact(ctx, true, func(orm *evmTxStore) error { var dbAttempts []DbEthTxAttempt err = orm.q.SelectContext(ctx, &dbAttempts, ` SELECT evm.tx_attempts.* FROM evm.tx_attempts @@ -1046,7 +1046,7 @@ func (o *evmTxStore) FindTxWithSequence(ctx context.Context, fromAddress common. ctx, cancel = o.mergeContexts(ctx) defer cancel() etx = new(Tx) - err = o.Transaction(ctx, true, func(orm *evmTxStore) error { + err = o.Transact(ctx, true, func(orm *evmTxStore) error { var dbEtx DbEthTx err = orm.q.GetContext(ctx, &dbEtx, ` SELECT * FROM evm.txes WHERE from_address = $1 AND nonce = $2 AND state IN ('confirmed', 'confirmed_missing_receipt', 'unconfirmed') @@ -1094,7 +1094,7 @@ func (o *evmTxStore) UpdateTxForRebroadcast(ctx context.Context, etx Tx, etxAtte var cancel context.CancelFunc ctx, cancel = o.mergeContexts(ctx) defer cancel() - return o.Transaction(ctx, false, func(orm *evmTxStore) error { + return o.Transact(ctx, false, func(orm *evmTxStore) error { if err := deleteEthReceipts(ctx, orm, etx.ID); err != nil { return pkgerrors.Wrapf(err, "deleteEthReceipts failed for etx %v", etx.ID) } @@ -1109,7 +1109,7 @@ func (o *evmTxStore) FindTransactionsConfirmedInBlockRange(ctx context.Context, var cancel context.CancelFunc ctx, cancel = o.mergeContexts(ctx) defer cancel() - err = o.Transaction(ctx, true, func(orm *evmTxStore) error { + err = o.Transact(ctx, true, func(orm *evmTxStore) error { var dbEtxs []DbEthTx err = orm.q.SelectContext(ctx, &dbEtxs, ` SELECT DISTINCT evm.txes.* FROM evm.txes @@ -1136,7 +1136,7 @@ func (o *evmTxStore) FindEarliestUnconfirmedBroadcastTime(ctx context.Context, c var cancel context.CancelFunc ctx, cancel = o.mergeContexts(ctx) defer cancel() - err = o.Transaction(ctx, true, func(orm *evmTxStore) error { + err = o.Transact(ctx, true, func(orm *evmTxStore) error { if err = orm.q.QueryRowxContext(ctx, `SELECT min(initial_broadcast_at) FROM evm.txes WHERE state = 'unconfirmed' AND evm_chain_id = $1`, chainID.String()).Scan(&broadcastAt); err != nil { return fmt.Errorf("failed to query for unconfirmed eth_tx count: %w", err) } @@ -1149,7 +1149,7 @@ func (o *evmTxStore) FindEarliestUnconfirmedTxAttemptBlock(ctx context.Context, var cancel context.CancelFunc ctx, cancel = o.mergeContexts(ctx) defer cancel() - err = o.Transaction(ctx, true, func(orm *evmTxStore) error { + err = o.Transact(ctx, true, func(orm *evmTxStore) error { err = orm.q.QueryRowxContext(ctx, ` SELECT MIN(broadcast_before_block_num) FROM evm.tx_attempts JOIN evm.txes ON evm.txes.id = evm.tx_attempts.eth_tx_id @@ -1184,7 +1184,7 @@ func (o *evmTxStore) IsTxFinalized(ctx context.Context, blockHeight int64, txID func (o *evmTxStore) saveAttemptWithNewState(ctx context.Context, attempt TxAttempt, broadcastAt time.Time) error { var dbAttempt DbEthTxAttempt dbAttempt.FromTxAttempt(&attempt) - return o.Transaction(ctx, false, func(orm *evmTxStore) error { + return o.Transact(ctx, false, func(orm *evmTxStore) error { // In case of null broadcast_at (shouldn't happen) we don't want to // update anyway because it indicates a state where broadcast_at makes // no sense e.g. fatal_error @@ -1230,7 +1230,7 @@ func (o *evmTxStore) SaveConfirmedMissingReceiptAttempt(ctx context.Context, tim var cancel context.CancelFunc ctx, cancel = o.mergeContexts(ctx) defer cancel() - err := o.Transaction(ctx, false, func(orm *evmTxStore) error { + err := o.Transact(ctx, false, func(orm *evmTxStore) error { if err := orm.saveSentAttempt(ctx, timeout, attempt, broadcastAt); err != nil { return err } @@ -1321,7 +1321,7 @@ func (o *evmTxStore) GetTxByID(ctx context.Context, id int64) (txe *Tx, err erro ctx, cancel = o.mergeContexts(ctx) defer cancel() - err = o.Transaction(ctx, true, func(orm *evmTxStore) error { + err = o.Transact(ctx, true, func(orm *evmTxStore) error { stmt := `SELECT * FROM evm.txes WHERE id = $1` var dbEtxs []DbEthTx if err = orm.q.SelectContext(ctx, &dbEtxs, stmt, id); err != nil { @@ -1355,7 +1355,7 @@ func (o *evmTxStore) FindTxsRequiringGasBump(ctx context.Context, address common var cancel context.CancelFunc ctx, cancel = o.mergeContexts(ctx) defer cancel() - err = o.Transaction(ctx, true, func(orm *evmTxStore) error { + err = o.Transact(ctx, true, func(orm *evmTxStore) error { stmt := ` SELECT evm.txes.* FROM evm.txes LEFT JOIN evm.tx_attempts ON evm.txes.id = evm.tx_attempts.eth_tx_id AND (broadcast_before_block_num > $4 OR broadcast_before_block_num IS NULL OR evm.tx_attempts.state != 'broadcast') @@ -1382,7 +1382,7 @@ func (o *evmTxStore) FindTxsRequiringResubmissionDueToInsufficientFunds(ctx cont var cancel context.CancelFunc ctx, cancel = o.mergeContexts(ctx) defer cancel() - err = o.Transaction(ctx, true, func(orm *evmTxStore) error { + err = o.Transact(ctx, true, func(orm *evmTxStore) error { var dbEtxs []DbEthTx err = orm.q.SelectContext(ctx, &dbEtxs, ` SELECT DISTINCT evm.txes.* FROM evm.txes @@ -1423,7 +1423,7 @@ func (o *evmTxStore) MarkOldTxesMissingReceiptAsErrored(ctx context.Context, blo return nil } // note: if QOpt passes in a sql.Tx this will reuse it - return o.Transaction(ctx, false, func(orm *evmTxStore) error { + return o.Transact(ctx, false, func(orm *evmTxStore) error { type etx struct { ID int64 Nonce int64 @@ -1511,7 +1511,7 @@ func (o *evmTxStore) SaveReplacementInProgressAttempt(ctx context.Context, oldAt if oldAttempt.ID == 0 { return errors.New("expected oldAttempt to have an ID") } - return o.Transaction(ctx, false, func(orm *evmTxStore) error { + return o.Transact(ctx, false, func(orm *evmTxStore) error { if _, err := orm.q.ExecContext(ctx, `DELETE FROM evm.tx_attempts WHERE id=$1`, oldAttempt.ID); err != nil { return pkgerrors.Wrap(err, "saveReplacementInProgressAttempt failed to delete from evm.tx_attempts") } @@ -1557,7 +1557,7 @@ func (o *evmTxStore) UpdateTxFatalError(ctx context.Context, etx *Tx) error { etx.Sequence = nil etx.State = txmgr.TxFatalError - return o.Transaction(ctx, false, func(orm *evmTxStore) error { + return o.Transact(ctx, false, func(orm *evmTxStore) error { if _, err := orm.q.ExecContext(ctx, `DELETE FROM evm.tx_attempts WHERE eth_tx_id = $1`, etx.ID); err != nil { return pkgerrors.Wrapf(err, "saveFatallyErroredTransaction failed to delete eth_tx_attempt with eth_tx.ID %v", etx.ID) } @@ -1591,7 +1591,7 @@ func (o *evmTxStore) UpdateTxAttemptInProgressToBroadcast(ctx context.Context, e } etx.State = txmgr.TxUnconfirmed attempt.State = NewAttemptState - return o.Transaction(ctx, false, func(orm *evmTxStore) error { + return o.Transact(ctx, false, func(orm *evmTxStore) error { var dbEtx DbEthTx dbEtx.FromTx(etx) if err := orm.q.GetContext(ctx, &dbEtx, `UPDATE evm.txes SET state=$1, error=$2, broadcast_at=$3, initial_broadcast_at=$4 WHERE id = $5 RETURNING *`, dbEtx.State, dbEtx.Error, dbEtx.BroadcastAt, dbEtx.InitialBroadcastAt, dbEtx.ID); err != nil { @@ -1622,7 +1622,7 @@ func (o *evmTxStore) UpdateTxUnstartedToInProgress(ctx context.Context, etx *Tx, return errors.New("attempt state must be in_progress") } etx.State = txmgr.TxInProgress - return o.Transaction(ctx, false, func(orm *evmTxStore) error { + return o.Transact(ctx, false, func(orm *evmTxStore) error { // If a replay was triggered while unconfirmed transactions were pending, they will be marked as fatal_error => abandoned. // In this case, we must remove the abandoned attempt from evm.tx_attempts before replacing it with a new one. In any other // case, we uphold the constraint, leaving the original tx attempt as-is and returning the constraint violation error. @@ -1688,7 +1688,7 @@ func (o *evmTxStore) GetTxInProgress(ctx context.Context, fromAddress common.Add if err != nil { return etx, pkgerrors.Wrap(err, "getInProgressEthTx failed") } - err = o.Transaction(ctx, true, func(orm *evmTxStore) error { + err = o.Transact(ctx, true, func(orm *evmTxStore) error { var dbEtx DbEthTx err = orm.q.GetContext(ctx, &dbEtx, `SELECT * FROM evm.txes WHERE from_address = $1 and state = 'in_progress'`, fromAddress) if errors.Is(err, sql.ErrNoRows) { @@ -1776,7 +1776,7 @@ func (o *evmTxStore) CreateTransaction(ctx context.Context, txRequest TxRequest, ctx, cancel = o.mergeContexts(ctx) defer cancel() var dbEtx DbEthTx - err = o.Transaction(ctx, false, func(orm *evmTxStore) error { + err = o.Transact(ctx, false, func(orm *evmTxStore) error { if txRequest.PipelineTaskRunID != nil { err = orm.q.GetContext(ctx, &dbEtx, `SELECT * FROM evm.txes WHERE pipeline_task_run_id = $1 AND evm_chain_id = $2`, txRequest.PipelineTaskRunID, chainID.String()) @@ -1810,7 +1810,7 @@ func (o *evmTxStore) PruneUnstartedTxQueue(ctx context.Context, queueSize uint32 var cancel context.CancelFunc ctx, cancel = o.mergeContexts(ctx) defer cancel() - err = o.Transaction(ctx, false, func(orm *evmTxStore) error { + err = o.Transact(ctx, false, func(orm *evmTxStore) error { err := orm.q.SelectContext(ctx, &ids, ` DELETE FROM evm.txes WHERE state = 'unstarted' AND subject = $1 AND @@ -1945,7 +1945,7 @@ func (o *evmTxStore) FindTxesWithAttemptsAndReceiptsByIdsAndState(ctx context.Co var cancel context.CancelFunc ctx, cancel = o.mergeContexts(ctx) defer cancel() - err = o.Transaction(ctx, true, func(orm *evmTxStore) error { + err = o.Transact(ctx, true, func(orm *evmTxStore) error { var dbEtxs []DbEthTx if err = orm.q.SelectContext(ctx, &dbEtxs, `SELECT * FROM evm.txes WHERE id = ANY($1) AND state = ANY($2) AND evm_chain_id = $3`, pq.Array(ids), pq.Array(states), chainID.String()); err != nil { return pkgerrors.Wrapf(err, "failed to find evm.txes") diff --git a/core/chains/evm/txmgr/txmgr_test.go b/core/chains/evm/txmgr/txmgr_test.go index aac9d89c490..85d25d8a70b 100644 --- a/core/chains/evm/txmgr/txmgr_test.go +++ b/core/chains/evm/txmgr/txmgr_test.go @@ -68,7 +68,6 @@ func makeTestEvmTxm( ) return txmgr.NewTxm( - db, db, ccfg, fcfg, diff --git a/core/chains/legacyevm/chain.go b/core/chains/legacyevm/chain.go index 920532518ab..27e0155da52 100644 --- a/core/chains/legacyevm/chain.go +++ b/core/chains/legacyevm/chain.go @@ -9,8 +9,6 @@ import ( gotoml "github.com/pelletier/go-toml/v2" "go.uber.org/multierr" - "github.com/jmoiron/sqlx" - common "github.com/smartcontractkit/chainlink-common/pkg/chains" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" @@ -162,8 +160,7 @@ type ChainOpts struct { MailMon *mailbox.Monitor GasEstimator gas.EvmFeeEstimator - SqlxDB *sqlx.DB // Deprecated: use DB instead - DB sqlutil.DataSource + DS sqlutil.DataSource // TODO BCF-2513 remove test code from the API // Gen-functions are useful for dependency injection by tests @@ -184,11 +181,8 @@ func (o ChainOpts) Validate() error { if o.MailMon == nil { err = errors.Join(err, errors.New("nil MailMon")) } - if o.SqlxDB == nil { - err = errors.Join(err, errors.New("nil SqlxDB")) - } - if o.DB == nil { - err = errors.Join(err, errors.New("nil DB")) + if o.DS == nil { + err = errors.Join(err, errors.New("nil DS")) } if err != nil { err = fmt.Errorf("invalid ChainOpts: %w", err) @@ -229,7 +223,7 @@ func newChain(ctx context.Context, cfg *evmconfig.ChainScoped, nodes []*toml.Nod if !opts.AppConfig.EVMRPCEnabled() { headTracker = headtracker.NullTracker } else if opts.GenHeadTracker == nil { - orm := headtracker.NewORM(*chainID, opts.DB) + orm := headtracker.NewORM(*chainID, opts.DS) headSaver = headtracker.NewHeadSaver(l, orm, cfg.EVM(), cfg.EVM().HeadTracker()) headTracker = headtracker.NewHeadTracker(l, client, cfg.EVM(), cfg.EVM().HeadTracker(), headBroadcaster, headSaver, opts.MailMon) } else { @@ -251,12 +245,12 @@ func newChain(ctx context.Context, cfg *evmconfig.ChainScoped, nodes []*toml.Nod LogPrunePageSize: int64(cfg.EVM().LogPrunePageSize()), BackupPollerBlockDelay: int64(cfg.EVM().BackupLogPollerBlockDelay()), } - logPoller = logpoller.NewLogPoller(logpoller.NewObservedORM(chainID, opts.DB, l), client, l, lpOpts) + logPoller = logpoller.NewLogPoller(logpoller.NewObservedORM(chainID, opts.DS, l), client, l, lpOpts) } } // note: gas estimator is started as a part of the txm - txm, gasEstimator, err := newEvmTxm(opts.SqlxDB, opts.DB, cfg.EVM(), opts.AppConfig.EVMRPCEnabled(), opts.AppConfig.Database(), opts.AppConfig.Database().Listener(), client, l, logPoller, opts) + txm, gasEstimator, err := newEvmTxm(opts.DS, cfg.EVM(), opts.AppConfig.EVMRPCEnabled(), opts.AppConfig.Database(), opts.AppConfig.Database().Listener(), client, l, logPoller, opts) if err != nil { return nil, fmt.Errorf("failed to instantiate EvmTxm for chain with ID %s: %w", chainID.String(), err) } @@ -279,7 +273,7 @@ func newChain(ctx context.Context, cfg *evmconfig.ChainScoped, nodes []*toml.Nod if !opts.AppConfig.EVMRPCEnabled() { logBroadcaster = &log.NullBroadcaster{ErrMsg: fmt.Sprintf("Ethereum is disabled for chain %d", chainID)} } else if opts.GenLogBroadcaster == nil { - logORM := log.NewORM(opts.SqlxDB, *chainID) + logORM := log.NewORM(opts.DS, *chainID) logBroadcaster = log.NewBroadcaster(logORM, client, cfg.EVM(), l, highestSeenHead, opts.MailMon) } else { logBroadcaster = opts.GenLogBroadcaster(chainID) diff --git a/core/chains/legacyevm/chain_test.go b/core/chains/legacyevm/chain_test.go index 5dd7eb1c6ed..c10712d4b6b 100644 --- a/core/chains/legacyevm/chain_test.go +++ b/core/chains/legacyevm/chain_test.go @@ -65,8 +65,7 @@ func TestChainOpts_Validate(t *testing.T) { o := legacyevm.ChainOpts{ AppConfig: tt.fields.AppConfig, MailMon: tt.fields.MailMon, - SqlxDB: tt.fields.DB, - DB: tt.fields.DB, + DS: tt.fields.DB, } if err := o.Validate(); (err != nil) != tt.wantErr { t.Errorf("ChainOpts.Validate() error = %v, wantErr %v", err, tt.wantErr) diff --git a/core/chains/legacyevm/evm_txm.go b/core/chains/legacyevm/evm_txm.go index 6b2d1262ce8..df1f4248ce2 100644 --- a/core/chains/legacyevm/evm_txm.go +++ b/core/chains/legacyevm/evm_txm.go @@ -3,8 +3,6 @@ package legacyevm import ( "fmt" - "github.com/jmoiron/sqlx" - "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" evmconfig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config" @@ -15,8 +13,7 @@ import ( ) func newEvmTxm( - sqlxDB *sqlx.DB, - db sqlutil.DataSource, + ds sqlutil.DataSource, cfg evmconfig.EVM, evmRPCEnabled bool, databaseConfig txmgr.DatabaseConfig, @@ -53,8 +50,7 @@ func newEvmTxm( if opts.GenTxManager == nil { txm, err = txmgr.NewTxm( - sqlxDB, - db, + ds, cfg, txmgr.NewEvmTxmFeeConfig(cfg.GasEstimator()), cfg.Transactions(), diff --git a/core/cmd/eth_keys_commands_test.go b/core/cmd/eth_keys_commands_test.go index 2f22cd1d3ae..64835c7f28b 100644 --- a/core/cmd/eth_keys_commands_test.go +++ b/core/cmd/eth_keys_commands_test.go @@ -182,7 +182,7 @@ func TestShell_CreateETHKey(t *testing.T) { withKey(), withMocks(ethClient), ) - db := app.GetSqlxDB() + db := app.GetDB() client, _ := app.NewShellAndRenderer() cltest.AssertCount(t, db, "evm.key_states", 1) // The initial funding key @@ -306,7 +306,7 @@ func TestShell_ImportExportETHKey_NoChains(t *testing.T) { _, err = ethKeyStore.Get(testutils.Context(t), address) require.Error(t, err) - cltest.AssertCount(t, app.GetSqlxDB(), "evm.key_states", 0) + cltest.AssertCount(t, app.GetDB(), "evm.key_states", 0) // Import the key set = flag.NewFlagSet("test", 0) diff --git a/core/cmd/evm_transaction_commands_test.go b/core/cmd/evm_transaction_commands_test.go index df5d066927a..5375abbacee 100644 --- a/core/cmd/evm_transaction_commands_test.go +++ b/core/cmd/evm_transaction_commands_test.go @@ -32,7 +32,7 @@ func TestShell_IndexTransactions(t *testing.T) { _, from := cltest.MustInsertRandomKey(t, app.KeyStore.Eth()) - txStore := cltest.NewTestTxStore(t, app.GetSqlxDB()) + txStore := cltest.NewTestTxStore(t, app.GetDB()) tx := cltest.MustInsertConfirmedEthTxWithLegacyAttempt(t, txStore, 0, 1, from) attempt := tx.TxAttempts[0] @@ -70,7 +70,7 @@ func TestShell_ShowTransaction(t *testing.T) { app := startNewApplicationV2(t, nil) client, r := app.NewShellAndRenderer() - db := app.GetSqlxDB() + db := app.GetDB() _, from := cltest.MustInsertRandomKey(t, app.KeyStore.Eth()) txStore := cltest.NewTestTxStore(t, db) @@ -97,7 +97,7 @@ func TestShell_IndexTxAttempts(t *testing.T) { _, from := cltest.MustInsertRandomKey(t, app.KeyStore.Eth()) - txStore := cltest.NewTestTxStore(t, app.GetSqlxDB()) + txStore := cltest.NewTestTxStore(t, app.GetDB()) tx := cltest.MustInsertConfirmedEthTxWithLegacyAttempt(t, txStore, 0, 1, from) // page 1 @@ -156,7 +156,7 @@ func TestShell_SendEther_From_Txm(t *testing.T) { withMocks(ethMock, key), ) client, r := app.NewShellAndRenderer() - db := app.GetSqlxDB() + db := app.GetDB() txStore := txmgr.NewTxStore(db, logger.TestLogger(t)) set := flag.NewFlagSet("sendether", 0) flagSetApplyFromAction(client.SendEther, set, "") @@ -221,7 +221,7 @@ func TestShell_SendEther_From_Txm_WEI(t *testing.T) { withMocks(ethMock, key), ) client, r := app.NewShellAndRenderer() - db := app.GetSqlxDB() + db := app.GetDB() txStore := txmgr.NewTxStore(db, logger.TestLogger(t)) set := flag.NewFlagSet("sendether", 0) diff --git a/core/cmd/jobs_commands_test.go b/core/cmd/jobs_commands_test.go index 75e95db84ca..77d2487509a 100644 --- a/core/cmd/jobs_commands_test.go +++ b/core/cmd/jobs_commands_test.go @@ -17,6 +17,7 @@ import ( commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink/v2/core/cmd" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/store/models" @@ -428,7 +429,8 @@ func TestShell_DeleteJob(t *testing.T) { requireJobsCount(t, app.JobORM(), 1) - jobs, _, err := app.JobORM().FindJobs(0, 1000) + ctx := testutils.Context(t) + jobs, _, err := app.JobORM().FindJobs(ctx, 0, 1000) require.NoError(t, err) jobID := jobs[0].ID cltest.AwaitJobActive(t, app.JobSpawner(), jobID, 3*time.Second) @@ -451,7 +453,8 @@ func TestShell_DeleteJob(t *testing.T) { } func requireJobsCount(t *testing.T, orm job.ORM, expected int) { - jobs, _, err := orm.FindJobs(0, 1000) + ctx := testutils.Context(t) + jobs, _, err := orm.FindJobs(ctx, 0, 1000) require.NoError(t, err) require.Len(t, jobs, expected) } diff --git a/core/cmd/shell.go b/core/cmd/shell.go index bc58c5cab6d..0372148e742 100644 --- a/core/cmd/shell.go +++ b/core/cmd/shell.go @@ -136,7 +136,7 @@ type AppFactory interface { type ChainlinkAppFactory struct{} // NewApplication returns a new instance of the node with the given config. -func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.GeneralConfig, appLggr logger.Logger, sqlxDB *sqlx.DB) (app chainlink.Application, err error) { +func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.GeneralConfig, appLggr logger.Logger, db *sqlx.DB) (app chainlink.Application, err error) { err = initGlobals(cfg.Prometheus(), cfg.Tracing(), appLggr) if err != nil { appLggr.Errorf("Failed to initialize globals: %v", err) @@ -147,14 +147,14 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G return nil, err } - db := sqlutil.WrapDataSource(sqlxDB, appLggr, sqlutil.TimeoutHook(cfg.Database().DefaultQueryTimeout), sqlutil.MonitorHook(cfg.Database().LogSQL)) - - err = handleNodeVersioning(ctx, sqlxDB, appLggr, cfg.RootDir(), cfg.Database(), cfg.WebServer().HTTPPort()) + err = handleNodeVersioning(ctx, db, appLggr, cfg.RootDir(), cfg.Database(), cfg.WebServer().HTTPPort()) if err != nil { return nil, err } - keyStore := keystore.New(db, utils.GetScryptParams(cfg), appLggr) + ds := sqlutil.WrapDataSource(db, appLggr, sqlutil.TimeoutHook(cfg.Database().DefaultQueryTimeout), sqlutil.MonitorHook(cfg.Database().LogSQL)) + + keyStore := keystore.New(ds, utils.GetScryptParams(cfg), appLggr) mailMon := mailbox.NewMonitor(cfg.AppID().String(), appLggr.Named("Mailbox")) loopRegistry := plugins.NewLoopRegistry(appLggr, cfg.Tracing()) @@ -175,7 +175,7 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G evmFactoryCfg := chainlink.EVMFactoryConfig{ CSAETHKeystore: keyStore, - ChainOpts: legacyevm.ChainOpts{AppConfig: cfg, MailMon: mailMon, SqlxDB: sqlxDB, DB: sqlxDB}, + ChainOpts: legacyevm.ChainOpts{AppConfig: cfg, MailMon: mailMon, DS: ds}, } // evm always enabled for backward compatibility // TODO BCF-2510 this needs to change in order to clear the path for EVM extraction @@ -185,8 +185,7 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G cosmosCfg := chainlink.CosmosFactoryConfig{ Keystore: keyStore.Cosmos(), TOMLConfigs: cfg.CosmosConfigs(), - DB: sqlxDB, - QConfig: cfg.Database(), + DS: ds, } initOps = append(initOps, chainlink.InitCosmos(ctx, relayerFactory, cosmosCfg)) } @@ -219,11 +218,10 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G restrictedClient := clhttp.NewRestrictedHTTPClient(cfg.Database(), appLggr) unrestrictedClient := clhttp.NewUnrestrictedHTTPClient() - externalInitiatorManager := webhook.NewExternalInitiatorManager(sqlxDB, unrestrictedClient, appLggr, cfg.Database()) + externalInitiatorManager := webhook.NewExternalInitiatorManager(ds, unrestrictedClient) return chainlink.NewApplication(chainlink.ApplicationOpts{ Config: cfg, - SqlxDB: sqlxDB, - DB: db, + DS: ds, KeyStore: keyStore, RelayerChainInteroperators: relayChainInterops, MailMon: mailMon, @@ -244,7 +242,7 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G func handleNodeVersioning(ctx context.Context, db *sqlx.DB, appLggr logger.Logger, rootDir string, cfg config.Database, healthReportPort uint16) error { var err error // Set up the versioning Configs - verORM := versioning.NewORM(db, appLggr, cfg.DefaultQueryTimeout()) + verORM := versioning.NewORM(db, appLggr) if static.Version != static.Unset { var appv, dbv *semver.Version @@ -272,7 +270,7 @@ func handleNodeVersioning(ctx context.Context, db *sqlx.DB, appLggr logger.Logge // Migrate the database if cfg.MigrateDatabase() { - if err = migrate.Migrate(ctx, db.DB, appLggr); err != nil { + if err = migrate.Migrate(ctx, db.DB); err != nil { return fmt.Errorf("initializeORM#Migrate: %w", err) } } diff --git a/core/cmd/shell_local.go b/core/cmd/shell_local.go index a61390a4886..6dbffbe404a 100644 --- a/core/cmd/shell_local.go +++ b/core/cmd/shell_local.go @@ -632,7 +632,7 @@ func (s *Shell) RebroadcastTransactions(c *cli.Context) (err error) { s.Logger.Infof("Rebroadcasting transactions from %v to %v", beginningNonce, endingNonce) - orm := txmgr.NewTxStore(app.GetSqlxDB(), lggr) + orm := txmgr.NewTxStore(app.GetDB(), lggr) txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), chain.Config().EVM().GasEstimator(), keyStore.Eth(), nil) cfg := txmgr.NewEvmTxmConfig(chain.Config().EVM()) feeCfg := txmgr.NewEvmTxmFeeConfig(chain.Config().EVM().GasEstimator()) @@ -923,7 +923,7 @@ func (s *Shell) RollbackDatabase(c *cli.Context) error { return fmt.Errorf("failed to initialize orm: %v", err) } - if err := migrate.Rollback(ctx, db.DB, s.Logger, version); err != nil { + if err := migrate.Rollback(ctx, db.DB, version); err != nil { return fmt.Errorf("migrateDB failed: %v", err) } @@ -938,7 +938,7 @@ func (s *Shell) VersionDatabase(_ *cli.Context) error { return fmt.Errorf("failed to initialize orm: %v", err) } - version, err := migrate.Current(ctx, db.DB, s.Logger) + version, err := migrate.Current(ctx, db.DB) if err != nil { return fmt.Errorf("migrateDB failed: %v", err) } @@ -955,7 +955,7 @@ func (s *Shell) StatusDatabase(_ *cli.Context) error { return fmt.Errorf("failed to initialize orm: %v", err) } - if err = migrate.Status(ctx, db.DB, s.Logger); err != nil { + if err = migrate.Status(ctx, db.DB); err != nil { return fmt.Errorf("Status failed: %v", err) } return nil @@ -1099,7 +1099,7 @@ func migrateDB(ctx context.Context, config dbConfig, lggr logger.Logger) error { return fmt.Errorf("failed to initialize orm: %v", err) } - if err = migrate.Migrate(ctx, db.DB, lggr); err != nil { + if err = migrate.Migrate(ctx, db.DB); err != nil { return fmt.Errorf("migrateDB failed: %v", err) } return db.Close() @@ -1110,10 +1110,10 @@ func downAndUpDB(ctx context.Context, cfg dbConfig, lggr logger.Logger, baseVers if err != nil { return fmt.Errorf("failed to initialize orm: %v", err) } - if err = migrate.Rollback(ctx, db.DB, lggr, null.IntFrom(baseVersionID)); err != nil { + if err = migrate.Rollback(ctx, db.DB, null.IntFrom(baseVersionID)); err != nil { return fmt.Errorf("test rollback failed: %v", err) } - if err = migrate.Migrate(ctx, db.DB, lggr); err != nil { + if err = migrate.Migrate(ctx, db.DB); err != nil { return fmt.Errorf("second migrateDB failed: %v", err) } return db.Close() diff --git a/core/cmd/shell_local_test.go b/core/cmd/shell_local_test.go index d608d3931d0..7427e6caedb 100644 --- a/core/cmd/shell_local_test.go +++ b/core/cmd/shell_local_test.go @@ -91,8 +91,7 @@ func TestShell_RunNodeWithPasswords(t *testing.T) { ChainOpts: legacyevm.ChainOpts{ AppConfig: cfg, MailMon: &mailbox.Monitor{}, - SqlxDB: db, - DB: db, + DS: db, }, } testRelayers := genTestEVMRelayers(t, opts, keyStore) @@ -196,8 +195,7 @@ func TestShell_RunNodeWithAPICredentialsFile(t *testing.T) { ChainOpts: legacyevm.ChainOpts{ AppConfig: cfg, MailMon: &mailbox.Monitor{}, - SqlxDB: db, - DB: db, + DS: db, }, } testRelayers := genTestEVMRelayers(t, opts, keyStore) @@ -299,7 +297,7 @@ func TestShell_RebroadcastTransactions_Txm(t *testing.T) { lggr := logger.TestLogger(t) app := mocks.NewApplication(t) - app.On("GetSqlxDB").Return(sqlxDB) + app.On("GetDB").Return(sqlxDB) app.On("GetKeyStore").Return(keyStore) app.On("ID").Maybe().Return(uuid.New()) app.On("GetConfig").Return(config) @@ -381,7 +379,7 @@ func TestShell_RebroadcastTransactions_OutsideRange_Txm(t *testing.T) { lggr := logger.TestLogger(t) app := mocks.NewApplication(t) - app.On("GetSqlxDB").Return(sqlxDB) + app.On("GetDB").Return(sqlxDB) app.On("GetKeyStore").Return(keyStore) app.On("ID").Maybe().Return(uuid.New()) app.On("GetConfig").Return(config) @@ -460,7 +458,7 @@ func TestShell_RebroadcastTransactions_AddressCheck(t *testing.T) { lggr := logger.TestLogger(t) app := mocks.NewApplication(t) - app.On("GetSqlxDB").Maybe().Return(sqlxDB) + app.On("GetDB").Maybe().Return(sqlxDB) app.On("GetKeyStore").Return(keyStore) app.On("ID").Maybe().Return(uuid.New()) ethClient := evmtest.NewEthClientMockWithDefaultChain(t) diff --git a/core/cmd/shell_remote_test.go b/core/cmd/shell_remote_test.go index a8c054cd9be..cdbe12d66b4 100644 --- a/core/cmd/shell_remote_test.go +++ b/core/cmd/shell_remote_test.go @@ -151,6 +151,7 @@ func TestShell_CreateExternalInitiator(t *testing.T) { for _, tt := range tests { test := tt t.Run(test.name, func(t *testing.T) { + ctx := testutils.Context(t) app := startNewApplicationV2(t, func(c *chainlink.Config, s *chainlink.Secrets) { c.JobPipeline.ExternalInitiatorsEnabled = ptr(true) }) @@ -165,7 +166,7 @@ func TestShell_CreateExternalInitiator(t *testing.T) { require.NoError(t, err) var exi bridges.ExternalInitiator - err = app.GetSqlxDB().Get(&exi, `SELECT * FROM external_initiators WHERE name = $1`, test.args[0]) + err = app.GetDB().GetContext(ctx, &exi, `SELECT * FROM external_initiators WHERE name = $1`, test.args[0]) require.NoError(t, err) if len(test.args) > 1 { @@ -195,7 +196,7 @@ func TestShell_CreateExternalInitiator_Errors(t *testing.T) { }) client, _ := app.NewShellAndRenderer() - initialExis := len(cltest.AllExternalInitiators(t, app.GetSqlxDB())) + initialExis := len(cltest.AllExternalInitiators(t, app.GetDB())) set := flag.NewFlagSet("create", 0) flagSetApplyFromAction(client.CreateExternalInitiator, set, "") @@ -206,7 +207,7 @@ func TestShell_CreateExternalInitiator_Errors(t *testing.T) { err := client.CreateExternalInitiator(c) assert.Error(t, err) - exis := cltest.AllExternalInitiators(t, app.GetSqlxDB()) + exis := cltest.AllExternalInitiators(t, app.GetDB()) assert.Len(t, exis, initialExis) }) } @@ -580,8 +581,8 @@ func TestShell_RunOCRJob_HappyPath(t *testing.T) { require.NoError(t, app.KeyStore.OCR().Add(ctx, cltest.DefaultOCRKey)) - _, bridge := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{}) - _, bridge2 := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{}) + _, bridge := cltest.MustCreateBridge(t, app.GetDB(), cltest.BridgeOpts{}) + _, bridge2 := cltest.MustCreateBridge(t, app.GetDB(), cltest.BridgeOpts{}) var jb job.Job ocrspec := testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{DS1BridgeName: bridge.Name.String(), DS2BridgeName: bridge2.Name.String()}) @@ -669,7 +670,7 @@ func TestShell_AutoLogin(t *testing.T) { require.NoError(t, err) // Expire the session and then try again - pgtest.MustExec(t, app.GetSqlxDB(), "delete from sessions where email = $1", user.Email) + pgtest.MustExec(t, app.GetDB(), "delete from sessions where email = $1", user.Email) err = client.ListJobs(cli.NewContext(nil, fs, nil)) require.NoError(t, err) } diff --git a/core/internal/cltest/cltest.go b/core/internal/cltest/cltest.go index 8123439dafb..dc7079e44d9 100644 --- a/core/internal/cltest/cltest.go +++ b/core/internal/cltest/cltest.go @@ -181,11 +181,11 @@ type JobPipelineConfig interface { MaxSuccessfulRuns() uint64 } -func NewJobPipelineV2(t testing.TB, cfg pipeline.BridgeConfig, jpcfg JobPipelineConfig, dbCfg pg.QConfig, legacyChains legacyevm.LegacyChainContainer, db *sqlx.DB, keyStore keystore.Master, restrictedHTTPClient, unrestrictedHTTPClient *http.Client) JobPipelineV2TestHelper { +func NewJobPipelineV2(t testing.TB, cfg pipeline.BridgeConfig, jpcfg JobPipelineConfig, legacyChains legacyevm.LegacyChainContainer, db *sqlx.DB, keyStore keystore.Master, restrictedHTTPClient, unrestrictedHTTPClient *http.Client) JobPipelineV2TestHelper { lggr := logger.TestLogger(t) prm := pipeline.NewORM(db, lggr, jpcfg.MaxSuccessfulRuns()) btORM := bridges.NewORM(db) - jrm := job.NewORM(db, prm, btORM, keyStore, lggr, dbCfg) + jrm := job.NewORM(db, prm, btORM, keyStore, lggr) pr := pipeline.NewRunner(prm, btORM, jpcfg, cfg, legacyChains, keyStore.Eth(), keyStore.VRF(), lggr, restrictedHTTPClient, unrestrictedHTTPClient) return JobPipelineV2TestHelper{ prm, @@ -323,6 +323,8 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn require.NoError(t, err) t.Cleanup(func() { assert.NoError(t, db.Close()) }) + ds := sqlutil.WrapDataSource(db, lggr, sqlutil.TimeoutHook(cfg.Database().DefaultQueryTimeout)) + var ethClient evmclient.Client var externalInitiatorManager webhook.ExternalInitiatorManager externalInitiatorManager = &webhook.NullExternalInitiatorManager{} @@ -337,13 +339,13 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn default: switch flag { case UseRealExternalInitiatorManager: - externalInitiatorManager = webhook.NewExternalInitiatorManager(db, clhttptest.NewTestLocalOnlyHTTPClient(), lggr, cfg.Database()) + externalInitiatorManager = webhook.NewExternalInitiatorManager(ds, clhttptest.NewTestLocalOnlyHTTPClient()) } } } - keyStore := keystore.NewInMemory(db, utils.FastScryptParams, lggr) + keyStore := keystore.NewInMemory(ds, utils.FastScryptParams, lggr) mailMon := mailbox.NewMonitor(cfg.AppID().String(), lggr.Named("Mailbox")) loopRegistry := plugins.NewLoopRegistry(lggr, nil) @@ -365,8 +367,7 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn ChainOpts: legacyevm.ChainOpts{ AppConfig: cfg, MailMon: mailMon, - SqlxDB: db, - DB: db, + DS: ds, }, CSAETHKeystore: keyStore, } @@ -392,8 +393,7 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn cosmosCfg := chainlink.CosmosFactoryConfig{ Keystore: keyStore.Cosmos(), TOMLConfigs: cfg.CosmosConfigs(), - DB: db, - QConfig: cfg.Database(), + DS: ds, } initOps = append(initOps, chainlink.InitCosmos(testCtx, relayerFactory, cosmosCfg)) } @@ -420,8 +420,7 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn appInstance, err := chainlink.NewApplication(chainlink.ApplicationOpts{ Config: cfg, MailMon: mailMon, - SqlxDB: db, - DB: db, + DS: ds, KeyStore: keyStore, RelayerChainInteroperators: relayChainInterops, Logger: lggr, @@ -569,9 +568,10 @@ func (ta *TestApplication) Stop() error { } func (ta *TestApplication) MustSeedNewSession(email string) (id string) { + ctx := testutils.Context(ta.t) session := NewSession() ta.Logger.Infof("TestApplication creating session (id: %s, email: %s, last used: %s)", session.ID, email, session.LastUsed.String()) - err := ta.GetSqlxDB().Get(&id, `INSERT INTO sessions (id, email, last_used, created_at) VALUES ($1, $2, $3, NOW()) RETURNING id`, session.ID, email, session.LastUsed) + err := ta.GetDB().GetContext(ctx, &id, `INSERT INTO sessions (id, email, last_used, created_at) VALUES ($1, $2, $3, NOW()) RETURNING id`, session.ID, email, session.LastUsed) require.NoError(ta.t, err) return id } @@ -903,13 +903,14 @@ const ( // WaitForSpecErrorV2 polls until the passed in jobID has count number // of job spec errors. -func WaitForSpecErrorV2(t *testing.T, db *sqlx.DB, jobID int32, count int) []job.SpecError { +func WaitForSpecErrorV2(t *testing.T, ds sqlutil.DataSource, jobID int32, count int) []job.SpecError { t.Helper() + ctx := testutils.Context(t) g := gomega.NewWithT(t) var jse []job.SpecError g.Eventually(func() []job.SpecError { - err := db.Select(&jse, `SELECT * FROM job_spec_errors WHERE job_id = $1`, jobID) + err := ds.SelectContext(ctx, &jse, `SELECT * FROM job_spec_errors WHERE job_id = $1`, jobID) assert.NoError(t, err) return jse }, testutils.WaitTimeout(t), DBPollingInterval).Should(gomega.HaveLen(count)) @@ -930,7 +931,7 @@ func WaitForPipeline(t testing.TB, nodeID int, jobID int32, expectedPipelineRuns var pr []pipeline.Run gomega.NewWithT(t).Eventually(func() bool { - prs, _, err := jo.PipelineRuns(&jobID, 0, 1000) + prs, _, err := jo.PipelineRuns(testutils.Context(t), &jobID, 0, 1000) require.NoError(t, err) var matched []pipeline.Run @@ -964,13 +965,14 @@ func WaitForPipeline(t testing.TB, nodeID int, jobID int32, expectedPipelineRuns } // AssertPipelineRunsStays asserts that the number of pipeline runs for a particular job remains at the provided values -func AssertPipelineRunsStays(t testing.TB, pipelineSpecID int32, db *sqlx.DB, want int) []pipeline.Run { +func AssertPipelineRunsStays(t testing.TB, pipelineSpecID int32, db sqlutil.DataSource, want int) []pipeline.Run { t.Helper() + ctx := testutils.Context(t) g := gomega.NewWithT(t) var prs []pipeline.Run g.Consistently(func() []pipeline.Run { - err := db.Select(&prs, `SELECT * FROM pipeline_runs WHERE pipeline_spec_id = $1`, pipelineSpecID) + err := db.SelectContext(ctx, &prs, `SELECT * FROM pipeline_runs WHERE pipeline_spec_id = $1`, pipelineSpecID) assert.NoError(t, err) return prs }, AssertNoActionTimeout, DBPollingInterval).Should(gomega.HaveLen(want)) @@ -1161,11 +1163,12 @@ func NewSession(optionalSessionID ...string) clsessions.Session { return session } -func AllExternalInitiators(t testing.TB, db *sqlx.DB) []bridges.ExternalInitiator { +func AllExternalInitiators(t testing.TB, ds sqlutil.DataSource) []bridges.ExternalInitiator { t.Helper() + ctx := testutils.Context(t) var all []bridges.ExternalInitiator - err := db.Select(&all, `SELECT * FROM external_initiators`) + err := ds.SelectContext(ctx, &all, `SELECT * FROM external_initiators`) require.NoError(t, err) return all } @@ -1518,35 +1521,38 @@ func AssertCount(t *testing.T, ds sqlutil.DataSource, tableName string, expected testutils.AssertCount(t, ds, tableName, expected) } -func WaitForCount(t *testing.T, db *sqlx.DB, tableName string, want int64) { +func WaitForCount(t *testing.T, ds sqlutil.DataSource, tableName string, want int64) { t.Helper() + ctx := testutils.Context(t) g := gomega.NewWithT(t) var count int64 var err error g.Eventually(func() int64 { - err = db.Get(&count, fmt.Sprintf(`SELECT count(*) FROM %s;`, tableName)) + err = ds.GetContext(ctx, &count, fmt.Sprintf(`SELECT count(*) FROM %s;`, tableName)) assert.NoError(t, err) return count }, testutils.WaitTimeout(t), DBPollingInterval).Should(gomega.Equal(want)) } -func AssertCountStays(t testing.TB, db *sqlx.DB, tableName string, want int64) { +func AssertCountStays(t testing.TB, ds sqlutil.DataSource, tableName string, want int64) { t.Helper() + ctx := testutils.Context(t) g := gomega.NewWithT(t) var count int64 var err error g.Consistently(func() int64 { - err = db.Get(&count, fmt.Sprintf(`SELECT count(*) FROM %s`, tableName)) + err = ds.GetContext(ctx, &count, fmt.Sprintf(`SELECT count(*) FROM %s`, tableName)) assert.NoError(t, err) return count }, AssertNoActionTimeout, DBPollingInterval).Should(gomega.Equal(want)) } -func AssertRecordEventually(t *testing.T, db *sqlx.DB, model interface{}, stmt string, check func() bool) { +func AssertRecordEventually(t *testing.T, ds sqlutil.DataSource, model interface{}, stmt string, check func() bool) { t.Helper() + ctx := testutils.Context(t) g := gomega.NewWithT(t) g.Eventually(func() bool { - err := db.Get(model, stmt) + err := ds.GetContext(ctx, model, stmt) require.NoError(t, err, "unable to find record in DB") return check() }, testutils.WaitTimeout(t), DBPollingInterval).Should(gomega.BeTrue()) diff --git a/core/internal/cltest/factories.go b/core/internal/cltest/factories.go index 43cf902ca8a..cd2fa9d9f63 100644 --- a/core/internal/cltest/factories.go +++ b/core/internal/cltest/factories.go @@ -98,9 +98,9 @@ func NewBridgeType(t testing.TB, opts BridgeOpts) (*bridges.BridgeTypeAuthentica // MustCreateBridge creates a bridge // Be careful not to specify a name here unless you ABSOLUTELY need to // This is because name is a unique index and identical names used across transactional tests will lock/deadlock -func MustCreateBridge(t testing.TB, db *sqlx.DB, opts BridgeOpts) (bta *bridges.BridgeTypeAuthentication, bt *bridges.BridgeType) { +func MustCreateBridge(t testing.TB, ds sqlutil.DataSource, opts BridgeOpts) (bta *bridges.BridgeTypeAuthentication, bt *bridges.BridgeType) { bta, bt = NewBridgeType(t, opts) - orm := bridges.NewORM(db) + orm := bridges.NewORM(ds) err := orm.CreateBridgeType(testutils.Context(t), bt) require.NoError(t, err) return bta, bt @@ -317,9 +317,9 @@ func MustGenerateRandomKeyState(_ testing.TB) ethkey.State { return ethkey.State{Address: NewEIP55Address()} } -func MustInsertHead(t *testing.T, db sqlutil.DataSource, number int64) evmtypes.Head { +func MustInsertHead(t *testing.T, ds sqlutil.DataSource, number int64) evmtypes.Head { h := evmtypes.NewHead(big.NewInt(number), evmutils.NewHash(), evmutils.NewHash(), 0, ubig.New(&FixtureChainID)) - horm := headtracker.NewORM(FixtureChainID, db) + horm := headtracker.NewORM(FixtureChainID, ds) err := horm.IdempotentInsertHead(testutils.Context(t), &h) require.NoError(t, err) @@ -347,8 +347,8 @@ func MustInsertV2JobSpec(t *testing.T, db *sqlx.DB, transmitterAddress common.Ad PipelineSpecID: pipelineSpec.ID, } - jorm := job.NewORM(db, nil, nil, nil, logger.TestLogger(t), configtest.NewTestGeneralConfig(t).Database()) - err = jorm.InsertJob(&jb) + jorm := job.NewORM(db, nil, nil, nil, logger.TestLogger(t)) + err = jorm.InsertJob(testutils.Context(t), &jb) require.NoError(t, err) return jb } @@ -404,8 +404,8 @@ func MustInsertKeeperJob(t *testing.T, db *sqlx.DB, korm *keeper.ORM, from evmty tlg := logger.TestLogger(t) prm := pipeline.NewORM(db, tlg, cfg.JobPipeline().MaxSuccessfulRuns()) btORM := bridges.NewORM(db) - jrm := job.NewORM(db, prm, btORM, nil, tlg, cfg.Database()) - err = jrm.InsertJob(&jb) + jrm := job.NewORM(db, prm, btORM, nil, tlg) + err = jrm.InsertJob(testutils.Context(t), &jb) require.NoError(t, err) jb.PipelineSpec.JobID = jb.ID return jb diff --git a/core/internal/cltest/job_factories.go b/core/internal/cltest/job_factories.go index d78440838b2..6ba13f97726 100644 --- a/core/internal/cltest/job_factories.go +++ b/core/internal/cltest/job_factories.go @@ -7,8 +7,7 @@ import ( "github.com/google/uuid" "github.com/stretchr/testify/require" - "github.com/jmoiron/sqlx" - + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" @@ -43,30 +42,30 @@ func MinimalOCRNonBootstrapSpec(contractAddress, transmitterAddress types.EIP55A return fmt.Sprintf(minimalOCRNonBootstrapTemplate, contractAddress, peerID, transmitterAddress.Hex(), keyBundleID) } -func MustInsertWebhookSpec(t *testing.T, db *sqlx.DB) (job.Job, job.WebhookSpec) { +func MustInsertWebhookSpec(t *testing.T, ds sqlutil.DataSource) (job.Job, job.WebhookSpec) { ctx := testutils.Context(t) - jobORM, pipelineORM := getORMs(t, db) + jobORM, pipelineORM := getORMs(t, ds) webhookSpec := job.WebhookSpec{} - require.NoError(t, jobORM.InsertWebhookSpec(&webhookSpec)) + require.NoError(t, jobORM.InsertWebhookSpec(ctx, &webhookSpec)) pSpec := pipeline.Pipeline{} - pipelineSpecID, err := pipelineORM.CreateSpec(ctx, nil, pSpec, 0) + pipelineSpecID, err := pipelineORM.CreateSpec(ctx, pSpec, 0) require.NoError(t, err) createdJob := job.Job{WebhookSpecID: &webhookSpec.ID, WebhookSpec: &webhookSpec, SchemaVersion: 1, Type: "webhook", ExternalJobID: uuid.New(), PipelineSpecID: pipelineSpecID} - require.NoError(t, jobORM.InsertJob(&createdJob)) + require.NoError(t, jobORM.InsertJob(ctx, &createdJob)) return createdJob, webhookSpec } -func getORMs(t *testing.T, db *sqlx.DB) (jobORM job.ORM, pipelineORM pipeline.ORM) { +func getORMs(t *testing.T, ds sqlutil.DataSource) (jobORM job.ORM, pipelineORM pipeline.ORM) { config := configtest.NewTestGeneralConfig(t) - keyStore := NewKeyStore(t, db) + keyStore := NewKeyStore(t, ds) lggr := logger.TestLogger(t) - pipelineORM = pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()) - bridgeORM := bridges.NewORM(db) - jobORM = job.NewORM(db, pipelineORM, bridgeORM, keyStore, lggr, config.Database()) + pipelineORM = pipeline.NewORM(ds, lggr, config.JobPipeline().MaxSuccessfulRuns()) + bridgeORM := bridges.NewORM(ds) + jobORM = job.NewORM(ds, pipelineORM, bridgeORM, keyStore, lggr) t.Cleanup(func() { jobORM.Close() }) return } diff --git a/core/internal/features/features_test.go b/core/internal/features/features_test.go index 75ff98d05be..26e7d5eae56 100644 --- a/core/internal/features/features_test.go +++ b/core/internal/features/features_test.go @@ -82,6 +82,7 @@ var oneETH = assets.Eth(*big.NewInt(1000000000000000000)) func TestIntegration_ExternalInitiatorV2(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) ethClient := cltest.NewEthMocksWithStartupAssertions(t) cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { @@ -175,7 +176,7 @@ func TestIntegration_ExternalInitiatorV2(t *testing.T) { require.NoError(t, err) })) u, _ := url.Parse(bridgeServer.URL) - err := app.BridgeORM().CreateBridgeType(testutils.Context(t), &bridges.BridgeType{ + err := app.BridgeORM().CreateBridgeType(ctx, &bridges.BridgeType{ Name: bridges.BridgeName("substrate-adapter1"), URL: models.WebURL(*u), }) @@ -205,7 +206,7 @@ observationSource = """ """ `, jobUUID, eiName, cltest.MustJSONMarshal(t, eiSpec)) - _, err := webhook.ValidatedWebhookSpec(tomlSpec, app.GetExternalInitiatorManager()) + _, err := webhook.ValidatedWebhookSpec(ctx, tomlSpec, app.GetExternalInitiatorManager()) require.NoError(t, err) job := cltest.CreateJobViaWeb(t, app, []byte(cltest.MustJSONMarshal(t, web.CreateJobRequest{TOML: tomlSpec}))) jobID = job.ID @@ -227,7 +228,7 @@ observationSource = """ defer cleanup() cltest.AssertServerResponse(t, resp, 401) - cltest.AssertCountStays(t, app.GetSqlxDB(), "pipeline_runs", 0) + cltest.AssertCountStays(t, app.GetDB(), "pipeline_runs", 0) }) t.Run("calling webhook_spec with matching external_initiator_id works", func(t *testing.T) { @@ -236,9 +237,9 @@ observationSource = """ _ = cltest.CreateJobRunViaExternalInitiatorV2(t, app, jobUUID, *eia, cltest.MustJSONMarshal(t, eiRequest)) - pipelineORM := pipeline.NewORM(app.GetSqlxDB(), logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns()) - bridgeORM := bridges.NewORM(app.GetSqlxDB()) - jobORM := job.NewORM(app.GetSqlxDB(), pipelineORM, bridgeORM, app.KeyStore, logger.TestLogger(t), cfg.Database()) + pipelineORM := pipeline.NewORM(app.GetDB(), logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns()) + bridgeORM := bridges.NewORM(app.GetDB()) + jobORM := job.NewORM(app.GetDB(), pipelineORM, bridgeORM, app.KeyStore, logger.TestLogger(t)) runs := cltest.WaitForPipelineComplete(t, 0, jobID, 1, 2, jobORM, 5*time.Second, 300*time.Millisecond) require.Len(t, runs, 1) @@ -992,8 +993,9 @@ observationSource = """ return answer.String() }, testutils.WaitTimeout(t), cltest.DBPollingInterval).Should(gomega.Equal("20")) + ctx := testutils.Context(t) for _, app := range apps { - jobs, _, err := app.JobORM().FindJobs(0, 1000) + jobs, _, err := app.JobORM().FindJobs(ctx, 0, 1000) require.NoError(t, err) // No spec errors for _, j := range jobs { @@ -1220,8 +1222,9 @@ observationSource = """ return answer.String() }, testutils.WaitTimeout(t), cltest.DBPollingInterval).Should(gomega.Equal("20")) + ctx := testutils.Context(t) for _, app := range apps { - jobs, _, err := app.JobORM().FindJobs(0, 1000) + jobs, _, err := app.JobORM().FindJobs(ctx, 0, 1000) require.NoError(t, err) // No spec errors for _, j := range jobs { diff --git a/core/internal/features/ocr2/features_ocr2_test.go b/core/internal/features/ocr2/features_ocr2_test.go index 07e0fc21d9a..fab9d34b4b1 100644 --- a/core/internal/features/ocr2/features_ocr2_test.go +++ b/core/internal/features/ocr2/features_ocr2_test.go @@ -519,6 +519,7 @@ updateInterval = "1m" } }() + ctx := testutils.Context(t) for trial := 0; trial < 2; trial++ { var retVal int @@ -537,7 +538,7 @@ updateInterval = "1m" wg.Add(1) go func() { defer wg.Done() - completedRuns, err2 := apps[ic].JobORM().FindPipelineRunIDsByJobID(jids[ic], 0, 1000) + completedRuns, err2 := apps[ic].JobORM().FindPipelineRunIDsByJobID(ctx, jids[ic], 0, 1000) require.NoError(t, err2) // Want at least 2 runs so we see all the metadata. pr := cltest.WaitForPipelineComplete(t, ic, jids[ic], len(completedRuns)+2, 7, apps[ic].JobORM(), 2*time.Minute, 5*time.Second) @@ -558,7 +559,7 @@ updateInterval = "1m" }, 1*time.Minute, 200*time.Millisecond).Should(gomega.Equal(fmt.Sprintf("%d", 2*retVal))) for _, app := range apps { - jobs, _, err2 := app.JobORM().FindJobs(0, 1000) + jobs, _, err2 := app.JobORM().FindJobs(ctx, 0, 1000) require.NoError(t, err2) // No spec errors for _, j := range jobs { @@ -758,6 +759,7 @@ chainID = 1337 expectedMeta := map[string]struct{}{ "0": {}, "10": {}, "20": {}, "30": {}, } + ctx := testutils.Context(t) for i := 0; i < 4; i++ { s := i require.NoError(t, apps[i].Start(testutils.Context(t))) @@ -790,7 +792,7 @@ chainID = 1337 servers[s].Close() }) u, _ := url.Parse(servers[i].URL) - require.NoError(t, apps[i].BridgeORM().CreateBridgeType(testutils.Context(t), &bridges.BridgeType{ + require.NoError(t, apps[i].BridgeORM().CreateBridgeType(ctx, &bridges.BridgeType{ Name: bridges.BridgeName(fmt.Sprintf("bridge%d", i)), URL: models.WebURL(*u), })) @@ -882,7 +884,7 @@ updateInterval = "1m" }, 1*time.Minute, 200*time.Millisecond).Should(gomega.Equal("20")) for _, app := range apps { - jobs, _, err := app.JobORM().FindJobs(0, 1000) + jobs, _, err := app.JobORM().FindJobs(ctx, 0, 1000) require.NoError(t, err) // No spec errors for _, j := range jobs { diff --git a/core/internal/mocks/application.go b/core/internal/mocks/application.go index 2438eb302c0..c83b37a0e5d 100644 --- a/core/internal/mocks/application.go +++ b/core/internal/mocks/application.go @@ -35,8 +35,6 @@ import ( sqlutil "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" - sqlx "github.com/jmoiron/sqlx" - txmgr "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" types "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" @@ -389,26 +387,6 @@ func (_m *Application) GetRelayers() chainlink.RelayerChainInteroperators { return r0 } -// GetSqlxDB provides a mock function with given fields: -func (_m *Application) GetSqlxDB() *sqlx.DB { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for GetSqlxDB") - } - - var r0 *sqlx.DB - if rf, ok := ret.Get(0).(func() *sqlx.DB); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*sqlx.DB) - } - } - - return r0 -} - // GetWebAuthnConfiguration provides a mock function with given fields: func (_m *Application) GetWebAuthnConfiguration() sessions.WebAuthnConfiguration { ret := _m.Called() diff --git a/core/internal/testutils/evmtest/evmtest.go b/core/internal/testutils/evmtest/evmtest.go index eedc6275928..276dea2ac5d 100644 --- a/core/internal/testutils/evmtest/evmtest.go +++ b/core/internal/testutils/evmtest/evmtest.go @@ -9,13 +9,13 @@ import ( "testing" "github.com/ethereum/go-ethereum" - "github.com/jmoiron/sqlx" "github.com/pelletier/go-toml/v2" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "gopkg.in/guregu/null.v4" "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox/mailboxtest" @@ -62,7 +62,7 @@ type TestChainOpts struct { LogPoller logpoller.LogPoller GeneralConfig legacyevm.AppConfig HeadTracker httypes.HeadTracker - DB *sqlx.DB + DB sqlutil.DataSource TxManager txmgr.TxManager KeyStore keystore.Eth MailMon *mailbox.Monitor @@ -88,8 +88,7 @@ func NewChainRelayExtOpts(t testing.TB, testopts TestChainOpts) legacyevm.ChainR AppConfig: testopts.GeneralConfig, MailMon: testopts.MailMon, GasEstimator: testopts.GasEstimator, - SqlxDB: testopts.DB, - DB: testopts.DB, + DS: testopts.DB, }, } opts.GenEthClient = func(*big.Int) evmclient.Client { diff --git a/core/internal/testutils/pgtest/pgtest.go b/core/internal/testutils/pgtest/pgtest.go index 686483f2d41..8464604b667 100644 --- a/core/internal/testutils/pgtest/pgtest.go +++ b/core/internal/testutils/pgtest/pgtest.go @@ -1,7 +1,6 @@ package pgtest import ( - "database/sql" "testing" "github.com/google/uuid" @@ -10,25 +9,12 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/store/dialects" ) -func NewQConfig(logSQL bool) pg.QConfig { - return pg.NewQConfig(logSQL) -} - -func NewSqlDB(t *testing.T) *sql.DB { - testutils.SkipShortDB(t) - db, err := sql.Open(string(dialects.TransactionWrappedPostgres), uuid.New().String()) - require.NoError(t, err) - t.Cleanup(func() { assert.NoError(t, db.Close()) }) - - return db -} - func NewSqlxDB(t testing.TB) *sqlx.DB { testutils.SkipShortDB(t) db, err := sqlx.Open(string(dialects.TransactionWrappedPostgres), uuid.New().String()) @@ -39,12 +25,9 @@ func NewSqlxDB(t testing.TB) *sqlx.DB { return db } -func MustExec(t *testing.T, db *sqlx.DB, stmt string, args ...interface{}) { - require.NoError(t, utils.JustError(db.Exec(stmt, args...))) -} - -func MustSelect(t *testing.T, db *sqlx.DB, dest interface{}, stmt string, args ...interface{}) { - require.NoError(t, db.Select(dest, stmt, args...)) +func MustExec(t *testing.T, ds sqlutil.DataSource, stmt string, args ...interface{}) { + ctx := testutils.Context(t) + require.NoError(t, utils.JustError(ds.ExecContext(ctx, stmt, args...))) } func MustCount(t *testing.T, db *sqlx.DB, stmt string, args ...interface{}) (cnt int) { diff --git a/core/internal/testutils/testutils.go b/core/internal/testutils/testutils.go index ba7e697fb62..f4867eda69a 100644 --- a/core/internal/testutils/testutils.go +++ b/core/internal/testutils/testutils.go @@ -420,8 +420,9 @@ func SkipShortDB(tb testing.TB) { func AssertCount(t *testing.T, ds sqlutil.DataSource, tableName string, expected int64) { t.Helper() + ctx := Context(t) var count int64 - err := ds.GetContext(Context(t), &count, fmt.Sprintf(`SELECT count(*) FROM %s;`, tableName)) + err := ds.GetContext(ctx, &count, fmt.Sprintf(`SELECT count(*) FROM %s;`, tableName)) require.NoError(t, err) require.Equal(t, expected, count) } diff --git a/core/scripts/gateway/run_gateway.go b/core/scripts/gateway/run_gateway.go index 5dbcd02bf56..2daca5190a5 100644 --- a/core/scripts/gateway/run_gateway.go +++ b/core/scripts/gateway/run_gateway.go @@ -48,7 +48,7 @@ func main() { lggr, _ := logger.NewLogger() - handlerFactory := gateway.NewHandlerFactory(nil, nil, nil, lggr) + handlerFactory := gateway.NewHandlerFactory(nil, nil, lggr) gw, err := gateway.NewGatewayFromConfig(&cfg, handlerFactory, lggr) if err != nil { fmt.Println("error creating Gateway object:", err) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 9788679dd98..08050c32167 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -256,7 +256,7 @@ require ( github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.10 // indirect - github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 // indirect + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 45ef18e49ca..48a66de1ec3 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1187,8 +1187,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfs github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 h1:54hM3/SrOM166it2K35hGb5K7gQ49/Op0aHp9WkqpqU= github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 h1:MvaNzuaQh1vX4CAYLM8qFd99cf0ZF1JNwtDZtLU7WvU= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee h1:eFuBKyEbL2b+eyfgV/Eu9+8HuCEev+IcBi+K9l1dG7g= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540/go.mod h1:sjAmX8K2kbQhvDarZE1ZZgDgmHJ50s0BBc/66vKY2ek= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab h1:Ct1oUlyn03HDUVdFHJqtRGRUujMqdoMzvf/Cjhe30Ag= diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 88a6fadf345..0ac6555aecc 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -16,8 +16,6 @@ import ( "go.uber.org/multierr" "go.uber.org/zap/zapcore" - "github.com/jmoiron/sqlx" - "github.com/smartcontractkit/chainlink-common/pkg/loop" commonservices "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" @@ -53,7 +51,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" externalp2p "github.com/smartcontractkit/chainlink/v2/core/services/p2p/wrapper" "github.com/smartcontractkit/chainlink/v2/core/services/periodicbackup" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/services/promreporter" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" @@ -78,7 +75,6 @@ type Application interface { GetLogger() logger.SugaredLogger GetAuditLogger() audit.AuditLogger GetHealthChecker() services.Checker - GetSqlxDB() *sqlx.DB // Deprecated: use GetDB GetDB() sqlutil.DataSource GetConfig() GeneralConfig SetLogLevel(lvl zapcore.Level) error @@ -146,8 +142,7 @@ type ChainlinkApplication struct { logger logger.SugaredLogger AuditLogger audit.AuditLogger closeLogger func() error - sqlxDB *sqlx.DB // Deprecated: use db instead - db sqlutil.DataSource + ds sqlutil.DataSource secretGenerator SecretGenerator profiler *pyroscope.Profiler loopRegistry *plugins.LoopRegistry @@ -161,8 +156,7 @@ type ApplicationOpts struct { Config GeneralConfig Logger logger.Logger MailMon *mailbox.Monitor - SqlxDB *sqlx.DB // Deprecated: use DB instead - DB sqlutil.DataSource + DS sqlutil.DataSource KeyStore keystore.Master RelayerChainInteroperators *CoreRelayerChainInteroperators AuditLogger audit.AuditLogger @@ -185,7 +179,6 @@ type ApplicationOpts struct { func NewApplication(opts ApplicationOpts) (Application, error) { var srvcs []services.ServiceCtx auditLogger := opts.AuditLogger - sqlxDB := opts.SqlxDB cfg := opts.Config relayerChainInterops := opts.RelayerChainInteroperators mailMon := opts.MailMon @@ -277,12 +270,12 @@ func NewApplication(opts ApplicationOpts) (Application, error) { srvcs = append(srvcs, mailMon) srvcs = append(srvcs, relayerChainInterops.Services()...) - promReporter := promreporter.NewPromReporter(sqlxDB.DB, legacyEVMChains, globalLogger) + promReporter := promreporter.NewPromReporter(opts.DS, legacyEVMChains, globalLogger) srvcs = append(srvcs, promReporter) // Initialize Local Users ORM and Authentication Provider specified in config // BasicAdminUsersORM is initialized and required regardless of separate Authentication Provider - localAdminUsersORM := localauth.NewORM(opts.DB, cfg.WebServer().SessionTimeout().Duration(), globalLogger, auditLogger) + localAdminUsersORM := localauth.NewORM(opts.DS, cfg.WebServer().SessionTimeout().Duration(), globalLogger, auditLogger) // Initialize Sessions ORM based on environment configured authenticator // localDB auth or remote LDAP auth @@ -294,26 +287,26 @@ func NewApplication(opts ApplicationOpts) (Application, error) { case sessions.LDAPAuth: var err error authenticationProvider, err = ldapauth.NewLDAPAuthenticator( - opts.DB, cfg.WebServer().LDAP(), cfg.Insecure().DevWebServer(), globalLogger, auditLogger, + opts.DS, cfg.WebServer().LDAP(), cfg.Insecure().DevWebServer(), globalLogger, auditLogger, ) if err != nil { return nil, errors.Wrap(err, "NewApplication: failed to initialize LDAP Authentication module") } - sessionReaper = ldapauth.NewLDAPServerStateSync(sqlxDB, cfg.Database(), cfg.WebServer().LDAP(), globalLogger) + sessionReaper = ldapauth.NewLDAPServerStateSync(opts.DS, cfg.WebServer().LDAP(), globalLogger) case sessions.LocalAuth: - authenticationProvider = localauth.NewORM(opts.DB, cfg.WebServer().SessionTimeout().Duration(), globalLogger, auditLogger) - sessionReaper = localauth.NewSessionReaper(sqlxDB.DB, cfg.WebServer(), globalLogger) + authenticationProvider = localauth.NewORM(opts.DS, cfg.WebServer().SessionTimeout().Duration(), globalLogger, auditLogger) + sessionReaper = localauth.NewSessionReaper(opts.DS, cfg.WebServer(), globalLogger) default: return nil, errors.Errorf("NewApplication: Unexpected 'AuthenticationMethod': %s supported values: %s, %s", authMethod, sessions.LocalAuth, sessions.LDAPAuth) } var ( - pipelineORM = pipeline.NewORM(sqlxDB, globalLogger, cfg.JobPipeline().MaxSuccessfulRuns()) - bridgeORM = bridges.NewORM(sqlxDB) - mercuryORM = mercury.NewORM(opts.DB) + pipelineORM = pipeline.NewORM(opts.DS, globalLogger, cfg.JobPipeline().MaxSuccessfulRuns()) + bridgeORM = bridges.NewORM(opts.DS) + mercuryORM = mercury.NewORM(opts.DS) pipelineRunner = pipeline.NewRunner(pipelineORM, bridgeORM, cfg.JobPipeline(), cfg.WebServer(), legacyEVMChains, keyStore.Eth(), keyStore.VRF(), globalLogger, restrictedHTTPClient, unrestrictedHTTPClient) - jobORM = job.NewORM(sqlxDB, pipelineORM, bridgeORM, keyStore, globalLogger, cfg.Database()) - txmORM = txmgr.NewTxStore(opts.DB, globalLogger) + jobORM = job.NewORM(opts.DS, pipelineORM, bridgeORM, keyStore, globalLogger) + txmORM = txmgr.NewTxStore(opts.DS, globalLogger) streamRegistry = streams.NewRegistry(globalLogger, pipelineRunner) ) @@ -334,14 +327,14 @@ func NewApplication(opts ApplicationOpts) (Application, error) { mailMon), job.Keeper: keeper.NewDelegate( cfg, - sqlxDB, + opts.DS, jobORM, pipelineRunner, globalLogger, legacyEVMChains, mailMon), job.VRF: vrf.NewDelegate( - sqlxDB, + opts.DS, keyStore, pipelineRunner, pipelineORM, @@ -368,8 +361,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { job.Gateway: gateway.NewDelegate( legacyEVMChains, keyStore.Eth(), - sqlxDB, - cfg.Database(), + opts.DS, globalLogger), job.Stream: streams.NewDelegate( globalLogger, @@ -395,7 +387,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { jobORM, pipelineORM, pipelineRunner, - sqlxDB, + opts.DS, legacyEVMChains, globalLogger, ) @@ -408,7 +400,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { if err := ocrcommon.ValidatePeerWrapperConfig(cfg.P2P()); err != nil { return nil, err } - peerWrapper = ocrcommon.NewSingletonPeerWrapper(keyStore, cfg.P2P(), cfg.OCR(), cfg.Database(), sqlxDB, globalLogger) + peerWrapper = ocrcommon.NewSingletonPeerWrapper(keyStore, cfg.P2P(), cfg.OCR(), opts.DS, globalLogger) srvcs = append(srvcs, peerWrapper) } else { return nil, fmt.Errorf("P2P stack required for OCR or OCR2") @@ -416,7 +408,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { if cfg.OCR().Enabled() { delegates[job.OffchainReporting] = ocr.NewDelegate( - sqlxDB, + opts.DS, jobORM, keyStore, pipelineRunner, @@ -436,11 +428,10 @@ func NewApplication(opts ApplicationOpts) (Application, error) { if cfg.OCR2().Enabled() { globalLogger.Debug("Off-chain reporting v2 enabled") - ocr2DelegateConfig := ocr2.NewDelegateConfig(cfg.OCR2(), cfg.Mercury(), cfg.Threshold(), cfg.Insecure(), cfg.JobPipeline(), cfg.Database(), loopRegistrarConfig) + ocr2DelegateConfig := ocr2.NewDelegateConfig(cfg.OCR2(), cfg.Mercury(), cfg.Threshold(), cfg.Insecure(), cfg.JobPipeline(), loopRegistrarConfig) delegates[job.OffchainReporting2] = ocr2.NewDelegate( - sqlxDB, - opts.DB, + opts.DS, jobORM, bridgeORM, mercuryORM, @@ -460,7 +451,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { registry, ) delegates[job.Bootstrap] = ocrbootstrap.NewDelegateBootstrap( - sqlxDB, + opts.DS, jobORM, peerWrapper, globalLogger, @@ -478,7 +469,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { for _, c := range legacyEVMChains.Slice() { lbs = append(lbs, c.LogBroadcaster()) } - jobSpawner := job.NewSpawner(jobORM, cfg.Database(), healthChecker, delegates, sqlxDB, globalLogger, lbs) + jobSpawner := job.NewSpawner(jobORM, cfg.Database(), healthChecker, delegates, globalLogger, lbs) srvcs = append(srvcs, jobSpawner, pipelineRunner) // We start the log poller after the job spawner @@ -491,11 +482,11 @@ func NewApplication(opts ApplicationOpts) (Application, error) { var feedsService feeds.Service if cfg.Feature().FeedsManager() { - feedsORM := feeds.NewORM(sqlxDB, opts.Logger, cfg.Database()) + feedsORM := feeds.NewORM(opts.DS) feedsService = feeds.NewService( feedsORM, jobORM, - sqlxDB, + opts.DS, jobSpawner, keyStore, cfg, @@ -503,7 +494,6 @@ func NewApplication(opts ApplicationOpts) (Application, error) { cfg.JobPipeline(), cfg.OCR(), cfg.OCR2(), - cfg.Database(), legacyEVMChains, globalLogger, opts.Version, @@ -548,8 +538,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) { loopRegistry: loopRegistry, loopRegistrarConfig: loopRegistrarConfig, - sqlxDB: opts.SqlxDB, - db: opts.DB, + ds: opts.DS, // NOTE: Can keep things clean by putting more things in srvcs instead of manually start/closing srvcs: srvcs, @@ -742,7 +731,7 @@ func (app *ChainlinkApplication) WakeSessionReaper() { } func (app *ChainlinkApplication) AddJobV2(ctx context.Context, j *job.Job) error { - return app.jobSpawner.CreateJob(j, pg.WithParentCtx(ctx)) + return app.jobSpawner.CreateJob(ctx, nil, j) } func (app *ChainlinkApplication) DeleteJob(ctx context.Context, jobID int32) error { @@ -756,7 +745,7 @@ func (app *ChainlinkApplication) DeleteJob(ctx context.Context, jobID int32) err return errors.New("job must be deleted in the feeds manager") } - return app.jobSpawner.DeleteJob(jobID, pg.WithParentCtx(ctx)) + return app.jobSpawner.DeleteJob(ctx, nil, jobID) } func (app *ChainlinkApplication) RunWebhookJobV2(ctx context.Context, jobUUID uuid.UUID, requestBody string, meta jsonserializable.JSONSerializable) (int64, error) { @@ -857,12 +846,8 @@ func (app *ChainlinkApplication) GetRelayers() RelayerChainInteroperators { return app.relayers } -func (app *ChainlinkApplication) GetSqlxDB() *sqlx.DB { - return app.sqlxDB -} - func (app *ChainlinkApplication) GetDB() sqlutil.DataSource { - return app.db + return app.ds } // Returns the configuration to use for creating and authenticating diff --git a/core/services/chainlink/relayer_chain_interoperators_test.go b/core/services/chainlink/relayer_chain_interoperators_test.go index 7126c73927c..8111c1f61b4 100644 --- a/core/services/chainlink/relayer_chain_interoperators_test.go +++ b/core/services/chainlink/relayer_chain_interoperators_test.go @@ -212,8 +212,7 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { ChainOpts: legacyevm.ChainOpts{ AppConfig: cfg, MailMon: &mailbox.Monitor{}, - SqlxDB: db, - DB: db, + DS: db, }, CSAETHKeystore: keyStore, }), @@ -265,8 +264,8 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { chainlink.InitCosmos(testctx, factory, chainlink.CosmosFactoryConfig{ Keystore: keyStore.Cosmos(), TOMLConfigs: cfg.CosmosConfigs(), - DB: db, - QConfig: cfg.Database()}), + DS: db, + }), }, expectedCosmosChainCnt: 2, expectedCosmosNodeCnt: 2, @@ -287,8 +286,7 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { AppConfig: cfg, MailMon: &mailbox.Monitor{}, - SqlxDB: db, - DB: db, + DS: db, }, CSAETHKeystore: keyStore, }), @@ -298,8 +296,7 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { chainlink.InitCosmos(testctx, factory, chainlink.CosmosFactoryConfig{ Keystore: keyStore.Cosmos(), TOMLConfigs: cfg.CosmosConfigs(), - DB: db, - QConfig: cfg.Database(), + DS: db, }), }, expectedEVMChainCnt: 2, diff --git a/core/services/chainlink/relayer_factory.go b/core/services/chainlink/relayer_factory.go index 5902555f79c..00db81cce37 100644 --- a/core/services/chainlink/relayer_factory.go +++ b/core/services/chainlink/relayer_factory.go @@ -5,10 +5,10 @@ import ( "errors" "fmt" - "github.com/jmoiron/sqlx" "github.com/pelletier/go-toml/v2" "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos" coscfg "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/config" @@ -22,7 +22,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/config/env" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/relay" evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" @@ -68,9 +67,7 @@ func (r *RelayerFactory) NewEVM(ctx context.Context, config EVMFactoryConfig) (m } relayerOpts := evmrelay.RelayerOpts{ - DB: ccOpts.SqlxDB, - DS: ccOpts.DB, - QConfig: ccOpts.AppConfig.Database(), + DS: ccOpts.DS, CSAETHKeystore: config.CSAETHKeystore, MercuryPool: r.MercuryPool, } @@ -239,8 +236,7 @@ func (r *RelayerFactory) NewStarkNet(ks keystore.StarkNet, chainCfgs config.TOML type CosmosFactoryConfig struct { Keystore keystore.Cosmos coscfg.TOMLConfigs - *sqlx.DB - pg.QConfig + DS sqlutil.DataSource } func (c CosmosFactoryConfig) Validate() error { @@ -251,11 +247,8 @@ func (c CosmosFactoryConfig) Validate() error { if len(c.TOMLConfigs) == 0 { err = errors.Join(err, fmt.Errorf("no CosmosConfigs provided")) } - if c.DB == nil { - err = errors.Join(err, fmt.Errorf("nil DB")) - } - if c.QConfig == nil { - err = errors.Join(err, fmt.Errorf("nil QConfig")) + if c.DS == nil { + err = errors.Join(err, fmt.Errorf("nil DataStore")) } if err != nil { @@ -284,7 +277,7 @@ func (r *RelayerFactory) NewCosmos(config CosmosFactoryConfig) (map[types.RelayI opts := cosmos.ChainOpts{ Logger: lggr, - DB: config.DB, + DS: config.DS, KeyStore: loopKs, } diff --git a/core/services/cron/cron_test.go b/core/services/cron/cron_test.go index b31a06a9591..38684e982d9 100644 --- a/core/services/cron/cron_test.go +++ b/core/services/cron/cron_test.go @@ -29,7 +29,7 @@ func TestCronV2Pipeline(t *testing.T) { lggr := logger.TestLogger(t) orm := pipeline.NewORM(db, lggr, cfg.JobPipeline().MaxSuccessfulRuns()) btORM := bridges.NewORM(db) - jobORM := job.NewORM(db, orm, btORM, keyStore, lggr, cfg.Database()) + jobORM := job.NewORM(db, orm, btORM, keyStore, lggr) jb := &job.Job{ Type: job.Cron, @@ -40,7 +40,7 @@ func TestCronV2Pipeline(t *testing.T) { } delegate := cron.NewDelegate(runner, lggr) - require.NoError(t, jobORM.CreateJob(jb)) + require.NoError(t, jobORM.CreateJob(testutils.Context(t), jb)) serviceArray, err := delegate.ServicesForSpec(testutils.Context(t), *jb) require.NoError(t, err) assert.Len(t, serviceArray, 1) diff --git a/core/services/directrequest/delegate.go b/core/services/directrequest/delegate.go index 33a0a7e73da..26f2c5f9c84 100644 --- a/core/services/directrequest/delegate.go +++ b/core/services/directrequest/delegate.go @@ -215,36 +215,37 @@ func (l *listener) HandleLog(ctx context.Context, lb log.Broadcast) { } func (l *listener) processOracleRequests() { + ctx, cancel := l.chStop.NewCtx() + defer cancel() for { select { case <-l.chStop: l.shutdownWaitGroup.Done() return case <-l.mbOracleRequests.Notify(): - l.handleReceivedLogs(l.mbOracleRequests) + l.handleReceivedLogs(ctx, l.mbOracleRequests) } } } func (l *listener) processCancelOracleRequests() { + ctx, cancel := l.chStop.NewCtx() + defer cancel() for { select { case <-l.chStop: l.shutdownWaitGroup.Done() return case <-l.mbOracleCancelRequests.Notify(): - l.handleReceivedLogs(l.mbOracleCancelRequests) + l.handleReceivedLogs(ctx, l.mbOracleCancelRequests) } } } -func (l *listener) handleReceivedLogs(mailbox *mailbox.Mailbox[log.Broadcast]) { - ctx, cancel := l.chStop.NewCtx() - defer cancel() - +func (l *listener) handleReceivedLogs(ctx context.Context, mailbox *mailbox.Mailbox[log.Broadcast]) { for { select { - case <-l.chStop: + case <-ctx.Done(): return default: } @@ -263,7 +264,7 @@ func (l *listener) handleReceivedLogs(mailbox *mailbox.Mailbox[log.Broadcast]) { logJobSpecID := lb.RawLog().Topics[1] if logJobSpecID == (common.Hash{}) || (logJobSpecID != l.job.ExternalIDEncodeStringToTopic() && logJobSpecID != l.job.ExternalIDEncodeBytesToTopic()) { l.logger.Debugw("Skipping Run for Log with wrong Job ID", "logJobSpecID", logJobSpecID) - l.markLogConsumed(ctx, lb) + l.markLogConsumed(ctx, nil, lb) continue } @@ -277,7 +278,7 @@ func (l *listener) handleReceivedLogs(mailbox *mailbox.Mailbox[log.Broadcast]) { case *operator_wrapper.OperatorOracleRequest: l.handleOracleRequest(ctx, log, lb) case *operator_wrapper.OperatorCancelOracleRequest: - l.handleCancelOracleRequest(ctx, log, lb) + l.handleCancelOracleRequest(ctx, nil, log, lb) default: l.logger.Warnf("Unexpected log type %T", log) } @@ -316,7 +317,7 @@ func (l *listener) handleOracleRequest(ctx context.Context, request *operator_wr "requester", request.Requester, "allowedRequesters", l.requesters.ToStrings(), ) - l.markLogConsumed(ctx, lb) + l.markLogConsumed(ctx, nil, lb) return } @@ -333,7 +334,7 @@ func (l *listener) handleOracleRequest(ctx context.Context, request *operator_wr "minContractPayment", minContractPayment.String(), "requestPayment", requestPayment.String(), ) - l.markLogConsumed(ctx, lb) + l.markLogConsumed(ctx, nil, lb) return } } @@ -375,7 +376,7 @@ func (l *listener) handleOracleRequest(ctx context.Context, request *operator_wr }) run := pipeline.NewRun(*l.job.PipelineSpec, vars) _, err := l.pipelineRunner.Run(ctx, run, l.logger, true, func(tx sqlutil.DataSource) error { - l.markLogConsumed(ctx, lb) + l.markLogConsumed(ctx, tx, lb) return nil }) if ctx.Err() != nil { @@ -398,16 +399,16 @@ func (l *listener) allowRequester(requester common.Address) bool { } // Cancels runs that haven't been started yet, with the given request ID -func (l *listener) handleCancelOracleRequest(ctx context.Context, request *operator_wrapper.OperatorCancelOracleRequest, lb log.Broadcast) { +func (l *listener) handleCancelOracleRequest(ctx context.Context, ds sqlutil.DataSource, request *operator_wrapper.OperatorCancelOracleRequest, lb log.Broadcast) { runCloserChannelIf, loaded := l.runs.LoadAndDelete(formatRequestId(request.RequestId)) if loaded { close(runCloserChannelIf.(services.StopChan)) } - l.markLogConsumed(ctx, lb) + l.markLogConsumed(ctx, ds, lb) } -func (l *listener) markLogConsumed(ctx context.Context, lb log.Broadcast) { - if err := l.logBroadcaster.MarkConsumed(ctx, nil, lb); err != nil { +func (l *listener) markLogConsumed(ctx context.Context, ds sqlutil.DataSource, lb log.Broadcast) { + if err := l.logBroadcaster.MarkConsumed(ctx, ds, lb); err != nil { l.logger.Errorw("Unable to mark log consumed", "err", err, "log", lb.String()) } } diff --git a/core/services/directrequest/delegate_test.go b/core/services/directrequest/delegate_test.go index 08f38865bec..e754713b010 100644 --- a/core/services/directrequest/delegate_test.go +++ b/core/services/directrequest/delegate_test.go @@ -90,7 +90,7 @@ func NewDirectRequestUniverseWithConfig(t *testing.T, cfg chainlink.GeneralConfi lggr := logger.TestLogger(t) orm := pipeline.NewORM(db, lggr, cfg.JobPipeline().MaxSuccessfulRuns()) btORM := bridges.NewORM(db) - jobORM := job.NewORM(db, orm, btORM, keyStore, lggr, cfg.Database()) + jobORM := job.NewORM(db, orm, btORM, keyStore, lggr) legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) delegate := directrequest.NewDelegate(lggr, runner, orm, legacyChains, mailMon) @@ -99,8 +99,9 @@ func NewDirectRequestUniverseWithConfig(t *testing.T, cfg chainlink.GeneralConfi if specF != nil { specF(jb) } - require.NoError(t, jobORM.CreateJob(jb)) - serviceArray, err := delegate.ServicesForSpec(testutils.Context(t), *jb) + ctx := testutils.Context(t) + require.NoError(t, jobORM.CreateJob(ctx, jb)) + serviceArray, err := delegate.ServicesForSpec(ctx, *jb) require.NoError(t, err) assert.Len(t, serviceArray, 1) service := serviceArray[0] diff --git a/core/services/feeds/mocks/orm.go b/core/services/feeds/mocks/orm.go index f84d80a6eb1..625a0b41d9a 100644 --- a/core/services/feeds/mocks/orm.go +++ b/core/services/feeds/mocks/orm.go @@ -3,10 +3,12 @@ package mocks import ( + context "context" + feeds "github.com/smartcontractkit/chainlink/v2/core/services/feeds" mock "github.com/stretchr/testify/mock" - pg "github.com/smartcontractkit/chainlink/v2/core/services/pg" + sqlutil "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" uuid "github.com/google/uuid" ) @@ -24,24 +26,17 @@ func (_m *ORM) EXPECT() *ORM_Expecter { return &ORM_Expecter{mock: &_m.Mock} } -// ApproveSpec provides a mock function with given fields: id, externalJobID, qopts -func (_m *ORM) ApproveSpec(id int64, externalJobID uuid.UUID, qopts ...pg.QOpt) error { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, id, externalJobID) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// ApproveSpec provides a mock function with given fields: ctx, id, externalJobID +func (_m *ORM) ApproveSpec(ctx context.Context, id int64, externalJobID uuid.UUID) error { + ret := _m.Called(ctx, id, externalJobID) if len(ret) == 0 { panic("no return value specified for ApproveSpec") } var r0 error - if rf, ok := ret.Get(0).(func(int64, uuid.UUID, ...pg.QOpt) error); ok { - r0 = rf(id, externalJobID, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64, uuid.UUID) error); ok { + r0 = rf(ctx, id, externalJobID) } else { r0 = ret.Error(0) } @@ -55,23 +50,16 @@ type ORM_ApproveSpec_Call struct { } // ApproveSpec is a helper method to define mock.On call +// - ctx context.Context // - id int64 // - externalJobID uuid.UUID -// - qopts ...pg.QOpt -func (_e *ORM_Expecter) ApproveSpec(id interface{}, externalJobID interface{}, qopts ...interface{}) *ORM_ApproveSpec_Call { - return &ORM_ApproveSpec_Call{Call: _e.mock.On("ApproveSpec", - append([]interface{}{id, externalJobID}, qopts...)...)} +func (_e *ORM_Expecter) ApproveSpec(ctx interface{}, id interface{}, externalJobID interface{}) *ORM_ApproveSpec_Call { + return &ORM_ApproveSpec_Call{Call: _e.mock.On("ApproveSpec", ctx, id, externalJobID)} } -func (_c *ORM_ApproveSpec_Call) Run(run func(id int64, externalJobID uuid.UUID, qopts ...pg.QOpt)) *ORM_ApproveSpec_Call { +func (_c *ORM_ApproveSpec_Call) Run(run func(ctx context.Context, id int64, externalJobID uuid.UUID)) *ORM_ApproveSpec_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]pg.QOpt, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(pg.QOpt) - } - } - run(args[0].(int64), args[1].(uuid.UUID), variadicArgs...) + run(args[0].(context.Context), args[1].(int64), args[2].(uuid.UUID)) }) return _c } @@ -81,29 +69,22 @@ func (_c *ORM_ApproveSpec_Call) Return(_a0 error) *ORM_ApproveSpec_Call { return _c } -func (_c *ORM_ApproveSpec_Call) RunAndReturn(run func(int64, uuid.UUID, ...pg.QOpt) error) *ORM_ApproveSpec_Call { +func (_c *ORM_ApproveSpec_Call) RunAndReturn(run func(context.Context, int64, uuid.UUID) error) *ORM_ApproveSpec_Call { _c.Call.Return(run) return _c } -// CancelSpec provides a mock function with given fields: id, qopts -func (_m *ORM) CancelSpec(id int64, qopts ...pg.QOpt) error { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, id) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// CancelSpec provides a mock function with given fields: ctx, id +func (_m *ORM) CancelSpec(ctx context.Context, id int64) error { + ret := _m.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for CancelSpec") } var r0 error - if rf, ok := ret.Get(0).(func(int64, ...pg.QOpt) error); ok { - r0 = rf(id, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok { + r0 = rf(ctx, id) } else { r0 = ret.Error(0) } @@ -117,22 +98,15 @@ type ORM_CancelSpec_Call struct { } // CancelSpec is a helper method to define mock.On call +// - ctx context.Context // - id int64 -// - qopts ...pg.QOpt -func (_e *ORM_Expecter) CancelSpec(id interface{}, qopts ...interface{}) *ORM_CancelSpec_Call { - return &ORM_CancelSpec_Call{Call: _e.mock.On("CancelSpec", - append([]interface{}{id}, qopts...)...)} +func (_e *ORM_Expecter) CancelSpec(ctx interface{}, id interface{}) *ORM_CancelSpec_Call { + return &ORM_CancelSpec_Call{Call: _e.mock.On("CancelSpec", ctx, id)} } -func (_c *ORM_CancelSpec_Call) Run(run func(id int64, qopts ...pg.QOpt)) *ORM_CancelSpec_Call { +func (_c *ORM_CancelSpec_Call) Run(run func(ctx context.Context, id int64)) *ORM_CancelSpec_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]pg.QOpt, len(args)-1) - for i, a := range args[1:] { - if a != nil { - variadicArgs[i] = a.(pg.QOpt) - } - } - run(args[0].(int64), variadicArgs...) + run(args[0].(context.Context), args[1].(int64)) }) return _c } @@ -142,14 +116,14 @@ func (_c *ORM_CancelSpec_Call) Return(_a0 error) *ORM_CancelSpec_Call { return _c } -func (_c *ORM_CancelSpec_Call) RunAndReturn(run func(int64, ...pg.QOpt) error) *ORM_CancelSpec_Call { +func (_c *ORM_CancelSpec_Call) RunAndReturn(run func(context.Context, int64) error) *ORM_CancelSpec_Call { _c.Call.Return(run) return _c } -// CountJobProposals provides a mock function with given fields: -func (_m *ORM) CountJobProposals() (int64, error) { - ret := _m.Called() +// CountJobProposals provides a mock function with given fields: ctx +func (_m *ORM) CountJobProposals(ctx context.Context) (int64, error) { + ret := _m.Called(ctx) if len(ret) == 0 { panic("no return value specified for CountJobProposals") @@ -157,17 +131,17 @@ func (_m *ORM) CountJobProposals() (int64, error) { var r0 int64 var r1 error - if rf, ok := ret.Get(0).(func() (int64, error)); ok { - return rf() + if rf, ok := ret.Get(0).(func(context.Context) (int64, error)); ok { + return rf(ctx) } - if rf, ok := ret.Get(0).(func() int64); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context) int64); ok { + r0 = rf(ctx) } else { r0 = ret.Get(0).(int64) } - 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) } @@ -181,13 +155,14 @@ type ORM_CountJobProposals_Call struct { } // CountJobProposals is a helper method to define mock.On call -func (_e *ORM_Expecter) CountJobProposals() *ORM_CountJobProposals_Call { - return &ORM_CountJobProposals_Call{Call: _e.mock.On("CountJobProposals")} +// - ctx context.Context +func (_e *ORM_Expecter) CountJobProposals(ctx interface{}) *ORM_CountJobProposals_Call { + return &ORM_CountJobProposals_Call{Call: _e.mock.On("CountJobProposals", ctx)} } -func (_c *ORM_CountJobProposals_Call) Run(run func()) *ORM_CountJobProposals_Call { +func (_c *ORM_CountJobProposals_Call) Run(run func(ctx context.Context)) *ORM_CountJobProposals_Call { _c.Call.Run(func(args mock.Arguments) { - run() + run(args[0].(context.Context)) }) return _c } @@ -197,14 +172,14 @@ func (_c *ORM_CountJobProposals_Call) Return(_a0 int64, _a1 error) *ORM_CountJob return _c } -func (_c *ORM_CountJobProposals_Call) RunAndReturn(run func() (int64, error)) *ORM_CountJobProposals_Call { +func (_c *ORM_CountJobProposals_Call) RunAndReturn(run func(context.Context) (int64, error)) *ORM_CountJobProposals_Call { _c.Call.Return(run) return _c } -// CountJobProposalsByStatus provides a mock function with given fields: -func (_m *ORM) CountJobProposalsByStatus() (*feeds.JobProposalCounts, error) { - ret := _m.Called() +// CountJobProposalsByStatus provides a mock function with given fields: ctx +func (_m *ORM) CountJobProposalsByStatus(ctx context.Context) (*feeds.JobProposalCounts, error) { + ret := _m.Called(ctx) if len(ret) == 0 { panic("no return value specified for CountJobProposalsByStatus") @@ -212,19 +187,19 @@ func (_m *ORM) CountJobProposalsByStatus() (*feeds.JobProposalCounts, error) { var r0 *feeds.JobProposalCounts var r1 error - if rf, ok := ret.Get(0).(func() (*feeds.JobProposalCounts, error)); ok { - return rf() + if rf, ok := ret.Get(0).(func(context.Context) (*feeds.JobProposalCounts, error)); ok { + return rf(ctx) } - if rf, ok := ret.Get(0).(func() *feeds.JobProposalCounts); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context) *feeds.JobProposalCounts); ok { + r0 = rf(ctx) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*feeds.JobProposalCounts) } } - 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) } @@ -238,13 +213,14 @@ type ORM_CountJobProposalsByStatus_Call struct { } // CountJobProposalsByStatus is a helper method to define mock.On call -func (_e *ORM_Expecter) CountJobProposalsByStatus() *ORM_CountJobProposalsByStatus_Call { - return &ORM_CountJobProposalsByStatus_Call{Call: _e.mock.On("CountJobProposalsByStatus")} +// - ctx context.Context +func (_e *ORM_Expecter) CountJobProposalsByStatus(ctx interface{}) *ORM_CountJobProposalsByStatus_Call { + return &ORM_CountJobProposalsByStatus_Call{Call: _e.mock.On("CountJobProposalsByStatus", ctx)} } -func (_c *ORM_CountJobProposalsByStatus_Call) Run(run func()) *ORM_CountJobProposalsByStatus_Call { +func (_c *ORM_CountJobProposalsByStatus_Call) Run(run func(ctx context.Context)) *ORM_CountJobProposalsByStatus_Call { _c.Call.Run(func(args mock.Arguments) { - run() + run(args[0].(context.Context)) }) return _c } @@ -254,14 +230,14 @@ func (_c *ORM_CountJobProposalsByStatus_Call) Return(counts *feeds.JobProposalCo return _c } -func (_c *ORM_CountJobProposalsByStatus_Call) RunAndReturn(run func() (*feeds.JobProposalCounts, error)) *ORM_CountJobProposalsByStatus_Call { +func (_c *ORM_CountJobProposalsByStatus_Call) RunAndReturn(run func(context.Context) (*feeds.JobProposalCounts, error)) *ORM_CountJobProposalsByStatus_Call { _c.Call.Return(run) return _c } -// CountManagers provides a mock function with given fields: -func (_m *ORM) CountManagers() (int64, error) { - ret := _m.Called() +// CountManagers provides a mock function with given fields: ctx +func (_m *ORM) CountManagers(ctx context.Context) (int64, error) { + ret := _m.Called(ctx) if len(ret) == 0 { panic("no return value specified for CountManagers") @@ -269,17 +245,17 @@ func (_m *ORM) CountManagers() (int64, error) { var r0 int64 var r1 error - if rf, ok := ret.Get(0).(func() (int64, error)); ok { - return rf() + if rf, ok := ret.Get(0).(func(context.Context) (int64, error)); ok { + return rf(ctx) } - if rf, ok := ret.Get(0).(func() int64); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context) int64); ok { + r0 = rf(ctx) } else { r0 = ret.Get(0).(int64) } - 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) } @@ -293,13 +269,14 @@ type ORM_CountManagers_Call struct { } // CountManagers is a helper method to define mock.On call -func (_e *ORM_Expecter) CountManagers() *ORM_CountManagers_Call { - return &ORM_CountManagers_Call{Call: _e.mock.On("CountManagers")} +// - ctx context.Context +func (_e *ORM_Expecter) CountManagers(ctx interface{}) *ORM_CountManagers_Call { + return &ORM_CountManagers_Call{Call: _e.mock.On("CountManagers", ctx)} } -func (_c *ORM_CountManagers_Call) Run(run func()) *ORM_CountManagers_Call { +func (_c *ORM_CountManagers_Call) Run(run func(ctx context.Context)) *ORM_CountManagers_Call { _c.Call.Run(func(args mock.Arguments) { - run() + run(args[0].(context.Context)) }) return _c } @@ -309,21 +286,14 @@ func (_c *ORM_CountManagers_Call) Return(_a0 int64, _a1 error) *ORM_CountManager return _c } -func (_c *ORM_CountManagers_Call) RunAndReturn(run func() (int64, error)) *ORM_CountManagers_Call { +func (_c *ORM_CountManagers_Call) RunAndReturn(run func(context.Context) (int64, error)) *ORM_CountManagers_Call { _c.Call.Return(run) return _c } -// CreateBatchChainConfig provides a mock function with given fields: cfgs, qopts -func (_m *ORM) CreateBatchChainConfig(cfgs []feeds.ChainConfig, qopts ...pg.QOpt) ([]int64, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, cfgs) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// CreateBatchChainConfig provides a mock function with given fields: ctx, cfgs +func (_m *ORM) CreateBatchChainConfig(ctx context.Context, cfgs []feeds.ChainConfig) ([]int64, error) { + ret := _m.Called(ctx, cfgs) if len(ret) == 0 { panic("no return value specified for CreateBatchChainConfig") @@ -331,19 +301,19 @@ func (_m *ORM) CreateBatchChainConfig(cfgs []feeds.ChainConfig, qopts ...pg.QOpt var r0 []int64 var r1 error - if rf, ok := ret.Get(0).(func([]feeds.ChainConfig, ...pg.QOpt) ([]int64, error)); ok { - return rf(cfgs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, []feeds.ChainConfig) ([]int64, error)); ok { + return rf(ctx, cfgs) } - if rf, ok := ret.Get(0).(func([]feeds.ChainConfig, ...pg.QOpt) []int64); ok { - r0 = rf(cfgs, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, []feeds.ChainConfig) []int64); ok { + r0 = rf(ctx, cfgs) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]int64) } } - if rf, ok := ret.Get(1).(func([]feeds.ChainConfig, ...pg.QOpt) error); ok { - r1 = rf(cfgs, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, []feeds.ChainConfig) error); ok { + r1 = rf(ctx, cfgs) } else { r1 = ret.Error(1) } @@ -357,22 +327,15 @@ type ORM_CreateBatchChainConfig_Call struct { } // CreateBatchChainConfig is a helper method to define mock.On call +// - ctx context.Context // - cfgs []feeds.ChainConfig -// - qopts ...pg.QOpt -func (_e *ORM_Expecter) CreateBatchChainConfig(cfgs interface{}, qopts ...interface{}) *ORM_CreateBatchChainConfig_Call { - return &ORM_CreateBatchChainConfig_Call{Call: _e.mock.On("CreateBatchChainConfig", - append([]interface{}{cfgs}, qopts...)...)} +func (_e *ORM_Expecter) CreateBatchChainConfig(ctx interface{}, cfgs interface{}) *ORM_CreateBatchChainConfig_Call { + return &ORM_CreateBatchChainConfig_Call{Call: _e.mock.On("CreateBatchChainConfig", ctx, cfgs)} } -func (_c *ORM_CreateBatchChainConfig_Call) Run(run func(cfgs []feeds.ChainConfig, qopts ...pg.QOpt)) *ORM_CreateBatchChainConfig_Call { +func (_c *ORM_CreateBatchChainConfig_Call) Run(run func(ctx context.Context, cfgs []feeds.ChainConfig)) *ORM_CreateBatchChainConfig_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]pg.QOpt, len(args)-1) - for i, a := range args[1:] { - if a != nil { - variadicArgs[i] = a.(pg.QOpt) - } - } - run(args[0].([]feeds.ChainConfig), variadicArgs...) + run(args[0].(context.Context), args[1].([]feeds.ChainConfig)) }) return _c } @@ -382,21 +345,14 @@ func (_c *ORM_CreateBatchChainConfig_Call) Return(_a0 []int64, _a1 error) *ORM_C return _c } -func (_c *ORM_CreateBatchChainConfig_Call) RunAndReturn(run func([]feeds.ChainConfig, ...pg.QOpt) ([]int64, error)) *ORM_CreateBatchChainConfig_Call { +func (_c *ORM_CreateBatchChainConfig_Call) RunAndReturn(run func(context.Context, []feeds.ChainConfig) ([]int64, error)) *ORM_CreateBatchChainConfig_Call { _c.Call.Return(run) return _c } -// CreateChainConfig provides a mock function with given fields: cfg, qopts -func (_m *ORM) CreateChainConfig(cfg feeds.ChainConfig, qopts ...pg.QOpt) (int64, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, cfg) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// CreateChainConfig provides a mock function with given fields: ctx, cfg +func (_m *ORM) CreateChainConfig(ctx context.Context, cfg feeds.ChainConfig) (int64, error) { + ret := _m.Called(ctx, cfg) if len(ret) == 0 { panic("no return value specified for CreateChainConfig") @@ -404,17 +360,17 @@ func (_m *ORM) CreateChainConfig(cfg feeds.ChainConfig, qopts ...pg.QOpt) (int64 var r0 int64 var r1 error - if rf, ok := ret.Get(0).(func(feeds.ChainConfig, ...pg.QOpt) (int64, error)); ok { - return rf(cfg, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, feeds.ChainConfig) (int64, error)); ok { + return rf(ctx, cfg) } - if rf, ok := ret.Get(0).(func(feeds.ChainConfig, ...pg.QOpt) int64); ok { - r0 = rf(cfg, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, feeds.ChainConfig) int64); ok { + r0 = rf(ctx, cfg) } else { r0 = ret.Get(0).(int64) } - if rf, ok := ret.Get(1).(func(feeds.ChainConfig, ...pg.QOpt) error); ok { - r1 = rf(cfg, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, feeds.ChainConfig) error); ok { + r1 = rf(ctx, cfg) } else { r1 = ret.Error(1) } @@ -428,22 +384,15 @@ type ORM_CreateChainConfig_Call struct { } // CreateChainConfig is a helper method to define mock.On call +// - ctx context.Context // - cfg feeds.ChainConfig -// - qopts ...pg.QOpt -func (_e *ORM_Expecter) CreateChainConfig(cfg interface{}, qopts ...interface{}) *ORM_CreateChainConfig_Call { - return &ORM_CreateChainConfig_Call{Call: _e.mock.On("CreateChainConfig", - append([]interface{}{cfg}, qopts...)...)} +func (_e *ORM_Expecter) CreateChainConfig(ctx interface{}, cfg interface{}) *ORM_CreateChainConfig_Call { + return &ORM_CreateChainConfig_Call{Call: _e.mock.On("CreateChainConfig", ctx, cfg)} } -func (_c *ORM_CreateChainConfig_Call) Run(run func(cfg feeds.ChainConfig, qopts ...pg.QOpt)) *ORM_CreateChainConfig_Call { +func (_c *ORM_CreateChainConfig_Call) Run(run func(ctx context.Context, cfg feeds.ChainConfig)) *ORM_CreateChainConfig_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]pg.QOpt, len(args)-1) - for i, a := range args[1:] { - if a != nil { - variadicArgs[i] = a.(pg.QOpt) - } - } - run(args[0].(feeds.ChainConfig), variadicArgs...) + run(args[0].(context.Context), args[1].(feeds.ChainConfig)) }) return _c } @@ -453,14 +402,14 @@ func (_c *ORM_CreateChainConfig_Call) Return(_a0 int64, _a1 error) *ORM_CreateCh return _c } -func (_c *ORM_CreateChainConfig_Call) RunAndReturn(run func(feeds.ChainConfig, ...pg.QOpt) (int64, error)) *ORM_CreateChainConfig_Call { +func (_c *ORM_CreateChainConfig_Call) RunAndReturn(run func(context.Context, feeds.ChainConfig) (int64, error)) *ORM_CreateChainConfig_Call { _c.Call.Return(run) return _c } -// CreateJobProposal provides a mock function with given fields: jp -func (_m *ORM) CreateJobProposal(jp *feeds.JobProposal) (int64, error) { - ret := _m.Called(jp) +// CreateJobProposal provides a mock function with given fields: ctx, jp +func (_m *ORM) CreateJobProposal(ctx context.Context, jp *feeds.JobProposal) (int64, error) { + ret := _m.Called(ctx, jp) if len(ret) == 0 { panic("no return value specified for CreateJobProposal") @@ -468,17 +417,17 @@ func (_m *ORM) CreateJobProposal(jp *feeds.JobProposal) (int64, error) { var r0 int64 var r1 error - if rf, ok := ret.Get(0).(func(*feeds.JobProposal) (int64, error)); ok { - return rf(jp) + if rf, ok := ret.Get(0).(func(context.Context, *feeds.JobProposal) (int64, error)); ok { + return rf(ctx, jp) } - if rf, ok := ret.Get(0).(func(*feeds.JobProposal) int64); ok { - r0 = rf(jp) + if rf, ok := ret.Get(0).(func(context.Context, *feeds.JobProposal) int64); ok { + r0 = rf(ctx, jp) } else { r0 = ret.Get(0).(int64) } - if rf, ok := ret.Get(1).(func(*feeds.JobProposal) error); ok { - r1 = rf(jp) + if rf, ok := ret.Get(1).(func(context.Context, *feeds.JobProposal) error); ok { + r1 = rf(ctx, jp) } else { r1 = ret.Error(1) } @@ -492,14 +441,15 @@ type ORM_CreateJobProposal_Call struct { } // CreateJobProposal is a helper method to define mock.On call +// - ctx context.Context // - jp *feeds.JobProposal -func (_e *ORM_Expecter) CreateJobProposal(jp interface{}) *ORM_CreateJobProposal_Call { - return &ORM_CreateJobProposal_Call{Call: _e.mock.On("CreateJobProposal", jp)} +func (_e *ORM_Expecter) CreateJobProposal(ctx interface{}, jp interface{}) *ORM_CreateJobProposal_Call { + return &ORM_CreateJobProposal_Call{Call: _e.mock.On("CreateJobProposal", ctx, jp)} } -func (_c *ORM_CreateJobProposal_Call) Run(run func(jp *feeds.JobProposal)) *ORM_CreateJobProposal_Call { +func (_c *ORM_CreateJobProposal_Call) Run(run func(ctx context.Context, jp *feeds.JobProposal)) *ORM_CreateJobProposal_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*feeds.JobProposal)) + run(args[0].(context.Context), args[1].(*feeds.JobProposal)) }) return _c } @@ -509,21 +459,14 @@ func (_c *ORM_CreateJobProposal_Call) Return(_a0 int64, _a1 error) *ORM_CreateJo return _c } -func (_c *ORM_CreateJobProposal_Call) RunAndReturn(run func(*feeds.JobProposal) (int64, error)) *ORM_CreateJobProposal_Call { +func (_c *ORM_CreateJobProposal_Call) RunAndReturn(run func(context.Context, *feeds.JobProposal) (int64, error)) *ORM_CreateJobProposal_Call { _c.Call.Return(run) return _c } -// CreateManager provides a mock function with given fields: ms, qopts -func (_m *ORM) CreateManager(ms *feeds.FeedsManager, qopts ...pg.QOpt) (int64, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, ms) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// CreateManager provides a mock function with given fields: ctx, ms +func (_m *ORM) CreateManager(ctx context.Context, ms *feeds.FeedsManager) (int64, error) { + ret := _m.Called(ctx, ms) if len(ret) == 0 { panic("no return value specified for CreateManager") @@ -531,17 +474,17 @@ func (_m *ORM) CreateManager(ms *feeds.FeedsManager, qopts ...pg.QOpt) (int64, e var r0 int64 var r1 error - if rf, ok := ret.Get(0).(func(*feeds.FeedsManager, ...pg.QOpt) (int64, error)); ok { - return rf(ms, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, *feeds.FeedsManager) (int64, error)); ok { + return rf(ctx, ms) } - if rf, ok := ret.Get(0).(func(*feeds.FeedsManager, ...pg.QOpt) int64); ok { - r0 = rf(ms, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, *feeds.FeedsManager) int64); ok { + r0 = rf(ctx, ms) } else { r0 = ret.Get(0).(int64) } - if rf, ok := ret.Get(1).(func(*feeds.FeedsManager, ...pg.QOpt) error); ok { - r1 = rf(ms, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, *feeds.FeedsManager) error); ok { + r1 = rf(ctx, ms) } else { r1 = ret.Error(1) } @@ -555,22 +498,15 @@ type ORM_CreateManager_Call struct { } // CreateManager is a helper method to define mock.On call +// - ctx context.Context // - ms *feeds.FeedsManager -// - qopts ...pg.QOpt -func (_e *ORM_Expecter) CreateManager(ms interface{}, qopts ...interface{}) *ORM_CreateManager_Call { - return &ORM_CreateManager_Call{Call: _e.mock.On("CreateManager", - append([]interface{}{ms}, qopts...)...)} +func (_e *ORM_Expecter) CreateManager(ctx interface{}, ms interface{}) *ORM_CreateManager_Call { + return &ORM_CreateManager_Call{Call: _e.mock.On("CreateManager", ctx, ms)} } -func (_c *ORM_CreateManager_Call) Run(run func(ms *feeds.FeedsManager, qopts ...pg.QOpt)) *ORM_CreateManager_Call { +func (_c *ORM_CreateManager_Call) Run(run func(ctx context.Context, ms *feeds.FeedsManager)) *ORM_CreateManager_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]pg.QOpt, len(args)-1) - for i, a := range args[1:] { - if a != nil { - variadicArgs[i] = a.(pg.QOpt) - } - } - run(args[0].(*feeds.FeedsManager), variadicArgs...) + run(args[0].(context.Context), args[1].(*feeds.FeedsManager)) }) return _c } @@ -580,21 +516,14 @@ func (_c *ORM_CreateManager_Call) Return(_a0 int64, _a1 error) *ORM_CreateManage return _c } -func (_c *ORM_CreateManager_Call) RunAndReturn(run func(*feeds.FeedsManager, ...pg.QOpt) (int64, error)) *ORM_CreateManager_Call { +func (_c *ORM_CreateManager_Call) RunAndReturn(run func(context.Context, *feeds.FeedsManager) (int64, error)) *ORM_CreateManager_Call { _c.Call.Return(run) return _c } -// CreateSpec provides a mock function with given fields: spec, qopts -func (_m *ORM) CreateSpec(spec feeds.JobProposalSpec, qopts ...pg.QOpt) (int64, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, spec) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// CreateSpec provides a mock function with given fields: ctx, spec +func (_m *ORM) CreateSpec(ctx context.Context, spec feeds.JobProposalSpec) (int64, error) { + ret := _m.Called(ctx, spec) if len(ret) == 0 { panic("no return value specified for CreateSpec") @@ -602,17 +531,17 @@ func (_m *ORM) CreateSpec(spec feeds.JobProposalSpec, qopts ...pg.QOpt) (int64, var r0 int64 var r1 error - if rf, ok := ret.Get(0).(func(feeds.JobProposalSpec, ...pg.QOpt) (int64, error)); ok { - return rf(spec, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, feeds.JobProposalSpec) (int64, error)); ok { + return rf(ctx, spec) } - if rf, ok := ret.Get(0).(func(feeds.JobProposalSpec, ...pg.QOpt) int64); ok { - r0 = rf(spec, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, feeds.JobProposalSpec) int64); ok { + r0 = rf(ctx, spec) } else { r0 = ret.Get(0).(int64) } - if rf, ok := ret.Get(1).(func(feeds.JobProposalSpec, ...pg.QOpt) error); ok { - r1 = rf(spec, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, feeds.JobProposalSpec) error); ok { + r1 = rf(ctx, spec) } else { r1 = ret.Error(1) } @@ -626,22 +555,15 @@ type ORM_CreateSpec_Call struct { } // CreateSpec is a helper method to define mock.On call +// - ctx context.Context // - spec feeds.JobProposalSpec -// - qopts ...pg.QOpt -func (_e *ORM_Expecter) CreateSpec(spec interface{}, qopts ...interface{}) *ORM_CreateSpec_Call { - return &ORM_CreateSpec_Call{Call: _e.mock.On("CreateSpec", - append([]interface{}{spec}, qopts...)...)} +func (_e *ORM_Expecter) CreateSpec(ctx interface{}, spec interface{}) *ORM_CreateSpec_Call { + return &ORM_CreateSpec_Call{Call: _e.mock.On("CreateSpec", ctx, spec)} } -func (_c *ORM_CreateSpec_Call) Run(run func(spec feeds.JobProposalSpec, qopts ...pg.QOpt)) *ORM_CreateSpec_Call { +func (_c *ORM_CreateSpec_Call) Run(run func(ctx context.Context, spec feeds.JobProposalSpec)) *ORM_CreateSpec_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]pg.QOpt, len(args)-1) - for i, a := range args[1:] { - if a != nil { - variadicArgs[i] = a.(pg.QOpt) - } - } - run(args[0].(feeds.JobProposalSpec), variadicArgs...) + run(args[0].(context.Context), args[1].(feeds.JobProposalSpec)) }) return _c } @@ -651,14 +573,14 @@ func (_c *ORM_CreateSpec_Call) Return(_a0 int64, _a1 error) *ORM_CreateSpec_Call return _c } -func (_c *ORM_CreateSpec_Call) RunAndReturn(run func(feeds.JobProposalSpec, ...pg.QOpt) (int64, error)) *ORM_CreateSpec_Call { +func (_c *ORM_CreateSpec_Call) RunAndReturn(run func(context.Context, feeds.JobProposalSpec) (int64, error)) *ORM_CreateSpec_Call { _c.Call.Return(run) return _c } -// DeleteChainConfig provides a mock function with given fields: id -func (_m *ORM) DeleteChainConfig(id int64) (int64, error) { - ret := _m.Called(id) +// DeleteChainConfig provides a mock function with given fields: ctx, id +func (_m *ORM) DeleteChainConfig(ctx context.Context, id int64) (int64, error) { + ret := _m.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for DeleteChainConfig") @@ -666,17 +588,17 @@ func (_m *ORM) DeleteChainConfig(id int64) (int64, error) { var r0 int64 var r1 error - if rf, ok := ret.Get(0).(func(int64) (int64, error)); ok { - return rf(id) + if rf, ok := ret.Get(0).(func(context.Context, int64) (int64, error)); ok { + return rf(ctx, id) } - if rf, ok := ret.Get(0).(func(int64) int64); ok { - r0 = rf(id) + if rf, ok := ret.Get(0).(func(context.Context, int64) int64); ok { + r0 = rf(ctx, id) } else { r0 = ret.Get(0).(int64) } - if rf, ok := ret.Get(1).(func(int64) error); ok { - r1 = rf(id) + if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok { + r1 = rf(ctx, id) } else { r1 = ret.Error(1) } @@ -690,14 +612,15 @@ type ORM_DeleteChainConfig_Call struct { } // DeleteChainConfig is a helper method to define mock.On call +// - ctx context.Context // - id int64 -func (_e *ORM_Expecter) DeleteChainConfig(id interface{}) *ORM_DeleteChainConfig_Call { - return &ORM_DeleteChainConfig_Call{Call: _e.mock.On("DeleteChainConfig", id)} +func (_e *ORM_Expecter) DeleteChainConfig(ctx interface{}, id interface{}) *ORM_DeleteChainConfig_Call { + return &ORM_DeleteChainConfig_Call{Call: _e.mock.On("DeleteChainConfig", ctx, id)} } -func (_c *ORM_DeleteChainConfig_Call) Run(run func(id int64)) *ORM_DeleteChainConfig_Call { +func (_c *ORM_DeleteChainConfig_Call) Run(run func(ctx context.Context, id int64)) *ORM_DeleteChainConfig_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(int64)) + run(args[0].(context.Context), args[1].(int64)) }) return _c } @@ -707,29 +630,22 @@ func (_c *ORM_DeleteChainConfig_Call) Return(_a0 int64, _a1 error) *ORM_DeleteCh return _c } -func (_c *ORM_DeleteChainConfig_Call) RunAndReturn(run func(int64) (int64, error)) *ORM_DeleteChainConfig_Call { +func (_c *ORM_DeleteChainConfig_Call) RunAndReturn(run func(context.Context, int64) (int64, error)) *ORM_DeleteChainConfig_Call { _c.Call.Return(run) return _c } -// DeleteProposal provides a mock function with given fields: id, qopts -func (_m *ORM) DeleteProposal(id int64, qopts ...pg.QOpt) error { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, id) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// DeleteProposal provides a mock function with given fields: ctx, id +func (_m *ORM) DeleteProposal(ctx context.Context, id int64) error { + ret := _m.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for DeleteProposal") } var r0 error - if rf, ok := ret.Get(0).(func(int64, ...pg.QOpt) error); ok { - r0 = rf(id, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok { + r0 = rf(ctx, id) } else { r0 = ret.Error(0) } @@ -743,22 +659,15 @@ type ORM_DeleteProposal_Call struct { } // DeleteProposal is a helper method to define mock.On call +// - ctx context.Context // - id int64 -// - qopts ...pg.QOpt -func (_e *ORM_Expecter) DeleteProposal(id interface{}, qopts ...interface{}) *ORM_DeleteProposal_Call { - return &ORM_DeleteProposal_Call{Call: _e.mock.On("DeleteProposal", - append([]interface{}{id}, qopts...)...)} +func (_e *ORM_Expecter) DeleteProposal(ctx interface{}, id interface{}) *ORM_DeleteProposal_Call { + return &ORM_DeleteProposal_Call{Call: _e.mock.On("DeleteProposal", ctx, id)} } -func (_c *ORM_DeleteProposal_Call) Run(run func(id int64, qopts ...pg.QOpt)) *ORM_DeleteProposal_Call { +func (_c *ORM_DeleteProposal_Call) Run(run func(ctx context.Context, id int64)) *ORM_DeleteProposal_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]pg.QOpt, len(args)-1) - for i, a := range args[1:] { - if a != nil { - variadicArgs[i] = a.(pg.QOpt) - } - } - run(args[0].(int64), variadicArgs...) + run(args[0].(context.Context), args[1].(int64)) }) return _c } @@ -768,21 +677,14 @@ func (_c *ORM_DeleteProposal_Call) Return(_a0 error) *ORM_DeleteProposal_Call { return _c } -func (_c *ORM_DeleteProposal_Call) RunAndReturn(run func(int64, ...pg.QOpt) error) *ORM_DeleteProposal_Call { +func (_c *ORM_DeleteProposal_Call) RunAndReturn(run func(context.Context, int64) error) *ORM_DeleteProposal_Call { _c.Call.Return(run) return _c } -// ExistsSpecByJobProposalIDAndVersion provides a mock function with given fields: jpID, version, qopts -func (_m *ORM) ExistsSpecByJobProposalIDAndVersion(jpID int64, version int32, qopts ...pg.QOpt) (bool, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, jpID, version) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// ExistsSpecByJobProposalIDAndVersion provides a mock function with given fields: ctx, jpID, version +func (_m *ORM) ExistsSpecByJobProposalIDAndVersion(ctx context.Context, jpID int64, version int32) (bool, error) { + ret := _m.Called(ctx, jpID, version) if len(ret) == 0 { panic("no return value specified for ExistsSpecByJobProposalIDAndVersion") @@ -790,17 +692,17 @@ func (_m *ORM) ExistsSpecByJobProposalIDAndVersion(jpID int64, version int32, qo var r0 bool var r1 error - if rf, ok := ret.Get(0).(func(int64, int32, ...pg.QOpt) (bool, error)); ok { - return rf(jpID, version, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64, int32) (bool, error)); ok { + return rf(ctx, jpID, version) } - if rf, ok := ret.Get(0).(func(int64, int32, ...pg.QOpt) bool); ok { - r0 = rf(jpID, version, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64, int32) bool); ok { + r0 = rf(ctx, jpID, version) } else { r0 = ret.Get(0).(bool) } - if rf, ok := ret.Get(1).(func(int64, int32, ...pg.QOpt) error); ok { - r1 = rf(jpID, version, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, int64, int32) error); ok { + r1 = rf(ctx, jpID, version) } else { r1 = ret.Error(1) } @@ -814,23 +716,16 @@ type ORM_ExistsSpecByJobProposalIDAndVersion_Call struct { } // ExistsSpecByJobProposalIDAndVersion is a helper method to define mock.On call +// - ctx context.Context // - jpID int64 // - version int32 -// - qopts ...pg.QOpt -func (_e *ORM_Expecter) ExistsSpecByJobProposalIDAndVersion(jpID interface{}, version interface{}, qopts ...interface{}) *ORM_ExistsSpecByJobProposalIDAndVersion_Call { - return &ORM_ExistsSpecByJobProposalIDAndVersion_Call{Call: _e.mock.On("ExistsSpecByJobProposalIDAndVersion", - append([]interface{}{jpID, version}, qopts...)...)} +func (_e *ORM_Expecter) ExistsSpecByJobProposalIDAndVersion(ctx interface{}, jpID interface{}, version interface{}) *ORM_ExistsSpecByJobProposalIDAndVersion_Call { + return &ORM_ExistsSpecByJobProposalIDAndVersion_Call{Call: _e.mock.On("ExistsSpecByJobProposalIDAndVersion", ctx, jpID, version)} } -func (_c *ORM_ExistsSpecByJobProposalIDAndVersion_Call) Run(run func(jpID int64, version int32, qopts ...pg.QOpt)) *ORM_ExistsSpecByJobProposalIDAndVersion_Call { +func (_c *ORM_ExistsSpecByJobProposalIDAndVersion_Call) Run(run func(ctx context.Context, jpID int64, version int32)) *ORM_ExistsSpecByJobProposalIDAndVersion_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]pg.QOpt, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(pg.QOpt) - } - } - run(args[0].(int64), args[1].(int32), variadicArgs...) + run(args[0].(context.Context), args[1].(int64), args[2].(int32)) }) return _c } @@ -840,21 +735,14 @@ func (_c *ORM_ExistsSpecByJobProposalIDAndVersion_Call) Return(exists bool, err return _c } -func (_c *ORM_ExistsSpecByJobProposalIDAndVersion_Call) RunAndReturn(run func(int64, int32, ...pg.QOpt) (bool, error)) *ORM_ExistsSpecByJobProposalIDAndVersion_Call { +func (_c *ORM_ExistsSpecByJobProposalIDAndVersion_Call) RunAndReturn(run func(context.Context, int64, int32) (bool, error)) *ORM_ExistsSpecByJobProposalIDAndVersion_Call { _c.Call.Return(run) return _c } -// GetApprovedSpec provides a mock function with given fields: jpID, qopts -func (_m *ORM) GetApprovedSpec(jpID int64, qopts ...pg.QOpt) (*feeds.JobProposalSpec, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, jpID) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// GetApprovedSpec provides a mock function with given fields: ctx, jpID +func (_m *ORM) GetApprovedSpec(ctx context.Context, jpID int64) (*feeds.JobProposalSpec, error) { + ret := _m.Called(ctx, jpID) if len(ret) == 0 { panic("no return value specified for GetApprovedSpec") @@ -862,19 +750,19 @@ func (_m *ORM) GetApprovedSpec(jpID int64, qopts ...pg.QOpt) (*feeds.JobProposal var r0 *feeds.JobProposalSpec var r1 error - if rf, ok := ret.Get(0).(func(int64, ...pg.QOpt) (*feeds.JobProposalSpec, error)); ok { - return rf(jpID, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64) (*feeds.JobProposalSpec, error)); ok { + return rf(ctx, jpID) } - if rf, ok := ret.Get(0).(func(int64, ...pg.QOpt) *feeds.JobProposalSpec); ok { - r0 = rf(jpID, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64) *feeds.JobProposalSpec); ok { + r0 = rf(ctx, jpID) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*feeds.JobProposalSpec) } } - if rf, ok := ret.Get(1).(func(int64, ...pg.QOpt) error); ok { - r1 = rf(jpID, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok { + r1 = rf(ctx, jpID) } else { r1 = ret.Error(1) } @@ -888,22 +776,15 @@ type ORM_GetApprovedSpec_Call struct { } // GetApprovedSpec is a helper method to define mock.On call +// - ctx context.Context // - jpID int64 -// - qopts ...pg.QOpt -func (_e *ORM_Expecter) GetApprovedSpec(jpID interface{}, qopts ...interface{}) *ORM_GetApprovedSpec_Call { - return &ORM_GetApprovedSpec_Call{Call: _e.mock.On("GetApprovedSpec", - append([]interface{}{jpID}, qopts...)...)} +func (_e *ORM_Expecter) GetApprovedSpec(ctx interface{}, jpID interface{}) *ORM_GetApprovedSpec_Call { + return &ORM_GetApprovedSpec_Call{Call: _e.mock.On("GetApprovedSpec", ctx, jpID)} } -func (_c *ORM_GetApprovedSpec_Call) Run(run func(jpID int64, qopts ...pg.QOpt)) *ORM_GetApprovedSpec_Call { +func (_c *ORM_GetApprovedSpec_Call) Run(run func(ctx context.Context, jpID int64)) *ORM_GetApprovedSpec_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]pg.QOpt, len(args)-1) - for i, a := range args[1:] { - if a != nil { - variadicArgs[i] = a.(pg.QOpt) - } - } - run(args[0].(int64), variadicArgs...) + run(args[0].(context.Context), args[1].(int64)) }) return _c } @@ -913,14 +794,14 @@ func (_c *ORM_GetApprovedSpec_Call) Return(_a0 *feeds.JobProposalSpec, _a1 error return _c } -func (_c *ORM_GetApprovedSpec_Call) RunAndReturn(run func(int64, ...pg.QOpt) (*feeds.JobProposalSpec, error)) *ORM_GetApprovedSpec_Call { +func (_c *ORM_GetApprovedSpec_Call) RunAndReturn(run func(context.Context, int64) (*feeds.JobProposalSpec, error)) *ORM_GetApprovedSpec_Call { _c.Call.Return(run) return _c } -// GetChainConfig provides a mock function with given fields: id -func (_m *ORM) GetChainConfig(id int64) (*feeds.ChainConfig, error) { - ret := _m.Called(id) +// GetChainConfig provides a mock function with given fields: ctx, id +func (_m *ORM) GetChainConfig(ctx context.Context, id int64) (*feeds.ChainConfig, error) { + ret := _m.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for GetChainConfig") @@ -928,19 +809,19 @@ func (_m *ORM) GetChainConfig(id int64) (*feeds.ChainConfig, error) { var r0 *feeds.ChainConfig var r1 error - if rf, ok := ret.Get(0).(func(int64) (*feeds.ChainConfig, error)); ok { - return rf(id) + if rf, ok := ret.Get(0).(func(context.Context, int64) (*feeds.ChainConfig, error)); ok { + return rf(ctx, id) } - if rf, ok := ret.Get(0).(func(int64) *feeds.ChainConfig); ok { - r0 = rf(id) + if rf, ok := ret.Get(0).(func(context.Context, int64) *feeds.ChainConfig); ok { + r0 = rf(ctx, id) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*feeds.ChainConfig) } } - if rf, ok := ret.Get(1).(func(int64) error); ok { - r1 = rf(id) + if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok { + r1 = rf(ctx, id) } else { r1 = ret.Error(1) } @@ -954,14 +835,15 @@ type ORM_GetChainConfig_Call struct { } // GetChainConfig is a helper method to define mock.On call +// - ctx context.Context // - id int64 -func (_e *ORM_Expecter) GetChainConfig(id interface{}) *ORM_GetChainConfig_Call { - return &ORM_GetChainConfig_Call{Call: _e.mock.On("GetChainConfig", id)} +func (_e *ORM_Expecter) GetChainConfig(ctx interface{}, id interface{}) *ORM_GetChainConfig_Call { + return &ORM_GetChainConfig_Call{Call: _e.mock.On("GetChainConfig", ctx, id)} } -func (_c *ORM_GetChainConfig_Call) Run(run func(id int64)) *ORM_GetChainConfig_Call { +func (_c *ORM_GetChainConfig_Call) Run(run func(ctx context.Context, id int64)) *ORM_GetChainConfig_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(int64)) + run(args[0].(context.Context), args[1].(int64)) }) return _c } @@ -971,21 +853,14 @@ func (_c *ORM_GetChainConfig_Call) Return(_a0 *feeds.ChainConfig, _a1 error) *OR return _c } -func (_c *ORM_GetChainConfig_Call) RunAndReturn(run func(int64) (*feeds.ChainConfig, error)) *ORM_GetChainConfig_Call { +func (_c *ORM_GetChainConfig_Call) RunAndReturn(run func(context.Context, int64) (*feeds.ChainConfig, error)) *ORM_GetChainConfig_Call { _c.Call.Return(run) return _c } -// GetJobProposal provides a mock function with given fields: id, qopts -func (_m *ORM) GetJobProposal(id int64, qopts ...pg.QOpt) (*feeds.JobProposal, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, id) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// GetJobProposal provides a mock function with given fields: ctx, id +func (_m *ORM) GetJobProposal(ctx context.Context, id int64) (*feeds.JobProposal, error) { + ret := _m.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for GetJobProposal") @@ -993,19 +868,19 @@ func (_m *ORM) GetJobProposal(id int64, qopts ...pg.QOpt) (*feeds.JobProposal, e var r0 *feeds.JobProposal var r1 error - if rf, ok := ret.Get(0).(func(int64, ...pg.QOpt) (*feeds.JobProposal, error)); ok { - return rf(id, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64) (*feeds.JobProposal, error)); ok { + return rf(ctx, id) } - if rf, ok := ret.Get(0).(func(int64, ...pg.QOpt) *feeds.JobProposal); ok { - r0 = rf(id, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64) *feeds.JobProposal); ok { + r0 = rf(ctx, id) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*feeds.JobProposal) } } - if rf, ok := ret.Get(1).(func(int64, ...pg.QOpt) error); ok { - r1 = rf(id, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok { + r1 = rf(ctx, id) } else { r1 = ret.Error(1) } @@ -1019,22 +894,15 @@ type ORM_GetJobProposal_Call struct { } // GetJobProposal is a helper method to define mock.On call +// - ctx context.Context // - id int64 -// - qopts ...pg.QOpt -func (_e *ORM_Expecter) GetJobProposal(id interface{}, qopts ...interface{}) *ORM_GetJobProposal_Call { - return &ORM_GetJobProposal_Call{Call: _e.mock.On("GetJobProposal", - append([]interface{}{id}, qopts...)...)} +func (_e *ORM_Expecter) GetJobProposal(ctx interface{}, id interface{}) *ORM_GetJobProposal_Call { + return &ORM_GetJobProposal_Call{Call: _e.mock.On("GetJobProposal", ctx, id)} } -func (_c *ORM_GetJobProposal_Call) Run(run func(id int64, qopts ...pg.QOpt)) *ORM_GetJobProposal_Call { +func (_c *ORM_GetJobProposal_Call) Run(run func(ctx context.Context, id int64)) *ORM_GetJobProposal_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]pg.QOpt, len(args)-1) - for i, a := range args[1:] { - if a != nil { - variadicArgs[i] = a.(pg.QOpt) - } - } - run(args[0].(int64), variadicArgs...) + run(args[0].(context.Context), args[1].(int64)) }) return _c } @@ -1044,14 +912,14 @@ func (_c *ORM_GetJobProposal_Call) Return(_a0 *feeds.JobProposal, _a1 error) *OR return _c } -func (_c *ORM_GetJobProposal_Call) RunAndReturn(run func(int64, ...pg.QOpt) (*feeds.JobProposal, error)) *ORM_GetJobProposal_Call { +func (_c *ORM_GetJobProposal_Call) RunAndReturn(run func(context.Context, int64) (*feeds.JobProposal, error)) *ORM_GetJobProposal_Call { _c.Call.Return(run) return _c } -// GetJobProposalByRemoteUUID provides a mock function with given fields: _a0 -func (_m *ORM) GetJobProposalByRemoteUUID(_a0 uuid.UUID) (*feeds.JobProposal, error) { - ret := _m.Called(_a0) +// GetJobProposalByRemoteUUID provides a mock function with given fields: ctx, _a1 +func (_m *ORM) GetJobProposalByRemoteUUID(ctx context.Context, _a1 uuid.UUID) (*feeds.JobProposal, error) { + ret := _m.Called(ctx, _a1) if len(ret) == 0 { panic("no return value specified for GetJobProposalByRemoteUUID") @@ -1059,19 +927,19 @@ func (_m *ORM) GetJobProposalByRemoteUUID(_a0 uuid.UUID) (*feeds.JobProposal, er var r0 *feeds.JobProposal var r1 error - if rf, ok := ret.Get(0).(func(uuid.UUID) (*feeds.JobProposal, error)); ok { - return rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID) (*feeds.JobProposal, error)); ok { + return rf(ctx, _a1) } - if rf, ok := ret.Get(0).(func(uuid.UUID) *feeds.JobProposal); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID) *feeds.JobProposal); ok { + r0 = rf(ctx, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*feeds.JobProposal) } } - if rf, ok := ret.Get(1).(func(uuid.UUID) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { + r1 = rf(ctx, _a1) } else { r1 = ret.Error(1) } @@ -1085,14 +953,15 @@ type ORM_GetJobProposalByRemoteUUID_Call struct { } // GetJobProposalByRemoteUUID is a helper method to define mock.On call -// - _a0 uuid.UUID -func (_e *ORM_Expecter) GetJobProposalByRemoteUUID(_a0 interface{}) *ORM_GetJobProposalByRemoteUUID_Call { - return &ORM_GetJobProposalByRemoteUUID_Call{Call: _e.mock.On("GetJobProposalByRemoteUUID", _a0)} +// - ctx context.Context +// - _a1 uuid.UUID +func (_e *ORM_Expecter) GetJobProposalByRemoteUUID(ctx interface{}, _a1 interface{}) *ORM_GetJobProposalByRemoteUUID_Call { + return &ORM_GetJobProposalByRemoteUUID_Call{Call: _e.mock.On("GetJobProposalByRemoteUUID", ctx, _a1)} } -func (_c *ORM_GetJobProposalByRemoteUUID_Call) Run(run func(_a0 uuid.UUID)) *ORM_GetJobProposalByRemoteUUID_Call { +func (_c *ORM_GetJobProposalByRemoteUUID_Call) Run(run func(ctx context.Context, _a1 uuid.UUID)) *ORM_GetJobProposalByRemoteUUID_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(uuid.UUID)) + run(args[0].(context.Context), args[1].(uuid.UUID)) }) return _c } @@ -1102,14 +971,14 @@ func (_c *ORM_GetJobProposalByRemoteUUID_Call) Return(_a0 *feeds.JobProposal, _a return _c } -func (_c *ORM_GetJobProposalByRemoteUUID_Call) RunAndReturn(run func(uuid.UUID) (*feeds.JobProposal, error)) *ORM_GetJobProposalByRemoteUUID_Call { +func (_c *ORM_GetJobProposalByRemoteUUID_Call) RunAndReturn(run func(context.Context, uuid.UUID) (*feeds.JobProposal, error)) *ORM_GetJobProposalByRemoteUUID_Call { _c.Call.Return(run) return _c } -// GetLatestSpec provides a mock function with given fields: jpID -func (_m *ORM) GetLatestSpec(jpID int64) (*feeds.JobProposalSpec, error) { - ret := _m.Called(jpID) +// GetLatestSpec provides a mock function with given fields: ctx, jpID +func (_m *ORM) GetLatestSpec(ctx context.Context, jpID int64) (*feeds.JobProposalSpec, error) { + ret := _m.Called(ctx, jpID) if len(ret) == 0 { panic("no return value specified for GetLatestSpec") @@ -1117,19 +986,19 @@ func (_m *ORM) GetLatestSpec(jpID int64) (*feeds.JobProposalSpec, error) { var r0 *feeds.JobProposalSpec var r1 error - if rf, ok := ret.Get(0).(func(int64) (*feeds.JobProposalSpec, error)); ok { - return rf(jpID) + if rf, ok := ret.Get(0).(func(context.Context, int64) (*feeds.JobProposalSpec, error)); ok { + return rf(ctx, jpID) } - if rf, ok := ret.Get(0).(func(int64) *feeds.JobProposalSpec); ok { - r0 = rf(jpID) + if rf, ok := ret.Get(0).(func(context.Context, int64) *feeds.JobProposalSpec); ok { + r0 = rf(ctx, jpID) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*feeds.JobProposalSpec) } } - if rf, ok := ret.Get(1).(func(int64) error); ok { - r1 = rf(jpID) + if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok { + r1 = rf(ctx, jpID) } else { r1 = ret.Error(1) } @@ -1143,14 +1012,15 @@ type ORM_GetLatestSpec_Call struct { } // GetLatestSpec is a helper method to define mock.On call +// - ctx context.Context // - jpID int64 -func (_e *ORM_Expecter) GetLatestSpec(jpID interface{}) *ORM_GetLatestSpec_Call { - return &ORM_GetLatestSpec_Call{Call: _e.mock.On("GetLatestSpec", jpID)} +func (_e *ORM_Expecter) GetLatestSpec(ctx interface{}, jpID interface{}) *ORM_GetLatestSpec_Call { + return &ORM_GetLatestSpec_Call{Call: _e.mock.On("GetLatestSpec", ctx, jpID)} } -func (_c *ORM_GetLatestSpec_Call) Run(run func(jpID int64)) *ORM_GetLatestSpec_Call { +func (_c *ORM_GetLatestSpec_Call) Run(run func(ctx context.Context, jpID int64)) *ORM_GetLatestSpec_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(int64)) + run(args[0].(context.Context), args[1].(int64)) }) return _c } @@ -1160,14 +1030,14 @@ func (_c *ORM_GetLatestSpec_Call) Return(_a0 *feeds.JobProposalSpec, _a1 error) return _c } -func (_c *ORM_GetLatestSpec_Call) RunAndReturn(run func(int64) (*feeds.JobProposalSpec, error)) *ORM_GetLatestSpec_Call { +func (_c *ORM_GetLatestSpec_Call) RunAndReturn(run func(context.Context, int64) (*feeds.JobProposalSpec, error)) *ORM_GetLatestSpec_Call { _c.Call.Return(run) return _c } -// GetManager provides a mock function with given fields: id -func (_m *ORM) GetManager(id int64) (*feeds.FeedsManager, error) { - ret := _m.Called(id) +// GetManager provides a mock function with given fields: ctx, id +func (_m *ORM) GetManager(ctx context.Context, id int64) (*feeds.FeedsManager, error) { + ret := _m.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for GetManager") @@ -1175,19 +1045,19 @@ func (_m *ORM) GetManager(id int64) (*feeds.FeedsManager, error) { var r0 *feeds.FeedsManager var r1 error - if rf, ok := ret.Get(0).(func(int64) (*feeds.FeedsManager, error)); ok { - return rf(id) + if rf, ok := ret.Get(0).(func(context.Context, int64) (*feeds.FeedsManager, error)); ok { + return rf(ctx, id) } - if rf, ok := ret.Get(0).(func(int64) *feeds.FeedsManager); ok { - r0 = rf(id) + if rf, ok := ret.Get(0).(func(context.Context, int64) *feeds.FeedsManager); ok { + r0 = rf(ctx, id) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*feeds.FeedsManager) } } - if rf, ok := ret.Get(1).(func(int64) error); ok { - r1 = rf(id) + if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok { + r1 = rf(ctx, id) } else { r1 = ret.Error(1) } @@ -1201,14 +1071,15 @@ type ORM_GetManager_Call struct { } // GetManager is a helper method to define mock.On call +// - ctx context.Context // - id int64 -func (_e *ORM_Expecter) GetManager(id interface{}) *ORM_GetManager_Call { - return &ORM_GetManager_Call{Call: _e.mock.On("GetManager", id)} +func (_e *ORM_Expecter) GetManager(ctx interface{}, id interface{}) *ORM_GetManager_Call { + return &ORM_GetManager_Call{Call: _e.mock.On("GetManager", ctx, id)} } -func (_c *ORM_GetManager_Call) Run(run func(id int64)) *ORM_GetManager_Call { +func (_c *ORM_GetManager_Call) Run(run func(ctx context.Context, id int64)) *ORM_GetManager_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(int64)) + run(args[0].(context.Context), args[1].(int64)) }) return _c } @@ -1218,21 +1089,14 @@ func (_c *ORM_GetManager_Call) Return(_a0 *feeds.FeedsManager, _a1 error) *ORM_G return _c } -func (_c *ORM_GetManager_Call) RunAndReturn(run func(int64) (*feeds.FeedsManager, error)) *ORM_GetManager_Call { +func (_c *ORM_GetManager_Call) RunAndReturn(run func(context.Context, int64) (*feeds.FeedsManager, error)) *ORM_GetManager_Call { _c.Call.Return(run) return _c } -// GetSpec provides a mock function with given fields: id, qopts -func (_m *ORM) GetSpec(id int64, qopts ...pg.QOpt) (*feeds.JobProposalSpec, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, id) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// GetSpec provides a mock function with given fields: ctx, id +func (_m *ORM) GetSpec(ctx context.Context, id int64) (*feeds.JobProposalSpec, error) { + ret := _m.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for GetSpec") @@ -1240,19 +1104,19 @@ func (_m *ORM) GetSpec(id int64, qopts ...pg.QOpt) (*feeds.JobProposalSpec, erro var r0 *feeds.JobProposalSpec var r1 error - if rf, ok := ret.Get(0).(func(int64, ...pg.QOpt) (*feeds.JobProposalSpec, error)); ok { - return rf(id, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64) (*feeds.JobProposalSpec, error)); ok { + return rf(ctx, id) } - if rf, ok := ret.Get(0).(func(int64, ...pg.QOpt) *feeds.JobProposalSpec); ok { - r0 = rf(id, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64) *feeds.JobProposalSpec); ok { + r0 = rf(ctx, id) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*feeds.JobProposalSpec) } } - if rf, ok := ret.Get(1).(func(int64, ...pg.QOpt) error); ok { - r1 = rf(id, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok { + r1 = rf(ctx, id) } else { r1 = ret.Error(1) } @@ -1266,22 +1130,15 @@ type ORM_GetSpec_Call struct { } // GetSpec is a helper method to define mock.On call +// - ctx context.Context // - id int64 -// - qopts ...pg.QOpt -func (_e *ORM_Expecter) GetSpec(id interface{}, qopts ...interface{}) *ORM_GetSpec_Call { - return &ORM_GetSpec_Call{Call: _e.mock.On("GetSpec", - append([]interface{}{id}, qopts...)...)} +func (_e *ORM_Expecter) GetSpec(ctx interface{}, id interface{}) *ORM_GetSpec_Call { + return &ORM_GetSpec_Call{Call: _e.mock.On("GetSpec", ctx, id)} } -func (_c *ORM_GetSpec_Call) Run(run func(id int64, qopts ...pg.QOpt)) *ORM_GetSpec_Call { +func (_c *ORM_GetSpec_Call) Run(run func(ctx context.Context, id int64)) *ORM_GetSpec_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]pg.QOpt, len(args)-1) - for i, a := range args[1:] { - if a != nil { - variadicArgs[i] = a.(pg.QOpt) - } - } - run(args[0].(int64), variadicArgs...) + run(args[0].(context.Context), args[1].(int64)) }) return _c } @@ -1291,21 +1148,14 @@ func (_c *ORM_GetSpec_Call) Return(_a0 *feeds.JobProposalSpec, _a1 error) *ORM_G return _c } -func (_c *ORM_GetSpec_Call) RunAndReturn(run func(int64, ...pg.QOpt) (*feeds.JobProposalSpec, error)) *ORM_GetSpec_Call { +func (_c *ORM_GetSpec_Call) RunAndReturn(run func(context.Context, int64) (*feeds.JobProposalSpec, error)) *ORM_GetSpec_Call { _c.Call.Return(run) return _c } -// IsJobManaged provides a mock function with given fields: jobID, qopts -func (_m *ORM) IsJobManaged(jobID int64, qopts ...pg.QOpt) (bool, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, jobID) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// IsJobManaged provides a mock function with given fields: ctx, jobID +func (_m *ORM) IsJobManaged(ctx context.Context, jobID int64) (bool, error) { + ret := _m.Called(ctx, jobID) if len(ret) == 0 { panic("no return value specified for IsJobManaged") @@ -1313,17 +1163,17 @@ func (_m *ORM) IsJobManaged(jobID int64, qopts ...pg.QOpt) (bool, error) { var r0 bool var r1 error - if rf, ok := ret.Get(0).(func(int64, ...pg.QOpt) (bool, error)); ok { - return rf(jobID, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64) (bool, error)); ok { + return rf(ctx, jobID) } - if rf, ok := ret.Get(0).(func(int64, ...pg.QOpt) bool); ok { - r0 = rf(jobID, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64) bool); ok { + r0 = rf(ctx, jobID) } else { r0 = ret.Get(0).(bool) } - if rf, ok := ret.Get(1).(func(int64, ...pg.QOpt) error); ok { - r1 = rf(jobID, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok { + r1 = rf(ctx, jobID) } else { r1 = ret.Error(1) } @@ -1337,22 +1187,15 @@ type ORM_IsJobManaged_Call struct { } // IsJobManaged is a helper method to define mock.On call +// - ctx context.Context // - jobID int64 -// - qopts ...pg.QOpt -func (_e *ORM_Expecter) IsJobManaged(jobID interface{}, qopts ...interface{}) *ORM_IsJobManaged_Call { - return &ORM_IsJobManaged_Call{Call: _e.mock.On("IsJobManaged", - append([]interface{}{jobID}, qopts...)...)} +func (_e *ORM_Expecter) IsJobManaged(ctx interface{}, jobID interface{}) *ORM_IsJobManaged_Call { + return &ORM_IsJobManaged_Call{Call: _e.mock.On("IsJobManaged", ctx, jobID)} } -func (_c *ORM_IsJobManaged_Call) Run(run func(jobID int64, qopts ...pg.QOpt)) *ORM_IsJobManaged_Call { +func (_c *ORM_IsJobManaged_Call) Run(run func(ctx context.Context, jobID int64)) *ORM_IsJobManaged_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]pg.QOpt, len(args)-1) - for i, a := range args[1:] { - if a != nil { - variadicArgs[i] = a.(pg.QOpt) - } - } - run(args[0].(int64), variadicArgs...) + run(args[0].(context.Context), args[1].(int64)) }) return _c } @@ -1362,14 +1205,14 @@ func (_c *ORM_IsJobManaged_Call) Return(_a0 bool, _a1 error) *ORM_IsJobManaged_C return _c } -func (_c *ORM_IsJobManaged_Call) RunAndReturn(run func(int64, ...pg.QOpt) (bool, error)) *ORM_IsJobManaged_Call { +func (_c *ORM_IsJobManaged_Call) RunAndReturn(run func(context.Context, int64) (bool, error)) *ORM_IsJobManaged_Call { _c.Call.Return(run) return _c } -// ListChainConfigsByManagerIDs provides a mock function with given fields: mgrIDs -func (_m *ORM) ListChainConfigsByManagerIDs(mgrIDs []int64) ([]feeds.ChainConfig, error) { - ret := _m.Called(mgrIDs) +// ListChainConfigsByManagerIDs provides a mock function with given fields: ctx, mgrIDs +func (_m *ORM) ListChainConfigsByManagerIDs(ctx context.Context, mgrIDs []int64) ([]feeds.ChainConfig, error) { + ret := _m.Called(ctx, mgrIDs) if len(ret) == 0 { panic("no return value specified for ListChainConfigsByManagerIDs") @@ -1377,19 +1220,19 @@ func (_m *ORM) ListChainConfigsByManagerIDs(mgrIDs []int64) ([]feeds.ChainConfig var r0 []feeds.ChainConfig var r1 error - if rf, ok := ret.Get(0).(func([]int64) ([]feeds.ChainConfig, error)); ok { - return rf(mgrIDs) + if rf, ok := ret.Get(0).(func(context.Context, []int64) ([]feeds.ChainConfig, error)); ok { + return rf(ctx, mgrIDs) } - if rf, ok := ret.Get(0).(func([]int64) []feeds.ChainConfig); ok { - r0 = rf(mgrIDs) + if rf, ok := ret.Get(0).(func(context.Context, []int64) []feeds.ChainConfig); ok { + r0 = rf(ctx, mgrIDs) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]feeds.ChainConfig) } } - if rf, ok := ret.Get(1).(func([]int64) error); ok { - r1 = rf(mgrIDs) + if rf, ok := ret.Get(1).(func(context.Context, []int64) error); ok { + r1 = rf(ctx, mgrIDs) } else { r1 = ret.Error(1) } @@ -1403,14 +1246,15 @@ type ORM_ListChainConfigsByManagerIDs_Call struct { } // ListChainConfigsByManagerIDs is a helper method to define mock.On call +// - ctx context.Context // - mgrIDs []int64 -func (_e *ORM_Expecter) ListChainConfigsByManagerIDs(mgrIDs interface{}) *ORM_ListChainConfigsByManagerIDs_Call { - return &ORM_ListChainConfigsByManagerIDs_Call{Call: _e.mock.On("ListChainConfigsByManagerIDs", mgrIDs)} +func (_e *ORM_Expecter) ListChainConfigsByManagerIDs(ctx interface{}, mgrIDs interface{}) *ORM_ListChainConfigsByManagerIDs_Call { + return &ORM_ListChainConfigsByManagerIDs_Call{Call: _e.mock.On("ListChainConfigsByManagerIDs", ctx, mgrIDs)} } -func (_c *ORM_ListChainConfigsByManagerIDs_Call) Run(run func(mgrIDs []int64)) *ORM_ListChainConfigsByManagerIDs_Call { +func (_c *ORM_ListChainConfigsByManagerIDs_Call) Run(run func(ctx context.Context, mgrIDs []int64)) *ORM_ListChainConfigsByManagerIDs_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].([]int64)) + run(args[0].(context.Context), args[1].([]int64)) }) return _c } @@ -1420,14 +1264,14 @@ func (_c *ORM_ListChainConfigsByManagerIDs_Call) Return(_a0 []feeds.ChainConfig, return _c } -func (_c *ORM_ListChainConfigsByManagerIDs_Call) RunAndReturn(run func([]int64) ([]feeds.ChainConfig, error)) *ORM_ListChainConfigsByManagerIDs_Call { +func (_c *ORM_ListChainConfigsByManagerIDs_Call) RunAndReturn(run func(context.Context, []int64) ([]feeds.ChainConfig, error)) *ORM_ListChainConfigsByManagerIDs_Call { _c.Call.Return(run) return _c } -// ListJobProposals provides a mock function with given fields: -func (_m *ORM) ListJobProposals() ([]feeds.JobProposal, error) { - ret := _m.Called() +// ListJobProposals provides a mock function with given fields: ctx +func (_m *ORM) ListJobProposals(ctx context.Context) ([]feeds.JobProposal, error) { + ret := _m.Called(ctx) if len(ret) == 0 { panic("no return value specified for ListJobProposals") @@ -1435,19 +1279,19 @@ func (_m *ORM) ListJobProposals() ([]feeds.JobProposal, error) { var r0 []feeds.JobProposal var r1 error - if rf, ok := ret.Get(0).(func() ([]feeds.JobProposal, error)); ok { - return rf() + if rf, ok := ret.Get(0).(func(context.Context) ([]feeds.JobProposal, error)); ok { + return rf(ctx) } - if rf, ok := ret.Get(0).(func() []feeds.JobProposal); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context) []feeds.JobProposal); ok { + r0 = rf(ctx) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]feeds.JobProposal) } } - 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) } @@ -1461,13 +1305,14 @@ type ORM_ListJobProposals_Call struct { } // ListJobProposals is a helper method to define mock.On call -func (_e *ORM_Expecter) ListJobProposals() *ORM_ListJobProposals_Call { - return &ORM_ListJobProposals_Call{Call: _e.mock.On("ListJobProposals")} +// - ctx context.Context +func (_e *ORM_Expecter) ListJobProposals(ctx interface{}) *ORM_ListJobProposals_Call { + return &ORM_ListJobProposals_Call{Call: _e.mock.On("ListJobProposals", ctx)} } -func (_c *ORM_ListJobProposals_Call) Run(run func()) *ORM_ListJobProposals_Call { +func (_c *ORM_ListJobProposals_Call) Run(run func(ctx context.Context)) *ORM_ListJobProposals_Call { _c.Call.Run(func(args mock.Arguments) { - run() + run(args[0].(context.Context)) }) return _c } @@ -1477,21 +1322,14 @@ func (_c *ORM_ListJobProposals_Call) Return(jps []feeds.JobProposal, err error) return _c } -func (_c *ORM_ListJobProposals_Call) RunAndReturn(run func() ([]feeds.JobProposal, error)) *ORM_ListJobProposals_Call { +func (_c *ORM_ListJobProposals_Call) RunAndReturn(run func(context.Context) ([]feeds.JobProposal, error)) *ORM_ListJobProposals_Call { _c.Call.Return(run) return _c } -// ListJobProposalsByManagersIDs provides a mock function with given fields: ids, qopts -func (_m *ORM) ListJobProposalsByManagersIDs(ids []int64, qopts ...pg.QOpt) ([]feeds.JobProposal, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, ids) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// ListJobProposalsByManagersIDs provides a mock function with given fields: ctx, ids +func (_m *ORM) ListJobProposalsByManagersIDs(ctx context.Context, ids []int64) ([]feeds.JobProposal, error) { + ret := _m.Called(ctx, ids) if len(ret) == 0 { panic("no return value specified for ListJobProposalsByManagersIDs") @@ -1499,19 +1337,19 @@ func (_m *ORM) ListJobProposalsByManagersIDs(ids []int64, qopts ...pg.QOpt) ([]f var r0 []feeds.JobProposal var r1 error - if rf, ok := ret.Get(0).(func([]int64, ...pg.QOpt) ([]feeds.JobProposal, error)); ok { - return rf(ids, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, []int64) ([]feeds.JobProposal, error)); ok { + return rf(ctx, ids) } - if rf, ok := ret.Get(0).(func([]int64, ...pg.QOpt) []feeds.JobProposal); ok { - r0 = rf(ids, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, []int64) []feeds.JobProposal); ok { + r0 = rf(ctx, ids) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]feeds.JobProposal) } } - if rf, ok := ret.Get(1).(func([]int64, ...pg.QOpt) error); ok { - r1 = rf(ids, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, []int64) error); ok { + r1 = rf(ctx, ids) } else { r1 = ret.Error(1) } @@ -1525,22 +1363,15 @@ type ORM_ListJobProposalsByManagersIDs_Call struct { } // ListJobProposalsByManagersIDs is a helper method to define mock.On call +// - ctx context.Context // - ids []int64 -// - qopts ...pg.QOpt -func (_e *ORM_Expecter) ListJobProposalsByManagersIDs(ids interface{}, qopts ...interface{}) *ORM_ListJobProposalsByManagersIDs_Call { - return &ORM_ListJobProposalsByManagersIDs_Call{Call: _e.mock.On("ListJobProposalsByManagersIDs", - append([]interface{}{ids}, qopts...)...)} +func (_e *ORM_Expecter) ListJobProposalsByManagersIDs(ctx interface{}, ids interface{}) *ORM_ListJobProposalsByManagersIDs_Call { + return &ORM_ListJobProposalsByManagersIDs_Call{Call: _e.mock.On("ListJobProposalsByManagersIDs", ctx, ids)} } -func (_c *ORM_ListJobProposalsByManagersIDs_Call) Run(run func(ids []int64, qopts ...pg.QOpt)) *ORM_ListJobProposalsByManagersIDs_Call { +func (_c *ORM_ListJobProposalsByManagersIDs_Call) Run(run func(ctx context.Context, ids []int64)) *ORM_ListJobProposalsByManagersIDs_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]pg.QOpt, len(args)-1) - for i, a := range args[1:] { - if a != nil { - variadicArgs[i] = a.(pg.QOpt) - } - } - run(args[0].([]int64), variadicArgs...) + run(args[0].(context.Context), args[1].([]int64)) }) return _c } @@ -1550,14 +1381,14 @@ func (_c *ORM_ListJobProposalsByManagersIDs_Call) Return(_a0 []feeds.JobProposal return _c } -func (_c *ORM_ListJobProposalsByManagersIDs_Call) RunAndReturn(run func([]int64, ...pg.QOpt) ([]feeds.JobProposal, error)) *ORM_ListJobProposalsByManagersIDs_Call { +func (_c *ORM_ListJobProposalsByManagersIDs_Call) RunAndReturn(run func(context.Context, []int64) ([]feeds.JobProposal, error)) *ORM_ListJobProposalsByManagersIDs_Call { _c.Call.Return(run) return _c } -// ListManagers provides a mock function with given fields: -func (_m *ORM) ListManagers() ([]feeds.FeedsManager, error) { - ret := _m.Called() +// ListManagers provides a mock function with given fields: ctx +func (_m *ORM) ListManagers(ctx context.Context) ([]feeds.FeedsManager, error) { + ret := _m.Called(ctx) if len(ret) == 0 { panic("no return value specified for ListManagers") @@ -1565,19 +1396,19 @@ func (_m *ORM) ListManagers() ([]feeds.FeedsManager, error) { var r0 []feeds.FeedsManager var r1 error - if rf, ok := ret.Get(0).(func() ([]feeds.FeedsManager, error)); ok { - return rf() + if rf, ok := ret.Get(0).(func(context.Context) ([]feeds.FeedsManager, error)); ok { + return rf(ctx) } - if rf, ok := ret.Get(0).(func() []feeds.FeedsManager); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context) []feeds.FeedsManager); ok { + r0 = rf(ctx) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]feeds.FeedsManager) } } - 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) } @@ -1591,13 +1422,14 @@ type ORM_ListManagers_Call struct { } // ListManagers is a helper method to define mock.On call -func (_e *ORM_Expecter) ListManagers() *ORM_ListManagers_Call { - return &ORM_ListManagers_Call{Call: _e.mock.On("ListManagers")} +// - ctx context.Context +func (_e *ORM_Expecter) ListManagers(ctx interface{}) *ORM_ListManagers_Call { + return &ORM_ListManagers_Call{Call: _e.mock.On("ListManagers", ctx)} } -func (_c *ORM_ListManagers_Call) Run(run func()) *ORM_ListManagers_Call { +func (_c *ORM_ListManagers_Call) Run(run func(ctx context.Context)) *ORM_ListManagers_Call { _c.Call.Run(func(args mock.Arguments) { - run() + run(args[0].(context.Context)) }) return _c } @@ -1607,14 +1439,14 @@ func (_c *ORM_ListManagers_Call) Return(mgrs []feeds.FeedsManager, err error) *O return _c } -func (_c *ORM_ListManagers_Call) RunAndReturn(run func() ([]feeds.FeedsManager, error)) *ORM_ListManagers_Call { +func (_c *ORM_ListManagers_Call) RunAndReturn(run func(context.Context) ([]feeds.FeedsManager, error)) *ORM_ListManagers_Call { _c.Call.Return(run) return _c } -// ListManagersByIDs provides a mock function with given fields: ids -func (_m *ORM) ListManagersByIDs(ids []int64) ([]feeds.FeedsManager, error) { - ret := _m.Called(ids) +// ListManagersByIDs provides a mock function with given fields: ctx, ids +func (_m *ORM) ListManagersByIDs(ctx context.Context, ids []int64) ([]feeds.FeedsManager, error) { + ret := _m.Called(ctx, ids) if len(ret) == 0 { panic("no return value specified for ListManagersByIDs") @@ -1622,19 +1454,19 @@ func (_m *ORM) ListManagersByIDs(ids []int64) ([]feeds.FeedsManager, error) { var r0 []feeds.FeedsManager var r1 error - if rf, ok := ret.Get(0).(func([]int64) ([]feeds.FeedsManager, error)); ok { - return rf(ids) + if rf, ok := ret.Get(0).(func(context.Context, []int64) ([]feeds.FeedsManager, error)); ok { + return rf(ctx, ids) } - if rf, ok := ret.Get(0).(func([]int64) []feeds.FeedsManager); ok { - r0 = rf(ids) + if rf, ok := ret.Get(0).(func(context.Context, []int64) []feeds.FeedsManager); ok { + r0 = rf(ctx, ids) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]feeds.FeedsManager) } } - if rf, ok := ret.Get(1).(func([]int64) error); ok { - r1 = rf(ids) + if rf, ok := ret.Get(1).(func(context.Context, []int64) error); ok { + r1 = rf(ctx, ids) } else { r1 = ret.Error(1) } @@ -1648,14 +1480,15 @@ type ORM_ListManagersByIDs_Call struct { } // ListManagersByIDs is a helper method to define mock.On call +// - ctx context.Context // - ids []int64 -func (_e *ORM_Expecter) ListManagersByIDs(ids interface{}) *ORM_ListManagersByIDs_Call { - return &ORM_ListManagersByIDs_Call{Call: _e.mock.On("ListManagersByIDs", ids)} +func (_e *ORM_Expecter) ListManagersByIDs(ctx interface{}, ids interface{}) *ORM_ListManagersByIDs_Call { + return &ORM_ListManagersByIDs_Call{Call: _e.mock.On("ListManagersByIDs", ctx, ids)} } -func (_c *ORM_ListManagersByIDs_Call) Run(run func(ids []int64)) *ORM_ListManagersByIDs_Call { +func (_c *ORM_ListManagersByIDs_Call) Run(run func(ctx context.Context, ids []int64)) *ORM_ListManagersByIDs_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].([]int64)) + run(args[0].(context.Context), args[1].([]int64)) }) return _c } @@ -1665,21 +1498,14 @@ func (_c *ORM_ListManagersByIDs_Call) Return(_a0 []feeds.FeedsManager, _a1 error return _c } -func (_c *ORM_ListManagersByIDs_Call) RunAndReturn(run func([]int64) ([]feeds.FeedsManager, error)) *ORM_ListManagersByIDs_Call { +func (_c *ORM_ListManagersByIDs_Call) RunAndReturn(run func(context.Context, []int64) ([]feeds.FeedsManager, error)) *ORM_ListManagersByIDs_Call { _c.Call.Return(run) return _c } -// ListSpecsByJobProposalIDs provides a mock function with given fields: ids, qopts -func (_m *ORM) ListSpecsByJobProposalIDs(ids []int64, qopts ...pg.QOpt) ([]feeds.JobProposalSpec, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, ids) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// ListSpecsByJobProposalIDs provides a mock function with given fields: ctx, ids +func (_m *ORM) ListSpecsByJobProposalIDs(ctx context.Context, ids []int64) ([]feeds.JobProposalSpec, error) { + ret := _m.Called(ctx, ids) if len(ret) == 0 { panic("no return value specified for ListSpecsByJobProposalIDs") @@ -1687,19 +1513,19 @@ func (_m *ORM) ListSpecsByJobProposalIDs(ids []int64, qopts ...pg.QOpt) ([]feeds var r0 []feeds.JobProposalSpec var r1 error - if rf, ok := ret.Get(0).(func([]int64, ...pg.QOpt) ([]feeds.JobProposalSpec, error)); ok { - return rf(ids, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, []int64) ([]feeds.JobProposalSpec, error)); ok { + return rf(ctx, ids) } - if rf, ok := ret.Get(0).(func([]int64, ...pg.QOpt) []feeds.JobProposalSpec); ok { - r0 = rf(ids, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, []int64) []feeds.JobProposalSpec); ok { + r0 = rf(ctx, ids) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]feeds.JobProposalSpec) } } - if rf, ok := ret.Get(1).(func([]int64, ...pg.QOpt) error); ok { - r1 = rf(ids, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, []int64) error); ok { + r1 = rf(ctx, ids) } else { r1 = ret.Error(1) } @@ -1713,22 +1539,15 @@ type ORM_ListSpecsByJobProposalIDs_Call struct { } // ListSpecsByJobProposalIDs is a helper method to define mock.On call +// - ctx context.Context // - ids []int64 -// - qopts ...pg.QOpt -func (_e *ORM_Expecter) ListSpecsByJobProposalIDs(ids interface{}, qopts ...interface{}) *ORM_ListSpecsByJobProposalIDs_Call { - return &ORM_ListSpecsByJobProposalIDs_Call{Call: _e.mock.On("ListSpecsByJobProposalIDs", - append([]interface{}{ids}, qopts...)...)} +func (_e *ORM_Expecter) ListSpecsByJobProposalIDs(ctx interface{}, ids interface{}) *ORM_ListSpecsByJobProposalIDs_Call { + return &ORM_ListSpecsByJobProposalIDs_Call{Call: _e.mock.On("ListSpecsByJobProposalIDs", ctx, ids)} } -func (_c *ORM_ListSpecsByJobProposalIDs_Call) Run(run func(ids []int64, qopts ...pg.QOpt)) *ORM_ListSpecsByJobProposalIDs_Call { +func (_c *ORM_ListSpecsByJobProposalIDs_Call) Run(run func(ctx context.Context, ids []int64)) *ORM_ListSpecsByJobProposalIDs_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]pg.QOpt, len(args)-1) - for i, a := range args[1:] { - if a != nil { - variadicArgs[i] = a.(pg.QOpt) - } - } - run(args[0].([]int64), variadicArgs...) + run(args[0].(context.Context), args[1].([]int64)) }) return _c } @@ -1738,29 +1557,22 @@ func (_c *ORM_ListSpecsByJobProposalIDs_Call) Return(_a0 []feeds.JobProposalSpec return _c } -func (_c *ORM_ListSpecsByJobProposalIDs_Call) RunAndReturn(run func([]int64, ...pg.QOpt) ([]feeds.JobProposalSpec, error)) *ORM_ListSpecsByJobProposalIDs_Call { +func (_c *ORM_ListSpecsByJobProposalIDs_Call) RunAndReturn(run func(context.Context, []int64) ([]feeds.JobProposalSpec, error)) *ORM_ListSpecsByJobProposalIDs_Call { _c.Call.Return(run) return _c } -// RejectSpec provides a mock function with given fields: id, qopts -func (_m *ORM) RejectSpec(id int64, qopts ...pg.QOpt) error { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, id) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// RejectSpec provides a mock function with given fields: ctx, id +func (_m *ORM) RejectSpec(ctx context.Context, id int64) error { + ret := _m.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for RejectSpec") } var r0 error - if rf, ok := ret.Get(0).(func(int64, ...pg.QOpt) error); ok { - r0 = rf(id, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok { + r0 = rf(ctx, id) } else { r0 = ret.Error(0) } @@ -1774,22 +1586,15 @@ type ORM_RejectSpec_Call struct { } // RejectSpec is a helper method to define mock.On call +// - ctx context.Context // - id int64 -// - qopts ...pg.QOpt -func (_e *ORM_Expecter) RejectSpec(id interface{}, qopts ...interface{}) *ORM_RejectSpec_Call { - return &ORM_RejectSpec_Call{Call: _e.mock.On("RejectSpec", - append([]interface{}{id}, qopts...)...)} +func (_e *ORM_Expecter) RejectSpec(ctx interface{}, id interface{}) *ORM_RejectSpec_Call { + return &ORM_RejectSpec_Call{Call: _e.mock.On("RejectSpec", ctx, id)} } -func (_c *ORM_RejectSpec_Call) Run(run func(id int64, qopts ...pg.QOpt)) *ORM_RejectSpec_Call { +func (_c *ORM_RejectSpec_Call) Run(run func(ctx context.Context, id int64)) *ORM_RejectSpec_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]pg.QOpt, len(args)-1) - for i, a := range args[1:] { - if a != nil { - variadicArgs[i] = a.(pg.QOpt) - } - } - run(args[0].(int64), variadicArgs...) + run(args[0].(context.Context), args[1].(int64)) }) return _c } @@ -1799,29 +1604,22 @@ func (_c *ORM_RejectSpec_Call) Return(_a0 error) *ORM_RejectSpec_Call { return _c } -func (_c *ORM_RejectSpec_Call) RunAndReturn(run func(int64, ...pg.QOpt) error) *ORM_RejectSpec_Call { +func (_c *ORM_RejectSpec_Call) RunAndReturn(run func(context.Context, int64) error) *ORM_RejectSpec_Call { _c.Call.Return(run) return _c } -// RevokeSpec provides a mock function with given fields: id, qopts -func (_m *ORM) RevokeSpec(id int64, qopts ...pg.QOpt) error { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, id) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// RevokeSpec provides a mock function with given fields: ctx, id +func (_m *ORM) RevokeSpec(ctx context.Context, id int64) error { + ret := _m.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for RevokeSpec") } var r0 error - if rf, ok := ret.Get(0).(func(int64, ...pg.QOpt) error); ok { - r0 = rf(id, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok { + r0 = rf(ctx, id) } else { r0 = ret.Error(0) } @@ -1835,22 +1633,15 @@ type ORM_RevokeSpec_Call struct { } // RevokeSpec is a helper method to define mock.On call +// - ctx context.Context // - id int64 -// - qopts ...pg.QOpt -func (_e *ORM_Expecter) RevokeSpec(id interface{}, qopts ...interface{}) *ORM_RevokeSpec_Call { - return &ORM_RevokeSpec_Call{Call: _e.mock.On("RevokeSpec", - append([]interface{}{id}, qopts...)...)} +func (_e *ORM_Expecter) RevokeSpec(ctx interface{}, id interface{}) *ORM_RevokeSpec_Call { + return &ORM_RevokeSpec_Call{Call: _e.mock.On("RevokeSpec", ctx, id)} } -func (_c *ORM_RevokeSpec_Call) Run(run func(id int64, qopts ...pg.QOpt)) *ORM_RevokeSpec_Call { +func (_c *ORM_RevokeSpec_Call) Run(run func(ctx context.Context, id int64)) *ORM_RevokeSpec_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]pg.QOpt, len(args)-1) - for i, a := range args[1:] { - if a != nil { - variadicArgs[i] = a.(pg.QOpt) - } - } - run(args[0].(int64), variadicArgs...) + run(args[0].(context.Context), args[1].(int64)) }) return _c } @@ -1860,14 +1651,61 @@ func (_c *ORM_RevokeSpec_Call) Return(_a0 error) *ORM_RevokeSpec_Call { return _c } -func (_c *ORM_RevokeSpec_Call) RunAndReturn(run func(int64, ...pg.QOpt) error) *ORM_RevokeSpec_Call { +func (_c *ORM_RevokeSpec_Call) RunAndReturn(run func(context.Context, int64) error) *ORM_RevokeSpec_Call { _c.Call.Return(run) return _c } -// UpdateChainConfig provides a mock function with given fields: cfg -func (_m *ORM) UpdateChainConfig(cfg feeds.ChainConfig) (int64, error) { - ret := _m.Called(cfg) +// Transact provides a mock function with given fields: _a0, _a1 +func (_m *ORM) Transact(_a0 context.Context, _a1 func(feeds.ORM) error) error { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for Transact") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, func(feeds.ORM) error) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ORM_Transact_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Transact' +type ORM_Transact_Call struct { + *mock.Call +} + +// Transact is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 func(feeds.ORM) error +func (_e *ORM_Expecter) Transact(_a0 interface{}, _a1 interface{}) *ORM_Transact_Call { + return &ORM_Transact_Call{Call: _e.mock.On("Transact", _a0, _a1)} +} + +func (_c *ORM_Transact_Call) Run(run func(_a0 context.Context, _a1 func(feeds.ORM) error)) *ORM_Transact_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(func(feeds.ORM) error)) + }) + return _c +} + +func (_c *ORM_Transact_Call) Return(_a0 error) *ORM_Transact_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ORM_Transact_Call) RunAndReturn(run func(context.Context, func(feeds.ORM) error) error) *ORM_Transact_Call { + _c.Call.Return(run) + return _c +} + +// UpdateChainConfig provides a mock function with given fields: ctx, cfg +func (_m *ORM) UpdateChainConfig(ctx context.Context, cfg feeds.ChainConfig) (int64, error) { + ret := _m.Called(ctx, cfg) if len(ret) == 0 { panic("no return value specified for UpdateChainConfig") @@ -1875,17 +1713,17 @@ func (_m *ORM) UpdateChainConfig(cfg feeds.ChainConfig) (int64, error) { var r0 int64 var r1 error - if rf, ok := ret.Get(0).(func(feeds.ChainConfig) (int64, error)); ok { - return rf(cfg) + if rf, ok := ret.Get(0).(func(context.Context, feeds.ChainConfig) (int64, error)); ok { + return rf(ctx, cfg) } - if rf, ok := ret.Get(0).(func(feeds.ChainConfig) int64); ok { - r0 = rf(cfg) + if rf, ok := ret.Get(0).(func(context.Context, feeds.ChainConfig) int64); ok { + r0 = rf(ctx, cfg) } else { r0 = ret.Get(0).(int64) } - if rf, ok := ret.Get(1).(func(feeds.ChainConfig) error); ok { - r1 = rf(cfg) + if rf, ok := ret.Get(1).(func(context.Context, feeds.ChainConfig) error); ok { + r1 = rf(ctx, cfg) } else { r1 = ret.Error(1) } @@ -1899,14 +1737,15 @@ type ORM_UpdateChainConfig_Call struct { } // UpdateChainConfig is a helper method to define mock.On call +// - ctx context.Context // - cfg feeds.ChainConfig -func (_e *ORM_Expecter) UpdateChainConfig(cfg interface{}) *ORM_UpdateChainConfig_Call { - return &ORM_UpdateChainConfig_Call{Call: _e.mock.On("UpdateChainConfig", cfg)} +func (_e *ORM_Expecter) UpdateChainConfig(ctx interface{}, cfg interface{}) *ORM_UpdateChainConfig_Call { + return &ORM_UpdateChainConfig_Call{Call: _e.mock.On("UpdateChainConfig", ctx, cfg)} } -func (_c *ORM_UpdateChainConfig_Call) Run(run func(cfg feeds.ChainConfig)) *ORM_UpdateChainConfig_Call { +func (_c *ORM_UpdateChainConfig_Call) Run(run func(ctx context.Context, cfg feeds.ChainConfig)) *ORM_UpdateChainConfig_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(feeds.ChainConfig)) + run(args[0].(context.Context), args[1].(feeds.ChainConfig)) }) return _c } @@ -1916,29 +1755,22 @@ func (_c *ORM_UpdateChainConfig_Call) Return(_a0 int64, _a1 error) *ORM_UpdateCh return _c } -func (_c *ORM_UpdateChainConfig_Call) RunAndReturn(run func(feeds.ChainConfig) (int64, error)) *ORM_UpdateChainConfig_Call { +func (_c *ORM_UpdateChainConfig_Call) RunAndReturn(run func(context.Context, feeds.ChainConfig) (int64, error)) *ORM_UpdateChainConfig_Call { _c.Call.Return(run) return _c } -// UpdateJobProposalStatus provides a mock function with given fields: id, status, qopts -func (_m *ORM) UpdateJobProposalStatus(id int64, status feeds.JobProposalStatus, qopts ...pg.QOpt) error { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, id, status) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// UpdateJobProposalStatus provides a mock function with given fields: ctx, id, status +func (_m *ORM) UpdateJobProposalStatus(ctx context.Context, id int64, status feeds.JobProposalStatus) error { + ret := _m.Called(ctx, id, status) if len(ret) == 0 { panic("no return value specified for UpdateJobProposalStatus") } var r0 error - if rf, ok := ret.Get(0).(func(int64, feeds.JobProposalStatus, ...pg.QOpt) error); ok { - r0 = rf(id, status, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64, feeds.JobProposalStatus) error); ok { + r0 = rf(ctx, id, status) } else { r0 = ret.Error(0) } @@ -1952,23 +1784,16 @@ type ORM_UpdateJobProposalStatus_Call struct { } // UpdateJobProposalStatus is a helper method to define mock.On call +// - ctx context.Context // - id int64 // - status feeds.JobProposalStatus -// - qopts ...pg.QOpt -func (_e *ORM_Expecter) UpdateJobProposalStatus(id interface{}, status interface{}, qopts ...interface{}) *ORM_UpdateJobProposalStatus_Call { - return &ORM_UpdateJobProposalStatus_Call{Call: _e.mock.On("UpdateJobProposalStatus", - append([]interface{}{id, status}, qopts...)...)} +func (_e *ORM_Expecter) UpdateJobProposalStatus(ctx interface{}, id interface{}, status interface{}) *ORM_UpdateJobProposalStatus_Call { + return &ORM_UpdateJobProposalStatus_Call{Call: _e.mock.On("UpdateJobProposalStatus", ctx, id, status)} } -func (_c *ORM_UpdateJobProposalStatus_Call) Run(run func(id int64, status feeds.JobProposalStatus, qopts ...pg.QOpt)) *ORM_UpdateJobProposalStatus_Call { +func (_c *ORM_UpdateJobProposalStatus_Call) Run(run func(ctx context.Context, id int64, status feeds.JobProposalStatus)) *ORM_UpdateJobProposalStatus_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]pg.QOpt, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(pg.QOpt) - } - } - run(args[0].(int64), args[1].(feeds.JobProposalStatus), variadicArgs...) + run(args[0].(context.Context), args[1].(int64), args[2].(feeds.JobProposalStatus)) }) return _c } @@ -1978,29 +1803,22 @@ func (_c *ORM_UpdateJobProposalStatus_Call) Return(_a0 error) *ORM_UpdateJobProp return _c } -func (_c *ORM_UpdateJobProposalStatus_Call) RunAndReturn(run func(int64, feeds.JobProposalStatus, ...pg.QOpt) error) *ORM_UpdateJobProposalStatus_Call { +func (_c *ORM_UpdateJobProposalStatus_Call) RunAndReturn(run func(context.Context, int64, feeds.JobProposalStatus) error) *ORM_UpdateJobProposalStatus_Call { _c.Call.Return(run) return _c } -// UpdateManager provides a mock function with given fields: mgr, qopts -func (_m *ORM) UpdateManager(mgr feeds.FeedsManager, qopts ...pg.QOpt) error { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, mgr) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// UpdateManager provides a mock function with given fields: ctx, mgr +func (_m *ORM) UpdateManager(ctx context.Context, mgr feeds.FeedsManager) error { + ret := _m.Called(ctx, mgr) if len(ret) == 0 { panic("no return value specified for UpdateManager") } var r0 error - if rf, ok := ret.Get(0).(func(feeds.FeedsManager, ...pg.QOpt) error); ok { - r0 = rf(mgr, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, feeds.FeedsManager) error); ok { + r0 = rf(ctx, mgr) } else { r0 = ret.Error(0) } @@ -2014,22 +1832,15 @@ type ORM_UpdateManager_Call struct { } // UpdateManager is a helper method to define mock.On call +// - ctx context.Context // - mgr feeds.FeedsManager -// - qopts ...pg.QOpt -func (_e *ORM_Expecter) UpdateManager(mgr interface{}, qopts ...interface{}) *ORM_UpdateManager_Call { - return &ORM_UpdateManager_Call{Call: _e.mock.On("UpdateManager", - append([]interface{}{mgr}, qopts...)...)} +func (_e *ORM_Expecter) UpdateManager(ctx interface{}, mgr interface{}) *ORM_UpdateManager_Call { + return &ORM_UpdateManager_Call{Call: _e.mock.On("UpdateManager", ctx, mgr)} } -func (_c *ORM_UpdateManager_Call) Run(run func(mgr feeds.FeedsManager, qopts ...pg.QOpt)) *ORM_UpdateManager_Call { +func (_c *ORM_UpdateManager_Call) Run(run func(ctx context.Context, mgr feeds.FeedsManager)) *ORM_UpdateManager_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]pg.QOpt, len(args)-1) - for i, a := range args[1:] { - if a != nil { - variadicArgs[i] = a.(pg.QOpt) - } - } - run(args[0].(feeds.FeedsManager), variadicArgs...) + run(args[0].(context.Context), args[1].(feeds.FeedsManager)) }) return _c } @@ -2039,29 +1850,22 @@ func (_c *ORM_UpdateManager_Call) Return(_a0 error) *ORM_UpdateManager_Call { return _c } -func (_c *ORM_UpdateManager_Call) RunAndReturn(run func(feeds.FeedsManager, ...pg.QOpt) error) *ORM_UpdateManager_Call { +func (_c *ORM_UpdateManager_Call) RunAndReturn(run func(context.Context, feeds.FeedsManager) error) *ORM_UpdateManager_Call { _c.Call.Return(run) return _c } -// UpdateSpecDefinition provides a mock function with given fields: id, spec, qopts -func (_m *ORM) UpdateSpecDefinition(id int64, spec string, qopts ...pg.QOpt) error { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, id, spec) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// UpdateSpecDefinition provides a mock function with given fields: ctx, id, spec +func (_m *ORM) UpdateSpecDefinition(ctx context.Context, id int64, spec string) error { + ret := _m.Called(ctx, id, spec) if len(ret) == 0 { panic("no return value specified for UpdateSpecDefinition") } var r0 error - if rf, ok := ret.Get(0).(func(int64, string, ...pg.QOpt) error); ok { - r0 = rf(id, spec, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64, string) error); ok { + r0 = rf(ctx, id, spec) } else { r0 = ret.Error(0) } @@ -2075,23 +1879,16 @@ type ORM_UpdateSpecDefinition_Call struct { } // UpdateSpecDefinition is a helper method to define mock.On call +// - ctx context.Context // - id int64 // - spec string -// - qopts ...pg.QOpt -func (_e *ORM_Expecter) UpdateSpecDefinition(id interface{}, spec interface{}, qopts ...interface{}) *ORM_UpdateSpecDefinition_Call { - return &ORM_UpdateSpecDefinition_Call{Call: _e.mock.On("UpdateSpecDefinition", - append([]interface{}{id, spec}, qopts...)...)} +func (_e *ORM_Expecter) UpdateSpecDefinition(ctx interface{}, id interface{}, spec interface{}) *ORM_UpdateSpecDefinition_Call { + return &ORM_UpdateSpecDefinition_Call{Call: _e.mock.On("UpdateSpecDefinition", ctx, id, spec)} } -func (_c *ORM_UpdateSpecDefinition_Call) Run(run func(id int64, spec string, qopts ...pg.QOpt)) *ORM_UpdateSpecDefinition_Call { +func (_c *ORM_UpdateSpecDefinition_Call) Run(run func(ctx context.Context, id int64, spec string)) *ORM_UpdateSpecDefinition_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]pg.QOpt, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(pg.QOpt) - } - } - run(args[0].(int64), args[1].(string), variadicArgs...) + run(args[0].(context.Context), args[1].(int64), args[2].(string)) }) return _c } @@ -2101,21 +1898,14 @@ func (_c *ORM_UpdateSpecDefinition_Call) Return(_a0 error) *ORM_UpdateSpecDefini return _c } -func (_c *ORM_UpdateSpecDefinition_Call) RunAndReturn(run func(int64, string, ...pg.QOpt) error) *ORM_UpdateSpecDefinition_Call { +func (_c *ORM_UpdateSpecDefinition_Call) RunAndReturn(run func(context.Context, int64, string) error) *ORM_UpdateSpecDefinition_Call { _c.Call.Return(run) return _c } -// UpsertJobProposal provides a mock function with given fields: jp, qopts -func (_m *ORM) UpsertJobProposal(jp *feeds.JobProposal, qopts ...pg.QOpt) (int64, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, jp) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// UpsertJobProposal provides a mock function with given fields: ctx, jp +func (_m *ORM) UpsertJobProposal(ctx context.Context, jp *feeds.JobProposal) (int64, error) { + ret := _m.Called(ctx, jp) if len(ret) == 0 { panic("no return value specified for UpsertJobProposal") @@ -2123,17 +1913,17 @@ func (_m *ORM) UpsertJobProposal(jp *feeds.JobProposal, qopts ...pg.QOpt) (int64 var r0 int64 var r1 error - if rf, ok := ret.Get(0).(func(*feeds.JobProposal, ...pg.QOpt) (int64, error)); ok { - return rf(jp, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, *feeds.JobProposal) (int64, error)); ok { + return rf(ctx, jp) } - if rf, ok := ret.Get(0).(func(*feeds.JobProposal, ...pg.QOpt) int64); ok { - r0 = rf(jp, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, *feeds.JobProposal) int64); ok { + r0 = rf(ctx, jp) } else { r0 = ret.Get(0).(int64) } - if rf, ok := ret.Get(1).(func(*feeds.JobProposal, ...pg.QOpt) error); ok { - r1 = rf(jp, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, *feeds.JobProposal) error); ok { + r1 = rf(ctx, jp) } else { r1 = ret.Error(1) } @@ -2147,22 +1937,15 @@ type ORM_UpsertJobProposal_Call struct { } // UpsertJobProposal is a helper method to define mock.On call +// - ctx context.Context // - jp *feeds.JobProposal -// - qopts ...pg.QOpt -func (_e *ORM_Expecter) UpsertJobProposal(jp interface{}, qopts ...interface{}) *ORM_UpsertJobProposal_Call { - return &ORM_UpsertJobProposal_Call{Call: _e.mock.On("UpsertJobProposal", - append([]interface{}{jp}, qopts...)...)} +func (_e *ORM_Expecter) UpsertJobProposal(ctx interface{}, jp interface{}) *ORM_UpsertJobProposal_Call { + return &ORM_UpsertJobProposal_Call{Call: _e.mock.On("UpsertJobProposal", ctx, jp)} } -func (_c *ORM_UpsertJobProposal_Call) Run(run func(jp *feeds.JobProposal, qopts ...pg.QOpt)) *ORM_UpsertJobProposal_Call { +func (_c *ORM_UpsertJobProposal_Call) Run(run func(ctx context.Context, jp *feeds.JobProposal)) *ORM_UpsertJobProposal_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]pg.QOpt, len(args)-1) - for i, a := range args[1:] { - if a != nil { - variadicArgs[i] = a.(pg.QOpt) - } - } - run(args[0].(*feeds.JobProposal), variadicArgs...) + run(args[0].(context.Context), args[1].(*feeds.JobProposal)) }) return _c } @@ -2172,7 +1955,55 @@ func (_c *ORM_UpsertJobProposal_Call) Return(_a0 int64, _a1 error) *ORM_UpsertJo return _c } -func (_c *ORM_UpsertJobProposal_Call) RunAndReturn(run func(*feeds.JobProposal, ...pg.QOpt) (int64, error)) *ORM_UpsertJobProposal_Call { +func (_c *ORM_UpsertJobProposal_Call) RunAndReturn(run func(context.Context, *feeds.JobProposal) (int64, error)) *ORM_UpsertJobProposal_Call { + _c.Call.Return(run) + return _c +} + +// WithDataSource provides a mock function with given fields: _a0 +func (_m *ORM) WithDataSource(_a0 sqlutil.DataSource) feeds.ORM { + ret := _m.Called(_a0) + + if len(ret) == 0 { + panic("no return value specified for WithDataSource") + } + + var r0 feeds.ORM + if rf, ok := ret.Get(0).(func(sqlutil.DataSource) feeds.ORM); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(feeds.ORM) + } + } + + return r0 +} + +// ORM_WithDataSource_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WithDataSource' +type ORM_WithDataSource_Call struct { + *mock.Call +} + +// WithDataSource is a helper method to define mock.On call +// - _a0 sqlutil.DataSource +func (_e *ORM_Expecter) WithDataSource(_a0 interface{}) *ORM_WithDataSource_Call { + return &ORM_WithDataSource_Call{Call: _e.mock.On("WithDataSource", _a0)} +} + +func (_c *ORM_WithDataSource_Call) Run(run func(_a0 sqlutil.DataSource)) *ORM_WithDataSource_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(sqlutil.DataSource)) + }) + return _c +} + +func (_c *ORM_WithDataSource_Call) Return(_a0 feeds.ORM) *ORM_WithDataSource_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ORM_WithDataSource_Call) RunAndReturn(run func(sqlutil.DataSource) feeds.ORM) *ORM_WithDataSource_Call { _c.Call.Return(run) return _c } diff --git a/core/services/feeds/mocks/service.go b/core/services/feeds/mocks/service.go index 05ede181f44..1e2e6393276 100644 --- a/core/services/feeds/mocks/service.go +++ b/core/services/feeds/mocks/service.go @@ -68,9 +68,9 @@ func (_m *Service) Close() error { return r0 } -// CountJobProposalsByStatus provides a mock function with given fields: -func (_m *Service) CountJobProposalsByStatus() (*feeds.JobProposalCounts, error) { - ret := _m.Called() +// CountJobProposalsByStatus provides a mock function with given fields: ctx +func (_m *Service) CountJobProposalsByStatus(ctx context.Context) (*feeds.JobProposalCounts, error) { + ret := _m.Called(ctx) if len(ret) == 0 { panic("no return value specified for CountJobProposalsByStatus") @@ -78,19 +78,19 @@ func (_m *Service) CountJobProposalsByStatus() (*feeds.JobProposalCounts, error) var r0 *feeds.JobProposalCounts var r1 error - if rf, ok := ret.Get(0).(func() (*feeds.JobProposalCounts, error)); ok { - return rf() + if rf, ok := ret.Get(0).(func(context.Context) (*feeds.JobProposalCounts, error)); ok { + return rf(ctx) } - if rf, ok := ret.Get(0).(func() *feeds.JobProposalCounts); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context) *feeds.JobProposalCounts); ok { + r0 = rf(ctx) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*feeds.JobProposalCounts) } } - 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) } @@ -98,9 +98,9 @@ func (_m *Service) CountJobProposalsByStatus() (*feeds.JobProposalCounts, error) return r0, r1 } -// CountManagers provides a mock function with given fields: -func (_m *Service) CountManagers() (int64, error) { - ret := _m.Called() +// CountManagers provides a mock function with given fields: ctx +func (_m *Service) CountManagers(ctx context.Context) (int64, error) { + ret := _m.Called(ctx) if len(ret) == 0 { panic("no return value specified for CountManagers") @@ -108,17 +108,17 @@ func (_m *Service) CountManagers() (int64, error) { var r0 int64 var r1 error - if rf, ok := ret.Get(0).(func() (int64, error)); ok { - return rf() + if rf, ok := ret.Get(0).(func(context.Context) (int64, error)); ok { + return rf(ctx) } - if rf, ok := ret.Get(0).(func() int64); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context) int64); ok { + r0 = rf(ctx) } else { r0 = ret.Get(0).(int64) } - 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) } @@ -210,9 +210,9 @@ func (_m *Service) DeleteJob(ctx context.Context, args *feeds.DeleteJobArgs) (in return r0, r1 } -// GetChainConfig provides a mock function with given fields: id -func (_m *Service) GetChainConfig(id int64) (*feeds.ChainConfig, error) { - ret := _m.Called(id) +// GetChainConfig provides a mock function with given fields: ctx, id +func (_m *Service) GetChainConfig(ctx context.Context, id int64) (*feeds.ChainConfig, error) { + ret := _m.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for GetChainConfig") @@ -220,19 +220,19 @@ func (_m *Service) GetChainConfig(id int64) (*feeds.ChainConfig, error) { var r0 *feeds.ChainConfig var r1 error - if rf, ok := ret.Get(0).(func(int64) (*feeds.ChainConfig, error)); ok { - return rf(id) + if rf, ok := ret.Get(0).(func(context.Context, int64) (*feeds.ChainConfig, error)); ok { + return rf(ctx, id) } - if rf, ok := ret.Get(0).(func(int64) *feeds.ChainConfig); ok { - r0 = rf(id) + if rf, ok := ret.Get(0).(func(context.Context, int64) *feeds.ChainConfig); ok { + r0 = rf(ctx, id) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*feeds.ChainConfig) } } - if rf, ok := ret.Get(1).(func(int64) error); ok { - r1 = rf(id) + if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok { + r1 = rf(ctx, id) } else { r1 = ret.Error(1) } @@ -240,9 +240,9 @@ func (_m *Service) GetChainConfig(id int64) (*feeds.ChainConfig, error) { return r0, r1 } -// GetJobProposal provides a mock function with given fields: id -func (_m *Service) GetJobProposal(id int64) (*feeds.JobProposal, error) { - ret := _m.Called(id) +// GetJobProposal provides a mock function with given fields: ctx, id +func (_m *Service) GetJobProposal(ctx context.Context, id int64) (*feeds.JobProposal, error) { + ret := _m.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for GetJobProposal") @@ -250,19 +250,19 @@ func (_m *Service) GetJobProposal(id int64) (*feeds.JobProposal, error) { var r0 *feeds.JobProposal var r1 error - if rf, ok := ret.Get(0).(func(int64) (*feeds.JobProposal, error)); ok { - return rf(id) + if rf, ok := ret.Get(0).(func(context.Context, int64) (*feeds.JobProposal, error)); ok { + return rf(ctx, id) } - if rf, ok := ret.Get(0).(func(int64) *feeds.JobProposal); ok { - r0 = rf(id) + if rf, ok := ret.Get(0).(func(context.Context, int64) *feeds.JobProposal); ok { + r0 = rf(ctx, id) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*feeds.JobProposal) } } - if rf, ok := ret.Get(1).(func(int64) error); ok { - r1 = rf(id) + if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok { + r1 = rf(ctx, id) } else { r1 = ret.Error(1) } @@ -270,9 +270,9 @@ func (_m *Service) GetJobProposal(id int64) (*feeds.JobProposal, error) { return r0, r1 } -// GetManager provides a mock function with given fields: id -func (_m *Service) GetManager(id int64) (*feeds.FeedsManager, error) { - ret := _m.Called(id) +// GetManager provides a mock function with given fields: ctx, id +func (_m *Service) GetManager(ctx context.Context, id int64) (*feeds.FeedsManager, error) { + ret := _m.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for GetManager") @@ -280,19 +280,19 @@ func (_m *Service) GetManager(id int64) (*feeds.FeedsManager, error) { var r0 *feeds.FeedsManager var r1 error - if rf, ok := ret.Get(0).(func(int64) (*feeds.FeedsManager, error)); ok { - return rf(id) + if rf, ok := ret.Get(0).(func(context.Context, int64) (*feeds.FeedsManager, error)); ok { + return rf(ctx, id) } - if rf, ok := ret.Get(0).(func(int64) *feeds.FeedsManager); ok { - r0 = rf(id) + if rf, ok := ret.Get(0).(func(context.Context, int64) *feeds.FeedsManager); ok { + r0 = rf(ctx, id) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*feeds.FeedsManager) } } - if rf, ok := ret.Get(1).(func(int64) error); ok { - r1 = rf(id) + if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok { + r1 = rf(ctx, id) } else { r1 = ret.Error(1) } @@ -300,9 +300,9 @@ func (_m *Service) GetManager(id int64) (*feeds.FeedsManager, error) { return r0, r1 } -// GetSpec provides a mock function with given fields: id -func (_m *Service) GetSpec(id int64) (*feeds.JobProposalSpec, error) { - ret := _m.Called(id) +// GetSpec provides a mock function with given fields: ctx, id +func (_m *Service) GetSpec(ctx context.Context, id int64) (*feeds.JobProposalSpec, error) { + ret := _m.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for GetSpec") @@ -310,19 +310,19 @@ func (_m *Service) GetSpec(id int64) (*feeds.JobProposalSpec, error) { var r0 *feeds.JobProposalSpec var r1 error - if rf, ok := ret.Get(0).(func(int64) (*feeds.JobProposalSpec, error)); ok { - return rf(id) + if rf, ok := ret.Get(0).(func(context.Context, int64) (*feeds.JobProposalSpec, error)); ok { + return rf(ctx, id) } - if rf, ok := ret.Get(0).(func(int64) *feeds.JobProposalSpec); ok { - r0 = rf(id) + if rf, ok := ret.Get(0).(func(context.Context, int64) *feeds.JobProposalSpec); ok { + r0 = rf(ctx, id) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*feeds.JobProposalSpec) } } - if rf, ok := ret.Get(1).(func(int64) error); ok { - r1 = rf(id) + if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok { + r1 = rf(ctx, id) } else { r1 = ret.Error(1) } @@ -358,9 +358,9 @@ func (_m *Service) IsJobManaged(ctx context.Context, jobID int64) (bool, error) return r0, r1 } -// ListChainConfigsByManagerIDs provides a mock function with given fields: mgrIDs -func (_m *Service) ListChainConfigsByManagerIDs(mgrIDs []int64) ([]feeds.ChainConfig, error) { - ret := _m.Called(mgrIDs) +// ListChainConfigsByManagerIDs provides a mock function with given fields: ctx, mgrIDs +func (_m *Service) ListChainConfigsByManagerIDs(ctx context.Context, mgrIDs []int64) ([]feeds.ChainConfig, error) { + ret := _m.Called(ctx, mgrIDs) if len(ret) == 0 { panic("no return value specified for ListChainConfigsByManagerIDs") @@ -368,19 +368,19 @@ func (_m *Service) ListChainConfigsByManagerIDs(mgrIDs []int64) ([]feeds.ChainCo var r0 []feeds.ChainConfig var r1 error - if rf, ok := ret.Get(0).(func([]int64) ([]feeds.ChainConfig, error)); ok { - return rf(mgrIDs) + if rf, ok := ret.Get(0).(func(context.Context, []int64) ([]feeds.ChainConfig, error)); ok { + return rf(ctx, mgrIDs) } - if rf, ok := ret.Get(0).(func([]int64) []feeds.ChainConfig); ok { - r0 = rf(mgrIDs) + if rf, ok := ret.Get(0).(func(context.Context, []int64) []feeds.ChainConfig); ok { + r0 = rf(ctx, mgrIDs) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]feeds.ChainConfig) } } - if rf, ok := ret.Get(1).(func([]int64) error); ok { - r1 = rf(mgrIDs) + if rf, ok := ret.Get(1).(func(context.Context, []int64) error); ok { + r1 = rf(ctx, mgrIDs) } else { r1 = ret.Error(1) } @@ -388,9 +388,9 @@ func (_m *Service) ListChainConfigsByManagerIDs(mgrIDs []int64) ([]feeds.ChainCo return r0, r1 } -// ListJobProposals provides a mock function with given fields: -func (_m *Service) ListJobProposals() ([]feeds.JobProposal, error) { - ret := _m.Called() +// ListJobProposals provides a mock function with given fields: ctx +func (_m *Service) ListJobProposals(ctx context.Context) ([]feeds.JobProposal, error) { + ret := _m.Called(ctx) if len(ret) == 0 { panic("no return value specified for ListJobProposals") @@ -398,19 +398,19 @@ func (_m *Service) ListJobProposals() ([]feeds.JobProposal, error) { var r0 []feeds.JobProposal var r1 error - if rf, ok := ret.Get(0).(func() ([]feeds.JobProposal, error)); ok { - return rf() + if rf, ok := ret.Get(0).(func(context.Context) ([]feeds.JobProposal, error)); ok { + return rf(ctx) } - if rf, ok := ret.Get(0).(func() []feeds.JobProposal); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context) []feeds.JobProposal); ok { + r0 = rf(ctx) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]feeds.JobProposal) } } - 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) } @@ -418,9 +418,9 @@ func (_m *Service) ListJobProposals() ([]feeds.JobProposal, error) { return r0, r1 } -// ListJobProposalsByManagersIDs provides a mock function with given fields: ids -func (_m *Service) ListJobProposalsByManagersIDs(ids []int64) ([]feeds.JobProposal, error) { - ret := _m.Called(ids) +// ListJobProposalsByManagersIDs provides a mock function with given fields: ctx, ids +func (_m *Service) ListJobProposalsByManagersIDs(ctx context.Context, ids []int64) ([]feeds.JobProposal, error) { + ret := _m.Called(ctx, ids) if len(ret) == 0 { panic("no return value specified for ListJobProposalsByManagersIDs") @@ -428,19 +428,19 @@ func (_m *Service) ListJobProposalsByManagersIDs(ids []int64) ([]feeds.JobPropos var r0 []feeds.JobProposal var r1 error - if rf, ok := ret.Get(0).(func([]int64) ([]feeds.JobProposal, error)); ok { - return rf(ids) + if rf, ok := ret.Get(0).(func(context.Context, []int64) ([]feeds.JobProposal, error)); ok { + return rf(ctx, ids) } - if rf, ok := ret.Get(0).(func([]int64) []feeds.JobProposal); ok { - r0 = rf(ids) + if rf, ok := ret.Get(0).(func(context.Context, []int64) []feeds.JobProposal); ok { + r0 = rf(ctx, ids) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]feeds.JobProposal) } } - if rf, ok := ret.Get(1).(func([]int64) error); ok { - r1 = rf(ids) + if rf, ok := ret.Get(1).(func(context.Context, []int64) error); ok { + r1 = rf(ctx, ids) } else { r1 = ret.Error(1) } @@ -448,9 +448,9 @@ func (_m *Service) ListJobProposalsByManagersIDs(ids []int64) ([]feeds.JobPropos return r0, r1 } -// ListManagers provides a mock function with given fields: -func (_m *Service) ListManagers() ([]feeds.FeedsManager, error) { - ret := _m.Called() +// ListManagers provides a mock function with given fields: ctx +func (_m *Service) ListManagers(ctx context.Context) ([]feeds.FeedsManager, error) { + ret := _m.Called(ctx) if len(ret) == 0 { panic("no return value specified for ListManagers") @@ -458,19 +458,19 @@ func (_m *Service) ListManagers() ([]feeds.FeedsManager, error) { var r0 []feeds.FeedsManager var r1 error - if rf, ok := ret.Get(0).(func() ([]feeds.FeedsManager, error)); ok { - return rf() + if rf, ok := ret.Get(0).(func(context.Context) ([]feeds.FeedsManager, error)); ok { + return rf(ctx) } - if rf, ok := ret.Get(0).(func() []feeds.FeedsManager); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context) []feeds.FeedsManager); ok { + r0 = rf(ctx) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]feeds.FeedsManager) } } - 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) } @@ -478,9 +478,9 @@ func (_m *Service) ListManagers() ([]feeds.FeedsManager, error) { return r0, r1 } -// ListManagersByIDs provides a mock function with given fields: ids -func (_m *Service) ListManagersByIDs(ids []int64) ([]feeds.FeedsManager, error) { - ret := _m.Called(ids) +// ListManagersByIDs provides a mock function with given fields: ctx, ids +func (_m *Service) ListManagersByIDs(ctx context.Context, ids []int64) ([]feeds.FeedsManager, error) { + ret := _m.Called(ctx, ids) if len(ret) == 0 { panic("no return value specified for ListManagersByIDs") @@ -488,19 +488,19 @@ func (_m *Service) ListManagersByIDs(ids []int64) ([]feeds.FeedsManager, error) var r0 []feeds.FeedsManager var r1 error - if rf, ok := ret.Get(0).(func([]int64) ([]feeds.FeedsManager, error)); ok { - return rf(ids) + if rf, ok := ret.Get(0).(func(context.Context, []int64) ([]feeds.FeedsManager, error)); ok { + return rf(ctx, ids) } - if rf, ok := ret.Get(0).(func([]int64) []feeds.FeedsManager); ok { - r0 = rf(ids) + if rf, ok := ret.Get(0).(func(context.Context, []int64) []feeds.FeedsManager); ok { + r0 = rf(ctx, ids) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]feeds.FeedsManager) } } - if rf, ok := ret.Get(1).(func([]int64) error); ok { - r1 = rf(ids) + if rf, ok := ret.Get(1).(func(context.Context, []int64) error); ok { + r1 = rf(ctx, ids) } else { r1 = ret.Error(1) } @@ -508,9 +508,9 @@ func (_m *Service) ListManagersByIDs(ids []int64) ([]feeds.FeedsManager, error) return r0, r1 } -// ListSpecsByJobProposalIDs provides a mock function with given fields: ids -func (_m *Service) ListSpecsByJobProposalIDs(ids []int64) ([]feeds.JobProposalSpec, error) { - ret := _m.Called(ids) +// ListSpecsByJobProposalIDs provides a mock function with given fields: ctx, ids +func (_m *Service) ListSpecsByJobProposalIDs(ctx context.Context, ids []int64) ([]feeds.JobProposalSpec, error) { + ret := _m.Called(ctx, ids) if len(ret) == 0 { panic("no return value specified for ListSpecsByJobProposalIDs") @@ -518,19 +518,19 @@ func (_m *Service) ListSpecsByJobProposalIDs(ids []int64) ([]feeds.JobProposalSp var r0 []feeds.JobProposalSpec var r1 error - if rf, ok := ret.Get(0).(func([]int64) ([]feeds.JobProposalSpec, error)); ok { - return rf(ids) + if rf, ok := ret.Get(0).(func(context.Context, []int64) ([]feeds.JobProposalSpec, error)); ok { + return rf(ctx, ids) } - if rf, ok := ret.Get(0).(func([]int64) []feeds.JobProposalSpec); ok { - r0 = rf(ids) + if rf, ok := ret.Get(0).(func(context.Context, []int64) []feeds.JobProposalSpec); ok { + r0 = rf(ctx, ids) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]feeds.JobProposalSpec) } } - if rf, ok := ret.Get(1).(func([]int64) error); ok { - r1 = rf(ids) + if rf, ok := ret.Get(1).(func(context.Context, []int64) error); ok { + r1 = rf(ctx, ids) } else { r1 = ret.Error(1) } @@ -676,11 +676,6 @@ func (_m *Service) SyncNodeInfo(ctx context.Context, id int64) error { return r0 } -// Unsafe_SetConnectionsManager provides a mock function with given fields: _a0 -func (_m *Service) Unsafe_SetConnectionsManager(_a0 feeds.ConnectionsManager) { - _m.Called(_a0) -} - // UpdateChainConfig provides a mock function with given fields: ctx, cfg func (_m *Service) UpdateChainConfig(ctx context.Context, cfg feeds.ChainConfig) (int64, error) { ret := _m.Called(ctx, cfg) diff --git a/core/services/feeds/orm.go b/core/services/feeds/orm.go index 24ed7b8b369..bf77051dad7 100644 --- a/core/services/feeds/orm.go +++ b/core/services/feeds/orm.go @@ -1,6 +1,7 @@ package feeds import ( + "context" "database/sql" "fmt" "strings" @@ -9,99 +10,104 @@ import ( "github.com/lib/pq" "github.com/pkg/errors" - "github.com/jmoiron/sqlx" - - "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" ) //go:generate mockery --with-expecter=true --quiet --name ORM --output ./mocks/ --case=underscore type ORM interface { - CountManagers() (int64, error) - CreateManager(ms *FeedsManager, qopts ...pg.QOpt) (int64, error) - GetManager(id int64) (*FeedsManager, error) - ListManagers() (mgrs []FeedsManager, err error) - ListManagersByIDs(ids []int64) ([]FeedsManager, error) - UpdateManager(mgr FeedsManager, qopts ...pg.QOpt) error - - CreateBatchChainConfig(cfgs []ChainConfig, qopts ...pg.QOpt) ([]int64, error) - CreateChainConfig(cfg ChainConfig, qopts ...pg.QOpt) (int64, error) - DeleteChainConfig(id int64) (int64, error) - GetChainConfig(id int64) (*ChainConfig, error) - ListChainConfigsByManagerIDs(mgrIDs []int64) ([]ChainConfig, error) - UpdateChainConfig(cfg ChainConfig) (int64, error) - - CountJobProposals() (int64, error) - CountJobProposalsByStatus() (counts *JobProposalCounts, err error) - CreateJobProposal(jp *JobProposal) (int64, error) - DeleteProposal(id int64, qopts ...pg.QOpt) error - GetJobProposal(id int64, qopts ...pg.QOpt) (*JobProposal, error) - GetJobProposalByRemoteUUID(uuid uuid.UUID) (*JobProposal, error) - ListJobProposals() (jps []JobProposal, err error) - ListJobProposalsByManagersIDs(ids []int64, qopts ...pg.QOpt) ([]JobProposal, error) - UpdateJobProposalStatus(id int64, status JobProposalStatus, qopts ...pg.QOpt) error // NEEDED? - UpsertJobProposal(jp *JobProposal, qopts ...pg.QOpt) (int64, error) - - ApproveSpec(id int64, externalJobID uuid.UUID, qopts ...pg.QOpt) error - CancelSpec(id int64, qopts ...pg.QOpt) error - CreateSpec(spec JobProposalSpec, qopts ...pg.QOpt) (int64, error) - ExistsSpecByJobProposalIDAndVersion(jpID int64, version int32, qopts ...pg.QOpt) (exists bool, err error) - GetApprovedSpec(jpID int64, qopts ...pg.QOpt) (*JobProposalSpec, error) - GetLatestSpec(jpID int64) (*JobProposalSpec, error) - GetSpec(id int64, qopts ...pg.QOpt) (*JobProposalSpec, error) - ListSpecsByJobProposalIDs(ids []int64, qopts ...pg.QOpt) ([]JobProposalSpec, error) - RejectSpec(id int64, qopts ...pg.QOpt) error - RevokeSpec(id int64, qopts ...pg.QOpt) error - UpdateSpecDefinition(id int64, spec string, qopts ...pg.QOpt) error - - IsJobManaged(jobID int64, qopts ...pg.QOpt) (bool, error) + CountManagers(ctx context.Context) (int64, error) + CreateManager(ctx context.Context, ms *FeedsManager) (int64, error) + GetManager(ctx context.Context, id int64) (*FeedsManager, error) + ListManagers(ctx context.Context) (mgrs []FeedsManager, err error) + ListManagersByIDs(ctx context.Context, ids []int64) ([]FeedsManager, error) + UpdateManager(ctx context.Context, mgr FeedsManager) error + + CreateBatchChainConfig(ctx context.Context, cfgs []ChainConfig) ([]int64, error) + CreateChainConfig(ctx context.Context, cfg ChainConfig) (int64, error) + DeleteChainConfig(ctx context.Context, id int64) (int64, error) + GetChainConfig(ctx context.Context, id int64) (*ChainConfig, error) + ListChainConfigsByManagerIDs(ctx context.Context, mgrIDs []int64) ([]ChainConfig, error) + UpdateChainConfig(ctx context.Context, cfg ChainConfig) (int64, error) + + CountJobProposals(ctx context.Context) (int64, error) + CountJobProposalsByStatus(ctx context.Context) (counts *JobProposalCounts, err error) + CreateJobProposal(ctx context.Context, jp *JobProposal) (int64, error) + DeleteProposal(ctx context.Context, id int64) error + GetJobProposal(ctx context.Context, id int64) (*JobProposal, error) + GetJobProposalByRemoteUUID(ctx context.Context, uuid uuid.UUID) (*JobProposal, error) + ListJobProposals(ctx context.Context) (jps []JobProposal, err error) + ListJobProposalsByManagersIDs(ctx context.Context, ids []int64) ([]JobProposal, error) + UpdateJobProposalStatus(ctx context.Context, id int64, status JobProposalStatus) error // NEEDED? + UpsertJobProposal(ctx context.Context, jp *JobProposal) (int64, error) + + ApproveSpec(ctx context.Context, id int64, externalJobID uuid.UUID) error + CancelSpec(ctx context.Context, id int64) error + CreateSpec(ctx context.Context, spec JobProposalSpec) (int64, error) + ExistsSpecByJobProposalIDAndVersion(ctx context.Context, jpID int64, version int32) (exists bool, err error) + GetApprovedSpec(ctx context.Context, jpID int64) (*JobProposalSpec, error) + GetLatestSpec(ctx context.Context, jpID int64) (*JobProposalSpec, error) + GetSpec(ctx context.Context, id int64) (*JobProposalSpec, error) + ListSpecsByJobProposalIDs(ctx context.Context, ids []int64) ([]JobProposalSpec, error) + RejectSpec(ctx context.Context, id int64) error + RevokeSpec(ctx context.Context, id int64) error + UpdateSpecDefinition(ctx context.Context, id int64, spec string) error + + IsJobManaged(ctx context.Context, jobID int64) (bool, error) + + Transact(context.Context, func(ORM) error) error + WithDataSource(sqlutil.DataSource) ORM } var _ ORM = &orm{} type orm struct { - q pg.Q + ds sqlutil.DataSource } -func NewORM(db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig) *orm { - return &orm{ - q: pg.NewQ(db, lggr, cfg), - } +func NewORM(ds sqlutil.DataSource) *orm { + return &orm{ds: ds} } +func (o *orm) Transact(ctx context.Context, fn func(ORM) error) error { + return sqlutil.Transact(ctx, o.WithDataSource, o.ds, nil, fn) +} + +func (o *orm) WithDataSource(ds sqlutil.DataSource) ORM { return &orm{ds} } + // Count counts the number of feeds manager records. -func (o *orm) CountManagers() (count int64, err error) { +func (o *orm) CountManagers(ctx context.Context) (count int64, err error) { stmt := ` SELECT COUNT(*) FROM feeds_managers ` - err = o.q.Get(&count, stmt) + err = o.ds.GetContext(ctx, &count, stmt) return count, errors.Wrap(err, "CountManagers failed") } // CreateManager creates a feeds manager. -func (o *orm) CreateManager(ms *FeedsManager, qopts ...pg.QOpt) (id int64, err error) { +func (o *orm) CreateManager(ctx context.Context, ms *FeedsManager) (id int64, err error) { stmt := ` INSERT INTO feeds_managers (name, uri, public_key, created_at, updated_at) VALUES ($1,$2,$3,NOW(),NOW()) RETURNING id; ` - err = o.q.WithOpts(qopts...).Get(&id, stmt, ms.Name, ms.URI, ms.PublicKey) + err = o.ds.GetContext(ctx, &id, stmt, ms.Name, ms.URI, ms.PublicKey) return id, errors.Wrap(err, "CreateManager failed") } // CreateChainConfig creates a new chain config. -func (o *orm) CreateChainConfig(cfg ChainConfig, qopts ...pg.QOpt) (id int64, err error) { +func (o *orm) CreateChainConfig(ctx context.Context, cfg ChainConfig) (id int64, err error) { stmt := ` INSERT INTO feeds_manager_chain_configs (feeds_manager_id, chain_id, chain_type, account_address, admin_address, flux_monitor_config, ocr1_config, ocr2_config, created_at, updated_at) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,NOW(),NOW()) RETURNING id; ` - err = o.q.WithOpts(qopts...).Get(&id, + err = o.ds.GetContext(ctx, + &id, stmt, cfg.FeedsManagerID, cfg.ChainID, @@ -117,7 +123,7 @@ RETURNING id; } // CreateBatchChainConfig creates multiple chain configs. -func (o *orm) CreateBatchChainConfig(cfgs []ChainConfig, qopts ...pg.QOpt) (ids []int64, err error) { +func (o *orm) CreateBatchChainConfig(ctx context.Context, cfgs []ChainConfig) (ids []int64, err error) { if len(cfgs) == 0 { return } @@ -160,7 +166,8 @@ RETURNING id; ) } - err = o.q.WithOpts(qopts...).Select(&ids, + err = o.ds.SelectContext(ctx, + &ids, fmt.Sprintf(stmt, strings.Join(vStrs, ",")), vArgs..., ) @@ -169,7 +176,7 @@ RETURNING id; } // DeleteChainConfig deletes a chain config. -func (o *orm) DeleteChainConfig(id int64) (int64, error) { +func (o *orm) DeleteChainConfig(ctx context.Context, id int64) (int64, error) { stmt := ` DELETE FROM feeds_manager_chain_configs WHERE id = $1 @@ -177,13 +184,13 @@ RETURNING id; ` var ccid int64 - err := o.q.Get(&ccid, stmt, id) + err := o.ds.GetContext(ctx, &ccid, stmt, id) return ccid, errors.Wrap(err, "DeleteChainConfig failed") } // GetChainConfig fetches a chain config. -func (o *orm) GetChainConfig(id int64) (*ChainConfig, error) { +func (o *orm) GetChainConfig(ctx context.Context, id int64) (*ChainConfig, error) { stmt := ` SELECT id, feeds_manager_id, chain_id, chain_type, account_address, admin_address, flux_monitor_config, ocr1_config, ocr2_config, created_at, updated_at FROM feeds_manager_chain_configs @@ -191,14 +198,14 @@ WHERE id = $1; ` var cfg ChainConfig - err := o.q.Get(&cfg, stmt, id) + err := o.ds.GetContext(ctx, &cfg, stmt, id) return &cfg, errors.Wrap(err, "GetChainConfig failed") } // ListChainConfigsByManagerIDs fetches the chain configs matching all manager // ids. -func (o *orm) ListChainConfigsByManagerIDs(mgrIDs []int64) ([]ChainConfig, error) { +func (o *orm) ListChainConfigsByManagerIDs(ctx context.Context, mgrIDs []int64) ([]ChainConfig, error) { stmt := ` SELECT id, feeds_manager_id, chain_id, chain_type, account_address, admin_address, flux_monitor_config, ocr1_config, ocr2_config, created_at, updated_at FROM feeds_manager_chain_configs @@ -206,13 +213,13 @@ WHERE feeds_manager_id = ANY($1) ` var cfgs []ChainConfig - err := o.q.Select(&cfgs, stmt, mgrIDs) + err := o.ds.SelectContext(ctx, &cfgs, stmt, mgrIDs) return cfgs, errors.Wrap(err, "ListJobProposalsByManagersIDs failed") } // UpdateChainConfig updates a chain config. -func (o *orm) UpdateChainConfig(cfg ChainConfig) (int64, error) { +func (o *orm) UpdateChainConfig(ctx context.Context, cfg ChainConfig) (int64, error) { stmt := ` UPDATE feeds_manager_chain_configs SET account_address = $1, @@ -226,7 +233,7 @@ RETURNING id; ` var cfgID int64 - err := o.q.Get(&cfgID, stmt, + err := o.ds.GetContext(ctx, &cfgID, stmt, cfg.AccountAddress, cfg.AdminAddress, cfg.FluxMonitorConfig, @@ -239,7 +246,7 @@ RETURNING id; } // GetManager gets a feeds manager by id. -func (o *orm) GetManager(id int64) (mgr *FeedsManager, err error) { +func (o *orm) GetManager(ctx context.Context, id int64) (mgr *FeedsManager, err error) { stmt := ` SELECT id, name, uri, public_key, created_at, updated_at FROM feeds_managers @@ -247,23 +254,23 @@ WHERE id = $1 ` mgr = new(FeedsManager) - err = o.q.Get(mgr, stmt, id) + err = o.ds.GetContext(ctx, mgr, stmt, id) return mgr, errors.Wrap(err, "GetManager failed") } // ListManager lists all feeds managers. -func (o *orm) ListManagers() (mgrs []FeedsManager, err error) { +func (o *orm) ListManagers(ctx context.Context) (mgrs []FeedsManager, err error) { stmt := ` SELECT id, name, uri, public_key, created_at, updated_at FROM feeds_managers; ` - err = o.q.Select(&mgrs, stmt) + err = o.ds.SelectContext(ctx, &mgrs, stmt) return mgrs, errors.Wrap(err, "ListManagers failed") } // ListManagersByIDs gets feeds managers by ids. -func (o *orm) ListManagersByIDs(ids []int64) (managers []FeedsManager, err error) { +func (o *orm) ListManagersByIDs(ctx context.Context, ids []int64) (managers []FeedsManager, err error) { stmt := ` SELECT id, name, uri, public_key, created_at, updated_at FROM feeds_managers @@ -271,20 +278,20 @@ WHERE id = ANY($1) ORDER BY created_at, id;` mgrIds := pq.Array(ids) - err = o.q.Select(&managers, stmt, mgrIds) + err = o.ds.SelectContext(ctx, &managers, stmt, mgrIds) return managers, errors.Wrap(err, "GetManagers failed") } // UpdateManager updates the manager details. -func (o *orm) UpdateManager(mgr FeedsManager, qopts ...pg.QOpt) (err error) { +func (o *orm) UpdateManager(ctx context.Context, mgr FeedsManager) (err error) { stmt := ` UPDATE feeds_managers SET name = $1, uri = $2, public_key = $3, updated_at = NOW() WHERE id = $4; ` - res, err := o.q.WithOpts(qopts...).Exec(stmt, mgr.Name, mgr.URI, mgr.PublicKey, mgr.ID) + res, err := o.ds.ExecContext(ctx, stmt, mgr.Name, mgr.URI, mgr.PublicKey, mgr.ID) if err != nil { return errors.Wrap(err, "UpdateManager failed to update feeds_managers") } @@ -299,27 +306,27 @@ WHERE id = $4; } // CreateJobProposal creates a job proposal. -func (o *orm) CreateJobProposal(jp *JobProposal) (id int64, err error) { +func (o *orm) CreateJobProposal(ctx context.Context, jp *JobProposal) (id int64, err error) { stmt := ` INSERT INTO job_proposals (name, remote_uuid, status, feeds_manager_id, multiaddrs, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, NOW(), NOW()) RETURNING id; ` - err = o.q.Get(&id, stmt, jp.Name, jp.RemoteUUID, jp.Status, jp.FeedsManagerID, jp.Multiaddrs) + err = o.ds.GetContext(ctx, &id, stmt, jp.Name, jp.RemoteUUID, jp.Status, jp.FeedsManagerID, jp.Multiaddrs) return id, errors.Wrap(err, "CreateJobProposal failed") } // CountJobProposals counts the number of job proposal records. -func (o *orm) CountJobProposals() (count int64, err error) { +func (o *orm) CountJobProposals(ctx context.Context) (count int64, err error) { stmt := `SELECT COUNT(*) FROM job_proposals` - err = o.q.Get(&count, stmt) + err = o.ds.GetContext(ctx, &count, stmt) return count, errors.Wrap(err, "CountJobProposals failed") } // CountJobProposals counts the number of job proposal records. -func (o *orm) CountJobProposalsByStatus() (counts *JobProposalCounts, err error) { +func (o *orm) CountJobProposalsByStatus(ctx context.Context) (counts *JobProposalCounts, err error) { stmt := ` SELECT COUNT(*) filter (where job_proposals.status = 'pending' OR job_proposals.pending_update = TRUE) as pending, @@ -332,26 +339,26 @@ FROM job_proposals; ` counts = new(JobProposalCounts) - err = o.q.Get(counts, stmt) + err = o.ds.GetContext(ctx, counts, stmt) return counts, errors.Wrap(err, "CountJobProposalsByStatus failed") } // GetJobProposal gets a job proposal by id. -func (o *orm) GetJobProposal(id int64, qopts ...pg.QOpt) (jp *JobProposal, err error) { +func (o *orm) GetJobProposal(ctx context.Context, id int64) (jp *JobProposal, err error) { stmt := ` SELECT * FROM job_proposals WHERE id = $1 ` jp = new(JobProposal) - err = o.q.WithOpts(qopts...).Get(jp, stmt, id) + err = o.ds.GetContext(ctx, jp, stmt, id) return jp, errors.Wrap(err, "GetJobProposal failed") } // GetJobProposalByRemoteUUID gets a job proposal by the remote FMS uuid. This // method will filter out the deleted job proposals. To get all job proposals, // use the GetJobProposal get by id method. -func (o *orm) GetJobProposalByRemoteUUID(id uuid.UUID) (jp *JobProposal, err error) { +func (o *orm) GetJobProposalByRemoteUUID(ctx context.Context, id uuid.UUID) (jp *JobProposal, err error) { stmt := ` SELECT * FROM job_proposals @@ -360,35 +367,35 @@ AND status <> $2; ` jp = new(JobProposal) - err = o.q.Get(jp, stmt, id, JobProposalStatusDeleted) + err = o.ds.GetContext(ctx, jp, stmt, id, JobProposalStatusDeleted) return jp, errors.Wrap(err, "GetJobProposalByRemoteUUID failed") } // ListJobProposals lists all job proposals. -func (o *orm) ListJobProposals() (jps []JobProposal, err error) { +func (o *orm) ListJobProposals(ctx context.Context) (jps []JobProposal, err error) { stmt := ` SELECT * FROM job_proposals; ` - err = o.q.Select(&jps, stmt) + err = o.ds.SelectContext(ctx, &jps, stmt) return jps, errors.Wrap(err, "ListJobProposals failed") } // ListJobProposalsByManagersIDs gets job proposals by feeds managers IDs. -func (o *orm) ListJobProposalsByManagersIDs(ids []int64, qopts ...pg.QOpt) ([]JobProposal, error) { +func (o *orm) ListJobProposalsByManagersIDs(ctx context.Context, ids []int64) ([]JobProposal, error) { stmt := ` SELECT * FROM job_proposals WHERE feeds_manager_id = ANY($1) ` var jps []JobProposal - err := o.q.WithOpts(qopts...).Select(&jps, stmt, ids) + err := o.ds.SelectContext(ctx, &jps, stmt, ids) return jps, errors.Wrap(err, "ListJobProposalsByManagersIDs failed") } // UpdateJobProposalStatus updates the status of a job proposal by id. -func (o *orm) UpdateJobProposalStatus(id int64, status JobProposalStatus, qopts ...pg.QOpt) error { +func (o *orm) UpdateJobProposalStatus(ctx context.Context, id int64, status JobProposalStatus) error { stmt := ` UPDATE job_proposals SET status = $1, @@ -396,7 +403,7 @@ SET status = $1, WHERE id = $2; ` - result, err := o.q.WithOpts(qopts...).Exec(stmt, status, id) + result, err := o.ds.ExecContext(ctx, stmt, status, id) if err != nil { return err } @@ -415,7 +422,7 @@ WHERE id = $2; // UpsertJobProposal creates a job proposal if it does not exist. If it does exist, // then we update the details of the existing job proposal only if the provided // feeds manager id exists. -func (o *orm) UpsertJobProposal(jp *JobProposal, qopts ...pg.QOpt) (id int64, err error) { +func (o *orm) UpsertJobProposal(ctx context.Context, jp *JobProposal) (id int64, err error) { stmt := ` INSERT INTO job_proposals (name, remote_uuid, status, feeds_manager_id, multiaddrs, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, NOW(), NOW()) @@ -436,13 +443,13 @@ DO RETURNING id; ` - err = o.q.WithOpts(qopts...).Get(&id, stmt, jp.Name, jp.RemoteUUID, jp.Status, jp.FeedsManagerID, jp.Multiaddrs) + err = o.ds.GetContext(ctx, &id, stmt, jp.Name, jp.RemoteUUID, jp.Status, jp.FeedsManagerID, jp.Multiaddrs) return id, errors.Wrap(err, "UpsertJobProposal") } // ApproveSpec approves the spec and sets the external job ID on the associated // job proposal. -func (o *orm) ApproveSpec(id int64, externalJobID uuid.UUID, qopts ...pg.QOpt) error { +func (o *orm) ApproveSpec(ctx context.Context, id int64, externalJobID uuid.UUID) error { // Update the status of the approval stmt := ` UPDATE job_proposal_specs @@ -454,7 +461,7 @@ RETURNING job_proposal_id; ` var jpID int64 - if err := o.q.WithOpts(qopts...).Get(&jpID, stmt, JobProposalStatusApproved, id); err != nil { + if err := o.ds.GetContext(ctx, &jpID, stmt, JobProposalStatusApproved, id); err != nil { return err } @@ -468,7 +475,7 @@ SET status = $1, WHERE id = $3; ` - result, err := o.q.WithOpts(qopts...).Exec(stmt, JobProposalStatusApproved, externalJobID, jpID) + result, err := o.ds.ExecContext(ctx, stmt, JobProposalStatusApproved, externalJobID, jpID) if err != nil { return err } @@ -487,7 +494,7 @@ WHERE id = $3; // CancelSpec cancels the spec and removes the external job id from the associated job proposal. It // sets the status of the spec and the proposal to cancelled, except in the case of deleted // proposals. -func (o *orm) CancelSpec(id int64, qopts ...pg.QOpt) error { +func (o *orm) CancelSpec(ctx context.Context, id int64) error { // Update the status of the approval stmt := ` UPDATE job_proposal_specs @@ -499,7 +506,7 @@ RETURNING job_proposal_id; ` var jpID int64 - if err := o.q.WithOpts(qopts...).Get(&jpID, stmt, SpecStatusCancelled, id); err != nil { + if err := o.ds.GetContext(ctx, &jpID, stmt, SpecStatusCancelled, id); err != nil { return err } @@ -516,7 +523,7 @@ SET status = ( updated_at = NOW() WHERE id = $1; ` - result, err := o.q.WithOpts(qopts...).Exec(stmt, jpID, nil) + result, err := o.ds.ExecContext(ctx, stmt, jpID, nil) if err != nil { return err } @@ -533,7 +540,7 @@ WHERE id = $1; } // CreateSpec creates a new job proposal spec -func (o *orm) CreateSpec(spec JobProposalSpec, qopts ...pg.QOpt) (int64, error) { +func (o *orm) CreateSpec(ctx context.Context, spec JobProposalSpec) (int64, error) { stmt := ` INSERT INTO job_proposal_specs (definition, version, status, job_proposal_id, status_updated_at, created_at, updated_at) VALUES ($1, $2, $3, $4, NOW(), NOW(), NOW()) @@ -541,14 +548,14 @@ RETURNING id; ` var id int64 - err := o.q.WithOpts(qopts...).Get(&id, stmt, spec.Definition, spec.Version, spec.Status, spec.JobProposalID) + err := o.ds.GetContext(ctx, &id, stmt, spec.Definition, spec.Version, spec.Status, spec.JobProposalID) return id, errors.Wrap(err, "CreateJobProposalSpec failed") } // ExistsSpecByJobProposalIDAndVersion checks if a job proposal spec exists for a specific job // proposal and version. -func (o *orm) ExistsSpecByJobProposalIDAndVersion(jpID int64, version int32, qopts ...pg.QOpt) (exists bool, err error) { +func (o *orm) ExistsSpecByJobProposalIDAndVersion(ctx context.Context, jpID int64, version int32) (exists bool, err error) { stmt := ` SELECT exists ( SELECT 1 @@ -557,12 +564,12 @@ SELECT exists ( ); ` - err = o.q.WithOpts(qopts...).Get(&exists, stmt, jpID, version) + err = o.ds.GetContext(ctx, &exists, stmt, jpID, version) return exists, errors.Wrap(err, "JobProposalSpecVersionExists failed") } // DeleteProposal performs a soft delete of the job proposal by setting the status to deleted -func (o *orm) DeleteProposal(id int64, qopts ...pg.QOpt) error { +func (o *orm) DeleteProposal(ctx context.Context, id int64) error { // Get the latest spec for the proposal. stmt := ` SELECT id, definition, version, status, job_proposal_id, status_updated_at, created_at, updated_at @@ -577,7 +584,7 @@ AND job_proposal_id = $1 ` var spec JobProposalSpec - err := o.q.WithOpts(qopts...).Get(&spec, stmt, id) + err := o.ds.GetContext(ctx, &spec, stmt, id) if err != nil { return err } @@ -593,7 +600,7 @@ SET status = $1, WHERE id = $2; ` - result, err := o.q.WithOpts(qopts...).Exec(stmt, JobProposalStatusDeleted, id, pendingUpdate) + result, err := o.ds.ExecContext(ctx, stmt, JobProposalStatusDeleted, id, pendingUpdate) if err != nil { return err } @@ -610,20 +617,20 @@ WHERE id = $2; } // GetSpec fetches the job proposal spec by id -func (o *orm) GetSpec(id int64, qopts ...pg.QOpt) (*JobProposalSpec, error) { +func (o *orm) GetSpec(ctx context.Context, id int64) (*JobProposalSpec, error) { stmt := ` SELECT id, definition, version, status, job_proposal_id, status_updated_at, created_at, updated_at FROM job_proposal_specs WHERE id = $1; ` var spec JobProposalSpec - err := o.q.WithOpts(qopts...).Get(&spec, stmt, id) + err := o.ds.GetContext(ctx, &spec, stmt, id) return &spec, errors.Wrap(err, "CreateJobProposalSpec failed") } // GetApprovedSpec gets the approved spec for a job proposal -func (o *orm) GetApprovedSpec(jpID int64, qopts ...pg.QOpt) (*JobProposalSpec, error) { +func (o *orm) GetApprovedSpec(ctx context.Context, jpID int64) (*JobProposalSpec, error) { stmt := ` SELECT id, definition, version, status, job_proposal_id, status_updated_at, created_at, updated_at FROM job_proposal_specs @@ -632,13 +639,13 @@ AND job_proposal_id = $2 ` var spec JobProposalSpec - err := o.q.WithOpts(qopts...).Get(&spec, stmt, SpecStatusApproved, jpID) + err := o.ds.GetContext(ctx, &spec, stmt, SpecStatusApproved, jpID) return &spec, errors.Wrap(err, "GetApprovedSpec failed") } // GetLatestSpec gets the latest spec for a job proposal. -func (o *orm) GetLatestSpec(jpID int64) (*JobProposalSpec, error) { +func (o *orm) GetLatestSpec(ctx context.Context, jpID int64) (*JobProposalSpec, error) { stmt := ` SELECT id, definition, version, status, job_proposal_id, status_updated_at, created_at, updated_at FROM job_proposal_specs @@ -652,26 +659,26 @@ AND job_proposal_id = $1 ` var spec JobProposalSpec - err := o.q.Get(&spec, stmt, jpID) + err := o.ds.GetContext(ctx, &spec, stmt, jpID) return &spec, errors.Wrap(err, "GetLatestSpec failed") } // ListSpecsByJobProposalIDs lists the specs which belong to any of job proposal // ids. -func (o *orm) ListSpecsByJobProposalIDs(ids []int64, qopts ...pg.QOpt) ([]JobProposalSpec, error) { +func (o *orm) ListSpecsByJobProposalIDs(ctx context.Context, ids []int64) ([]JobProposalSpec, error) { stmt := ` SELECT id, definition, version, status, job_proposal_id, status_updated_at, created_at, updated_at FROM job_proposal_specs WHERE job_proposal_id = ANY($1) ` var specs []JobProposalSpec - err := o.q.WithOpts(qopts...).Select(&specs, stmt, ids) + err := o.ds.SelectContext(ctx, &specs, stmt, ids) return specs, errors.Wrap(err, "GetJobProposalsByManagersIDs failed") } // RejectSpec rejects the spec and updates the job proposal -func (o *orm) RejectSpec(id int64, qopts ...pg.QOpt) error { +func (o *orm) RejectSpec(ctx context.Context, id int64) error { stmt := ` UPDATE job_proposal_specs SET status = $1, @@ -682,7 +689,7 @@ RETURNING job_proposal_id; ` var jpID int64 - if err := o.q.WithOpts(qopts...).Get(&jpID, stmt, SpecStatusRejected, id); err != nil { + if err := o.ds.GetContext(ctx, &jpID, stmt, SpecStatusRejected, id); err != nil { return err } @@ -700,7 +707,7 @@ SET status = ( WHERE id = $1 ` - result, err := o.q.WithOpts(qopts...).Exec(stmt, jpID) + result, err := o.ds.ExecContext(ctx, stmt, jpID) if err != nil { return err } @@ -719,7 +726,7 @@ WHERE id = $1 // RevokeSpec revokes a job proposal with a pending job spec. An approved // proposal cannot be revoked. A revoked proposal's job spec cannot be approved // or edited, but the job can be reproposed by FMS. -func (o *orm) RevokeSpec(id int64, qopts ...pg.QOpt) error { +func (o *orm) RevokeSpec(ctx context.Context, id int64) error { // Update the status of the spec stmt := ` UPDATE job_proposal_specs @@ -736,7 +743,7 @@ RETURNING job_proposal_id; ` var jpID int64 - if err := o.q.WithOpts(qopts...).Get(&jpID, stmt, id, SpecStatusRevoked); err != nil { + if err := o.ds.GetContext(ctx, &jpID, stmt, id, SpecStatusRevoked); err != nil { return err } @@ -760,7 +767,7 @@ SET status = ( WHERE id = $1 ` - result, err := o.q.WithOpts(qopts...).Exec(stmt, jpID, nil, JobProposalStatusRevoked) + result, err := o.ds.ExecContext(ctx, stmt, jpID, nil, JobProposalStatusRevoked) if err != nil { return err } @@ -777,7 +784,7 @@ WHERE id = $1 } // UpdateSpecDefinition updates the definition of a job proposal spec by id. -func (o *orm) UpdateSpecDefinition(id int64, spec string, qopts ...pg.QOpt) error { +func (o *orm) UpdateSpecDefinition(ctx context.Context, id int64, spec string) error { stmt := ` UPDATE job_proposal_specs SET definition = $1, @@ -785,7 +792,7 @@ SET definition = $1, WHERE id = $2; ` - res, err := o.q.WithOpts(qopts...).Exec(stmt, spec, id) + res, err := o.ds.ExecContext(ctx, stmt, spec, id) if err != nil { return errors.Wrap(err, "UpdateSpecDefinition failed to update definition") } @@ -803,7 +810,7 @@ WHERE id = $2; } // IsJobManaged determines if a job is managed by the feeds manager. -func (o *orm) IsJobManaged(jobID int64, qopts ...pg.QOpt) (exists bool, err error) { +func (o *orm) IsJobManaged(ctx context.Context, jobID int64) (exists bool, err error) { stmt := ` SELECT exists ( SELECT 1 @@ -813,6 +820,6 @@ SELECT exists ( ); ` - err = o.q.WithOpts(qopts...).Get(&exists, stmt, jobID) + err = o.ds.GetContext(ctx, &exists, stmt, jobID) return exists, errors.Wrap(err, "IsJobManaged failed") } diff --git a/core/services/feeds/orm_test.go b/core/services/feeds/orm_test.go index 3a0a17c99e0..df2624319f5 100644 --- a/core/services/feeds/orm_test.go +++ b/core/services/feeds/orm_test.go @@ -5,13 +5,12 @@ import ( "testing" "github.com/google/uuid" + "github.com/jmoiron/sqlx" "github.com/lib/pq" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gopkg.in/guregu/null.v4" - "github.com/jmoiron/sqlx" - "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" @@ -45,9 +44,8 @@ func setupORM(t *testing.T) *TestORM { t.Helper() var ( - db = pgtest.NewSqlxDB(t) - lggr = logger.TestLogger(t) - orm = feeds.NewORM(db, lggr, pgtest.NewQConfig(true)) + db = pgtest.NewSqlxDB(t) + orm = feeds.NewORM(db) ) return &TestORM{ORM: orm, db: db} @@ -57,6 +55,7 @@ func setupORM(t *testing.T) *TestORM { func Test_ORM_CreateManager(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( orm = setupORM(t) @@ -67,14 +66,14 @@ func Test_ORM_CreateManager(t *testing.T) { } ) - count, err := orm.CountManagers() + count, err := orm.CountManagers(ctx) require.NoError(t, err) require.Equal(t, int64(0), count) - id, err := orm.CreateManager(mgr) + id, err := orm.CreateManager(ctx, mgr) require.NoError(t, err) - count, err = orm.CountManagers() + count, err = orm.CountManagers(ctx) require.NoError(t, err) require.Equal(t, int64(1), count) @@ -83,6 +82,7 @@ func Test_ORM_CreateManager(t *testing.T) { func Test_ORM_GetManager(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( orm = setupORM(t) @@ -93,10 +93,10 @@ func Test_ORM_GetManager(t *testing.T) { } ) - id, err := orm.CreateManager(mgr) + id, err := orm.CreateManager(ctx, mgr) require.NoError(t, err) - actual, err := orm.GetManager(id) + actual, err := orm.GetManager(ctx, id) require.NoError(t, err) assert.Equal(t, id, actual.ID) @@ -104,12 +104,13 @@ func Test_ORM_GetManager(t *testing.T) { assert.Equal(t, name, actual.Name) assert.Equal(t, publicKey, actual.PublicKey) - _, err = orm.GetManager(-1) + _, err = orm.GetManager(ctx, -1) require.Error(t, err) } func Test_ORM_ListManagers(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( orm = setupORM(t) @@ -120,10 +121,10 @@ func Test_ORM_ListManagers(t *testing.T) { } ) - id, err := orm.CreateManager(mgr) + id, err := orm.CreateManager(ctx, mgr) require.NoError(t, err) - mgrs, err := orm.ListManagers() + mgrs, err := orm.ListManagers(ctx) require.NoError(t, err) require.Len(t, mgrs, 1) @@ -136,6 +137,7 @@ func Test_ORM_ListManagers(t *testing.T) { func Test_ORM_ListManagersByIDs(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( orm = setupORM(t) @@ -146,10 +148,10 @@ func Test_ORM_ListManagersByIDs(t *testing.T) { } ) - id, err := orm.CreateManager(mgr) + id, err := orm.CreateManager(ctx, mgr) require.NoError(t, err) - mgrs, err := orm.ListManagersByIDs([]int64{id}) + mgrs, err := orm.ListManagersByIDs(ctx, []int64{id}) require.NoError(t, err) require.Equal(t, 1, len(mgrs)) @@ -162,6 +164,7 @@ func Test_ORM_ListManagersByIDs(t *testing.T) { func Test_ORM_UpdateManager(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( orm = setupORM(t) @@ -172,7 +175,7 @@ func Test_ORM_UpdateManager(t *testing.T) { } ) - id, err := orm.CreateManager(mgr) + id, err := orm.CreateManager(ctx, mgr) require.NoError(t, err) updatedMgr := feeds.FeedsManager{ @@ -182,10 +185,10 @@ func Test_ORM_UpdateManager(t *testing.T) { PublicKey: crypto.PublicKey([]byte("22222222222222222222222222222222")), } - err = orm.UpdateManager(updatedMgr) + err = orm.UpdateManager(ctx, updatedMgr) require.NoError(t, err) - actual, err := orm.GetManager(id) + actual, err := orm.GetManager(ctx, id) require.NoError(t, err) assert.Equal(t, updatedMgr.URI, actual.URI) @@ -197,6 +200,7 @@ func Test_ORM_UpdateManager(t *testing.T) { func Test_ORM_CreateChainConfig(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( orm = setupORM(t) @@ -224,10 +228,10 @@ func Test_ORM_CreateChainConfig(t *testing.T) { } ) - id, err := orm.CreateChainConfig(cfg1) + id, err := orm.CreateChainConfig(ctx, cfg1) require.NoError(t, err) - actual, err := orm.GetChainConfig(id) + actual, err := orm.GetChainConfig(ctx, id) require.NoError(t, err) assertChainConfigEqual(t, map[string]interface{}{ @@ -244,6 +248,7 @@ func Test_ORM_CreateChainConfig(t *testing.T) { func Test_ORM_CreateBatchChainConfig(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( orm = setupORM(t) @@ -264,12 +269,12 @@ func Test_ORM_CreateBatchChainConfig(t *testing.T) { } ) - ids, err := orm.CreateBatchChainConfig([]feeds.ChainConfig{cfg1, cfg2}) + ids, err := orm.CreateBatchChainConfig(ctx, []feeds.ChainConfig{cfg1, cfg2}) require.NoError(t, err) assert.Len(t, ids, 2) - actual, err := orm.GetChainConfig(ids[0]) + actual, err := orm.GetChainConfig(ctx, ids[0]) require.NoError(t, err) assertChainConfigEqual(t, map[string]interface{}{ @@ -283,7 +288,7 @@ func Test_ORM_CreateBatchChainConfig(t *testing.T) { "ocr2Config": cfg1.OCR2Config, }, *actual) - actual, err = orm.GetChainConfig(ids[1]) + actual, err = orm.GetChainConfig(ctx, ids[1]) require.NoError(t, err) assertChainConfigEqual(t, map[string]interface{}{ @@ -298,13 +303,14 @@ func Test_ORM_CreateBatchChainConfig(t *testing.T) { }, *actual) // Test empty configs - ids, err = orm.CreateBatchChainConfig([]feeds.ChainConfig{}) + ids, err = orm.CreateBatchChainConfig(ctx, []feeds.ChainConfig{}) require.NoError(t, err) require.Empty(t, ids) } func Test_ORM_DeleteChainConfig(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( orm = setupORM(t) @@ -318,22 +324,23 @@ func Test_ORM_DeleteChainConfig(t *testing.T) { } ) - id, err := orm.CreateChainConfig(cfg1) + id, err := orm.CreateChainConfig(ctx, cfg1) require.NoError(t, err) - _, err = orm.GetChainConfig(id) + _, err = orm.GetChainConfig(ctx, id) require.NoError(t, err) - actual, err := orm.DeleteChainConfig(id) + actual, err := orm.DeleteChainConfig(ctx, id) require.NoError(t, err) require.Equal(t, id, actual) - _, err = orm.GetChainConfig(id) + _, err = orm.GetChainConfig(ctx, id) require.Error(t, err) } func Test_ORM_ListChainConfigsByManagerIDs(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( orm = setupORM(t) @@ -361,10 +368,10 @@ func Test_ORM_ListChainConfigsByManagerIDs(t *testing.T) { } ) - _, err := orm.CreateChainConfig(cfg1) + _, err := orm.CreateChainConfig(ctx, cfg1) require.NoError(t, err) - actual, err := orm.ListChainConfigsByManagerIDs([]int64{fmID}) + actual, err := orm.ListChainConfigsByManagerIDs(ctx, []int64{fmID}) require.NoError(t, err) require.Len(t, actual, 1) @@ -382,6 +389,7 @@ func Test_ORM_ListChainConfigsByManagerIDs(t *testing.T) { func Test_ORM_UpdateChainConfig(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( orm = setupORM(t) @@ -414,15 +422,15 @@ func Test_ORM_UpdateChainConfig(t *testing.T) { } ) - id, err := orm.CreateChainConfig(cfg1) + id, err := orm.CreateChainConfig(ctx, cfg1) require.NoError(t, err) updateCfg.ID = id - id, err = orm.UpdateChainConfig(updateCfg) + id, err = orm.UpdateChainConfig(ctx, updateCfg) require.NoError(t, err) - actual, err := orm.GetChainConfig(id) + actual, err := orm.GetChainConfig(ctx, id) require.NoError(t, err) assertChainConfigEqual(t, map[string]interface{}{ @@ -441,6 +449,7 @@ func Test_ORM_UpdateChainConfig(t *testing.T) { func Test_ORM_CreateJobProposal(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) orm := setupORM(t) fmID := createFeedsManager(t, orm) @@ -452,14 +461,14 @@ func Test_ORM_CreateJobProposal(t *testing.T) { FeedsManagerID: fmID, } - count, err := orm.CountJobProposals() + count, err := orm.CountJobProposals(ctx) require.NoError(t, err) require.Equal(t, int64(0), count) - id, err := orm.CreateJobProposal(jp) + id, err := orm.CreateJobProposal(ctx, jp) require.NoError(t, err) - actual, err := orm.GetJobProposal(id) + actual, err := orm.GetJobProposal(ctx, id) require.NoError(t, err) require.Equal(t, jp.Name, actual.Name) require.Equal(t, jp.RemoteUUID, actual.RemoteUUID) @@ -474,6 +483,7 @@ func Test_ORM_CreateJobProposal(t *testing.T) { func Test_ORM_GetJobProposal(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) orm := setupORM(t) fmID := createFeedsManager(t, orm) @@ -495,10 +505,10 @@ func Test_ORM_GetJobProposal(t *testing.T) { FeedsManagerID: fmID, } - id, err := orm.CreateJobProposal(jp) + id, err := orm.CreateJobProposal(ctx, jp) require.NoError(t, err) - _, err = orm.CreateJobProposal(deletedJp) + _, err = orm.CreateJobProposal(ctx, deletedJp) require.NoError(t, err) assertJobEquals := func(actual *feeds.JobProposal) { @@ -512,32 +522,33 @@ func Test_ORM_GetJobProposal(t *testing.T) { } t.Run("by id", func(t *testing.T) { - actual, err := orm.GetJobProposal(id) + actual, err := orm.GetJobProposal(ctx, id) require.NoError(t, err) assert.Equal(t, id, actual.ID) assertJobEquals(actual) - _, err = orm.GetJobProposal(int64(0)) + _, err = orm.GetJobProposal(ctx, int64(0)) require.Error(t, err) }) t.Run("by remote uuid", func(t *testing.T) { - actual, err := orm.GetJobProposalByRemoteUUID(remoteUUID) + actual, err := orm.GetJobProposalByRemoteUUID(ctx, remoteUUID) require.NoError(t, err) assertJobEquals(actual) - _, err = orm.GetJobProposalByRemoteUUID(deletedUUID) + _, err = orm.GetJobProposalByRemoteUUID(ctx, deletedUUID) require.Error(t, err) - _, err = orm.GetJobProposalByRemoteUUID(uuid.New()) + _, err = orm.GetJobProposalByRemoteUUID(ctx, uuid.New()) require.Error(t, err) }) } func Test_ORM_ListJobProposals(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) orm := setupORM(t) fmID := createFeedsManager(t, orm) @@ -551,10 +562,10 @@ func Test_ORM_ListJobProposals(t *testing.T) { FeedsManagerID: fmID, } - id, err := orm.CreateJobProposal(jp) + id, err := orm.CreateJobProposal(ctx, jp) require.NoError(t, err) - jps, err := orm.ListJobProposals() + jps, err := orm.ListJobProposals(ctx) require.NoError(t, err) require.Len(t, jps, 1) @@ -573,13 +584,14 @@ func Test_ORM_CountJobProposalsByStatus(t *testing.T) { testCases := []struct { name string - before func(orm *TestORM) *feeds.JobProposalCounts + before func(t *testing.T, orm *TestORM) *feeds.JobProposalCounts wantApproved, wantRejected, wantDeleted, wantRevoked, wantPending, wantCancelled int64 }{ { name: "correctly counts when there are no job proposals", - before: func(orm *TestORM) *feeds.JobProposalCounts { - counts, err := orm.CountJobProposalsByStatus() + before: func(t *testing.T, orm *TestORM) *feeds.JobProposalCounts { + ctx := testutils.Context(t) + counts, err := orm.CountJobProposalsByStatus(ctx) require.NoError(t, err) return counts @@ -587,12 +599,13 @@ func Test_ORM_CountJobProposalsByStatus(t *testing.T) { }, { name: "correctly counts a pending and cancelled job proposal by status", - before: func(orm *TestORM) *feeds.JobProposalCounts { + before: func(t *testing.T, orm *TestORM) *feeds.JobProposalCounts { + ctx := testutils.Context(t) fmID := createFeedsManager(t, orm) createJobProposal(t, orm, feeds.JobProposalStatusPending, fmID) createJobProposal(t, orm, feeds.JobProposalStatusCancelled, fmID) - counts, err := orm.CountJobProposalsByStatus() + counts, err := orm.CountJobProposalsByStatus(ctx) require.NoError(t, err) return counts @@ -604,12 +617,13 @@ func Test_ORM_CountJobProposalsByStatus(t *testing.T) { // Verify that the counts are correct even if the proposal status is not pending. A // spec is considered pending if its status is pending OR pending_update is TRUE name: "correctly counts the pending specs when pending_update is true but the status itself is not pending", - before: func(orm *TestORM) *feeds.JobProposalCounts { + before: func(t *testing.T, orm *TestORM) *feeds.JobProposalCounts { + ctx := testutils.Context(t) fmID := createFeedsManager(t, orm) // Create a pending job proposal. jUUID := uuid.New() - jpID, err := orm.CreateJobProposal(&feeds.JobProposal{ + jpID, err := orm.CreateJobProposal(ctx, &feeds.JobProposal{ RemoteUUID: jUUID, Status: feeds.JobProposalStatusPending, FeedsManagerID: fmID, @@ -617,7 +631,7 @@ func Test_ORM_CountJobProposalsByStatus(t *testing.T) { require.NoError(t, err) // Upsert the proposal and change its status to rejected - _, err = orm.UpsertJobProposal(&feeds.JobProposal{ + _, err = orm.UpsertJobProposal(ctx, &feeds.JobProposal{ RemoteUUID: jUUID, Status: feeds.JobProposalStatusRejected, FeedsManagerID: fmID, @@ -625,11 +639,11 @@ func Test_ORM_CountJobProposalsByStatus(t *testing.T) { require.NoError(t, err) // Assert that the upserted job proposal is now pending update. - jp, err := orm.GetJobProposal(jpID) + jp, err := orm.GetJobProposal(ctx, jpID) require.NoError(t, err) assert.Equal(t, true, jp.PendingUpdate) - counts, err := orm.CountJobProposalsByStatus() + counts, err := orm.CountJobProposalsByStatus(ctx) require.NoError(t, err) return counts @@ -638,7 +652,8 @@ func Test_ORM_CountJobProposalsByStatus(t *testing.T) { }, { name: "correctly counts when approving a job proposal", - before: func(orm *TestORM) *feeds.JobProposalCounts { + before: func(t *testing.T, orm *TestORM) *feeds.JobProposalCounts { + ctx := testutils.Context(t) fmID := createFeedsManager(t, orm) // Create a pending job proposal. @@ -649,15 +664,15 @@ func Test_ORM_CountJobProposalsByStatus(t *testing.T) { specID := createJobSpec(t, orm, jpID) // Defer the FK requirement of an existing job for a job proposal to be approved - require.NoError(t, utils.JustError(orm.db.Exec( + require.NoError(t, utils.JustError(orm.db.ExecContext(ctx, `SET CONSTRAINTS job_proposals_job_id_fkey DEFERRED`, ))) // Approve the pending job proposal. - err := orm.ApproveSpec(specID, jUUID) + err := orm.ApproveSpec(ctx, specID, jUUID) require.NoError(t, err) - counts, err := orm.CountJobProposalsByStatus() + counts, err := orm.CountJobProposalsByStatus(ctx) require.NoError(t, err) return counts @@ -666,16 +681,17 @@ func Test_ORM_CountJobProposalsByStatus(t *testing.T) { }, { name: "correctly counts when revoking a job proposal", - before: func(orm *TestORM) *feeds.JobProposalCounts { + before: func(t *testing.T, orm *TestORM) *feeds.JobProposalCounts { + ctx := testutils.Context(t) fmID := createFeedsManager(t, orm) jpID := createJobProposal(t, orm, feeds.JobProposalStatusPending, fmID) specID := createJobSpec(t, orm, jpID) // Revoke the pending job proposal. - err := orm.RevokeSpec(specID) + err := orm.RevokeSpec(ctx, specID) require.NoError(t, err) - counts, err := orm.CountJobProposalsByStatus() + counts, err := orm.CountJobProposalsByStatus(ctx) require.NoError(t, err) return counts @@ -684,16 +700,17 @@ func Test_ORM_CountJobProposalsByStatus(t *testing.T) { }, { name: "correctly counts when deleting a job proposal", - before: func(orm *TestORM) *feeds.JobProposalCounts { + before: func(t *testing.T, orm *TestORM) *feeds.JobProposalCounts { + ctx := testutils.Context(t) fmID := createFeedsManager(t, orm) jpID := createJobProposal(t, orm, feeds.JobProposalStatusPending, fmID) createJobSpec(t, orm, jpID) // Delete the pending job proposal. - err := orm.DeleteProposal(jpID) + err := orm.DeleteProposal(ctx, jpID) require.NoError(t, err) - counts, err := orm.CountJobProposalsByStatus() + counts, err := orm.CountJobProposalsByStatus(ctx) require.NoError(t, err) return counts @@ -702,12 +719,13 @@ func Test_ORM_CountJobProposalsByStatus(t *testing.T) { }, { name: "correctly counts when deleting a job proposal with an approved spec", - before: func(orm *TestORM) *feeds.JobProposalCounts { + before: func(t *testing.T, orm *TestORM) *feeds.JobProposalCounts { + ctx := testutils.Context(t) fmID := createFeedsManager(t, orm) // Create a pending job proposal. jUUID := uuid.New() - jpID, err := orm.CreateJobProposal(&feeds.JobProposal{ + jpID, err := orm.CreateJobProposal(ctx, &feeds.JobProposal{ RemoteUUID: jUUID, Status: feeds.JobProposalStatusPending, FeedsManagerID: fmID, @@ -719,18 +737,18 @@ func Test_ORM_CountJobProposalsByStatus(t *testing.T) { specID := createJobSpec(t, orm, jpID) // Defer the FK requirement of an existing job for a job proposal to be approved - require.NoError(t, utils.JustError(orm.db.Exec( + require.NoError(t, utils.JustError(orm.db.ExecContext(ctx, `SET CONSTRAINTS job_proposals_job_id_fkey DEFERRED`, ))) - err = orm.ApproveSpec(specID, jUUID) + err = orm.ApproveSpec(ctx, specID, jUUID) require.NoError(t, err) // Delete the pending job proposal. - err = orm.DeleteProposal(jpID) + err = orm.DeleteProposal(ctx, jpID) require.NoError(t, err) - counts, err := orm.CountJobProposalsByStatus() + counts, err := orm.CountJobProposalsByStatus(ctx) require.NoError(t, err) return counts @@ -745,7 +763,7 @@ func Test_ORM_CountJobProposalsByStatus(t *testing.T) { t.Run(tc.name, func(t *testing.T) { orm := setupORM(t) - counts := tc.before(orm) + counts := tc.before(t, orm) assert.Equal(t, tc.wantPending, counts.Pending) assert.Equal(t, tc.wantApproved, counts.Approved) @@ -759,6 +777,7 @@ func Test_ORM_CountJobProposalsByStatus(t *testing.T) { func Test_ORM_ListJobProposalByManagersIDs(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) orm := setupORM(t) fmID := createFeedsManager(t, orm) @@ -772,10 +791,10 @@ func Test_ORM_ListJobProposalByManagersIDs(t *testing.T) { FeedsManagerID: fmID, } - id, err := orm.CreateJobProposal(jp) + id, err := orm.CreateJobProposal(ctx, jp) require.NoError(t, err) - jps, err := orm.ListJobProposalsByManagersIDs([]int64{fmID}) + jps, err := orm.ListJobProposalsByManagersIDs(ctx, []int64{fmID}) require.NoError(t, err) require.Len(t, jps, 1) @@ -791,18 +810,19 @@ func Test_ORM_ListJobProposalByManagersIDs(t *testing.T) { func Test_ORM_UpdateJobProposalStatus(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) orm := setupORM(t) fmID := createFeedsManager(t, orm) jpID := createJobProposal(t, orm, feeds.JobProposalStatusPending, fmID) - actualCreated, err := orm.GetJobProposal(jpID) + actualCreated, err := orm.GetJobProposal(ctx, jpID) require.NoError(t, err) - err = orm.UpdateJobProposalStatus(jpID, feeds.JobProposalStatusRejected) + err = orm.UpdateJobProposalStatus(ctx, jpID, feeds.JobProposalStatusRejected) require.NoError(t, err) - actual, err := orm.GetJobProposal(jpID) + actual, err := orm.GetJobProposal(ctx, jpID) require.NoError(t, err) assert.Equal(t, jpID, actual.ID) @@ -812,6 +832,7 @@ func Test_ORM_UpdateJobProposalStatus(t *testing.T) { func Test_ORM_UpsertJobProposal(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( orm = setupORM(t) @@ -833,19 +854,19 @@ func Test_ORM_UpsertJobProposal(t *testing.T) { // from pending to approved, and then approved to pending, and pending to deleted and so forth. // Create - count, err := orm.CountJobProposals() + count, err := orm.CountJobProposals(ctx) require.NoError(t, err) require.Equal(t, int64(0), count) - jpID, err := orm.UpsertJobProposal(jp) + jpID, err := orm.UpsertJobProposal(ctx, jp) require.NoError(t, err) - createdActual, err := orm.GetJobProposal(jpID) + createdActual, err := orm.GetJobProposal(ctx, jpID) require.NoError(t, err) assert.False(t, createdActual.PendingUpdate) - count, err = orm.CountJobProposals() + count, err = orm.CountJobProposals(ctx) require.NoError(t, err) require.Equal(t, int64(1), count) @@ -855,10 +876,10 @@ func Test_ORM_UpsertJobProposal(t *testing.T) { jp.Multiaddrs = pq.StringArray{"dns/example.com"} jp.Name = null.StringFrom("jp1_updated") - jpID, err = orm.UpsertJobProposal(jp) + jpID, err = orm.UpsertJobProposal(ctx, jp) require.NoError(t, err) - actual, err := orm.GetJobProposal(jpID) + actual, err := orm.GetJobProposal(ctx, jpID) require.NoError(t, err) assert.Equal(t, jp.Name, actual.Name) assert.Equal(t, jp.Status, actual.Status) @@ -874,14 +895,14 @@ func Test_ORM_UpsertJobProposal(t *testing.T) { specID := createJobSpec(t, orm, jpID) // Defer the FK requirement of an existing job for a job proposal. - require.NoError(t, utils.JustError(orm.db.Exec( + require.NoError(t, utils.JustError(orm.db.ExecContext(ctx, `SET CONSTRAINTS job_proposals_job_id_fkey DEFERRED`, ))) - err = orm.ApproveSpec(specID, externalJobID.UUID) + err = orm.ApproveSpec(ctx, specID, externalJobID.UUID) require.NoError(t, err) - actual, err = orm.GetJobProposal(jpID) + actual, err = orm.GetJobProposal(ctx, jpID) require.NoError(t, err) // Assert that the job proposal is now approved. @@ -893,10 +914,10 @@ func Test_ORM_UpsertJobProposal(t *testing.T) { jp.Name = null.StringFrom("jp1_updated_again") jp.Status = feeds.JobProposalStatusPending - _, err = orm.UpsertJobProposal(jp) + _, err = orm.UpsertJobProposal(ctx, jp) require.NoError(t, err) - actual, err = orm.GetJobProposal(jpID) + actual, err = orm.GetJobProposal(ctx, jpID) require.NoError(t, err) assert.Equal(t, feeds.JobProposalStatusApproved, actual.Status) @@ -904,10 +925,10 @@ func Test_ORM_UpsertJobProposal(t *testing.T) { assert.True(t, actual.PendingUpdate) // Delete the proposal - err = orm.DeleteProposal(jpID) + err = orm.DeleteProposal(ctx, jpID) require.NoError(t, err) - actual, err = orm.GetJobProposal(jpID) + actual, err = orm.GetJobProposal(ctx, jpID) require.NoError(t, err) assert.Equal(t, feeds.JobProposalStatusDeleted, actual.Status) @@ -915,11 +936,11 @@ func Test_ORM_UpsertJobProposal(t *testing.T) { // Update deleted proposal jp.Status = feeds.JobProposalStatusRejected - jpID, err = orm.UpsertJobProposal(jp) + jpID, err = orm.UpsertJobProposal(ctx, jp) require.NoError(t, err) // Ensure the deleted proposal does not get updated - actual, err = orm.GetJobProposal(jpID) + actual, err = orm.GetJobProposal(ctx, jpID) require.NoError(t, err) assert.NotEqual(t, jp.Status, actual.Status) assert.Equal(t, feeds.JobProposalStatusDeleted, actual.Status) @@ -929,6 +950,7 @@ func Test_ORM_UpsertJobProposal(t *testing.T) { func Test_ORM_ApproveSpec(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( orm = setupORM(t) @@ -937,7 +959,7 @@ func Test_ORM_ApproveSpec(t *testing.T) { ) // Manually create the job proposal to set pending update - jpID, err := orm.CreateJobProposal(&feeds.JobProposal{ + jpID, err := orm.CreateJobProposal(ctx, &feeds.JobProposal{ RemoteUUID: uuid.New(), Status: feeds.JobProposalStatusPending, FeedsManagerID: fmID, @@ -947,20 +969,20 @@ func Test_ORM_ApproveSpec(t *testing.T) { specID := createJobSpec(t, orm, jpID) // Defer the FK requirement of an existing job for a job proposal. - require.NoError(t, utils.JustError(orm.db.Exec( + require.NoError(t, utils.JustError(orm.db.ExecContext(ctx, `SET CONSTRAINTS job_proposals_job_id_fkey DEFERRED`, ))) - err = orm.ApproveSpec(specID, externalJobID.UUID) + err = orm.ApproveSpec(ctx, specID, externalJobID.UUID) require.NoError(t, err) - actual, err := orm.GetSpec(specID) + actual, err := orm.GetSpec(ctx, specID) require.NoError(t, err) assert.Equal(t, specID, actual.ID) assert.Equal(t, feeds.SpecStatusApproved, actual.Status) - actualJP, err := orm.GetJobProposal(jpID) + actualJP, err := orm.GetJobProposal(ctx, jpID) require.NoError(t, err) assert.Equal(t, externalJobID, actualJP.ExternalJobID) @@ -973,14 +995,14 @@ func Test_ORM_CancelSpec(t *testing.T) { testCases := []struct { name string - before func(orm *TestORM) (int64, int64) + before func(t *testing.T, orm *TestORM) (int64, int64) wantSpecStatus feeds.SpecStatus wantProposalStatus feeds.JobProposalStatus wantErr string }{ { name: "pending proposal", - before: func(orm *TestORM) (int64, int64) { + before: func(t *testing.T, orm *TestORM) (int64, int64) { fmID := createFeedsManager(t, orm) jpID := createJobProposal(t, orm, feeds.JobProposalStatusPending, fmID) specID := createJobSpec(t, orm, jpID) @@ -992,7 +1014,7 @@ func Test_ORM_CancelSpec(t *testing.T) { }, { name: "deleted proposal", - before: func(orm *TestORM) (int64, int64) { + before: func(t *testing.T, orm *TestORM) (int64, int64) { fmID := createFeedsManager(t, orm) jpID := createJobProposal(t, orm, feeds.JobProposalStatusDeleted, fmID) specID := createJobSpec(t, orm, jpID) @@ -1004,7 +1026,7 @@ func Test_ORM_CancelSpec(t *testing.T) { }, { name: "not found", - before: func(orm *TestORM) (int64, int64) { + before: func(t *testing.T, orm *TestORM) (int64, int64) { return 0, 0 }, wantErr: "sql: no rows in result set", @@ -1015,24 +1037,25 @@ func Test_ORM_CancelSpec(t *testing.T) { tc := tc t.Run(tc.name, func(t *testing.T) { + ctx := testutils.Context(t) orm := setupORM(t) - jpID, specID := tc.before(orm) + jpID, specID := tc.before(t, orm) - err := orm.CancelSpec(specID) + err := orm.CancelSpec(ctx, specID) if tc.wantErr != "" { require.EqualError(t, err, tc.wantErr) } else { require.NoError(t, err) - actual, err := orm.GetSpec(specID) + actual, err := orm.GetSpec(ctx, specID) require.NoError(t, err) assert.Equal(t, specID, actual.ID) assert.Equal(t, tc.wantSpecStatus, actual.Status) - actualJP, err := orm.GetJobProposal(jpID) + actualJP, err := orm.GetJobProposal(ctx, jpID) require.NoError(t, err) assert.Equal(t, tc.wantProposalStatus, actualJP.Status) @@ -1047,14 +1070,14 @@ func Test_ORM_DeleteProposal(t *testing.T) { testCases := []struct { name string - before func(orm *TestORM) int64 + before func(t *testing.T, orm *TestORM) int64 wantProposalStatus feeds.JobProposalStatus wantProposalPendingUpdate bool wantErr string }{ { name: "pending proposal", - before: func(orm *TestORM) int64 { + before: func(t *testing.T, orm *TestORM) int64 { fmID := createFeedsManager(t, orm) jpID := createJobProposal(t, orm, feeds.JobProposalStatusPending, fmID) createJobSpec(t, orm, jpID) @@ -1066,7 +1089,8 @@ func Test_ORM_DeleteProposal(t *testing.T) { }, { name: "approved proposal with approved spec", - before: func(orm *TestORM) int64 { + before: func(t *testing.T, orm *TestORM) int64 { + ctx := testutils.Context(t) fmID := createFeedsManager(t, orm) jpID := createJobProposal(t, orm, feeds.JobProposalStatusPending, fmID) specID := createJobSpec(t, orm, jpID) @@ -1074,11 +1098,11 @@ func Test_ORM_DeleteProposal(t *testing.T) { externalJobID := uuid.NullUUID{UUID: uuid.New(), Valid: true} // Defer the FK requirement of an existing job for a job proposal. - require.NoError(t, utils.JustError(orm.db.Exec( + require.NoError(t, utils.JustError(orm.db.ExecContext(ctx, `SET CONSTRAINTS job_proposals_job_id_fkey DEFERRED`, ))) - err := orm.ApproveSpec(specID, externalJobID.UUID) + err := orm.ApproveSpec(ctx, specID, externalJobID.UUID) require.NoError(t, err) return jpID @@ -1088,7 +1112,8 @@ func Test_ORM_DeleteProposal(t *testing.T) { }, { name: "approved proposal with pending spec", - before: func(orm *TestORM) int64 { + before: func(t *testing.T, orm *TestORM) int64 { + ctx := testutils.Context(t) fmID := createFeedsManager(t, orm) jpID := createJobProposal(t, orm, feeds.JobProposalStatusPending, fmID) specID := createJobSpec(t, orm, jpID) @@ -1096,25 +1121,25 @@ func Test_ORM_DeleteProposal(t *testing.T) { externalJobID := uuid.NullUUID{UUID: uuid.New(), Valid: true} // Defer the FK requirement of an existing job for a job proposal. - require.NoError(t, utils.JustError(orm.db.Exec( + require.NoError(t, utils.JustError(orm.db.ExecContext(ctx, `SET CONSTRAINTS job_proposals_job_id_fkey DEFERRED`, ))) - err := orm.ApproveSpec(specID, externalJobID.UUID) + err := orm.ApproveSpec(ctx, specID, externalJobID.UUID) require.NoError(t, err) - jp, err := orm.GetJobProposal(jpID) + jp, err := orm.GetJobProposal(ctx, jpID) require.NoError(t, err) // Update the proposal to pending and create a new pending spec - _, err = orm.UpsertJobProposal(&feeds.JobProposal{ + _, err = orm.UpsertJobProposal(ctx, &feeds.JobProposal{ RemoteUUID: jp.RemoteUUID, Status: feeds.JobProposalStatusPending, FeedsManagerID: fmID, }) require.NoError(t, err) - _, err = orm.CreateSpec(feeds.JobProposalSpec{ + _, err = orm.CreateSpec(ctx, feeds.JobProposalSpec{ Definition: "spec data", Version: 2, Status: feeds.SpecStatusPending, @@ -1129,7 +1154,7 @@ func Test_ORM_DeleteProposal(t *testing.T) { }, { name: "cancelled proposal", - before: func(orm *TestORM) int64 { + before: func(t *testing.T, orm *TestORM) int64 { fmID := createFeedsManager(t, orm) jpID := createJobProposal(t, orm, feeds.JobProposalStatusCancelled, fmID) createJobSpec(t, orm, jpID) @@ -1141,7 +1166,7 @@ func Test_ORM_DeleteProposal(t *testing.T) { }, { name: "rejected proposal", - before: func(orm *TestORM) int64 { + before: func(t *testing.T, orm *TestORM) int64 { fmID := createFeedsManager(t, orm) jpID := createJobProposal(t, orm, feeds.JobProposalStatusRejected, fmID) createJobSpec(t, orm, jpID) @@ -1153,7 +1178,7 @@ func Test_ORM_DeleteProposal(t *testing.T) { }, { name: "not found spec", - before: func(orm *TestORM) int64 { + before: func(t *testing.T, orm *TestORM) int64 { fmID := createFeedsManager(t, orm) jpID := createJobProposal(t, orm, feeds.JobProposalStatusRejected, fmID) @@ -1163,7 +1188,7 @@ func Test_ORM_DeleteProposal(t *testing.T) { }, { name: "not found proposal", - before: func(orm *TestORM) int64 { + before: func(t *testing.T, orm *TestORM) int64 { return 0 }, wantErr: "sql: no rows in result set", @@ -1174,18 +1199,19 @@ func Test_ORM_DeleteProposal(t *testing.T) { tc := tc t.Run(tc.name, func(t *testing.T) { + ctx := testutils.Context(t) orm := setupORM(t) - jpID := tc.before(orm) + jpID := tc.before(t, orm) - err := orm.DeleteProposal(jpID) + err := orm.DeleteProposal(ctx, jpID) if tc.wantErr != "" { require.EqualError(t, err, tc.wantErr) } else { require.NoError(t, err) - actual, err := orm.GetJobProposal(jpID) + actual, err := orm.GetJobProposal(ctx, jpID) require.NoError(t, err) assert.Equal(t, jpID, actual.ID) @@ -1201,7 +1227,7 @@ func Test_ORM_RevokeSpec(t *testing.T) { testCases := []struct { name string - before func(orm *TestORM) (int64, int64) + before func(t *testing.T, orm *TestORM) (int64, int64) wantProposalStatus feeds.JobProposalStatus wantSpecStatus feeds.SpecStatus wantErr string @@ -1209,7 +1235,7 @@ func Test_ORM_RevokeSpec(t *testing.T) { }{ { name: "pending proposal", - before: func(orm *TestORM) (int64, int64) { + before: func(t *testing.T, orm *TestORM) (int64, int64) { fmID := createFeedsManager(t, orm) jpID := createJobProposal(t, orm, feeds.JobProposalStatusPending, fmID) specID := createJobSpec(t, orm, jpID) @@ -1222,7 +1248,8 @@ func Test_ORM_RevokeSpec(t *testing.T) { }, { name: "approved proposal", - before: func(orm *TestORM) (int64, int64) { + before: func(t *testing.T, orm *TestORM) (int64, int64) { + ctx := testutils.Context(t) fmID := createFeedsManager(t, orm) jpID := createJobProposal(t, orm, feeds.JobProposalStatusPending, fmID) specID := createJobSpec(t, orm, jpID) @@ -1230,11 +1257,11 @@ func Test_ORM_RevokeSpec(t *testing.T) { externalJobID := uuid.NullUUID{UUID: uuid.New(), Valid: true} // Defer the FK requirement of an existing job for a job proposal. - require.NoError(t, utils.JustError(orm.db.Exec( + require.NoError(t, utils.JustError(orm.db.ExecContext(ctx, `SET CONSTRAINTS job_proposals_job_id_fkey DEFERRED`, ))) - err := orm.ApproveSpec(specID, externalJobID.UUID) + err := orm.ApproveSpec(ctx, specID, externalJobID.UUID) require.NoError(t, err) return jpID, specID @@ -1244,7 +1271,7 @@ func Test_ORM_RevokeSpec(t *testing.T) { }, { name: "cancelled proposal", - before: func(orm *TestORM) (int64, int64) { + before: func(t *testing.T, orm *TestORM) (int64, int64) { fmID := createFeedsManager(t, orm) jpID := createJobProposal(t, orm, feeds.JobProposalStatusCancelled, fmID) specID := createJobSpec(t, orm, jpID) @@ -1256,7 +1283,7 @@ func Test_ORM_RevokeSpec(t *testing.T) { }, { name: "rejected proposal", - before: func(orm *TestORM) (int64, int64) { + before: func(t *testing.T, orm *TestORM) (int64, int64) { fmID := createFeedsManager(t, orm) jpID := createJobProposal(t, orm, feeds.JobProposalStatusRejected, fmID) specID := createJobSpec(t, orm, jpID) @@ -1268,7 +1295,7 @@ func Test_ORM_RevokeSpec(t *testing.T) { }, { name: "deleted proposal", - before: func(orm *TestORM) (int64, int64) { + before: func(t *testing.T, orm *TestORM) (int64, int64) { fmID := createFeedsManager(t, orm) jpID := createJobProposal(t, orm, feeds.JobProposalStatusDeleted, fmID) specID := createJobSpec(t, orm, jpID) @@ -1280,7 +1307,7 @@ func Test_ORM_RevokeSpec(t *testing.T) { }, { name: "not found", - before: func(orm *TestORM) (int64, int64) { + before: func(t *testing.T, orm *TestORM) (int64, int64) { return 0, 0 }, wantErr: "sql: no rows in result set", @@ -1291,18 +1318,19 @@ func Test_ORM_RevokeSpec(t *testing.T) { tc := tc t.Run(tc.name, func(t *testing.T) { + ctx := testutils.Context(t) orm := setupORM(t) - jpID, specID := tc.before(orm) + jpID, specID := tc.before(t, orm) - err := orm.RevokeSpec(specID) + err := orm.RevokeSpec(ctx, specID) if tc.wantErr != "" { require.EqualError(t, err, tc.wantErr) } else { require.NoError(t, err) - actualJP, err := orm.GetJobProposal(jpID) + actualJP, err := orm.GetJobProposal(ctx, jpID) require.NoError(t, err) assert.Equal(t, tc.wantProposalStatus, actualJP.Status) @@ -1318,6 +1346,7 @@ func Test_ORM_RevokeSpec(t *testing.T) { func Test_ORM_ExistsSpecByJobProposalIDAndVersion(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( orm = setupORM(t) @@ -1327,17 +1356,18 @@ func Test_ORM_ExistsSpecByJobProposalIDAndVersion(t *testing.T) { createJobSpec(t, orm, jpID) - exists, err := orm.ExistsSpecByJobProposalIDAndVersion(jpID, 1) + exists, err := orm.ExistsSpecByJobProposalIDAndVersion(ctx, jpID, 1) require.NoError(t, err) require.True(t, exists) - exists, err = orm.ExistsSpecByJobProposalIDAndVersion(jpID, 2) + exists, err = orm.ExistsSpecByJobProposalIDAndVersion(ctx, jpID, 2) require.NoError(t, err) require.False(t, exists) } func Test_ORM_GetSpec(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( orm = setupORM(t) @@ -1346,7 +1376,7 @@ func Test_ORM_GetSpec(t *testing.T) { specID = createJobSpec(t, orm, jpID) ) - actual, err := orm.GetSpec(specID) + actual, err := orm.GetSpec(ctx, specID) require.NoError(t, err) assert.Equal(t, "spec data", actual.Definition) @@ -1357,6 +1387,7 @@ func Test_ORM_GetSpec(t *testing.T) { func Test_ORM_GetApprovedSpec(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( orm = setupORM(t) @@ -1368,23 +1399,23 @@ func Test_ORM_GetApprovedSpec(t *testing.T) { // Defer the FK requirement of a job proposal so we don't have to setup a // real job. - require.NoError(t, utils.JustError(orm.db.Exec( + require.NoError(t, utils.JustError(orm.db.ExecContext(ctx, `SET CONSTRAINTS job_proposals_job_id_fkey DEFERRED`, ))) - err := orm.ApproveSpec(specID, externalJobID.UUID) + err := orm.ApproveSpec(ctx, specID, externalJobID.UUID) require.NoError(t, err) - actual, err := orm.GetApprovedSpec(jpID) + actual, err := orm.GetApprovedSpec(ctx, jpID) require.NoError(t, err) assert.Equal(t, specID, actual.ID) assert.Equal(t, feeds.SpecStatusApproved, actual.Status) - err = orm.CancelSpec(specID) + err = orm.CancelSpec(ctx, specID) require.NoError(t, err) - _, err = orm.GetApprovedSpec(jpID) + _, err = orm.GetApprovedSpec(ctx, jpID) require.Error(t, err) assert.ErrorIs(t, err, sql.ErrNoRows) @@ -1392,6 +1423,7 @@ func Test_ORM_GetApprovedSpec(t *testing.T) { func Test_ORM_GetLatestSpec(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( orm = setupORM(t) @@ -1400,7 +1432,7 @@ func Test_ORM_GetLatestSpec(t *testing.T) { ) _ = createJobSpec(t, orm, jpID) - spec2ID, err := orm.CreateSpec(feeds.JobProposalSpec{ + spec2ID, err := orm.CreateSpec(ctx, feeds.JobProposalSpec{ Definition: "spec data", Version: 2, Status: feeds.SpecStatusPending, @@ -1408,7 +1440,7 @@ func Test_ORM_GetLatestSpec(t *testing.T) { }) require.NoError(t, err) - actual, err := orm.GetSpec(spec2ID) + actual, err := orm.GetSpec(ctx, spec2ID) require.NoError(t, err) assert.Equal(t, spec2ID, actual.ID) @@ -1420,6 +1452,7 @@ func Test_ORM_GetLatestSpec(t *testing.T) { func Test_ORM_ListSpecsByJobProposalIDs(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( orm = setupORM(t) @@ -1433,7 +1466,7 @@ func Test_ORM_ListSpecsByJobProposalIDs(t *testing.T) { createJobSpec(t, orm, jp1ID) createJobSpec(t, orm, jp2ID) - specs, err := orm.ListSpecsByJobProposalIDs([]int64{jp1ID, jp2ID}) + specs, err := orm.ListSpecsByJobProposalIDs(ctx, []int64{jp1ID, jp2ID}) require.NoError(t, err) require.Len(t, specs, 2) @@ -1457,14 +1490,14 @@ func Test_ORM_RejectSpec(t *testing.T) { testCases := []struct { name string - before func(orm *TestORM) (int64, int64) + before func(t *testing.T, orm *TestORM) (int64, int64) wantSpecStatus feeds.SpecStatus wantProposalStatus feeds.JobProposalStatus wantErr string }{ { name: "pending proposal", - before: func(orm *TestORM) (int64, int64) { + before: func(t *testing.T, orm *TestORM) (int64, int64) { fmID := createFeedsManager(t, orm) jpID := createJobProposal(t, orm, feeds.JobProposalStatusPending, fmID) specID := createJobSpec(t, orm, jpID) @@ -1476,7 +1509,8 @@ func Test_ORM_RejectSpec(t *testing.T) { }, { name: "approved proposal", - before: func(orm *TestORM) (int64, int64) { + before: func(t *testing.T, orm *TestORM) (int64, int64) { + ctx := testutils.Context(t) fmID := createFeedsManager(t, orm) jpID := createJobProposal(t, orm, feeds.JobProposalStatusPending, fmID) specID := createJobSpec(t, orm, jpID) @@ -1484,11 +1518,11 @@ func Test_ORM_RejectSpec(t *testing.T) { externalJobID := uuid.NullUUID{UUID: uuid.New(), Valid: true} // Defer the FK requirement of an existing job for a job proposal. - require.NoError(t, utils.JustError(orm.db.Exec( + require.NoError(t, utils.JustError(orm.db.ExecContext(ctx, `SET CONSTRAINTS job_proposals_job_id_fkey DEFERRED`, ))) - err := orm.ApproveSpec(specID, externalJobID.UUID) + err := orm.ApproveSpec(ctx, specID, externalJobID.UUID) require.NoError(t, err) return jpID, specID @@ -1498,7 +1532,7 @@ func Test_ORM_RejectSpec(t *testing.T) { }, { name: "cancelled proposal", - before: func(orm *TestORM) (int64, int64) { + before: func(t *testing.T, orm *TestORM) (int64, int64) { fmID := createFeedsManager(t, orm) jpID := createJobProposal(t, orm, feeds.JobProposalStatusCancelled, fmID) specID := createJobSpec(t, orm, jpID) @@ -1510,7 +1544,7 @@ func Test_ORM_RejectSpec(t *testing.T) { }, { name: "deleted proposal", - before: func(orm *TestORM) (int64, int64) { + before: func(t *testing.T, orm *TestORM) (int64, int64) { fmID := createFeedsManager(t, orm) jpID := createJobProposal(t, orm, feeds.JobProposalStatusDeleted, fmID) specID := createJobSpec(t, orm, jpID) @@ -1522,7 +1556,7 @@ func Test_ORM_RejectSpec(t *testing.T) { }, { name: "not found", - before: func(orm *TestORM) (int64, int64) { + before: func(t *testing.T, orm *TestORM) (int64, int64) { return 0, 0 }, wantErr: "sql: no rows in result set", @@ -1533,24 +1567,25 @@ func Test_ORM_RejectSpec(t *testing.T) { tc := tc t.Run(tc.name, func(t *testing.T) { + ctx := testutils.Context(t) orm := setupORM(t) - jpID, specID := tc.before(orm) + jpID, specID := tc.before(t, orm) - err := orm.RejectSpec(specID) + err := orm.RejectSpec(ctx, specID) if tc.wantErr != "" { require.EqualError(t, err, tc.wantErr) } else { require.NoError(t, err) - actual, err := orm.GetSpec(specID) + actual, err := orm.GetSpec(ctx, specID) require.NoError(t, err) assert.Equal(t, specID, actual.ID) assert.Equal(t, tc.wantSpecStatus, actual.Status) - actualJP, err := orm.GetJobProposal(jpID) + actualJP, err := orm.GetJobProposal(ctx, jpID) require.NoError(t, err) assert.Equal(t, tc.wantProposalStatus, actualJP.Status) @@ -1562,6 +1597,7 @@ func Test_ORM_RejectSpec(t *testing.T) { func Test_ORM_UpdateSpecDefinition(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( orm = setupORM(t) @@ -1570,13 +1606,13 @@ func Test_ORM_UpdateSpecDefinition(t *testing.T) { specID = createJobSpec(t, orm, jpID) ) - prev, err := orm.GetSpec(specID) + prev, err := orm.GetSpec(ctx, specID) require.NoError(t, err) - err = orm.UpdateSpecDefinition(specID, "updated spec") + err = orm.UpdateSpecDefinition(ctx, specID, "updated spec") require.NoError(t, err) - actual, err := orm.GetSpec(specID) + actual, err := orm.GetSpec(ctx, specID) require.NoError(t, err) assert.Equal(t, specID, actual.ID) @@ -1584,7 +1620,7 @@ func Test_ORM_UpdateSpecDefinition(t *testing.T) { require.Equal(t, "updated spec", actual.Definition) // Not found - err = orm.UpdateSpecDefinition(-1, "updated spec") + err = orm.UpdateSpecDefinition(ctx, -1, "updated spec") require.Error(t, err) } @@ -1592,6 +1628,7 @@ func Test_ORM_UpdateSpecDefinition(t *testing.T) { func Test_ORM_IsJobManaged(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( orm = setupORM(t) @@ -1603,14 +1640,14 @@ func Test_ORM_IsJobManaged(t *testing.T) { j := createJob(t, orm.db, externalJobID.UUID) - isManaged, err := orm.IsJobManaged(int64(j.ID)) + isManaged, err := orm.IsJobManaged(ctx, int64(j.ID)) require.NoError(t, err) assert.False(t, isManaged) - err = orm.ApproveSpec(specID, externalJobID.UUID) + err = orm.ApproveSpec(ctx, specID, externalJobID.UUID) require.NoError(t, err) - isManaged, err = orm.IsJobManaged(int64(j.ID)) + isManaged, err = orm.IsJobManaged(ctx, int64(j.ID)) require.NoError(t, err) assert.True(t, isManaged) } @@ -1640,7 +1677,8 @@ func createFeedsManager(t *testing.T, orm feeds.ORM) int64 { PublicKey: publicKey, } - id, err := orm.CreateManager(mgr) + ctx := testutils.Context(t) + id, err := orm.CreateManager(ctx, mgr) require.NoError(t, err) return id @@ -1658,7 +1696,7 @@ func createJob(t *testing.T, db *sqlx.DB, externalJobID uuid.UUID) *job.Job { bridgeORM = bridges.NewORM(db) relayExtenders = evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) ) - orm := job.NewORM(db, pipelineORM, bridgeORM, keyStore, lggr, config.Database()) + orm := job.NewORM(db, pipelineORM, bridgeORM, keyStore, lggr) require.NoError(t, keyStore.OCR().Add(ctx, cltest.DefaultOCRKey)) require.NoError(t, keyStore.P2P().Add(ctx, cltest.DefaultP2PKey)) @@ -1679,7 +1717,7 @@ func createJob(t *testing.T, db *sqlx.DB, externalJobID uuid.UUID) *job.Job { ) require.NoError(t, err) - err = orm.CreateJob(&jb) + err = orm.CreateJob(ctx, &jb) require.NoError(t, err) return &jb @@ -1688,7 +1726,8 @@ func createJob(t *testing.T, db *sqlx.DB, externalJobID uuid.UUID) *job.Job { func createJobProposal(t *testing.T, orm feeds.ORM, status feeds.JobProposalStatus, fmID int64) int64 { t.Helper() - id, err := orm.CreateJobProposal(&feeds.JobProposal{ + ctx := testutils.Context(t) + id, err := orm.CreateJobProposal(ctx, &feeds.JobProposal{ RemoteUUID: uuid.New(), Status: status, FeedsManagerID: fmID, @@ -1702,7 +1741,8 @@ func createJobProposal(t *testing.T, orm feeds.ORM, status feeds.JobProposalStat func createJobSpec(t *testing.T, orm feeds.ORM, jpID int64) int64 { t.Helper() - id, err := orm.CreateSpec(feeds.JobProposalSpec{ + ctx := testutils.Context(t) + id, err := orm.CreateSpec(ctx, feeds.JobProposalSpec{ Definition: "spec data", Version: 1, Status: feeds.SpecStatusPending, diff --git a/core/services/feeds/service.go b/core/services/feeds/service.go index 8c4ea7a36bf..d6032befbdc 100644 --- a/core/services/feeds/service.go +++ b/core/services/feeds/service.go @@ -15,9 +15,8 @@ import ( "github.com/prometheus/client_golang/prometheus/promauto" "gopkg.in/guregu/null.v4" - "github.com/jmoiron/sqlx" - "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink/v2/plugins" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" @@ -33,7 +32,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr" ocr2 "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/utils/crypto" ) @@ -66,17 +64,17 @@ type Service interface { Start(ctx context.Context) error Close() error - CountManagers() (int64, error) - GetManager(id int64) (*FeedsManager, error) - ListManagers() ([]FeedsManager, error) - ListManagersByIDs(ids []int64) ([]FeedsManager, error) + CountManagers(ctx context.Context) (int64, error) + GetManager(ctx context.Context, id int64) (*FeedsManager, error) + ListManagers(ctx context.Context) ([]FeedsManager, error) + ListManagersByIDs(ctx context.Context, ids []int64) ([]FeedsManager, error) RegisterManager(ctx context.Context, params RegisterManagerParams) (int64, error) UpdateManager(ctx context.Context, mgr FeedsManager) error CreateChainConfig(ctx context.Context, cfg ChainConfig) (int64, error) DeleteChainConfig(ctx context.Context, id int64) (int64, error) - GetChainConfig(id int64) (*ChainConfig, error) - ListChainConfigsByManagerIDs(mgrIDs []int64) ([]ChainConfig, error) + GetChainConfig(ctx context.Context, id int64) (*ChainConfig, error) + ListChainConfigsByManagerIDs(ctx context.Context, mgrIDs []int64) ([]ChainConfig, error) UpdateChainConfig(ctx context.Context, cfg ChainConfig) (int64, error) DeleteJob(ctx context.Context, args *DeleteJobArgs) (int64, error) @@ -85,19 +83,17 @@ type Service interface { RevokeJob(ctx context.Context, args *RevokeJobArgs) (int64, error) SyncNodeInfo(ctx context.Context, id int64) error - CountJobProposalsByStatus() (*JobProposalCounts, error) - GetJobProposal(id int64) (*JobProposal, error) - ListJobProposals() ([]JobProposal, error) - ListJobProposalsByManagersIDs(ids []int64) ([]JobProposal, error) + CountJobProposalsByStatus(ctx context.Context) (*JobProposalCounts, error) + GetJobProposal(ctx context.Context, id int64) (*JobProposal, error) + ListJobProposals(ctx context.Context) ([]JobProposal, error) + ListJobProposalsByManagersIDs(ctx context.Context, ids []int64) ([]JobProposal, error) ApproveSpec(ctx context.Context, id int64, force bool) error CancelSpec(ctx context.Context, id int64) error - GetSpec(id int64) (*JobProposalSpec, error) - ListSpecsByJobProposalIDs(ids []int64) ([]JobProposalSpec, error) + GetSpec(ctx context.Context, id int64) (*JobProposalSpec, error) + ListSpecsByJobProposalIDs(ctx context.Context, ids []int64) ([]JobProposalSpec, error) RejectSpec(ctx context.Context, id int64) error UpdateSpecDefinition(ctx context.Context, id int64, spec string) error - - Unsafe_SetConnectionsManager(ConnectionsManager) } type service struct { @@ -105,7 +101,7 @@ type service struct { orm ORM jobORM job.ORM - q pg.Q + ds sqlutil.DataSource csaKeyStore keystore.CSA p2pKeyStore keystore.P2P ocr1KeyStore keystore.OCR @@ -127,7 +123,7 @@ type service struct { func NewService( orm ORM, jobORM job.ORM, - db *sqlx.DB, + ds sqlutil.DataSource, jobSpawner job.Spawner, keyStore keystore.Master, gCfg GeneralConfig, @@ -135,7 +131,6 @@ func NewService( jobCfg JobConfig, ocrCfg OCRConfig, ocr2Cfg OCR2Config, - dbCfg pg.QConfig, legacyChains legacyevm.LegacyChainContainer, lggr logger.Logger, version string, @@ -145,7 +140,7 @@ func NewService( svc := &service{ orm: orm, jobORM: jobORM, - q: pg.NewQ(db, lggr, dbCfg), + ds: ds, jobSpawner: jobSpawner, p2pKeyStore: keyStore.P2P(), csaKeyStore: keyStore.CSA(), @@ -178,7 +173,7 @@ type RegisterManagerParams struct { // // Only a single feeds manager is currently supported. func (s *service) RegisterManager(ctx context.Context, params RegisterManagerParams) (int64, error) { - count, err := s.CountManagers() + count, err := s.CountManagers(ctx) if err != nil { return 0, err } @@ -193,16 +188,16 @@ func (s *service) RegisterManager(ctx context.Context, params RegisterManagerPar } var id int64 - q := s.q.WithOpts(pg.WithParentCtx(ctx)) - err = q.Transaction(func(tx pg.Queryer) error { + + err = s.orm.Transact(ctx, func(tx ORM) error { var txerr error - id, txerr = s.orm.CreateManager(&mgr, pg.WithQueryer(tx)) + id, txerr = tx.CreateManager(ctx, &mgr) if err != nil { return txerr } - if _, txerr = s.orm.CreateBatchChainConfig(params.ChainConfigs, pg.WithQueryer(tx)); txerr != nil { + if _, txerr = tx.CreateBatchChainConfig(ctx, params.ChainConfigs); txerr != nil { return txerr } @@ -229,7 +224,7 @@ func (s *service) SyncNodeInfo(ctx context.Context, id int64) error { return errors.Wrap(err, "could not fetch client") } - cfgs, err := s.orm.ListChainConfigsByManagerIDs([]int64{id}) + cfgs, err := s.orm.ListChainConfigsByManagerIDs(ctx, []int64{id}) if err != nil { return errors.Wrap(err, "could not fetch chain configs") } @@ -259,17 +254,9 @@ func (s *service) SyncNodeInfo(ctx context.Context, id int64) error { // UpdateManager updates the feed manager details, takes down the // connection and reestablishes a new connection with the updated public key. func (s *service) UpdateManager(ctx context.Context, mgr FeedsManager) error { - q := s.q.WithOpts(pg.WithParentCtx(ctx)) - err := q.Transaction(func(tx pg.Queryer) error { - txerr := s.orm.UpdateManager(mgr, pg.WithQueryer(tx)) - if txerr != nil { - return errors.Wrap(txerr, "could not update manager") - } - - return nil - }) + err := s.orm.UpdateManager(ctx, mgr) if err != nil { - return err + return errors.Wrap(err, "could not update manager") } if err := s.restartConnection(ctx, mgr); err != nil { @@ -280,8 +267,8 @@ func (s *service) UpdateManager(ctx context.Context, mgr FeedsManager) error { } // ListManagerServices lists all the manager services. -func (s *service) ListManagers() ([]FeedsManager, error) { - managers, err := s.orm.ListManagers() +func (s *service) ListManagers(ctx context.Context) ([]FeedsManager, error) { + managers, err := s.orm.ListManagers(ctx) if err != nil { return nil, errors.Wrap(err, "failed to get a list of managers") } @@ -294,8 +281,8 @@ func (s *service) ListManagers() ([]FeedsManager, error) { } // GetManager gets a manager service by id. -func (s *service) GetManager(id int64) (*FeedsManager, error) { - manager, err := s.orm.GetManager(id) +func (s *service) GetManager(ctx context.Context, id int64) (*FeedsManager, error) { + manager, err := s.orm.GetManager(ctx, id) if err != nil { return nil, errors.Wrap(err, "failed to get manager by ID") } @@ -305,8 +292,8 @@ func (s *service) GetManager(id int64) (*FeedsManager, error) { } // ListManagersByIDs get managers services by ids. -func (s *service) ListManagersByIDs(ids []int64) ([]FeedsManager, error) { - managers, err := s.orm.ListManagersByIDs(ids) +func (s *service) ListManagersByIDs(ctx context.Context, ids []int64) ([]FeedsManager, error) { + managers, err := s.orm.ListManagersByIDs(ctx, ids) if err != nil { return nil, errors.Wrap(err, "failed to list managers by IDs") } @@ -319,8 +306,8 @@ func (s *service) ListManagersByIDs(ids []int64) ([]FeedsManager, error) { } // CountManagers gets the total number of manager services -func (s *service) CountManagers() (int64, error) { - return s.orm.CountManagers() +func (s *service) CountManagers(ctx context.Context) (int64, error) { + return s.orm.CountManagers(ctx) } // CreateChainConfig creates a chain config. @@ -333,12 +320,12 @@ func (s *service) CreateChainConfig(ctx context.Context, cfg ChainConfig) (int64 } } - id, err := s.orm.CreateChainConfig(cfg) + id, err := s.orm.CreateChainConfig(ctx, cfg) if err != nil { return 0, errors.Wrap(err, "CreateChainConfig failed") } - mgr, err := s.orm.GetManager(cfg.FeedsManagerID) + mgr, err := s.orm.GetManager(ctx, cfg.FeedsManagerID) if err != nil { return 0, errors.Wrap(err, "CreateChainConfig: failed to fetch manager") } @@ -352,17 +339,17 @@ func (s *service) CreateChainConfig(ctx context.Context, cfg ChainConfig) (int64 // DeleteChainConfig deletes the chain config by id. func (s *service) DeleteChainConfig(ctx context.Context, id int64) (int64, error) { - cfg, err := s.orm.GetChainConfig(id) + cfg, err := s.orm.GetChainConfig(ctx, id) if err != nil { return 0, errors.Wrap(err, "DeleteChainConfig failed: could not get chain config") } - _, err = s.orm.DeleteChainConfig(id) + _, err = s.orm.DeleteChainConfig(ctx, id) if err != nil { return 0, errors.Wrap(err, "DeleteChainConfig failed") } - mgr, err := s.orm.GetManager(cfg.FeedsManagerID) + mgr, err := s.orm.GetManager(ctx, cfg.FeedsManagerID) if err != nil { return 0, errors.Wrap(err, "DeleteChainConfig: failed to fetch manager") } @@ -374,8 +361,8 @@ func (s *service) DeleteChainConfig(ctx context.Context, id int64) (int64, error return id, nil } -func (s *service) GetChainConfig(id int64) (*ChainConfig, error) { - cfg, err := s.orm.GetChainConfig(id) +func (s *service) GetChainConfig(ctx context.Context, id int64) (*ChainConfig, error) { + cfg, err := s.orm.GetChainConfig(ctx, id) if err != nil { return nil, errors.Wrap(err, "GetChainConfig failed") } @@ -383,8 +370,8 @@ func (s *service) GetChainConfig(id int64) (*ChainConfig, error) { return cfg, nil } -func (s *service) ListChainConfigsByManagerIDs(mgrIDs []int64) ([]ChainConfig, error) { - cfgs, err := s.orm.ListChainConfigsByManagerIDs(mgrIDs) +func (s *service) ListChainConfigsByManagerIDs(ctx context.Context, mgrIDs []int64) ([]ChainConfig, error) { + cfgs, err := s.orm.ListChainConfigsByManagerIDs(ctx, mgrIDs) return cfgs, errors.Wrap(err, "ListChainConfigsByManagerIDs failed") } @@ -398,12 +385,12 @@ func (s *service) UpdateChainConfig(ctx context.Context, cfg ChainConfig) (int64 } } - id, err := s.orm.UpdateChainConfig(cfg) + id, err := s.orm.UpdateChainConfig(ctx, cfg) if err != nil { return 0, errors.Wrap(err, "UpdateChainConfig failed") } - ccfg, err := s.orm.GetChainConfig(cfg.ID) + ccfg, err := s.orm.GetChainConfig(ctx, cfg.ID) if err != nil { return 0, errors.Wrap(err, "UpdateChainConfig failed: could not get chain config") } @@ -419,13 +406,13 @@ func (s *service) UpdateChainConfig(ctx context.Context, cfg ChainConfig) (int64 // // When we support multiple feed managers, we will need to change this to filter // by feeds manager -func (s *service) ListJobProposals() ([]JobProposal, error) { - return s.orm.ListJobProposals() +func (s *service) ListJobProposals(ctx context.Context) ([]JobProposal, error) { + return s.orm.ListJobProposals(ctx) } // ListJobProposalsByManagersIDs gets job proposals by feeds managers IDs -func (s *service) ListJobProposalsByManagersIDs(ids []int64) ([]JobProposal, error) { - return s.orm.ListJobProposalsByManagersIDs(ids) +func (s *service) ListJobProposalsByManagersIDs(ctx context.Context, ids []int64) ([]JobProposal, error) { + return s.orm.ListJobProposalsByManagersIDs(ctx, ids) } // DeleteJobArgs are the arguments to provide to the DeleteJob method. @@ -437,7 +424,7 @@ type DeleteJobArgs struct { // DeleteJob deletes a job proposal if it exist. The feeds manager id check // ensures that only the intended feed manager can make this request. func (s *service) DeleteJob(ctx context.Context, args *DeleteJobArgs) (int64, error) { - proposal, err := s.orm.GetJobProposalByRemoteUUID(args.RemoteUUID) + proposal, err := s.orm.GetJobProposalByRemoteUUID(ctx, args.RemoteUUID) if err != nil { if !errors.Is(err, sql.ErrNoRows) { return 0, errors.Wrap(err, "GetJobProposalByRemoteUUID failed to check existence of job proposal") @@ -456,14 +443,13 @@ func (s *service) DeleteJob(ctx context.Context, args *DeleteJobArgs) (int64, er return 0, errors.New("cannot delete a job proposal belonging to another feeds manager") } - pctx := pg.WithParentCtx(ctx) - if err = s.orm.DeleteProposal(proposal.ID, pctx); err != nil { + if err = s.orm.DeleteProposal(ctx, proposal.ID); err != nil { s.lggr.Errorw("Failed to delete the proposal", "err", err) return 0, errors.Wrap(err, "DeleteProposal failed") } - if err = s.observeJobProposalCounts(); err != nil { + if err = s.observeJobProposalCounts(ctx); err != nil { logger.Errorw("Failed to push metrics for job proposal deletion", err) } @@ -479,7 +465,7 @@ type RevokeJobArgs struct { // RevokeJob revokes a pending job proposal if it exist. The feeds manager // id check ensures that only the intended feed manager can make this request. func (s *service) RevokeJob(ctx context.Context, args *RevokeJobArgs) (int64, error) { - proposal, err := s.orm.GetJobProposalByRemoteUUID(args.RemoteUUID) + proposal, err := s.orm.GetJobProposalByRemoteUUID(ctx, args.RemoteUUID) if err != nil { if !errors.Is(err, sql.ErrNoRows) { return 0, errors.Wrap(err, "GetJobProposalByRemoteUUID failed to check existence of job proposal") @@ -495,7 +481,7 @@ func (s *service) RevokeJob(ctx context.Context, args *RevokeJobArgs) (int64, er } // get the latest spec for the proposal - latest, err := s.orm.GetLatestSpec(proposal.ID) + latest, err := s.orm.GetLatestSpec(ctx, proposal.ID) if err != nil { return 0, errors.Wrap(err, "GetLatestSpec failed to get latest spec") } @@ -504,8 +490,7 @@ func (s *service) RevokeJob(ctx context.Context, args *RevokeJobArgs) (int64, er return 0, errors.New("only pending job specs can be revoked") } - pctx := pg.WithParentCtx(ctx) - if err = s.orm.RevokeSpec(latest.ID, pctx); err != nil { + if err = s.orm.RevokeSpec(ctx, latest.ID); err != nil { s.lggr.Errorw("Failed to revoke the proposal", "err", err) return 0, errors.Wrap(err, "RevokeSpec failed") @@ -516,7 +501,7 @@ func (s *service) RevokeJob(ctx context.Context, args *RevokeJobArgs) (int64, er "job_proposal_spec_id", latest.ID, ) - if err = s.observeJobProposalCounts(); err != nil { + if err = s.observeJobProposalCounts(ctx); err != nil { logger.Errorw("Failed to push metrics for revoke job", err) } @@ -545,7 +530,7 @@ func (s *service) ProposeJob(ctx context.Context, args *ProposeJobArgs) (int64, return 0, err } - existing, err := s.orm.GetJobProposalByRemoteUUID(args.RemoteUUID) + existing, err := s.orm.GetJobProposalByRemoteUUID(ctx, args.RemoteUUID) if err != nil { if !errors.Is(err, sql.ErrNoRows) { return 0, errors.Wrap(err, "failed to check existence of job proposal") @@ -562,7 +547,7 @@ func (s *service) ProposeJob(ctx context.Context, args *ProposeJobArgs) (int64, // Check the version being proposed has not been previously proposed. var exists bool - exists, err = s.orm.ExistsSpecByJobProposalIDAndVersion(existing.ID, args.Version) + exists, err = s.orm.ExistsSpecByJobProposalIDAndVersion(ctx, existing.ID, args.Version) if err != nil { return 0, errors.Wrap(err, "failed to check existence of spec") } @@ -577,32 +562,31 @@ func (s *service) ProposeJob(ctx context.Context, args *ProposeJobArgs) (int64, ) var id int64 - q := s.q.WithOpts(pg.WithParentCtx(ctx)) - err = q.Transaction(func(tx pg.Queryer) error { + err = s.orm.Transact(ctx, func(tx ORM) error { var txerr error // Parse the Job Spec TOML to extract the name name := extractName(args.Spec) // Upsert job proposal - id, txerr = s.orm.UpsertJobProposal(&JobProposal{ + id, txerr = tx.UpsertJobProposal(ctx, &JobProposal{ Name: name, RemoteUUID: args.RemoteUUID, Status: JobProposalStatusPending, FeedsManagerID: args.FeedsManagerID, Multiaddrs: args.Multiaddrs, - }, pg.WithQueryer(tx)) + }) if txerr != nil { return errors.Wrap(txerr, "failed to upsert job proposal") } // Create the spec version - _, txerr = s.orm.CreateSpec(JobProposalSpec{ + _, txerr = tx.CreateSpec(ctx, JobProposalSpec{ Definition: args.Spec, Status: SpecStatusPending, Version: args.Version, JobProposalID: id, - }, pg.WithQueryer(tx)) + }) if txerr != nil { return errors.Wrap(txerr, "failed to create spec") } @@ -616,7 +600,7 @@ func (s *service) ProposeJob(ctx context.Context, args *ProposeJobArgs) (int64, // Track the given job proposal request promJobProposalRequest.Inc() - if err = s.observeJobProposalCounts(); err != nil { + if err = s.observeJobProposalCounts(ctx); err != nil { logger.Errorw("Failed to push metrics for propose job", err) } @@ -624,20 +608,18 @@ func (s *service) ProposeJob(ctx context.Context, args *ProposeJobArgs) (int64, } // GetJobProposal gets a job proposal by id. -func (s *service) GetJobProposal(id int64) (*JobProposal, error) { - return s.orm.GetJobProposal(id) +func (s *service) GetJobProposal(ctx context.Context, id int64) (*JobProposal, error) { + return s.orm.GetJobProposal(ctx, id) } // CountJobProposalsByStatus returns the count of job proposals with a given status. -func (s *service) CountJobProposalsByStatus() (*JobProposalCounts, error) { - return s.orm.CountJobProposalsByStatus() +func (s *service) CountJobProposalsByStatus(ctx context.Context) (*JobProposalCounts, error) { + return s.orm.CountJobProposalsByStatus(ctx) } // RejectSpec rejects a spec. func (s *service) RejectSpec(ctx context.Context, id int64) error { - pctx := pg.WithParentCtx(ctx) - - spec, err := s.orm.GetSpec(id, pctx) + spec, err := s.orm.GetSpec(ctx, id) if err != nil { return errors.Wrap(err, "orm: job proposal spec") } @@ -647,7 +629,7 @@ func (s *service) RejectSpec(ctx context.Context, id int64) error { return errors.New("must be a pending job proposal spec") } - proposal, err := s.orm.GetJobProposal(spec.JobProposalID, pctx) + proposal, err := s.orm.GetJobProposal(ctx, spec.JobProposalID) if err != nil { return errors.Wrap(err, "orm: job proposal") } @@ -662,9 +644,8 @@ func (s *service) RejectSpec(ctx context.Context, id int64) error { "job_proposal_spec_id", id, ) - q := s.q.WithOpts(pctx) - err = q.Transaction(func(tx pg.Queryer) error { - if err = s.orm.RejectSpec(id, pg.WithQueryer(tx)); err != nil { + err = s.orm.Transact(ctx, func(tx ORM) error { + if err = tx.RejectSpec(ctx, id); err != nil { return err } @@ -681,7 +662,7 @@ func (s *service) RejectSpec(ctx context.Context, id int64) error { return errors.Wrap(err, "could not reject job proposal") } - if err = s.observeJobProposalCounts(); err != nil { + if err = s.observeJobProposalCounts(ctx); err != nil { logger.Errorw("Failed to push metrics for job rejection", err) } @@ -690,25 +671,23 @@ func (s *service) RejectSpec(ctx context.Context, id int64) error { // IsJobManaged determines is a job is managed by the Feeds Manager. func (s *service) IsJobManaged(ctx context.Context, jobID int64) (bool, error) { - return s.orm.IsJobManaged(jobID, pg.WithParentCtx(ctx)) + return s.orm.IsJobManaged(ctx, jobID) } // ApproveSpec approves a spec for a job proposal and creates a job with the // spec. func (s *service) ApproveSpec(ctx context.Context, id int64, force bool) error { - pctx := pg.WithParentCtx(ctx) - - spec, err := s.orm.GetSpec(id, pctx) + spec, err := s.orm.GetSpec(ctx, id) if err != nil { return errors.Wrap(err, "orm: job proposal spec") } - proposal, err := s.orm.GetJobProposal(spec.JobProposalID, pctx) + proposal, err := s.orm.GetJobProposal(ctx, spec.JobProposalID) if err != nil { return errors.Wrap(err, "orm: job proposal") } - if err = s.isApprovable(proposal.Status, proposal.ID, spec.Status, spec.ID); err != nil { + if err = s.isApprovable(ctx, proposal.Status, proposal.ID, spec.Status, spec.ID); err != nil { return err } @@ -741,17 +720,14 @@ func (s *service) ApproveSpec(ctx context.Context, id int64, force bool) error { return errors.Wrap(err, "failed to approve job spec due to bridge check") } - q := s.q.WithOpts(pctx) - err = q.Transaction(func(tx pg.Queryer) error { + err = s.transact(ctx, func(tx datasources) error { var ( txerr error existingJobID int32 - - pgOpts = pg.WithQueryer(tx) ) // Use the external job id to check if a job already exists - foundJob, txerr := s.jobORM.FindJobByExternalJobID(j.ExternalJobID, pgOpts) + foundJob, txerr := tx.jobORM.FindJobByExternalJobID(ctx, j.ExternalJobID) if txerr != nil { // Return an error if the repository errors. If there is a not found // error we want to continue with approving the job. @@ -768,7 +744,7 @@ func (s *service) ApproveSpec(ctx context.Context, id int64, force bool) error { if existingJobID == 0 { switch j.Type { case job.OffchainReporting, job.FluxMonitor: - existingJobID, txerr = s.findExistingJobForOCRFlux(j, pgOpts) + existingJobID, txerr = findExistingJobForOCRFlux(ctx, j, tx.jobORM) if txerr != nil { // Return an error if the repository errors. If there is a not found // error we want to continue with approving the job. @@ -777,7 +753,7 @@ func (s *service) ApproveSpec(ctx context.Context, id int64, force bool) error { } } case job.OffchainReporting2, job.Bootstrap: - existingJobID, txerr = s.findExistingJobForOCR2(j, pgOpts) + existingJobID, txerr = findExistingJobForOCR2(ctx, j, tx.jobORM) if txerr != nil { // Return an error if the repository errors. If there is a not found // error we want to continue with approving the job. @@ -798,7 +774,7 @@ func (s *service) ApproveSpec(ctx context.Context, id int64, force bool) error { } // Check if the job is managed by FMS - approvedSpec, serr := s.orm.GetApprovedSpec(proposal.ID, pgOpts) + approvedSpec, serr := tx.orm.GetApprovedSpec(ctx, proposal.ID) if serr != nil { if !errors.Is(serr, sql.ErrNoRows) { logger.Errorw("Failed to get approved spec", "err", serr) @@ -811,7 +787,7 @@ func (s *service) ApproveSpec(ctx context.Context, id int64, force bool) error { // If a spec is found, cancel the existing job spec if serr == nil { - if cerr := s.orm.CancelSpec(approvedSpec.ID, pgOpts); cerr != nil { + if cerr := tx.orm.CancelSpec(ctx, approvedSpec.ID); cerr != nil { logger.Errorw("Failed to delete the cancel the spec", "err", cerr) return cerr @@ -819,7 +795,7 @@ func (s *service) ApproveSpec(ctx context.Context, id int64, force bool) error { } // Delete the job - if serr = s.jobSpawner.DeleteJob(existingJobID, pgOpts); serr != nil { + if serr = s.jobSpawner.DeleteJob(ctx, tx.ds, existingJobID); serr != nil { logger.Errorw("Failed to delete the job", "err", serr) return errors.Wrap(serr, "DeleteJob failed") @@ -827,14 +803,14 @@ func (s *service) ApproveSpec(ctx context.Context, id int64, force bool) error { } // Create the job - if txerr = s.jobSpawner.CreateJob(j, pgOpts); txerr != nil { + if txerr = s.jobSpawner.CreateJob(ctx, tx.ds, j); txerr != nil { logger.Errorw("Failed to create job", "err", txerr) return txerr } // Approve the job proposal spec - if txerr = s.orm.ApproveSpec(id, j.ExternalJobID, pgOpts); txerr != nil { + if txerr = tx.orm.ApproveSpec(ctx, id, j.ExternalJobID); txerr != nil { logger.Errorw("Failed to approve spec", "err", txerr) return txerr @@ -856,18 +832,32 @@ func (s *service) ApproveSpec(ctx context.Context, id int64, force bool) error { return errors.Wrap(err, "could not approve job proposal") } - if err = s.observeJobProposalCounts(); err != nil { + if err = s.observeJobProposalCounts(ctx); err != nil { logger.Errorw("Failed to push metrics for job approval", err) } return nil } +type datasources struct { + ds sqlutil.DataSource + orm ORM + jobORM job.ORM +} + +func (s *service) transact(ctx context.Context, fn func(datasources) error) error { + return sqlutil.Transact(ctx, func(tx sqlutil.DataSource) datasources { + return datasources{ + ds: tx, + orm: s.orm.WithDataSource(tx), + jobORM: s.jobORM.WithDataSource(tx), + } + }, s.ds, nil, fn) +} + // CancelSpec cancels a spec for a job proposal. func (s *service) CancelSpec(ctx context.Context, id int64) error { - pctx := pg.WithParentCtx(ctx) - - spec, err := s.orm.GetSpec(id, pctx) + spec, err := s.orm.GetSpec(ctx, id) if err != nil { return errors.Wrap(err, "orm: job proposal spec") } @@ -876,7 +866,7 @@ func (s *service) CancelSpec(ctx context.Context, id int64) error { return errors.New("must be an approved job proposal spec") } - jp, err := s.orm.GetJobProposal(spec.JobProposalID, pg.WithParentCtx(ctx)) + jp, err := s.orm.GetJobProposal(ctx, spec.JobProposalID) if err != nil { return errors.Wrap(err, "orm: job proposal") } @@ -891,20 +881,18 @@ func (s *service) CancelSpec(ctx context.Context, id int64) error { "job_proposal_spec_id", id, ) - q := s.q.WithOpts(pctx) - err = q.Transaction(func(tx pg.Queryer) error { + err = s.transact(ctx, func(tx datasources) error { var ( - txerr error - pgOpts = pg.WithQueryer(tx) + txerr error ) - if txerr = s.orm.CancelSpec(id, pgOpts); txerr != nil { + if txerr = tx.orm.CancelSpec(ctx, id); txerr != nil { return txerr } // Delete the job if jp.ExternalJobID.Valid { - j, txerr := s.jobORM.FindJobByExternalJobID(jp.ExternalJobID.UUID, pgOpts) + j, txerr := tx.jobORM.FindJobByExternalJobID(ctx, jp.ExternalJobID.UUID) if txerr != nil { // Return an error if the repository errors. If there is a not found error we want // to continue with cancelling the spec but we won't have to cancel any jobs. @@ -914,7 +902,7 @@ func (s *service) CancelSpec(ctx context.Context, id int64) error { } if txerr == nil { - if serr := s.jobSpawner.DeleteJob(j.ID, pgOpts); serr != nil { + if serr := s.jobSpawner.DeleteJob(ctx, tx.ds, j.ID); serr != nil { return errors.Wrap(serr, "DeleteJob failed") } } @@ -934,7 +922,7 @@ func (s *service) CancelSpec(ctx context.Context, id int64) error { return err } - if err = s.observeJobProposalCounts(); err != nil { + if err = s.observeJobProposalCounts(ctx); err != nil { logger.Errorw("Failed to push metrics for job cancellation", err) } @@ -942,20 +930,18 @@ func (s *service) CancelSpec(ctx context.Context, id int64) error { } // ListSpecsByJobProposalIDs gets the specs which belong to the job proposal ids. -func (s *service) ListSpecsByJobProposalIDs(ids []int64) ([]JobProposalSpec, error) { - return s.orm.ListSpecsByJobProposalIDs(ids) +func (s *service) ListSpecsByJobProposalIDs(ctx context.Context, ids []int64) ([]JobProposalSpec, error) { + return s.orm.ListSpecsByJobProposalIDs(ctx, ids) } // GetSpec gets the spec details by id. -func (s *service) GetSpec(id int64) (*JobProposalSpec, error) { - return s.orm.GetSpec(id) +func (s *service) GetSpec(ctx context.Context, id int64) (*JobProposalSpec, error) { + return s.orm.GetSpec(ctx, id) } // UpdateSpecDefinition updates the spec's TOML definition. func (s *service) UpdateSpecDefinition(ctx context.Context, id int64, defn string) error { - pctx := pg.WithParentCtx(ctx) - - spec, err := s.orm.GetSpec(id, pctx) + spec, err := s.orm.GetSpec(ctx, id) if err != nil { if errors.Is(err, sql.ErrNoRows) { return errors.Wrap(err, "job proposal spec does not exist") @@ -969,7 +955,7 @@ func (s *service) UpdateSpecDefinition(ctx context.Context, id int64, defn strin } // Update the spec definition - if err = s.orm.UpdateSpecDefinition(id, defn, pctx); err != nil { + if err = s.orm.UpdateSpecDefinition(ctx, id, defn); err != nil { return errors.Wrap(err, "could not update job proposal") } @@ -985,7 +971,7 @@ func (s *service) Start(ctx context.Context) error { } // We only support a single feeds manager right now - mgrs, err := s.ListManagers() + mgrs, err := s.ListManagers(ctx) if err != nil { return err } @@ -998,7 +984,7 @@ func (s *service) Start(ctx context.Context) error { mgr := mgrs[0] s.connectFeedManager(ctx, mgr, privkey) - if err = s.observeJobProposalCounts(); err != nil { + if err = s.observeJobProposalCounts(ctx); err != nil { s.lggr.Error("failed to observe job proposal count when starting service", err) } @@ -1052,8 +1038,8 @@ func (s *service) getCSAPrivateKey() (privkey []byte, err error) { // observeJobProposalCounts is a helper method that queries the repository for the count of // job proposals by status and then updates prometheus gauges. -func (s *service) observeJobProposalCounts() error { - counts, err := s.CountJobProposalsByStatus() +func (s *service) observeJobProposalCounts(ctx context.Context) error { + counts, err := s.CountJobProposalsByStatus(ctx) if err != nil { return errors.Wrap(err, "failed to fetch counts of job proposals") } @@ -1073,18 +1059,8 @@ func (s *service) observeJobProposalCounts() error { return nil } -// Unsafe_SetConnectionsManager sets the ConnectionsManager on the service. -// -// We need to be able to inject a mock for the client to facilitate integration -// tests. -// -// ONLY TO BE USED FOR TESTING. -func (s *service) Unsafe_SetConnectionsManager(connMgr ConnectionsManager) { - s.connMgr = connMgr -} - // findExistingJobForOCR2 looks for existing job for OCR2 -func (s *service) findExistingJobForOCR2(j *job.Job, qopts pg.QOpt) (int32, error) { +func findExistingJobForOCR2(ctx context.Context, j *job.Job, tx job.ORM) (int32, error) { var contractID string var feedID *common.Hash @@ -1103,11 +1079,11 @@ func (s *service) findExistingJobForOCR2(j *job.Job, qopts pg.QOpt) (int32, erro return 0, errors.Errorf("unsupported job type: %s", j.Type) } - return s.jobORM.FindOCR2JobIDByAddress(contractID, feedID, qopts) + return tx.FindOCR2JobIDByAddress(ctx, contractID, feedID) } // findExistingJobForOCRFlux looks for existing job for OCR or flux -func (s *service) findExistingJobForOCRFlux(j *job.Job, qopts pg.QOpt) (int32, error) { +func findExistingJobForOCRFlux(ctx context.Context, j *job.Job, tx job.ORM) (int32, error) { var address types.EIP55Address var evmChainID *big.Big @@ -1124,7 +1100,7 @@ func (s *service) findExistingJobForOCRFlux(j *job.Job, qopts pg.QOpt) (int32, e return 0, errors.Errorf("unsupported job type: %s", j.Type) } - return s.jobORM.FindJobIDByAddress(address, evmChainID, qopts) + return tx.FindJobIDByAddress(ctx, address, evmChainID) } // generateJob validates and generates a job from a spec. @@ -1354,7 +1330,7 @@ func extractName(defn string) null.String { // isApprovable returns nil if a spec can be approved based on the current // proposal and spec status, and if it can't be approved, the reason as an // error. -func (s *service) isApprovable(propStatus JobProposalStatus, proposalID int64, specStatus SpecStatus, specID int64) error { +func (s *service) isApprovable(ctx context.Context, propStatus JobProposalStatus, proposalID int64, specStatus SpecStatus, specID int64) error { if propStatus == JobProposalStatusDeleted { return errors.New("cannot approve spec for a deleted job proposal") } @@ -1372,7 +1348,7 @@ func (s *service) isApprovable(propStatus JobProposalStatus, proposalID int64, s return errors.New("cannot approve a revoked spec") case SpecStatusCancelled: // Allowed to approve a cancelled job if it is the latest job - latest, serr := s.orm.GetLatestSpec(proposalID) + latest, serr := s.orm.GetLatestSpec(ctx, proposalID) if serr != nil { return errors.Wrap(serr, "failed to get latest spec") } @@ -1405,46 +1381,46 @@ func (ns NullService) Close() error { return nil } func (ns NullService) ApproveSpec(ctx context.Context, id int64, force bool) error { return ErrFeedsManagerDisabled } -func (ns NullService) CountManagers() (int64, error) { return 0, nil } -func (ns NullService) CountJobProposalsByStatus() (*JobProposalCounts, error) { +func (ns NullService) CountManagers(ctx context.Context) (int64, error) { return 0, nil } +func (ns NullService) CountJobProposalsByStatus(ctx context.Context) (*JobProposalCounts, error) { return nil, ErrFeedsManagerDisabled } func (ns NullService) CancelSpec(ctx context.Context, id int64) error { return ErrFeedsManagerDisabled } -func (ns NullService) GetJobProposal(id int64) (*JobProposal, error) { +func (ns NullService) GetJobProposal(ctx context.Context, id int64) (*JobProposal, error) { return nil, ErrFeedsManagerDisabled } -func (ns NullService) ListSpecsByJobProposalIDs(ids []int64) ([]JobProposalSpec, error) { +func (ns NullService) ListSpecsByJobProposalIDs(ctx context.Context, ids []int64) ([]JobProposalSpec, error) { return nil, ErrFeedsManagerDisabled } -func (ns NullService) GetManager(id int64) (*FeedsManager, error) { +func (ns NullService) GetManager(ctx context.Context, id int64) (*FeedsManager, error) { return nil, ErrFeedsManagerDisabled } -func (ns NullService) ListManagersByIDs(ids []int64) ([]FeedsManager, error) { +func (ns NullService) ListManagersByIDs(ctx context.Context, ids []int64) ([]FeedsManager, error) { return nil, ErrFeedsManagerDisabled } -func (ns NullService) GetSpec(id int64) (*JobProposalSpec, error) { +func (ns NullService) GetSpec(ctx context.Context, id int64) (*JobProposalSpec, error) { return nil, ErrFeedsManagerDisabled } -func (ns NullService) ListManagers() ([]FeedsManager, error) { return nil, nil } +func (ns NullService) ListManagers(ctx context.Context) ([]FeedsManager, error) { return nil, nil } func (ns NullService) CreateChainConfig(ctx context.Context, cfg ChainConfig) (int64, error) { return 0, ErrFeedsManagerDisabled } -func (ns NullService) GetChainConfig(id int64) (*ChainConfig, error) { +func (ns NullService) GetChainConfig(ctx context.Context, id int64) (*ChainConfig, error) { return nil, ErrFeedsManagerDisabled } func (ns NullService) DeleteChainConfig(ctx context.Context, id int64) (int64, error) { return 0, ErrFeedsManagerDisabled } -func (ns NullService) ListChainConfigsByManagerIDs(mgrIDs []int64) ([]ChainConfig, error) { +func (ns NullService) ListChainConfigsByManagerIDs(ctx context.Context, mgrIDs []int64) ([]ChainConfig, error) { return nil, ErrFeedsManagerDisabled } func (ns NullService) UpdateChainConfig(ctx context.Context, cfg ChainConfig) (int64, error) { return 0, ErrFeedsManagerDisabled } -func (ns NullService) ListJobProposals() ([]JobProposal, error) { return nil, nil } -func (ns NullService) ListJobProposalsByManagersIDs(ids []int64) ([]JobProposal, error) { +func (ns NullService) ListJobProposals(ctx context.Context) ([]JobProposal, error) { return nil, nil } +func (ns NullService) ListJobProposalsByManagersIDs(ctx context.Context, ids []int64) ([]JobProposal, error) { return nil, ErrFeedsManagerDisabled } func (ns NullService) ProposeJob(ctx context.Context, args *ProposeJobArgs) (int64, error) { @@ -1472,6 +1448,5 @@ func (ns NullService) IsJobManaged(ctx context.Context, jobID int64) (bool, erro func (ns NullService) UpdateSpecDefinition(ctx context.Context, id int64, spec string) error { return ErrFeedsManagerDisabled } -func (ns NullService) Unsafe_SetConnectionsManager(_ ConnectionsManager) {} //revive:enable diff --git a/core/services/feeds/service_test.go b/core/services/feeds/service_test.go index f83a98986e2..af656618f78 100644 --- a/core/services/feeds/service_test.go +++ b/core/services/feeds/service_test.go @@ -186,7 +186,7 @@ func setupTestServiceCfg(t *testing.T, overrideCfg func(c *chainlink.Config, s * keyStore.On("P2P").Return(p2pKeystore) keyStore.On("OCR").Return(ocr1Keystore) keyStore.On("OCR2").Return(ocr2Keystore) - svc := feeds.NewService(orm, jobORM, db, spawner, keyStore, gcfg, gcfg.Insecure(), gcfg.JobPipeline(), gcfg.OCR(), gcfg.OCR2(), gcfg.Database(), legacyChains, lggr, "1.0.0", nil) + svc := feeds.NewService(orm, jobORM, db, spawner, keyStore, gcfg, gcfg.Insecure(), gcfg.JobPipeline(), gcfg.OCR(), gcfg.OCR2(), legacyChains, lggr, "1.0.0", nil) svc.SetConnectionsManager(connMgr) return &TestService{ @@ -233,14 +233,19 @@ func Test_Service_RegisterManager(t *testing.T) { svc := setupTestService(t) - svc.orm.On("CountManagers").Return(int64(0), nil) - svc.orm.On("CreateManager", &mgr, mock.Anything). + svc.orm.On("CountManagers", mock.Anything).Return(int64(0), nil) + svc.orm.On("CreateManager", mock.Anything, &mgr, mock.Anything). Return(id, nil) - svc.orm.On("CreateBatchChainConfig", params.ChainConfigs, mock.Anything). + svc.orm.On("CreateBatchChainConfig", mock.Anything, params.ChainConfigs, mock.Anything). Return([]int64{}, nil) svc.csaKeystore.On("GetAll").Return([]csakey.KeyV2{key}, nil) // ListManagers runs in a goroutine so it might be called. svc.orm.On("ListManagers", testutils.Context(t)).Return([]feeds.FeedsManager{mgr}, nil).Maybe() + transactCall := svc.orm.On("Transact", mock.Anything, mock.Anything) + transactCall.Run(func(args mock.Arguments) { + fn := args[1].(func(orm feeds.ORM) error) + transactCall.ReturnArguments = mock.Arguments{fn(svc.orm)} + }) svc.connMgr.On("Connect", mock.IsType(feeds.ConnectOpts{})) actual, err := svc.RegisterManager(testutils.Context(t), params) @@ -254,6 +259,7 @@ func Test_Service_RegisterManager(t *testing.T) { func Test_Service_ListManagers(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( mgr = feeds.FeedsManager{} @@ -261,10 +267,10 @@ func Test_Service_ListManagers(t *testing.T) { ) svc := setupTestService(t) - svc.orm.On("ListManagers").Return(mgrs, nil) + svc.orm.On("ListManagers", mock.Anything).Return(mgrs, nil) svc.connMgr.On("IsConnected", mgr.ID).Return(false) - actual, err := svc.ListManagers() + actual, err := svc.ListManagers(ctx) require.NoError(t, err) assert.Equal(t, mgrs, actual) @@ -272,6 +278,7 @@ func Test_Service_ListManagers(t *testing.T) { func Test_Service_GetManager(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( id = int64(1) @@ -279,11 +286,11 @@ func Test_Service_GetManager(t *testing.T) { ) svc := setupTestService(t) - svc.orm.On("GetManager", id). + svc.orm.On("GetManager", mock.Anything, id). Return(&mgr, nil) svc.connMgr.On("IsConnected", mgr.ID).Return(false) - actual, err := svc.GetManager(id) + actual, err := svc.GetManager(ctx, id) require.NoError(t, err) assert.Equal(t, actual, &mgr) @@ -298,7 +305,7 @@ func Test_Service_UpdateFeedsManager(t *testing.T) { svc := setupTestService(t) - svc.orm.On("UpdateManager", mgr, mock.Anything).Return(nil) + svc.orm.On("UpdateManager", mock.Anything, mgr, mock.Anything).Return(nil) svc.csaKeystore.On("GetAll").Return([]csakey.KeyV2{key}, nil) svc.connMgr.On("Disconnect", mgr.ID).Return(nil) svc.connMgr.On("Connect", mock.IsType(feeds.ConnectOpts{})).Return(nil) @@ -309,6 +316,7 @@ func Test_Service_UpdateFeedsManager(t *testing.T) { func Test_Service_ListManagersByIDs(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( mgr = feeds.FeedsManager{} @@ -316,11 +324,11 @@ func Test_Service_ListManagersByIDs(t *testing.T) { ) svc := setupTestService(t) - svc.orm.On("ListManagersByIDs", []int64{mgr.ID}). + svc.orm.On("ListManagersByIDs", mock.Anything, []int64{mgr.ID}). Return(mgrs, nil) svc.connMgr.On("IsConnected", mgr.ID).Return(false) - actual, err := svc.ListManagersByIDs([]int64{mgr.ID}) + actual, err := svc.ListManagersByIDs(ctx, []int64{mgr.ID}) require.NoError(t, err) assert.Equal(t, mgrs, actual) @@ -328,16 +336,17 @@ func Test_Service_ListManagersByIDs(t *testing.T) { func Test_Service_CountManagers(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( count = int64(1) ) svc := setupTestService(t) - svc.orm.On("CountManagers"). + svc.orm.On("CountManagers", mock.Anything). Return(count, nil) - actual, err := svc.CountManagers() + actual, err := svc.CountManagers(ctx) require.NoError(t, err) assert.Equal(t, count, actual) @@ -369,10 +378,10 @@ func Test_Service_CreateChainConfig(t *testing.T) { svc = setupTestService(t) ) - svc.orm.On("CreateChainConfig", cfg).Return(int64(1), nil) - svc.orm.On("GetManager", mgr.ID).Return(&mgr, nil) + svc.orm.On("CreateChainConfig", mock.Anything, cfg).Return(int64(1), nil) + svc.orm.On("GetManager", mock.Anything, mgr.ID).Return(&mgr, nil) svc.connMgr.On("GetClient", mgr.ID).Return(svc.fmsClient, nil) - svc.orm.On("ListChainConfigsByManagerIDs", []int64{mgr.ID}).Return([]feeds.ChainConfig{cfg}, nil) + svc.orm.On("ListChainConfigsByManagerIDs", mock.Anything, []int64{mgr.ID}).Return([]feeds.ChainConfig{cfg}, nil) svc.fmsClient.On("UpdateNode", mock.Anything, &proto.UpdateNodeRequest{ Version: nodeVersion.Version, ChainConfigs: []*proto.ChainConfig{ @@ -430,11 +439,11 @@ func Test_Service_DeleteChainConfig(t *testing.T) { svc = setupTestService(t) ) - svc.orm.On("GetChainConfig", cfg.ID).Return(&cfg, nil) - svc.orm.On("DeleteChainConfig", cfg.ID).Return(cfg.ID, nil) - svc.orm.On("GetManager", mgr.ID).Return(&mgr, nil) + svc.orm.On("GetChainConfig", mock.Anything, cfg.ID).Return(&cfg, nil) + svc.orm.On("DeleteChainConfig", mock.Anything, cfg.ID).Return(cfg.ID, nil) + svc.orm.On("GetManager", mock.Anything, mgr.ID).Return(&mgr, nil) svc.connMgr.On("GetClient", mgr.ID).Return(svc.fmsClient, nil) - svc.orm.On("ListChainConfigsByManagerIDs", []int64{mgr.ID}).Return([]feeds.ChainConfig{}, nil) + svc.orm.On("ListChainConfigsByManagerIDs", mock.Anything, []int64{mgr.ID}).Return([]feeds.ChainConfig{}, nil) svc.fmsClient.On("UpdateNode", mock.Anything, &proto.UpdateNodeRequest{ Version: nodeVersion.Version, ChainConfigs: []*proto.ChainConfig{}, @@ -446,6 +455,7 @@ func Test_Service_DeleteChainConfig(t *testing.T) { } func Test_Service_ListChainConfigsByManagerIDs(t *testing.T) { + ctx := testutils.Context(t) var ( mgr = feeds.FeedsManager{ID: 1} cfg = feeds.ChainConfig{ @@ -457,9 +467,9 @@ func Test_Service_ListChainConfigsByManagerIDs(t *testing.T) { svc = setupTestService(t) ) - svc.orm.On("ListChainConfigsByManagerIDs", ids).Return([]feeds.ChainConfig{cfg}, nil) + svc.orm.On("ListChainConfigsByManagerIDs", mock.Anything, ids).Return([]feeds.ChainConfig{cfg}, nil) - actual, err := svc.ListChainConfigsByManagerIDs(ids) + actual, err := svc.ListChainConfigsByManagerIDs(ctx, ids) require.NoError(t, err) assert.Equal(t, []feeds.ChainConfig{cfg}, actual) } @@ -484,10 +494,10 @@ func Test_Service_UpdateChainConfig(t *testing.T) { svc = setupTestService(t) ) - svc.orm.On("UpdateChainConfig", cfg).Return(int64(1), nil) - svc.orm.On("GetChainConfig", cfg.ID).Return(&cfg, nil) + svc.orm.On("UpdateChainConfig", mock.Anything, cfg).Return(int64(1), nil) + svc.orm.On("GetChainConfig", mock.Anything, cfg.ID).Return(&cfg, nil) svc.connMgr.On("GetClient", mgr.ID).Return(svc.fmsClient, nil) - svc.orm.On("ListChainConfigsByManagerIDs", []int64{mgr.ID}).Return([]feeds.ChainConfig{cfg}, nil) + svc.orm.On("ListChainConfigsByManagerIDs", mock.Anything, []int64{mgr.ID}).Return([]feeds.ChainConfig{cfg}, nil) svc.fmsClient.On("UpdateNode", mock.Anything, &proto.UpdateNodeRequest{ Version: nodeVersion.Version, ChainConfigs: []*proto.ChainConfig{ @@ -640,10 +650,15 @@ func Test_Service_ProposeJob(t *testing.T) { { name: "Create success (Flux Monitor)", before: func(svc *TestService) { - svc.orm.On("GetJobProposalByRemoteUUID", jpFluxMonitor.RemoteUUID).Return(new(feeds.JobProposal), sql.ErrNoRows) - svc.orm.On("UpsertJobProposal", &jpFluxMonitor, mock.Anything).Return(idFluxMonitor, nil) - svc.orm.On("CreateSpec", specFluxMonitor, mock.Anything).Return(int64(100), nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("GetJobProposalByRemoteUUID", mock.Anything, jpFluxMonitor.RemoteUUID).Return(new(feeds.JobProposal), sql.ErrNoRows) + svc.orm.On("UpsertJobProposal", mock.Anything, &jpFluxMonitor).Return(idFluxMonitor, nil) + svc.orm.On("CreateSpec", mock.Anything, specFluxMonitor).Return(int64(100), nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + transactCall := svc.orm.On("Transact", mock.Anything, mock.Anything) + transactCall.Run(func(args mock.Arguments) { + fn := args[1].(func(orm feeds.ORM) error) + transactCall.ReturnArguments = mock.Arguments{fn(svc.orm)} + }) }, args: argsFluxMonitor, wantID: idFluxMonitor, @@ -651,10 +666,15 @@ func Test_Service_ProposeJob(t *testing.T) { { name: "Create success (OCR1)", before: func(svc *TestService) { - svc.orm.On("GetJobProposalByRemoteUUID", jpOCR1.RemoteUUID).Return(new(feeds.JobProposal), sql.ErrNoRows) - svc.orm.On("UpsertJobProposal", &jpOCR1, mock.Anything).Return(idOCR1, nil) - svc.orm.On("CreateSpec", specOCR1, mock.Anything).Return(int64(100), nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("GetJobProposalByRemoteUUID", mock.Anything, jpOCR1.RemoteUUID).Return(new(feeds.JobProposal), sql.ErrNoRows) + svc.orm.On("UpsertJobProposal", mock.Anything, &jpOCR1).Return(idOCR1, nil) + svc.orm.On("CreateSpec", mock.Anything, specOCR1).Return(int64(100), nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + transactCall := svc.orm.On("Transact", mock.Anything, mock.Anything) + transactCall.Run(func(args mock.Arguments) { + fn := args[1].(func(orm feeds.ORM) error) + transactCall.ReturnArguments = mock.Arguments{fn(svc.orm)} + }) }, args: argsOCR1, wantID: idOCR1, @@ -662,10 +682,15 @@ func Test_Service_ProposeJob(t *testing.T) { { name: "Create success (OCR2)", before: func(svc *TestService) { - svc.orm.On("GetJobProposalByRemoteUUID", jpOCR2.RemoteUUID).Return(new(feeds.JobProposal), sql.ErrNoRows) - svc.orm.On("UpsertJobProposal", &jpOCR2, mock.Anything).Return(idOCR2, nil) - svc.orm.On("CreateSpec", specOCR2, mock.Anything).Return(int64(100), nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("GetJobProposalByRemoteUUID", mock.Anything, jpOCR2.RemoteUUID).Return(new(feeds.JobProposal), sql.ErrNoRows) + svc.orm.On("UpsertJobProposal", mock.Anything, &jpOCR2).Return(idOCR2, nil) + svc.orm.On("CreateSpec", mock.Anything, specOCR2).Return(int64(100), nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + transactCall := svc.orm.On("Transact", mock.Anything, mock.Anything) + transactCall.Run(func(args mock.Arguments) { + fn := args[1].(func(orm feeds.ORM) error) + transactCall.ReturnArguments = mock.Arguments{fn(svc.orm)} + }) }, args: argsOCR2, wantID: idOCR2, @@ -673,10 +698,15 @@ func Test_Service_ProposeJob(t *testing.T) { { name: "Create success (Bootstrap)", before: func(svc *TestService) { - svc.orm.On("GetJobProposalByRemoteUUID", jpBootstrap.RemoteUUID).Return(new(feeds.JobProposal), sql.ErrNoRows) - svc.orm.On("UpsertJobProposal", &jpBootstrap, mock.Anything).Return(idBootstrap, nil) - svc.orm.On("CreateSpec", specBootstrap, mock.Anything).Return(int64(102), nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("GetJobProposalByRemoteUUID", mock.Anything, jpBootstrap.RemoteUUID).Return(new(feeds.JobProposal), sql.ErrNoRows) + svc.orm.On("UpsertJobProposal", mock.Anything, &jpBootstrap).Return(idBootstrap, nil) + svc.orm.On("CreateSpec", mock.Anything, specBootstrap).Return(int64(102), nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + transactCall := svc.orm.On("Transact", mock.Anything, mock.Anything) + transactCall.Run(func(args mock.Arguments) { + fn := args[1].(func(orm feeds.ORM) error) + transactCall.ReturnArguments = mock.Arguments{fn(svc.orm)} + }) }, args: argsBootstrap, wantID: idBootstrap, @@ -685,16 +715,21 @@ func Test_Service_ProposeJob(t *testing.T) { name: "Update success", before: func(svc *TestService) { svc.orm. - On("GetJobProposalByRemoteUUID", jpFluxMonitor.RemoteUUID). + On("GetJobProposalByRemoteUUID", mock.Anything, jpFluxMonitor.RemoteUUID). Return(&feeds.JobProposal{ FeedsManagerID: jpFluxMonitor.FeedsManagerID, RemoteUUID: jpFluxMonitor.RemoteUUID, Status: feeds.JobProposalStatusPending, }, nil) - svc.orm.On("ExistsSpecByJobProposalIDAndVersion", jpFluxMonitor.ID, argsFluxMonitor.Version).Return(false, nil) - svc.orm.On("UpsertJobProposal", &jpFluxMonitor, mock.Anything).Return(idFluxMonitor, nil) - svc.orm.On("CreateSpec", specFluxMonitor, mock.Anything).Return(int64(100), nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("ExistsSpecByJobProposalIDAndVersion", mock.Anything, jpFluxMonitor.ID, argsFluxMonitor.Version).Return(false, nil) + svc.orm.On("UpsertJobProposal", mock.Anything, &jpFluxMonitor).Return(idFluxMonitor, nil) + svc.orm.On("CreateSpec", mock.Anything, specFluxMonitor).Return(int64(100), nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + transactCall := svc.orm.On("Transact", mock.Anything, mock.Anything) + transactCall.Run(func(args mock.Arguments) { + fn := args[1].(func(orm feeds.ORM) error) + transactCall.ReturnArguments = mock.Arguments{fn(svc.orm)} + }) }, args: argsFluxMonitor, wantID: idFluxMonitor, @@ -717,7 +752,7 @@ func Test_Service_ProposeJob(t *testing.T) { name: "ensure an upsert validates the job proposal belongs to the feeds manager", before: func(svc *TestService) { svc.orm. - On("GetJobProposalByRemoteUUID", jpFluxMonitor.RemoteUUID). + On("GetJobProposalByRemoteUUID", mock.Anything, jpFluxMonitor.RemoteUUID). Return(&feeds.JobProposal{ FeedsManagerID: 2, RemoteUUID: jpFluxMonitor.RemoteUUID, @@ -730,13 +765,13 @@ func Test_Service_ProposeJob(t *testing.T) { name: "spec version already exists", before: func(svc *TestService) { svc.orm. - On("GetJobProposalByRemoteUUID", jpFluxMonitor.RemoteUUID). + On("GetJobProposalByRemoteUUID", mock.Anything, jpFluxMonitor.RemoteUUID). Return(&feeds.JobProposal{ FeedsManagerID: jpFluxMonitor.FeedsManagerID, RemoteUUID: jpFluxMonitor.RemoteUUID, Status: feeds.JobProposalStatusPending, }, nil) - svc.orm.On("ExistsSpecByJobProposalIDAndVersion", jpFluxMonitor.ID, argsFluxMonitor.Version).Return(true, nil) + svc.orm.On("ExistsSpecByJobProposalIDAndVersion", mock.Anything, jpFluxMonitor.ID, argsFluxMonitor.Version).Return(true, nil) }, args: argsFluxMonitor, wantErr: "proposed job spec version already exists", @@ -744,8 +779,13 @@ func Test_Service_ProposeJob(t *testing.T) { { name: "upsert error", before: func(svc *TestService) { - svc.orm.On("GetJobProposalByRemoteUUID", jpFluxMonitor.RemoteUUID).Return(new(feeds.JobProposal), sql.ErrNoRows) - svc.orm.On("UpsertJobProposal", &jpFluxMonitor, mock.Anything).Return(int64(0), errors.New("orm error")) + svc.orm.On("GetJobProposalByRemoteUUID", mock.Anything, jpFluxMonitor.RemoteUUID).Return(new(feeds.JobProposal), sql.ErrNoRows) + svc.orm.On("UpsertJobProposal", mock.Anything, &jpFluxMonitor).Return(int64(0), errors.New("orm error")) + transactCall := svc.orm.On("Transact", mock.Anything, mock.Anything) + transactCall.Run(func(args mock.Arguments) { + fn := args[1].(func(orm feeds.ORM) error) + transactCall.ReturnArguments = mock.Arguments{fn(svc.orm)} + }) }, args: argsFluxMonitor, wantErr: "failed to upsert job proposal", @@ -753,9 +793,14 @@ func Test_Service_ProposeJob(t *testing.T) { { name: "Create spec error", before: func(svc *TestService) { - svc.orm.On("GetJobProposalByRemoteUUID", jpFluxMonitor.RemoteUUID).Return(new(feeds.JobProposal), sql.ErrNoRows) - svc.orm.On("UpsertJobProposal", &jpFluxMonitor, mock.Anything).Return(idFluxMonitor, nil) - svc.orm.On("CreateSpec", specFluxMonitor, mock.Anything).Return(int64(0), errors.New("orm error")) + svc.orm.On("GetJobProposalByRemoteUUID", mock.Anything, jpFluxMonitor.RemoteUUID).Return(new(feeds.JobProposal), sql.ErrNoRows) + svc.orm.On("UpsertJobProposal", mock.Anything, &jpFluxMonitor).Return(idFluxMonitor, nil) + svc.orm.On("CreateSpec", mock.Anything, specFluxMonitor).Return(int64(0), errors.New("orm error")) + transactCall := svc.orm.On("Transact", mock.Anything, mock.Anything) + transactCall.Run(func(args mock.Arguments) { + fn := args[1].(func(orm feeds.ORM) error) + transactCall.ReturnArguments = mock.Arguments{fn(svc.orm)} + }) }, args: argsFluxMonitor, wantErr: "failed to create spec", @@ -820,9 +865,9 @@ func Test_Service_DeleteJob(t *testing.T) { { name: "Delete success", before: func(svc *TestService) { - svc.orm.On("GetJobProposalByRemoteUUID", approved.RemoteUUID).Return(&approved, nil) - svc.orm.On("DeleteProposal", approved.ID, mock.Anything).Return(nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("GetJobProposalByRemoteUUID", mock.Anything, approved.RemoteUUID).Return(&approved, nil) + svc.orm.On("DeleteProposal", mock.Anything, approved.ID).Return(nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) }, args: args, wantID: approved.ID, @@ -831,7 +876,7 @@ func Test_Service_DeleteJob(t *testing.T) { name: "Job proposal being deleted belongs to the feeds manager", before: func(svc *TestService) { svc.orm. - On("GetJobProposalByRemoteUUID", approved.RemoteUUID). + On("GetJobProposalByRemoteUUID", mock.Anything, approved.RemoteUUID). Return(&feeds.JobProposal{ FeedsManagerID: 2, RemoteUUID: approved.RemoteUUID, @@ -844,7 +889,7 @@ func Test_Service_DeleteJob(t *testing.T) { { name: "Get proposal error", before: func(svc *TestService) { - svc.orm.On("GetJobProposalByRemoteUUID", approved.RemoteUUID).Return(nil, errors.New("orm error")) + svc.orm.On("GetJobProposalByRemoteUUID", mock.Anything, approved.RemoteUUID).Return(nil, errors.New("orm error")) }, args: args, wantErr: "GetJobProposalByRemoteUUID failed", @@ -852,7 +897,7 @@ func Test_Service_DeleteJob(t *testing.T) { { name: "No proposal error", before: func(svc *TestService) { - svc.orm.On("GetJobProposalByRemoteUUID", approved.RemoteUUID).Return(nil, sql.ErrNoRows) + svc.orm.On("GetJobProposalByRemoteUUID", mock.Anything, approved.RemoteUUID).Return(nil, sql.ErrNoRows) }, args: args, wantErr: "GetJobProposalByRemoteUUID did not find any proposals to delete", @@ -860,8 +905,8 @@ func Test_Service_DeleteJob(t *testing.T) { { name: "Delete proposal error", before: func(svc *TestService) { - svc.orm.On("GetJobProposalByRemoteUUID", approved.RemoteUUID).Return(&approved, nil) - svc.orm.On("DeleteProposal", approved.ID, mock.Anything).Return(errors.New("orm error")) + svc.orm.On("GetJobProposalByRemoteUUID", mock.Anything, approved.RemoteUUID).Return(&approved, nil) + svc.orm.On("DeleteProposal", mock.Anything, approved.ID).Return(errors.New("orm error")) }, args: args, wantErr: "DeleteProposal failed", @@ -960,10 +1005,10 @@ answer1 [type=median index=0]; { name: "Revoke success when latest spec status is pending", before: func(svc *TestService) { - svc.orm.On("GetJobProposalByRemoteUUID", pendingProposal.RemoteUUID).Return(pendingProposal, nil) - svc.orm.On("GetLatestSpec", pendingSpec.JobProposalID).Return(pendingSpec, nil) - svc.orm.On("RevokeSpec", pendingSpec.ID, mock.Anything).Return(nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("GetJobProposalByRemoteUUID", mock.Anything, pendingProposal.RemoteUUID).Return(pendingProposal, nil) + svc.orm.On("GetLatestSpec", mock.Anything, pendingSpec.JobProposalID).Return(pendingSpec, nil) + svc.orm.On("RevokeSpec", mock.Anything, pendingSpec.ID).Return(nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) }, args: args, wantID: pendingProposal.ID, @@ -971,16 +1016,16 @@ answer1 [type=median index=0]; { name: "Revoke success when latest spec status is cancelled", before: func(svc *TestService) { - svc.orm.On("GetJobProposalByRemoteUUID", pendingProposal.RemoteUUID).Return(pendingProposal, nil) - svc.orm.On("GetLatestSpec", pendingSpec.JobProposalID).Return(&feeds.JobProposalSpec{ + svc.orm.On("GetJobProposalByRemoteUUID", mock.Anything, pendingProposal.RemoteUUID).Return(pendingProposal, nil) + svc.orm.On("GetLatestSpec", mock.Anything, pendingSpec.JobProposalID).Return(&feeds.JobProposalSpec{ ID: 20, Status: feeds.SpecStatusCancelled, JobProposalID: pendingProposal.ID, Version: 1, Definition: defn, }, nil) - svc.orm.On("RevokeSpec", pendingSpec.ID, mock.Anything).Return(nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("RevokeSpec", mock.Anything, pendingSpec.ID).Return(nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) }, args: args, wantID: pendingProposal.ID, @@ -989,7 +1034,7 @@ answer1 [type=median index=0]; name: "Job proposal being revoked belongs to the feeds manager", before: func(svc *TestService) { svc.orm. - On("GetJobProposalByRemoteUUID", pendingProposal.RemoteUUID). + On("GetJobProposalByRemoteUUID", mock.Anything, pendingProposal.RemoteUUID). Return(&feeds.JobProposal{ FeedsManagerID: 2, RemoteUUID: pendingProposal.RemoteUUID, @@ -1002,7 +1047,7 @@ answer1 [type=median index=0]; { name: "Get proposal error", before: func(svc *TestService) { - svc.orm.On("GetJobProposalByRemoteUUID", pendingProposal.RemoteUUID).Return(nil, errors.New("orm error")) + svc.orm.On("GetJobProposalByRemoteUUID", mock.Anything, pendingProposal.RemoteUUID).Return(nil, errors.New("orm error")) }, args: args, wantErr: "GetJobProposalByRemoteUUID failed", @@ -1010,7 +1055,7 @@ answer1 [type=median index=0]; { name: "No proposal error", before: func(svc *TestService) { - svc.orm.On("GetJobProposalByRemoteUUID", pendingProposal.RemoteUUID).Return(nil, sql.ErrNoRows) + svc.orm.On("GetJobProposalByRemoteUUID", mock.Anything, pendingProposal.RemoteUUID).Return(nil, sql.ErrNoRows) }, args: args, wantErr: "GetJobProposalByRemoteUUID did not find any proposals to revoke", @@ -1018,8 +1063,8 @@ answer1 [type=median index=0]; { name: "Get latest spec error", before: func(svc *TestService) { - svc.orm.On("GetJobProposalByRemoteUUID", pendingProposal.RemoteUUID).Return(pendingProposal, nil) - svc.orm.On("GetLatestSpec", pendingSpec.JobProposalID).Return(nil, sql.ErrNoRows) + svc.orm.On("GetJobProposalByRemoteUUID", mock.Anything, pendingProposal.RemoteUUID).Return(pendingProposal, nil) + svc.orm.On("GetLatestSpec", mock.Anything, pendingSpec.JobProposalID).Return(nil, sql.ErrNoRows) }, args: args, wantErr: "GetLatestSpec failed to get latest spec", @@ -1027,8 +1072,8 @@ answer1 [type=median index=0]; { name: "Not revokable due to spec status approved", before: func(svc *TestService) { - svc.orm.On("GetJobProposalByRemoteUUID", pendingProposal.RemoteUUID).Return(pendingProposal, nil) - svc.orm.On("GetLatestSpec", pendingSpec.JobProposalID).Return(&feeds.JobProposalSpec{ + svc.orm.On("GetJobProposalByRemoteUUID", mock.Anything, pendingProposal.RemoteUUID).Return(pendingProposal, nil) + svc.orm.On("GetLatestSpec", mock.Anything, pendingSpec.JobProposalID).Return(&feeds.JobProposalSpec{ ID: 20, Status: feeds.SpecStatusApproved, JobProposalID: pendingProposal.ID, @@ -1042,8 +1087,8 @@ answer1 [type=median index=0]; { name: "Not revokable due to spec status rejected", before: func(svc *TestService) { - svc.orm.On("GetJobProposalByRemoteUUID", pendingProposal.RemoteUUID).Return(pendingProposal, nil) - svc.orm.On("GetLatestSpec", pendingSpec.JobProposalID).Return(&feeds.JobProposalSpec{ + svc.orm.On("GetJobProposalByRemoteUUID", mock.Anything, pendingProposal.RemoteUUID).Return(pendingProposal, nil) + svc.orm.On("GetLatestSpec", mock.Anything, pendingSpec.JobProposalID).Return(&feeds.JobProposalSpec{ ID: 20, Status: feeds.SpecStatusRejected, JobProposalID: pendingProposal.ID, @@ -1057,8 +1102,8 @@ answer1 [type=median index=0]; { name: "Not revokable due to spec status already revoked", before: func(svc *TestService) { - svc.orm.On("GetJobProposalByRemoteUUID", pendingProposal.RemoteUUID).Return(pendingProposal, nil) - svc.orm.On("GetLatestSpec", pendingSpec.JobProposalID).Return(&feeds.JobProposalSpec{ + svc.orm.On("GetJobProposalByRemoteUUID", mock.Anything, pendingProposal.RemoteUUID).Return(pendingProposal, nil) + svc.orm.On("GetLatestSpec", mock.Anything, pendingSpec.JobProposalID).Return(&feeds.JobProposalSpec{ ID: 20, Status: feeds.SpecStatusRevoked, JobProposalID: pendingProposal.ID, @@ -1072,13 +1117,13 @@ answer1 [type=median index=0]; { name: "Not revokable due to proposal status deleted", before: func(svc *TestService) { - svc.orm.On("GetJobProposalByRemoteUUID", pendingProposal.RemoteUUID).Return(&feeds.JobProposal{ + svc.orm.On("GetJobProposalByRemoteUUID", mock.Anything, pendingProposal.RemoteUUID).Return(&feeds.JobProposal{ ID: 1, FeedsManagerID: 1, RemoteUUID: remoteUUID, Status: feeds.JobProposalStatusDeleted, }, nil) - svc.orm.On("GetLatestSpec", pendingSpec.JobProposalID).Return(pendingSpec, nil) + svc.orm.On("GetLatestSpec", mock.Anything, pendingSpec.JobProposalID).Return(pendingSpec, nil) }, args: args, wantErr: "only pending job specs can be revoked", @@ -1086,9 +1131,9 @@ answer1 [type=median index=0]; { name: "Revoke proposal error", before: func(svc *TestService) { - svc.orm.On("GetJobProposalByRemoteUUID", pendingProposal.RemoteUUID).Return(pendingProposal, nil) - svc.orm.On("GetLatestSpec", pendingSpec.JobProposalID).Return(pendingSpec, nil) - svc.orm.On("RevokeSpec", pendingSpec.ID, mock.Anything).Return(errors.New("orm error")) + svc.orm.On("GetJobProposalByRemoteUUID", mock.Anything, pendingProposal.RemoteUUID).Return(pendingProposal, nil) + svc.orm.On("GetLatestSpec", mock.Anything, pendingSpec.JobProposalID).Return(pendingSpec, nil) + svc.orm.On("RevokeSpec", mock.Anything, pendingSpec.ID).Return(errors.New("orm error")) }, args: args, wantErr: "RevokeSpec failed", @@ -1168,7 +1213,7 @@ func Test_Service_SyncNodeInfo(t *testing.T) { svc := setupTestService(t) svc.connMgr.On("GetClient", mgr.ID).Return(svc.fmsClient, nil) - svc.orm.On("ListChainConfigsByManagerIDs", []int64{mgr.ID}).Return(chainConfigs, nil) + svc.orm.On("ListChainConfigsByManagerIDs", mock.Anything, []int64{mgr.ID}).Return(chainConfigs, nil) // OCR1 key fetching svc.p2pKeystore.On("Get", p2pKey.PeerID()).Return(p2pKey, nil) @@ -1227,7 +1272,7 @@ func Test_Service_IsJobManaged(t *testing.T) { ctx := testutils.Context(t) jobID := int64(1) - svc.orm.On("IsJobManaged", jobID, mock.Anything).Return(true, nil) + svc.orm.On("IsJobManaged", mock.Anything, jobID).Return(true, nil) isManaged, err := svc.IsJobManaged(ctx, jobID) require.NoError(t, err) @@ -1236,6 +1281,7 @@ func Test_Service_IsJobManaged(t *testing.T) { func Test_Service_ListJobProposals(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( jp = feeds.JobProposal{} @@ -1243,10 +1289,10 @@ func Test_Service_ListJobProposals(t *testing.T) { ) svc := setupTestService(t) - svc.orm.On("ListJobProposals"). + svc.orm.On("ListJobProposals", mock.Anything). Return(jps, nil) - actual, err := svc.ListJobProposals() + actual, err := svc.ListJobProposals(ctx) require.NoError(t, err) assert.Equal(t, actual, jps) @@ -1254,6 +1300,7 @@ func Test_Service_ListJobProposals(t *testing.T) { func Test_Service_ListJobProposalsByManagersIDs(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( jp = feeds.JobProposal{} @@ -1262,10 +1309,10 @@ func Test_Service_ListJobProposalsByManagersIDs(t *testing.T) { ) svc := setupTestService(t) - svc.orm.On("ListJobProposalsByManagersIDs", fmIDs). + svc.orm.On("ListJobProposalsByManagersIDs", mock.Anything, fmIDs). Return(jps, nil) - actual, err := svc.ListJobProposalsByManagersIDs(fmIDs) + actual, err := svc.ListJobProposalsByManagersIDs(ctx, fmIDs) require.NoError(t, err) assert.Equal(t, actual, jps) @@ -1273,6 +1320,7 @@ func Test_Service_ListJobProposalsByManagersIDs(t *testing.T) { func Test_Service_GetJobProposal(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( id = int64(1) @@ -1280,10 +1328,10 @@ func Test_Service_GetJobProposal(t *testing.T) { ) svc := setupTestService(t) - svc.orm.On("GetJobProposal", id). + svc.orm.On("GetJobProposal", mock.Anything, id). Return(&ms, nil) - actual, err := svc.GetJobProposal(id) + actual, err := svc.GetJobProposal(ctx, id) require.NoError(t, err) assert.Equal(t, actual, &ms) @@ -1320,12 +1368,12 @@ func Test_Service_CancelSpec(t *testing.T) { name: "success", before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) - svc.orm.On("CancelSpec", spec.ID, mock.Anything).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(j, nil) - svc.spawner.On("DeleteJob", j.ID, mock.Anything).Return(nil) + svc.orm.On("CancelSpec", mock.Anything, spec.ID).Return(nil) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(j, nil) + svc.spawner.On("DeleteJob", mock.Anything, mock.Anything, j.ID).Return(nil) svc.fmsClient.On("CancelledJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), @@ -1334,7 +1382,9 @@ func Test_Service_CancelSpec(t *testing.T) { Version: int64(spec.Version), }, ).Return(&proto.CancelledJobResponse{}, nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, specID: spec.ID, }, @@ -1342,14 +1392,14 @@ func Test_Service_CancelSpec(t *testing.T) { name: "success without external job id", before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(&feeds.JobProposal{ + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(&feeds.JobProposal{ ID: 1, RemoteUUID: externalJobID, FeedsManagerID: 100, }, nil) - svc.orm.On("CancelSpec", spec.ID, mock.Anything).Return(nil) + svc.orm.On("CancelSpec", mock.Anything, spec.ID).Return(nil) svc.fmsClient.On("CancelledJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), &proto.CancelledJobRequest{ @@ -1357,7 +1407,9 @@ func Test_Service_CancelSpec(t *testing.T) { Version: int64(spec.Version), }, ).Return(&proto.CancelledJobResponse{}, nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, specID: spec.ID, }, @@ -1365,11 +1417,11 @@ func Test_Service_CancelSpec(t *testing.T) { name: "success without jobs", before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) - svc.orm.On("CancelSpec", spec.ID, mock.Anything).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) + svc.orm.On("CancelSpec", mock.Anything, spec.ID).Return(nil) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) svc.fmsClient.On("CancelledJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), &proto.CancelledJobRequest{ @@ -1377,14 +1429,16 @@ func Test_Service_CancelSpec(t *testing.T) { Version: int64(spec.Version), }, ).Return(&proto.CancelledJobResponse{}, nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, specID: spec.ID, }, { name: "spec does not exist", before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(nil, errors.New("Not Found")) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(nil, errors.New("Not Found")) }, specID: spec.ID, wantErr: "orm: job proposal spec: Not Found", @@ -1396,7 +1450,7 @@ func Test_Service_CancelSpec(t *testing.T) { ID: spec.ID, Status: feeds.SpecStatusPending, } - svc.orm.On("GetSpec", pspec.ID, mock.Anything).Return(pspec, nil) + svc.orm.On("GetSpec", mock.Anything, pspec.ID, mock.Anything).Return(pspec, nil) }, specID: spec.ID, wantErr: "must be an approved job proposal spec", @@ -1404,8 +1458,8 @@ func Test_Service_CancelSpec(t *testing.T) { { name: "job proposal does not exist", before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(nil, errors.New("Not Found")) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(nil, errors.New("Not Found")) }, specID: spec.ID, wantErr: "orm: job proposal: Not Found", @@ -1413,8 +1467,8 @@ func Test_Service_CancelSpec(t *testing.T) { { name: "rpc client not connected", before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(nil, errors.New("Not Connected")) }, specID: spec.ID, @@ -1424,9 +1478,11 @@ func Test_Service_CancelSpec(t *testing.T) { name: "cancel spec orm fails", before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) - svc.orm.On("CancelSpec", spec.ID, mock.Anything).Return(errors.New("failure")) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) + svc.orm.On("CancelSpec", mock.Anything, spec.ID).Return(errors.New("failure")) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, specID: spec.ID, wantErr: "failure", @@ -1435,11 +1491,13 @@ func Test_Service_CancelSpec(t *testing.T) { name: "find by external uuid orm fails", before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) - svc.orm.On("CancelSpec", spec.ID, mock.Anything).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, errors.New("failure")) + svc.orm.On("CancelSpec", mock.Anything, spec.ID).Return(nil) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, errors.New("failure")) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, specID: spec.ID, wantErr: "FindJobByExternalJobID failed: failure", @@ -1448,12 +1506,14 @@ func Test_Service_CancelSpec(t *testing.T) { name: "delete job fails", before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) - svc.orm.On("CancelSpec", spec.ID, mock.Anything).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(j, nil) - svc.spawner.On("DeleteJob", j.ID, mock.Anything).Return(errors.New("failure")) + svc.orm.On("CancelSpec", mock.Anything, spec.ID).Return(nil) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(j, nil) + svc.spawner.On("DeleteJob", mock.Anything, mock.Anything, j.ID).Return(errors.New("failure")) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, specID: spec.ID, wantErr: "DeleteJob failed: failure", @@ -1462,12 +1522,12 @@ func Test_Service_CancelSpec(t *testing.T) { name: "cancelled job rpc call fails", before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) - svc.orm.On("CancelSpec", spec.ID, mock.Anything).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(j, nil) - svc.spawner.On("DeleteJob", j.ID, mock.Anything).Return(nil) + svc.orm.On("CancelSpec", mock.Anything, spec.ID).Return(nil) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(j, nil) + svc.spawner.On("DeleteJob", mock.Anything, mock.Anything, j.ID).Return(nil) svc.fmsClient.On("CancelledJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), @@ -1476,6 +1536,8 @@ func Test_Service_CancelSpec(t *testing.T) { Version: int64(spec.Version), }, ).Return(nil, errors.New("failure")) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, specID: spec.ID, wantErr: "failure", @@ -1509,6 +1571,7 @@ func Test_Service_CancelSpec(t *testing.T) { func Test_Service_GetSpec(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( id = int64(1) @@ -1516,10 +1579,10 @@ func Test_Service_GetSpec(t *testing.T) { ) svc := setupTestService(t) - svc.orm.On("GetSpec", id). + svc.orm.On("GetSpec", mock.Anything, id). Return(&spec, nil) - actual, err := svc.GetSpec(id) + actual, err := svc.GetSpec(ctx, id) require.NoError(t, err) assert.Equal(t, &spec, actual) @@ -1527,6 +1590,7 @@ func Test_Service_GetSpec(t *testing.T) { func Test_Service_ListSpecsByJobProposalIDs(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) var ( id = int64(1) @@ -1536,10 +1600,10 @@ func Test_Service_ListSpecsByJobProposalIDs(t *testing.T) { ) svc := setupTestService(t) - svc.orm.On("ListSpecsByJobProposalIDs", []int64{jpID}). + svc.orm.On("ListSpecsByJobProposalIDs", mock.Anything, []int64{jpID}). Return(specs, nil) - actual, err := svc.ListSpecsByJobProposalIDs([]int64{jpID}) + actual, err := svc.ListSpecsByJobProposalIDs(ctx, []int64{jpID}) require.NoError(t, err) assert.Equal(t, specs, actual) @@ -1624,26 +1688,27 @@ answer1 [type=median index=0]; httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.EXPECT().GetSpec(spec.ID, mock.Anything).Return(spec, nil) - svc.orm.EXPECT().GetJobProposal(jp.ID, mock.Anything).Return(jp, nil) + svc.orm.EXPECT().GetSpec(mock.Anything, spec.ID).Return(spec, nil) + svc.orm.EXPECT().GetJobProposal(mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindJobIDByAddress", address, evmChainID, mock.Anything).Return(int32(0), sql.ErrNoRows) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindJobIDByAddress", mock.Anything, address, evmChainID, mock.Anything).Return(int32(0), sql.ErrNoRows) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). - Run(func(args mock.Arguments) { (args.Get(0).(*job.Job)).ID = 1 }). + Run(func(args mock.Arguments) { (args.Get(2).(*job.Job)).ID = 1 }). Return(nil) svc.orm.On("ApproveSpec", + mock.Anything, spec.ID, mock.IsType(uuid.UUID{}), - mock.Anything, ).Return(nil) svc.fmsClient.On("ApprovedJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), @@ -1652,7 +1717,9 @@ answer1 [type=median index=0]; Version: int64(spec.Version), }, ).Return(&proto.ApprovedJobResponse{}, nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: false, @@ -1662,27 +1729,28 @@ answer1 [type=median index=0]; httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", cancelledSpec.ID, mock.Anything).Return(cancelledSpec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) - svc.orm.On("GetLatestSpec", cancelledSpec.JobProposalID).Return(cancelledSpec, nil) + svc.orm.On("GetSpec", mock.Anything, cancelledSpec.ID).Return(cancelledSpec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) + svc.orm.On("GetLatestSpec", mock.Anything, cancelledSpec.JobProposalID).Return(cancelledSpec, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindJobIDByAddress", address, evmChainID, mock.Anything).Return(int32(0), sql.ErrNoRows) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindJobIDByAddress", mock.Anything, address, evmChainID, mock.Anything).Return(int32(0), sql.ErrNoRows) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). - Run(func(args mock.Arguments) { (args.Get(0).(*job.Job)).ID = 1 }). + Run(func(args mock.Arguments) { (args.Get(2).(*job.Job)).ID = 1 }). Return(nil) svc.orm.On("ApproveSpec", + mock.Anything, cancelledSpec.ID, externalJobID, - mock.Anything, ).Return(nil) svc.fmsClient.On("ApprovedJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), @@ -1691,7 +1759,9 @@ answer1 [type=median index=0]; Version: int64(spec.Version), }, ).Return(&proto.ApprovedJobResponse{}, nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: cancelledSpec.ID, force: false, @@ -1701,8 +1771,8 @@ answer1 [type=median index=0]; httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.EXPECT().GetSpec(spec.ID, mock.Anything).Return(spec2, nil) - svc.orm.EXPECT().GetJobProposal(jp.ID, mock.Anything).Return(jp, nil) + svc.orm.EXPECT().GetSpec(mock.Anything, spec.ID).Return(spec2, nil) + svc.orm.EXPECT().GetJobProposal(mock.Anything, jp.ID).Return(jp, nil) }, id: spec.ID, force: false, @@ -1711,8 +1781,8 @@ answer1 [type=median index=0]; { name: "failed due to proposal being revoked", before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(&feeds.JobProposal{ + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(&feeds.JobProposal{ ID: 1, Status: feeds.JobProposalStatusRevoked, }, nil) @@ -1724,8 +1794,8 @@ answer1 [type=median index=0]; { name: "failed due to proposal being deleted", before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(&feeds.JobProposal{ + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(&feeds.JobProposal{ ID: jp.ID, Status: feeds.JobProposalStatusDeleted, }, nil) @@ -1742,8 +1812,8 @@ answer1 [type=median index=0]; Status: feeds.SpecStatusApproved, JobProposalID: jp.ID, } - svc.orm.On("GetSpec", aspec.ID, mock.Anything).Return(aspec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, aspec.ID, mock.Anything).Return(aspec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) }, id: spec.ID, force: false, @@ -1752,8 +1822,8 @@ answer1 [type=median index=0]; { name: "rejected spec fail", before: func(svc *TestService) { - svc.orm.On("GetSpec", cancelledSpec.ID, mock.Anything).Return(rejectedSpec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, cancelledSpec.ID, mock.Anything).Return(rejectedSpec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) }, id: rejectedSpec.ID, force: false, @@ -1762,9 +1832,9 @@ answer1 [type=median index=0]; { name: "cancelled spec failed not latest spec", before: func(svc *TestService) { - svc.orm.On("GetSpec", cancelledSpec.ID, mock.Anything).Return(cancelledSpec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) - svc.orm.On("GetLatestSpec", cancelledSpec.JobProposalID).Return(&feeds.JobProposalSpec{ + svc.orm.On("GetSpec", mock.Anything, cancelledSpec.ID, mock.Anything).Return(cancelledSpec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) + svc.orm.On("GetLatestSpec", mock.Anything, cancelledSpec.JobProposalID).Return(&feeds.JobProposalSpec{ ID: 21, Status: feeds.SpecStatusPending, JobProposalID: jp.ID, @@ -1781,11 +1851,13 @@ answer1 [type=median index=0]; httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(j, nil) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(j, nil) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: false, @@ -1796,12 +1868,14 @@ answer1 [type=median index=0]; httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindJobIDByAddress", address, evmChainID, mock.Anything).Return(j.ID, nil) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindJobIDByAddress", mock.Anything, address, evmChainID, mock.Anything).Return(j.ID, nil) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: false, @@ -1812,27 +1886,28 @@ answer1 [type=median index=0]; httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.EXPECT().GetSpec(spec.ID, mock.Anything).Return(spec, nil) - svc.orm.EXPECT().GetJobProposal(jp.ID, mock.Anything).Return(jp, nil) + svc.orm.EXPECT().GetSpec(mock.Anything, spec.ID).Return(spec, nil) + svc.orm.EXPECT().GetJobProposal(mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(j, nil) - svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(nil, sql.ErrNoRows) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(j, nil) + svc.orm.EXPECT().GetApprovedSpec(mock.Anything, jp.ID).Return(nil, sql.ErrNoRows) - svc.spawner.On("DeleteJob", j.ID, mock.Anything).Return(nil) + svc.spawner.On("DeleteJob", mock.Anything, mock.Anything, j.ID).Return(nil) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). - Run(func(args mock.Arguments) { (args.Get(0).(*job.Job)).ID = 1 }). + Run(func(args mock.Arguments) { (args.Get(2).(*job.Job)).ID = 1 }). Return(nil) svc.orm.On("ApproveSpec", + mock.Anything, spec.ID, externalJobID, - mock.Anything, ).Return(nil) svc.fmsClient.On("ApprovedJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), @@ -1841,7 +1916,9 @@ answer1 [type=median index=0]; Version: int64(spec.Version), }, ).Return(&proto.ApprovedJobResponse{}, nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: true, @@ -1851,28 +1928,29 @@ answer1 [type=median index=0]; httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.EXPECT().GetSpec(spec.ID, mock.Anything).Return(spec, nil) - svc.orm.EXPECT().GetJobProposal(jp.ID, mock.Anything).Return(jp, nil) + svc.orm.EXPECT().GetSpec(mock.Anything, spec.ID).Return(spec, nil) + svc.orm.EXPECT().GetJobProposal(mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindJobIDByAddress", address, evmChainID, mock.Anything).Return(j.ID, nil) - svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(nil, sql.ErrNoRows) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindJobIDByAddress", mock.Anything, address, evmChainID, mock.Anything).Return(j.ID, nil) + svc.orm.EXPECT().GetApprovedSpec(mock.Anything, jp.ID).Return(nil, sql.ErrNoRows) - svc.spawner.On("DeleteJob", j.ID, mock.Anything).Return(nil) + svc.spawner.On("DeleteJob", mock.Anything, mock.Anything, j.ID).Return(nil) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). - Run(func(args mock.Arguments) { (args.Get(0).(*job.Job)).ID = 1 }). + Run(func(args mock.Arguments) { (args.Get(2).(*job.Job)).ID = 1 }). Return(nil) svc.orm.On("ApproveSpec", + mock.Anything, spec.ID, externalJobID, - mock.Anything, ).Return(nil) svc.fmsClient.On("ApprovedJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), @@ -1881,7 +1959,9 @@ answer1 [type=median index=0]; Version: int64(spec.Version), }, ).Return(&proto.ApprovedJobResponse{}, nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: true, @@ -1891,29 +1971,30 @@ answer1 [type=median index=0]; httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.EXPECT().GetSpec(spec.ID, mock.Anything).Return(spec, nil) - svc.orm.EXPECT().GetJobProposal(jp.ID, mock.Anything).Return(jp, nil) + svc.orm.EXPECT().GetSpec(mock.Anything, spec.ID).Return(spec, nil) + svc.orm.EXPECT().GetJobProposal(mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindJobIDByAddress", address, evmChainID, mock.Anything).Return(j.ID, nil) - svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(&feeds.JobProposalSpec{ID: 100}, nil) - svc.orm.EXPECT().CancelSpec(int64(100), mock.Anything).Return(nil) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindJobIDByAddress", mock.Anything, address, evmChainID, mock.Anything).Return(j.ID, nil) + svc.orm.EXPECT().GetApprovedSpec(mock.Anything, jp.ID).Return(&feeds.JobProposalSpec{ID: 100}, nil) + svc.orm.EXPECT().CancelSpec(mock.Anything, int64(100)).Return(nil) - svc.spawner.On("DeleteJob", j.ID, mock.Anything).Return(nil) + svc.spawner.On("DeleteJob", mock.Anything, mock.Anything, j.ID).Return(nil) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). - Run(func(args mock.Arguments) { (args.Get(0).(*job.Job)).ID = 1 }). + Run(func(args mock.Arguments) { (args.Get(2).(*job.Job)).ID = 1 }). Return(nil) svc.orm.On("ApproveSpec", + mock.Anything, spec.ID, externalJobID, - mock.Anything, ).Return(nil) svc.fmsClient.On("ApprovedJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), @@ -1922,7 +2003,9 @@ answer1 [type=median index=0]; Version: int64(spec.Version), }, ).Return(&proto.ApprovedJobResponse{}, nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: true, @@ -1930,7 +2013,7 @@ answer1 [type=median index=0]; { name: "spec does not exist", before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(nil, errors.New("Not Found")) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(nil, errors.New("Not Found")) }, id: spec.ID, force: false, @@ -1939,8 +2022,8 @@ answer1 [type=median index=0]; { name: "job proposal does not exist", before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(nil, errors.New("Not Found")) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(nil, errors.New("Not Found")) }, id: spec.ID, wantErr: "orm: job proposal: Not Found", @@ -1950,8 +2033,8 @@ answer1 [type=median index=0]; httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(errors.New("bridges do not exist")) }, id: spec.ID, @@ -1960,8 +2043,8 @@ answer1 [type=median index=0]; { name: "rpc client not connected", before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(nil, errors.New("Not Connected")) }, id: spec.ID, @@ -1973,11 +2056,13 @@ answer1 [type=median index=0]; httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.EXPECT().GetSpec(spec.ID, mock.Anything).Return(spec, nil) - svc.orm.EXPECT().GetJobProposal(jp.ID, mock.Anything).Return(jp, nil) + svc.orm.EXPECT().GetSpec(mock.Anything, spec.ID).Return(spec, nil) + svc.orm.EXPECT().GetJobProposal(mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(j, nil) - svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(nil, errors.New("failure")) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(j, nil) + svc.orm.EXPECT().GetApprovedSpec(mock.Anything, jp.ID).Return(nil, errors.New("failure")) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: true, @@ -1988,12 +2073,14 @@ answer1 [type=median index=0]; httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.EXPECT().GetSpec(spec.ID, mock.Anything).Return(spec, nil) - svc.orm.EXPECT().GetJobProposal(jp.ID, mock.Anything).Return(jp, nil) + svc.orm.EXPECT().GetSpec(mock.Anything, spec.ID).Return(spec, nil) + svc.orm.EXPECT().GetJobProposal(mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindJobIDByAddress", address, evmChainID, mock.Anything).Return(j.ID, nil) - svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(nil, errors.New("failure")) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindJobIDByAddress", mock.Anything, address, evmChainID, mock.Anything).Return(j.ID, nil) + svc.orm.EXPECT().GetApprovedSpec(mock.Anything, jp.ID).Return(nil, errors.New("failure")) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: true, @@ -2004,12 +2091,14 @@ answer1 [type=median index=0]; httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.EXPECT().GetSpec(spec.ID, mock.Anything).Return(spec, nil) - svc.orm.EXPECT().GetJobProposal(jp.ID, mock.Anything).Return(jp, nil) + svc.orm.EXPECT().GetSpec(mock.Anything, spec.ID).Return(spec, nil) + svc.orm.EXPECT().GetJobProposal(mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(j, nil) - svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(&feeds.JobProposalSpec{ID: 100}, nil) - svc.orm.EXPECT().CancelSpec(int64(100), mock.Anything).Return(errors.New("failure")) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(j, nil) + svc.orm.EXPECT().GetApprovedSpec(mock.Anything, jp.ID).Return(&feeds.JobProposalSpec{ID: 100}, nil) + svc.orm.EXPECT().CancelSpec(mock.Anything, int64(100)).Return(errors.New("failure")) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: true, @@ -2020,13 +2109,15 @@ answer1 [type=median index=0]; httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.EXPECT().GetSpec(spec.ID, mock.Anything).Return(spec, nil) - svc.orm.EXPECT().GetJobProposal(jp.ID, mock.Anything).Return(jp, nil) + svc.orm.EXPECT().GetSpec(mock.Anything, spec.ID).Return(spec, nil) + svc.orm.EXPECT().GetJobProposal(mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindJobIDByAddress", address, evmChainID, mock.Anything).Return(j.ID, nil) - svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(&feeds.JobProposalSpec{ID: 100}, nil) - svc.orm.EXPECT().CancelSpec(int64(100), mock.Anything).Return(errors.New("failure")) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindJobIDByAddress", mock.Anything, address, evmChainID, mock.Anything).Return(j.ID, nil) + svc.orm.EXPECT().GetApprovedSpec(mock.Anything, jp.ID).Return(&feeds.JobProposalSpec{ID: 100}, nil) + svc.orm.EXPECT().CancelSpec(mock.Anything, int64(100)).Return(errors.New("failure")) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: true, @@ -2036,22 +2127,25 @@ answer1 [type=median index=0]; name: "create job error", httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindJobIDByAddress", address, evmChainID, mock.Anything).Return(int32(0), sql.ErrNoRows) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindJobIDByAddress", mock.Anything, address, evmChainID, mock.Anything).Return(int32(0), sql.ErrNoRows) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). Return(errors.New("could not save")) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: false, @@ -2061,28 +2155,31 @@ answer1 [type=median index=0]; name: "approve spec orm error", httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindJobIDByAddress", address, evmChainID, mock.Anything).Return(int32(0), sql.ErrNoRows) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindJobIDByAddress", mock.Anything, address, evmChainID, mock.Anything).Return(int32(0), sql.ErrNoRows) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). - Run(func(args mock.Arguments) { (args.Get(0).(*job.Job)).ID = 1 }). + Run(func(args mock.Arguments) { (args.Get(2).(*job.Job)).ID = 1 }). Return(nil) svc.orm.On("ApproveSpec", + mock.Anything, spec.ID, externalJobID, - mock.Anything, ).Return(errors.New("failure")) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: false, @@ -2092,27 +2189,28 @@ answer1 [type=median index=0]; name: "fms call error", httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindJobIDByAddress", address, evmChainID, mock.Anything).Return(int32(0), sql.ErrNoRows) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindJobIDByAddress", mock.Anything, address, evmChainID, mock.Anything).Return(int32(0), sql.ErrNoRows) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). - Run(func(args mock.Arguments) { (args.Get(0).(*job.Job)).ID = 1 }). + Run(func(args mock.Arguments) { (args.Get(2).(*job.Job)).ID = 1 }). Return(nil) svc.orm.On("ApproveSpec", + mock.Anything, spec.ID, externalJobID, - mock.Anything, ).Return(nil) svc.fmsClient.On("ApprovedJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), @@ -2121,6 +2219,8 @@ answer1 [type=median index=0]; Version: int64(spec.Version), }, ).Return(nil, errors.New("failure")) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: false, @@ -2268,25 +2368,26 @@ updateInterval = "20m" httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(int32(0), sql.ErrNoRows) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindOCR2JobIDByAddress", mock.Anything, address, (*common.Hash)(nil)).Return(int32(0), sql.ErrNoRows) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). - Run(func(args mock.Arguments) { (args.Get(0).(*job.Job)).ID = 1 }). + Run(func(args mock.Arguments) { (args.Get(2).(*job.Job)).ID = 1 }). Return(nil) svc.orm.On("ApproveSpec", + mock.Anything, spec.ID, externalJobID, - mock.Anything, ).Return(nil) svc.fmsClient.On("ApprovedJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), @@ -2295,7 +2396,9 @@ updateInterval = "20m" Version: int64(spec.Version), }, ).Return(&proto.ApprovedJobResponse{}, nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: false, @@ -2305,27 +2408,28 @@ updateInterval = "20m" httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", cancelledSpec.ID, mock.Anything).Return(cancelledSpec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) - svc.orm.On("GetLatestSpec", cancelledSpec.JobProposalID).Return(cancelledSpec, nil) + svc.orm.On("GetSpec", mock.Anything, cancelledSpec.ID, mock.Anything).Return(cancelledSpec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) + svc.orm.On("GetLatestSpec", mock.Anything, cancelledSpec.JobProposalID).Return(cancelledSpec, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(int32(0), sql.ErrNoRows) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindOCR2JobIDByAddress", mock.Anything, address, (*common.Hash)(nil)).Return(int32(0), sql.ErrNoRows) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). - Run(func(args mock.Arguments) { (args.Get(0).(*job.Job)).ID = 1 }). + Run(func(args mock.Arguments) { (args.Get(2).(*job.Job)).ID = 1 }). Return(nil) svc.orm.On("ApproveSpec", + mock.Anything, cancelledSpec.ID, externalJobID, - mock.Anything, ).Return(nil) svc.fmsClient.On("ApprovedJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), @@ -2334,7 +2438,9 @@ updateInterval = "20m" Version: int64(spec.Version), }, ).Return(&proto.ApprovedJobResponse{}, nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: cancelledSpec.ID, force: false, @@ -2342,9 +2448,9 @@ updateInterval = "20m" { name: "cancelled spec failed not latest spec", before: func(svc *TestService) { - svc.orm.On("GetSpec", cancelledSpec.ID, mock.Anything).Return(cancelledSpec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) - svc.orm.On("GetLatestSpec", cancelledSpec.JobProposalID).Return(&feeds.JobProposalSpec{ + svc.orm.On("GetSpec", mock.Anything, cancelledSpec.ID, mock.Anything).Return(cancelledSpec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) + svc.orm.On("GetLatestSpec", mock.Anything, cancelledSpec.JobProposalID).Return(&feeds.JobProposalSpec{ ID: 21, Status: feeds.SpecStatusPending, JobProposalID: jp.ID, @@ -2359,8 +2465,8 @@ updateInterval = "20m" { name: "rejected spec failed cannot be approved", before: func(svc *TestService) { - svc.orm.On("GetSpec", cancelledSpec.ID, mock.Anything).Return(rejectedSpec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, cancelledSpec.ID, mock.Anything).Return(rejectedSpec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) }, id: rejectedSpec.ID, force: false, @@ -2371,11 +2477,13 @@ updateInterval = "20m" httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(j.ID, nil) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindOCR2JobIDByAddress", mock.Anything, address, (*common.Hash)(nil)).Return(j.ID, nil) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: false, @@ -2386,27 +2494,28 @@ updateInterval = "20m" httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(nil, sql.ErrNoRows) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(j.ID, nil) - svc.spawner.On("DeleteJob", j.ID, mock.Anything).Return(nil) + svc.orm.EXPECT().GetApprovedSpec(mock.Anything, jp.ID).Return(nil, sql.ErrNoRows) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindOCR2JobIDByAddress", mock.Anything, address, (*common.Hash)(nil)).Return(j.ID, nil) + svc.spawner.On("DeleteJob", mock.Anything, mock.Anything, j.ID).Return(nil) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). - Run(func(args mock.Arguments) { (args.Get(0).(*job.Job)).ID = 1 }). + Run(func(args mock.Arguments) { (args.Get(2).(*job.Job)).ID = 1 }). Return(nil) svc.orm.On("ApproveSpec", + mock.Anything, spec.ID, externalJobID, - mock.Anything, ).Return(nil) svc.fmsClient.On("ApprovedJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), @@ -2415,7 +2524,9 @@ updateInterval = "20m" Version: int64(spec.Version), }, ).Return(&proto.ApprovedJobResponse{}, nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: true, @@ -2425,33 +2536,34 @@ updateInterval = "20m" httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(&feeds.JobProposalSpec{ + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(&feeds.JobProposalSpec{ ID: 20, Status: feeds.SpecStatusPending, JobProposalID: jp.ID, Version: 1, Definition: fmt.Sprintf(defn2, externalJobID.String(), &feedID), }, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(nil, sql.ErrNoRows) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindOCR2JobIDByAddress", address, &feedID, mock.Anything).Return(j.ID, nil) - svc.spawner.On("DeleteJob", j.ID, mock.Anything).Return(nil) + svc.orm.EXPECT().GetApprovedSpec(mock.Anything, jp.ID).Return(nil, sql.ErrNoRows) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindOCR2JobIDByAddress", mock.Anything, address, &feedID).Return(j.ID, nil) + svc.spawner.On("DeleteJob", mock.Anything, mock.Anything, j.ID).Return(nil) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). - Run(func(args mock.Arguments) { (args.Get(0).(*job.Job)).ID = 1 }). + Run(func(args mock.Arguments) { (args.Get(2).(*job.Job)).ID = 1 }). Return(nil) svc.orm.On("ApproveSpec", + mock.Anything, spec.ID, externalJobID, - mock.Anything, ).Return(nil) svc.fmsClient.On("ApprovedJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), @@ -2460,7 +2572,9 @@ updateInterval = "20m" Version: int64(spec.Version), }, ).Return(&proto.ApprovedJobResponse{}, nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: true, @@ -2470,28 +2584,29 @@ updateInterval = "20m" httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(&feeds.JobProposalSpec{ID: 100}, nil) - svc.orm.EXPECT().CancelSpec(int64(100), mock.Anything).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(j.ID, nil) - svc.spawner.On("DeleteJob", j.ID, mock.Anything).Return(nil) + svc.orm.EXPECT().GetApprovedSpec(mock.Anything, jp.ID).Return(&feeds.JobProposalSpec{ID: 100}, nil) + svc.orm.EXPECT().CancelSpec(mock.Anything, int64(100)).Return(nil) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindOCR2JobIDByAddress", mock.Anything, address, (*common.Hash)(nil)).Return(j.ID, nil) + svc.spawner.On("DeleteJob", mock.Anything, mock.Anything, j.ID).Return(nil) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). - Run(func(args mock.Arguments) { (args.Get(0).(*job.Job)).ID = 1 }). + Run(func(args mock.Arguments) { (args.Get(2).(*job.Job)).ID = 1 }). Return(nil) svc.orm.On("ApproveSpec", + mock.Anything, spec.ID, externalJobID, - mock.Anything, ).Return(nil) svc.fmsClient.On("ApprovedJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), @@ -2500,7 +2615,9 @@ updateInterval = "20m" Version: int64(spec.Version), }, ).Return(&proto.ApprovedJobResponse{}, nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: true, @@ -2508,7 +2625,7 @@ updateInterval = "20m" { name: "spec does not exist", before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(nil, errors.New("Not Found")) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(nil, errors.New("Not Found")) }, id: spec.ID, force: false, @@ -2522,8 +2639,8 @@ updateInterval = "20m" JobProposalID: jp.ID, Status: feeds.SpecStatusApproved, } - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(aspec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(aspec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) }, id: spec.ID, force: false, @@ -2537,8 +2654,8 @@ updateInterval = "20m" JobProposalID: jp.ID, Status: feeds.SpecStatusRejected, } - svc.orm.On("GetSpec", rspec.ID, mock.Anything).Return(rspec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, rspec.ID, mock.Anything).Return(rspec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) }, id: spec.ID, force: false, @@ -2547,8 +2664,8 @@ updateInterval = "20m" { name: "job proposal does not exist", before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(nil, errors.New("Not Found")) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(nil, errors.New("Not Found")) }, id: spec.ID, wantErr: "orm: job proposal: Not Found", @@ -2558,8 +2675,8 @@ updateInterval = "20m" httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(errors.New("bridges do not exist")) }, id: spec.ID, @@ -2568,8 +2685,8 @@ updateInterval = "20m" { name: "rpc client not connected", before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(nil, errors.New("Not Connected")) }, id: spec.ID, @@ -2580,22 +2697,25 @@ updateInterval = "20m" name: "create job error", httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(int32(0), sql.ErrNoRows) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindOCR2JobIDByAddress", mock.Anything, address, (*common.Hash)(nil)).Return(int32(0), sql.ErrNoRows) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). Return(errors.New("could not save")) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: false, @@ -2605,28 +2725,31 @@ updateInterval = "20m" name: "approve spec orm error", httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(int32(0), sql.ErrNoRows) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindOCR2JobIDByAddress", mock.Anything, address, (*common.Hash)(nil)).Return(int32(0), sql.ErrNoRows) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). - Run(func(args mock.Arguments) { (args.Get(0).(*job.Job)).ID = 1 }). + Run(func(args mock.Arguments) { (args.Get(2).(*job.Job)).ID = 1 }). Return(nil) svc.orm.On("ApproveSpec", + mock.Anything, spec.ID, externalJobID, - mock.Anything, ).Return(errors.New("failure")) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: false, @@ -2636,27 +2759,28 @@ updateInterval = "20m" name: "fms call error", httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(int32(0), sql.ErrNoRows) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindOCR2JobIDByAddress", mock.Anything, address, (*common.Hash)(nil)).Return(int32(0), sql.ErrNoRows) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). - Run(func(args mock.Arguments) { (args.Get(0).(*job.Job)).ID = 1 }). + Run(func(args mock.Arguments) { (args.Get(2).(*job.Job)).ID = 1 }). Return(nil) svc.orm.On("ApproveSpec", + mock.Anything, spec.ID, externalJobID, - mock.Anything, ).Return(nil) svc.fmsClient.On("ApprovedJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), @@ -2665,6 +2789,8 @@ updateInterval = "20m" Version: int64(spec.Version), }, ).Return(nil, errors.New("failure")) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: false, @@ -2774,25 +2900,26 @@ chainID = 0 httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(int32(0), sql.ErrNoRows) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindOCR2JobIDByAddress", mock.Anything, address, (*common.Hash)(nil)).Return(int32(0), sql.ErrNoRows) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). - Run(func(args mock.Arguments) { (args.Get(0).(*job.Job)).ID = 1 }). + Run(func(args mock.Arguments) { (args.Get(2).(*job.Job)).ID = 1 }). Return(nil) svc.orm.On("ApproveSpec", + mock.Anything, spec.ID, externalJobID, - mock.Anything, ).Return(nil) svc.fmsClient.On("ApprovedJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), @@ -2801,7 +2928,9 @@ chainID = 0 Version: int64(spec.Version), }, ).Return(&proto.ApprovedJobResponse{}, nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: false, @@ -2811,27 +2940,28 @@ chainID = 0 httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", cancelledSpec.ID, mock.Anything).Return(cancelledSpec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) - svc.orm.On("GetLatestSpec", cancelledSpec.JobProposalID).Return(cancelledSpec, nil) + svc.orm.On("GetSpec", mock.Anything, cancelledSpec.ID, mock.Anything).Return(cancelledSpec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) + svc.orm.On("GetLatestSpec", mock.Anything, cancelledSpec.JobProposalID).Return(cancelledSpec, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(int32(0), sql.ErrNoRows) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindOCR2JobIDByAddress", mock.Anything, address, (*common.Hash)(nil)).Return(int32(0), sql.ErrNoRows) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). - Run(func(args mock.Arguments) { (args.Get(0).(*job.Job)).ID = 1 }). + Run(func(args mock.Arguments) { (args.Get(2).(*job.Job)).ID = 1 }). Return(nil) svc.orm.On("ApproveSpec", + mock.Anything, cancelledSpec.ID, externalJobID, - mock.Anything, ).Return(nil) svc.fmsClient.On("ApprovedJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), @@ -2840,7 +2970,9 @@ chainID = 0 Version: int64(spec.Version), }, ).Return(&proto.ApprovedJobResponse{}, nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: cancelledSpec.ID, force: false, @@ -2848,9 +2980,9 @@ chainID = 0 { name: "cancelled spec failed not latest spec", before: func(svc *TestService) { - svc.orm.On("GetSpec", cancelledSpec.ID, mock.Anything).Return(cancelledSpec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) - svc.orm.On("GetLatestSpec", cancelledSpec.JobProposalID).Return(&feeds.JobProposalSpec{ + svc.orm.On("GetSpec", mock.Anything, cancelledSpec.ID, mock.Anything).Return(cancelledSpec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) + svc.orm.On("GetLatestSpec", mock.Anything, cancelledSpec.JobProposalID).Return(&feeds.JobProposalSpec{ ID: 21, Status: feeds.SpecStatusPending, JobProposalID: jp.ID, @@ -2865,8 +2997,8 @@ chainID = 0 { name: "rejected spec failed cannot be approved", before: func(svc *TestService) { - svc.orm.On("GetSpec", cancelledSpec.ID, mock.Anything).Return(rejectedSpec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, cancelledSpec.ID, mock.Anything).Return(rejectedSpec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) }, id: rejectedSpec.ID, force: false, @@ -2877,11 +3009,13 @@ chainID = 0 httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(j.ID, nil) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindOCR2JobIDByAddress", mock.Anything, address, (*common.Hash)(nil)).Return(j.ID, nil) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: false, @@ -2892,27 +3026,28 @@ chainID = 0 httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(nil, sql.ErrNoRows) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(j.ID, nil) - svc.spawner.On("DeleteJob", j.ID, mock.Anything).Return(nil) + svc.orm.EXPECT().GetApprovedSpec(mock.Anything, jp.ID).Return(nil, sql.ErrNoRows) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindOCR2JobIDByAddress", mock.Anything, address, (*common.Hash)(nil)).Return(j.ID, nil) + svc.spawner.On("DeleteJob", mock.Anything, mock.Anything, j.ID).Return(nil) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). - Run(func(args mock.Arguments) { (args.Get(0).(*job.Job)).ID = 1 }). + Run(func(args mock.Arguments) { (args.Get(2).(*job.Job)).ID = 1 }). Return(nil) svc.orm.On("ApproveSpec", + mock.Anything, spec.ID, externalJobID, - mock.Anything, ).Return(nil) svc.fmsClient.On("ApprovedJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), @@ -2921,7 +3056,9 @@ chainID = 0 Version: int64(spec.Version), }, ).Return(&proto.ApprovedJobResponse{}, nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: true, @@ -2931,33 +3068,34 @@ chainID = 0 httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(&feeds.JobProposalSpec{ + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(&feeds.JobProposalSpec{ ID: 20, Status: feeds.SpecStatusPending, JobProposalID: jp.ID, Version: 1, Definition: fmt.Sprintf(defn2, externalJobID.String(), feedID), }, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(nil, sql.ErrNoRows) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindOCR2JobIDByAddress", address, &feedID, mock.Anything).Return(j.ID, nil) - svc.spawner.On("DeleteJob", j.ID, mock.Anything).Return(nil) + svc.orm.EXPECT().GetApprovedSpec(mock.Anything, jp.ID).Return(nil, sql.ErrNoRows) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindOCR2JobIDByAddress", mock.Anything, address, &feedID).Return(j.ID, nil) + svc.spawner.On("DeleteJob", mock.Anything, mock.Anything, j.ID).Return(nil) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). - Run(func(args mock.Arguments) { (args.Get(0).(*job.Job)).ID = 1 }). + Run(func(args mock.Arguments) { (args.Get(2).(*job.Job)).ID = 1 }). Return(nil) svc.orm.On("ApproveSpec", + mock.Anything, spec.ID, externalJobID, - mock.Anything, ).Return(nil) svc.fmsClient.On("ApprovedJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), @@ -2966,7 +3104,9 @@ chainID = 0 Version: int64(spec.Version), }, ).Return(&proto.ApprovedJobResponse{}, nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: true, @@ -2976,28 +3116,29 @@ chainID = 0 httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.orm.EXPECT().GetApprovedSpec(jp.ID, mock.Anything).Return(&feeds.JobProposalSpec{ID: 100}, nil) - svc.orm.EXPECT().CancelSpec(int64(100), mock.Anything).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(j.ID, nil) - svc.spawner.On("DeleteJob", j.ID, mock.Anything).Return(nil) + svc.orm.EXPECT().GetApprovedSpec(mock.Anything, jp.ID).Return(&feeds.JobProposalSpec{ID: 100}, nil) + svc.orm.EXPECT().CancelSpec(mock.Anything, int64(100)).Return(nil) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindOCR2JobIDByAddress", mock.Anything, address, (*common.Hash)(nil)).Return(j.ID, nil) + svc.spawner.On("DeleteJob", mock.Anything, mock.Anything, j.ID).Return(nil) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). - Run(func(args mock.Arguments) { (args.Get(0).(*job.Job)).ID = 1 }). + Run(func(args mock.Arguments) { (args.Get(2).(*job.Job)).ID = 1 }). Return(nil) svc.orm.On("ApproveSpec", + mock.Anything, spec.ID, externalJobID, - mock.Anything, ).Return(nil) svc.fmsClient.On("ApprovedJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), @@ -3006,7 +3147,9 @@ chainID = 0 Version: int64(spec.Version), }, ).Return(&proto.ApprovedJobResponse{}, nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: true, @@ -3014,7 +3157,7 @@ chainID = 0 { name: "spec does not exist", before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(nil, errors.New("Not Found")) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(nil, errors.New("Not Found")) }, id: spec.ID, force: false, @@ -3028,8 +3171,8 @@ chainID = 0 JobProposalID: jp.ID, Status: feeds.SpecStatusApproved, } - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(aspec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(aspec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) }, id: spec.ID, force: false, @@ -3043,8 +3186,8 @@ chainID = 0 JobProposalID: jp.ID, Status: feeds.SpecStatusRejected, } - svc.orm.On("GetSpec", rspec.ID, mock.Anything).Return(rspec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, rspec.ID).Return(rspec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) }, id: spec.ID, force: false, @@ -3053,8 +3196,8 @@ chainID = 0 { name: "job proposal does not exist", before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(nil, errors.New("Not Found")) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(nil, errors.New("Not Found")) }, id: spec.ID, wantErr: "orm: job proposal: Not Found", @@ -3064,8 +3207,8 @@ chainID = 0 httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(errors.New("bridges do not exist")) }, id: spec.ID, @@ -3074,8 +3217,8 @@ chainID = 0 { name: "rpc client not connected", before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(nil, errors.New("Not Connected")) }, id: spec.ID, @@ -3086,22 +3229,25 @@ chainID = 0 name: "create job error", httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(int32(0), sql.ErrNoRows) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindOCR2JobIDByAddress", mock.Anything, address, (*common.Hash)(nil)).Return(int32(0), sql.ErrNoRows) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). Return(errors.New("could not save")) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: false, @@ -3111,28 +3257,31 @@ chainID = 0 name: "approve spec orm error", httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(int32(0), sql.ErrNoRows) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindOCR2JobIDByAddress", mock.Anything, address, (*common.Hash)(nil), mock.Anything).Return(int32(0), sql.ErrNoRows) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). - Run(func(args mock.Arguments) { (args.Get(0).(*job.Job)).ID = 1 }). + Run(func(args mock.Arguments) { (args.Get(2).(*job.Job)).ID = 1 }). Return(nil) svc.orm.On("ApproveSpec", + mock.Anything, spec.ID, externalJobID, - mock.Anything, ).Return(errors.New("failure")) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: false, @@ -3142,27 +3291,28 @@ chainID = 0 name: "fms call error", httpTimeout: commonconfig.MustNewDuration(1 * time.Minute), before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) svc.jobORM.On("AssertBridgesExist", mock.Anything, mock.IsType(pipeline.Pipeline{})).Return(nil) - svc.jobORM.On("FindJobByExternalJobID", externalJobID, mock.Anything).Return(job.Job{}, sql.ErrNoRows) - svc.jobORM.On("FindOCR2JobIDByAddress", address, (*common.Hash)(nil), mock.Anything).Return(int32(0), sql.ErrNoRows) + svc.jobORM.On("FindJobByExternalJobID", mock.Anything, externalJobID).Return(job.Job{}, sql.ErrNoRows) + svc.jobORM.On("FindOCR2JobIDByAddress", mock.Anything, address, (*common.Hash)(nil)).Return(int32(0), sql.ErrNoRows) svc.spawner. On("CreateJob", + mock.Anything, + mock.Anything, mock.MatchedBy(func(j *job.Job) bool { return j.Name.String == "LINK / ETH | version 3 | contract 0x0000000000000000000000000000000000000000" }), - mock.Anything, ). - Run(func(args mock.Arguments) { (args.Get(0).(*job.Job)).ID = 1 }). + Run(func(args mock.Arguments) { (args.Get(2).(*job.Job)).ID = 1 }). Return(nil) svc.orm.On("ApproveSpec", + mock.Anything, spec.ID, externalJobID, - mock.Anything, ).Return(nil) svc.fmsClient.On("ApprovedJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), @@ -3171,6 +3321,8 @@ chainID = 0 Version: int64(spec.Version), }, ).Return(nil, errors.New("failure")) + svc.orm.On("WithDataSource", mock.Anything).Return(feeds.ORM(svc.orm)) + svc.jobORM.On("WithDataSource", mock.Anything).Return(job.ORM(svc.jobORM)) }, id: spec.ID, force: false, @@ -3227,12 +3379,12 @@ func Test_Service_RejectSpec(t *testing.T) { { name: "Success", before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) svc.orm.On("RejectSpec", - spec.ID, mock.Anything, + spec.ID, ).Return(nil) svc.fmsClient.On("RejectedJob", mock.MatchedBy(func(ctx context.Context) bool { return true }), @@ -3241,20 +3393,25 @@ func Test_Service_RejectSpec(t *testing.T) { Version: int64(spec.Version), }, ).Return(&proto.RejectedJobResponse{}, nil) - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) + transactCall := svc.orm.On("Transact", mock.Anything, mock.Anything) + transactCall.Run(func(args mock.Arguments) { + fn := args[1].(func(orm feeds.ORM) error) + transactCall.ReturnArguments = mock.Arguments{fn(svc.orm)} + }) }, }, { name: "Fails to get spec", before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(nil, errors.New("failure")) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(nil, errors.New("failure")) }, wantErr: "failure", }, { name: "Cannot be a rejected proposal", before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(&feeds.JobProposalSpec{ + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(&feeds.JobProposalSpec{ Status: feeds.SpecStatusRejected, }, nil) }, @@ -3263,16 +3420,16 @@ func Test_Service_RejectSpec(t *testing.T) { { name: "Fails to get proposal", before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(nil, errors.New("failure")) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(nil, errors.New("failure")) }, wantErr: "failure", }, { name: "FMS not connected", before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(nil, errors.New("disconnected")) }, wantErr: "disconnected", @@ -3280,18 +3437,23 @@ func Test_Service_RejectSpec(t *testing.T) { { name: "Fails to update spec", before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) svc.orm.On("RejectSpec", mock.Anything, mock.Anything).Return(errors.New("failure")) + transactCall := svc.orm.On("Transact", mock.Anything, mock.Anything) + transactCall.Run(func(args mock.Arguments) { + fn := args[1].(func(orm feeds.ORM) error) + transactCall.ReturnArguments = mock.Arguments{fn(svc.orm)} + }) }, wantErr: "failure", }, { name: "Fails to update spec", before: func(svc *TestService) { - svc.orm.On("GetSpec", spec.ID, mock.Anything).Return(spec, nil) - svc.orm.On("GetJobProposal", jp.ID, mock.Anything).Return(jp, nil) + svc.orm.On("GetSpec", mock.Anything, spec.ID).Return(spec, nil) + svc.orm.On("GetJobProposal", mock.Anything, jp.ID).Return(jp, nil) svc.connMgr.On("GetClient", jp.FeedsManagerID).Return(svc.fmsClient, nil) svc.orm.On("RejectSpec", mock.Anything, mock.Anything).Return(nil) svc.fmsClient. @@ -3302,6 +3464,11 @@ func Test_Service_RejectSpec(t *testing.T) { Version: int64(spec.Version), }). Return(nil, errors.New("rpc failure")) + transactCall := svc.orm.On("Transact", mock.Anything, mock.Anything) + transactCall.Run(func(args mock.Arguments) { + fn := args[1].(func(orm feeds.ORM) error) + transactCall.ReturnArguments = mock.Arguments{fn(svc.orm)} + }) }, wantErr: "rpc failure", }, @@ -3352,9 +3519,9 @@ func Test_Service_UpdateSpecDefinition(t *testing.T) { name: "success", before: func(svc *TestService) { svc.orm. - On("GetSpec", specID, mock.Anything). + On("GetSpec", mock.Anything, specID, mock.Anything). Return(spec, nil) - svc.orm.On("UpdateSpecDefinition", + svc.orm.On("UpdateSpecDefinition", mock.Anything, specID, updatedSpec, mock.Anything, @@ -3366,7 +3533,7 @@ func Test_Service_UpdateSpecDefinition(t *testing.T) { name: "does not exist", before: func(svc *TestService) { svc.orm. - On("GetSpec", specID, mock.Anything). + On("GetSpec", mock.Anything, specID, mock.Anything). Return(nil, sql.ErrNoRows) }, specID: specID, @@ -3376,7 +3543,7 @@ func Test_Service_UpdateSpecDefinition(t *testing.T) { name: "other get errors", before: func(svc *TestService) { svc.orm. - On("GetSpec", specID, mock.Anything). + On("GetSpec", mock.Anything, specID, mock.Anything). Return(nil, errors.New("other db error")) }, specID: specID, @@ -3391,7 +3558,7 @@ func Test_Service_UpdateSpecDefinition(t *testing.T) { } svc.orm. - On("GetSpec", specID, mock.Anything). + On("GetSpec", mock.Anything, specID, mock.Anything). Return(spec, nil) }, specID: specID, @@ -3443,18 +3610,18 @@ func Test_Service_StartStop(t *testing.T) { name: "success with a feeds manager connection", beforeFunc: func(svc *TestService) { svc.csaKeystore.On("GetAll").Return([]csakey.KeyV2{key}, nil) - svc.orm.On("ListManagers").Return([]feeds.FeedsManager{mgr}, nil) + svc.orm.On("ListManagers", mock.Anything).Return([]feeds.FeedsManager{mgr}, nil) svc.connMgr.On("IsConnected", mgr.ID).Return(false) svc.connMgr.On("Connect", mock.IsType(feeds.ConnectOpts{})) svc.connMgr.On("Close") - svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil) + svc.orm.On("CountJobProposalsByStatus", mock.Anything).Return(&feeds.JobProposalCounts{}, nil) }, }, { name: "success with no registered managers", beforeFunc: func(svc *TestService) { svc.csaKeystore.On("GetAll").Return([]csakey.KeyV2{key}, nil) - svc.orm.On("ListManagers").Return([]feeds.FeedsManager{}, nil) + svc.orm.On("ListManagers", mock.Anything).Return([]feeds.FeedsManager{}, nil) svc.connMgr.On("Close") }, }, diff --git a/core/services/fluxmonitorv2/delegate.go b/core/services/fluxmonitorv2/delegate.go index b7b0df77cc4..1f0b72877ff 100644 --- a/core/services/fluxmonitorv2/delegate.go +++ b/core/services/fluxmonitorv2/delegate.go @@ -5,8 +5,7 @@ import ( "github.com/pkg/errors" - "github.com/jmoiron/sqlx" - + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" @@ -25,7 +24,7 @@ type DelegateConfig interface { // Delegate represents a Flux Monitor delegate type Delegate struct { cfg DelegateConfig - db *sqlx.DB + ds sqlutil.DataSource ethKeyStore keystore.Eth jobORM job.ORM pipelineORM pipeline.ORM @@ -43,13 +42,13 @@ func NewDelegate( jobORM job.ORM, pipelineORM pipeline.ORM, pipelineRunner pipeline.Runner, - db *sqlx.DB, + ds sqlutil.DataSource, legacyChains legacyevm.LegacyChainContainer, lggr logger.Logger, ) *Delegate { return &Delegate{ cfg: cfg, - db: db, + ds: ds, ethKeyStore: ethKeyStore, jobORM: jobORM, pipelineORM: pipelineORM, @@ -86,8 +85,8 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) (services [] fm, err := NewFromJobSpec( jb, - d.db, - NewORM(d.db, d.lggr, chain.TxManager(), strategy, checker), + d.ds, + NewORM(d.ds, d.lggr, chain.TxManager(), strategy, checker), d.jobORM, d.pipelineORM, NewKeyStore(d.ethKeyStore), diff --git a/core/services/fluxmonitorv2/flux_monitor.go b/core/services/fluxmonitorv2/flux_monitor.go index 5eebb319030..dd30156e15e 100644 --- a/core/services/fluxmonitorv2/flux_monitor.go +++ b/core/services/fluxmonitorv2/flux_monitor.go @@ -13,8 +13,6 @@ import ( "github.com/pkg/errors" "github.com/shopspring/decimal" - "github.com/jmoiron/sqlx" - "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" @@ -149,7 +147,7 @@ func NewFluxMonitor( // validation. func NewFromJobSpec( jobSpec job.Job, - db *sqlx.DB, + ds sqlutil.DataSource, orm ORM, jobORM job.ORM, pipelineORM pipeline.ORM, @@ -250,7 +248,7 @@ func NewFromJobSpec( pipelineRunner, jobSpec, *jobSpec.PipelineSpec, - db, + ds, orm, jobORM, pipelineORM, @@ -760,7 +758,7 @@ func (fm *FluxMonitor) respondToNewRoundLog(log flux_aggregator_wrapper.FluxAggr result, err := results.FinalResult(newRoundLogger).SingularResult() if err != nil || result.Error != nil { newRoundLogger.Errorw("can't fetch answer", "err", err, "result", result) - fm.jobORM.TryRecordError(fm.spec.JobID, "Error polling") + fm.jobORM.TryRecordError(ctx, fm.spec.JobID, "Error polling") return } answer, err := utils.ToDecimal(result.Value) @@ -865,7 +863,7 @@ func (fm *FluxMonitor) pollIfEligible(pollReq PollRequestType, deviationChecker roundState, err := fm.roundState(0) if err != nil { l.Errorw("unable to determine eligibility to submit from FluxAggregator contract", "err", err) - fm.jobORM.TryRecordError(fm.spec.JobID, + fm.jobORM.TryRecordError(ctx, fm.spec.JobID, "Unable to call roundState method on provided contract. Check contract address.", ) @@ -885,7 +883,7 @@ func (fm *FluxMonitor) pollIfEligible(pollReq PollRequestType, deviationChecker roundStateNew, err2 := fm.roundState(roundState.RoundId) if err2 != nil { l.Errorw("unable to determine eligibility to submit from FluxAggregator contract", "err", err2) - fm.jobORM.TryRecordError(fm.spec.JobID, + fm.jobORM.TryRecordError(ctx, fm.spec.JobID, "Unable to call roundState method on provided contract. Check contract address.", ) @@ -962,13 +960,13 @@ func (fm *FluxMonitor) pollIfEligible(pollReq PollRequestType, deviationChecker run, results, err := fm.runner.ExecuteRun(ctx, fm.spec, vars, fm.logger) if err != nil { l.Errorw("can't fetch answer", "err", err) - fm.jobORM.TryRecordError(fm.spec.JobID, "Error polling") + fm.jobORM.TryRecordError(ctx, fm.spec.JobID, "Error polling") return } result, err := results.FinalResult(l).SingularResult() if err != nil || result.Error != nil { l.Errorw("can't fetch answer", "err", err, "result", result) - fm.jobORM.TryRecordError(fm.spec.JobID, "Error polling") + fm.jobORM.TryRecordError(ctx, fm.spec.JobID, "Error polling") return } answer, err := utils.ToDecimal(result.Value) @@ -1041,7 +1039,7 @@ func (fm *FluxMonitor) isValidSubmission(ctx context.Context, l logger.Logger, a "max", fm.submissionChecker.Max, "answer", answer, ) - fm.jobORM.TryRecordError(fm.spec.JobID, "Answer is outside acceptable range") + fm.jobORM.TryRecordError(ctx, fm.spec.JobID, "Answer is outside acceptable range") jobId := fm.spec.JobID jobName := fm.spec.JobName diff --git a/core/services/fluxmonitorv2/flux_monitor_test.go b/core/services/fluxmonitorv2/flux_monitor_test.go index 2ac424bceab..b3a5bcee6b9 100644 --- a/core/services/fluxmonitorv2/flux_monitor_test.go +++ b/core/services/fluxmonitorv2/flux_monitor_test.go @@ -515,6 +515,7 @@ func TestFluxMonitor_PollIfEligible_Creates_JobErr(t *testing.T) { tm.jobORM. On("TryRecordError", + mock.Anything, pipelineSpec.JobID, "Unable to call roundState method on provided contract. Check contract address.", ).Once() diff --git a/core/services/fluxmonitorv2/integrations_test.go b/core/services/fluxmonitorv2/integrations_test.go index 7a967300867..6b9dcb99262 100644 --- a/core/services/fluxmonitorv2/integrations_test.go +++ b/core/services/fluxmonitorv2/integrations_test.go @@ -24,9 +24,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/jmoiron/sqlx" - commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log" @@ -43,7 +42,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/fluxmonitorv2" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/store/models" "github.com/smartcontractkit/chainlink/v2/core/utils" @@ -393,32 +391,34 @@ func assertNoSubmission(t *testing.T, // assertPipelineRunCreated checks that a pipeline exists for a given round and // verifies the answer -func assertPipelineRunCreated(t *testing.T, db *sqlx.DB, roundID int64, result int64) pipeline.Run { +func assertPipelineRunCreated(t *testing.T, ds sqlutil.DataSource, roundID int64, result int64) pipeline.Run { + ctx := testutils.Context(t) // Fetch the stats to extract the run id stats := fluxmonitorv2.FluxMonitorRoundStatsV2{} - require.NoError(t, db.Get(&stats, "SELECT * FROM flux_monitor_round_stats_v2 WHERE round_id = $1", roundID)) + require.NoError(t, ds.GetContext(ctx, &stats, "SELECT * FROM flux_monitor_round_stats_v2 WHERE round_id = $1", roundID)) if stats.ID == 0 { t.Fatalf("Stats for round id: %v not found!", roundID) } require.True(t, stats.PipelineRunID.Valid) // Verify the pipeline run data run := pipeline.Run{} - require.NoError(t, db.Get(&run, `SELECT * FROM pipeline_runs WHERE id = $1`, stats.PipelineRunID.Int64), "runID %v", stats.PipelineRunID) + require.NoError(t, ds.GetContext(ctx, &run, `SELECT * FROM pipeline_runs WHERE id = $1`, stats.PipelineRunID.Int64), "runID %v", stats.PipelineRunID) assert.Equal(t, []interface{}{result}, run.Outputs.Val) return run } -func checkLogWasConsumed(t *testing.T, fa fluxAggregatorUniverse, db *sqlx.DB, pipelineSpecID int32, blockNumber uint64, cfg pg.QConfig) { +func checkLogWasConsumed(t *testing.T, fa fluxAggregatorUniverse, ds sqlutil.DataSource, pipelineSpecID int32, blockNumber uint64) { t.Helper() lggr := logger.TestLogger(t) lggr.Infof("Waiting for log on block: %v, job id: %v", blockNumber, pipelineSpecID) g := gomega.NewWithT(t) g.Eventually(func() bool { + ctx := testutils.Context(t) block := fa.backend.Blockchain().GetBlockByNumber(blockNumber) require.NotNil(t, block) - orm := log.NewORM(db, fa.evmChainID) - consumed, err := orm.WasBroadcastConsumed(testutils.Context(t), block.Hash(), 0, pipelineSpecID) + orm := log.NewORM(ds, fa.evmChainID) + consumed, err := orm.WasBroadcastConsumed(ctx, block.Hash(), 0, pipelineSpecID) require.NoError(t, err) fa.backend.Commit() return consumed @@ -559,12 +559,12 @@ func TestFluxMonitor_Deviation(t *testing.T) { initialBalance, receiptBlock, ) - assertPipelineRunCreated(t, app.GetSqlxDB(), 1, int64(100)) + assertPipelineRunCreated(t, app.GetDB(), 1, int64(100)) // Need to wait until NewRound log is consumed - otherwise there is a chance // it will arrive after the next answer is submitted, and cause // DeleteFluxMonitorRoundsBackThrough to delete previous stats - checkLogWasConsumed(t, fa, app.GetSqlxDB(), jobID, receiptBlock, app.GetConfig().Database()) + checkLogWasConsumed(t, fa, app.GetDB(), jobID, receiptBlock) lggr.Info("Updating price to 103") // Change reported price to a value outside the deviation @@ -588,12 +588,12 @@ func TestFluxMonitor_Deviation(t *testing.T) { initialBalance-fee, receiptBlock, ) - assertPipelineRunCreated(t, app.GetSqlxDB(), 2, int64(103)) + assertPipelineRunCreated(t, app.GetDB(), 2, int64(103)) // Need to wait until NewRound log is consumed - otherwise there is a chance // it will arrive after the next answer is submitted, and cause // DeleteFluxMonitorRoundsBackThrough to delete previous stats - checkLogWasConsumed(t, fa, app.GetSqlxDB(), jobID, receiptBlock, app.GetConfig().Database()) + checkLogWasConsumed(t, fa, app.GetDB(), jobID, receiptBlock) // Should not received a submission as it is inside the deviation reportPrice.Store(104) @@ -795,7 +795,7 @@ ds1 -> ds1_parse // node doesn't submit initial response, because flag is up // Wait here so the next lower flags doesn't trigger immediately - cltest.AssertPipelineRunsStays(t, j.PipelineSpec.ID, app.GetSqlxDB(), 0) + cltest.AssertPipelineRunsStays(t, j.PipelineSpec.ID, app.GetDB(), 0) // lower global kill switch flag - should trigger job run _, err = fa.flagsContract.LowerFlags(fa.sergey, []common.Address{evmutils.ZeroAddress}) @@ -910,7 +910,7 @@ ds1 -> ds1_parse jobID, err := strconv.ParseInt(j.ID, 10, 32) require.NoError(t, err) - jse := cltest.WaitForSpecErrorV2(t, app.GetSqlxDB(), int32(jobID), 1) + jse := cltest.WaitForSpecErrorV2(t, app.GetDB(), int32(jobID), 1) assert.Contains(t, jse[0].Description, "Answer is outside acceptable range") } diff --git a/core/services/fluxmonitorv2/orm_test.go b/core/services/fluxmonitorv2/orm_test.go index db00fabb4ff..9652c0b0e27 100644 --- a/core/services/fluxmonitorv2/orm_test.go +++ b/core/services/fluxmonitorv2/orm_test.go @@ -99,14 +99,14 @@ func TestORM_UpdateFluxMonitorRoundStats(t *testing.T) { // Instantiate a real job ORM because we need to create a job to satisfy // a check in pipeline.CreateRun - jobORM := job.NewORM(db, pipelineORM, bridgeORM, keyStore, lggr, cfg.Database()) + jobORM := job.NewORM(db, pipelineORM, bridgeORM, keyStore, lggr) orm := newORM(t, db, nil) address := testutils.NewAddress() var roundID uint32 = 1 jb := makeJob(t) - require.NoError(t, jobORM.CreateJob(jb)) + require.NoError(t, jobORM.CreateJob(ctx, jb)) for expectedCount := uint64(1); expectedCount < 4; expectedCount++ { f := time.Now() diff --git a/core/services/functions/listener_test.go b/core/services/functions/listener_test.go index f3754bbbc29..a1a29bf2500 100644 --- a/core/services/functions/listener_test.go +++ b/core/services/functions/listener_test.go @@ -186,7 +186,7 @@ func TestFunctionsListener_HandleOffchainRequest_Success(t *testing.T) { uni := NewFunctionsListenerUniverse(t, 0, 1_000_000) - uni.pluginORM.On("CreateRequest", mock.Anything, mock.Anything).Return(nil) + uni.pluginORM.On("CreateRequest", mock.Anything, mock.Anything, mock.Anything).Return(nil) uni.bridgeAccessor.On("NewExternalAdapterClient", mock.Anything).Return(uni.eaClient, nil) uni.eaClient.On("RunComputation", mock.Anything, RequestIDStr, mock.Anything, SubscriptionOwner.Hex(), SubscriptionID, mock.Anything, mock.Anything, mock.Anything).Return(ResultBytes, nil, nil, nil) uni.pluginORM.On("SetResult", mock.Anything, RequestID, ResultBytes, mock.Anything, mock.Anything).Return(nil) @@ -230,7 +230,7 @@ func TestFunctionsListener_HandleOffchainRequest_InternalError(t *testing.T) { testutils.SkipShortDB(t) t.Parallel() uni := NewFunctionsListenerUniverse(t, 0, 1_000_000) - uni.pluginORM.On("CreateRequest", mock.Anything, mock.Anything).Return(nil) + uni.pluginORM.On("CreateRequest", mock.Anything, mock.Anything, mock.Anything).Return(nil) uni.bridgeAccessor.On("NewExternalAdapterClient", mock.Anything).Return(uni.eaClient, nil) uni.eaClient.On("RunComputation", mock.Anything, RequestIDStr, mock.Anything, SubscriptionOwner.Hex(), SubscriptionID, mock.Anything, mock.Anything, mock.Anything).Return(nil, nil, nil, errors.New("error")) uni.pluginORM.On("SetError", mock.Anything, RequestID, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) diff --git a/core/services/gateway/delegate.go b/core/services/gateway/delegate.go index 8cddc027803..5a30228db4c 100644 --- a/core/services/gateway/delegate.go +++ b/core/services/gateway/delegate.go @@ -5,34 +5,31 @@ import ( "encoding/json" "github.com/google/uuid" - "github.com/jmoiron/sqlx" "github.com/pelletier/go-toml" "github.com/pkg/errors" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/config" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) type Delegate struct { legacyChains legacyevm.LegacyChainContainer ks keystore.Eth - db *sqlx.DB - cfg pg.QConfig + ds sqlutil.DataSource lggr logger.Logger } var _ job.Delegate = (*Delegate)(nil) -func NewDelegate(legacyChains legacyevm.LegacyChainContainer, ks keystore.Eth, db *sqlx.DB, cfg pg.QConfig, lggr logger.Logger) *Delegate { +func NewDelegate(legacyChains legacyevm.LegacyChainContainer, ks keystore.Eth, ds sqlutil.DataSource, lggr logger.Logger) *Delegate { return &Delegate{ legacyChains: legacyChains, ks: ks, - db: db, - cfg: cfg, + ds: ds, lggr: lggr, } } @@ -57,7 +54,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) (services if err2 != nil { return nil, errors.Wrap(err2, "unmarshal gateway config") } - handlerFactory := NewHandlerFactory(d.legacyChains, d.db, d.cfg, d.lggr) + handlerFactory := NewHandlerFactory(d.legacyChains, d.ds, d.lggr) gateway, err := NewGatewayFromConfig(&gatewayConfig, handlerFactory, d.lggr) if err != nil { return nil, err diff --git a/core/services/gateway/gateway_test.go b/core/services/gateway/gateway_test.go index 7a5457c788c..3218c5428a2 100644 --- a/core/services/gateway/gateway_test.go +++ b/core/services/gateway/gateway_test.go @@ -57,7 +57,7 @@ Address = "0x0001020304050607080900010203040506070809" `) lggr := logger.TestLogger(t) - _, err := gateway.NewGatewayFromConfig(parseTOMLConfig(t, tomlConfig), gateway.NewHandlerFactory(nil, nil, nil, lggr), lggr) + _, err := gateway.NewGatewayFromConfig(parseTOMLConfig(t, tomlConfig), gateway.NewHandlerFactory(nil, nil, lggr), lggr) require.NoError(t, err) } @@ -75,7 +75,7 @@ HandlerName = "dummy" `) lggr := logger.TestLogger(t) - _, err := gateway.NewGatewayFromConfig(parseTOMLConfig(t, tomlConfig), gateway.NewHandlerFactory(nil, nil, nil, lggr), lggr) + _, err := gateway.NewGatewayFromConfig(parseTOMLConfig(t, tomlConfig), gateway.NewHandlerFactory(nil, nil, lggr), lggr) require.Error(t, err) } @@ -89,7 +89,7 @@ HandlerName = "no_such_handler" `) lggr := logger.TestLogger(t) - _, err := gateway.NewGatewayFromConfig(parseTOMLConfig(t, tomlConfig), gateway.NewHandlerFactory(nil, nil, nil, lggr), lggr) + _, err := gateway.NewGatewayFromConfig(parseTOMLConfig(t, tomlConfig), gateway.NewHandlerFactory(nil, nil, lggr), lggr) require.Error(t, err) } @@ -103,7 +103,7 @@ SomeOtherField = "abcd" `) lggr := logger.TestLogger(t) - _, err := gateway.NewGatewayFromConfig(parseTOMLConfig(t, tomlConfig), gateway.NewHandlerFactory(nil, nil, nil, lggr), lggr) + _, err := gateway.NewGatewayFromConfig(parseTOMLConfig(t, tomlConfig), gateway.NewHandlerFactory(nil, nil, lggr), lggr) require.Error(t, err) } @@ -121,7 +121,7 @@ Address = "0xnot_an_address" `) lggr := logger.TestLogger(t) - _, err := gateway.NewGatewayFromConfig(parseTOMLConfig(t, tomlConfig), gateway.NewHandlerFactory(nil, nil, nil, lggr), lggr) + _, err := gateway.NewGatewayFromConfig(parseTOMLConfig(t, tomlConfig), gateway.NewHandlerFactory(nil, nil, lggr), lggr) require.Error(t, err) } @@ -129,7 +129,7 @@ func TestGateway_CleanStartAndClose(t *testing.T) { t.Parallel() lggr := logger.TestLogger(t) - gateway, err := gateway.NewGatewayFromConfig(parseTOMLConfig(t, buildConfig("")), gateway.NewHandlerFactory(nil, nil, nil, lggr), lggr) + gateway, err := gateway.NewGatewayFromConfig(parseTOMLConfig(t, buildConfig("")), gateway.NewHandlerFactory(nil, nil, lggr), lggr) require.NoError(t, err) servicetest.Run(t, gateway) } diff --git a/core/services/gateway/handler_factory.go b/core/services/gateway/handler_factory.go index 8ccae8c7c4b..ca6b98e55aa 100644 --- a/core/services/gateway/handler_factory.go +++ b/core/services/gateway/handler_factory.go @@ -4,14 +4,12 @@ import ( "encoding/json" "fmt" - "github.com/jmoiron/sqlx" - + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/config" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) const ( @@ -21,21 +19,20 @@ const ( type handlerFactory struct { legacyChains legacyevm.LegacyChainContainer - db *sqlx.DB - cfg pg.QConfig + ds sqlutil.DataSource lggr logger.Logger } var _ HandlerFactory = (*handlerFactory)(nil) -func NewHandlerFactory(legacyChains legacyevm.LegacyChainContainer, db *sqlx.DB, cfg pg.QConfig, lggr logger.Logger) HandlerFactory { - return &handlerFactory{legacyChains, db, cfg, lggr} +func NewHandlerFactory(legacyChains legacyevm.LegacyChainContainer, ds sqlutil.DataSource, lggr logger.Logger) HandlerFactory { + return &handlerFactory{legacyChains, ds, lggr} } func (hf *handlerFactory) NewHandler(handlerType HandlerType, handlerConfig json.RawMessage, donConfig *config.DONConfig, don handlers.DON) (handlers.Handler, error) { switch handlerType { case FunctionsHandlerType: - return functions.NewFunctionsHandlerFromConfig(handlerConfig, donConfig, don, hf.legacyChains, hf.db, hf.cfg, hf.lggr) + return functions.NewFunctionsHandlerFromConfig(handlerConfig, donConfig, don, hf.legacyChains, hf.ds, hf.lggr) case DummyHandlerType: return handlers.NewDummyHandler(donConfig, don, hf.lggr) default: diff --git a/core/services/gateway/handlers/functions/handler.functions.go b/core/services/gateway/handlers/functions/handler.functions.go index 692534db598..2d55bb23fde 100644 --- a/core/services/gateway/handlers/functions/handler.functions.go +++ b/core/services/gateway/handlers/functions/handler.functions.go @@ -10,13 +10,13 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - "github.com/jmoiron/sqlx" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "go.uber.org/multierr" "github.com/smartcontractkit/chainlink-common/pkg/assets" "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/api" @@ -25,7 +25,6 @@ import ( hc "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/common" fallow "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/allowlist" fsub "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/subscriptions" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) var ( @@ -100,7 +99,7 @@ type PendingRequest struct { var _ handlers.Handler = (*functionsHandler)(nil) -func NewFunctionsHandlerFromConfig(handlerConfig json.RawMessage, donConfig *config.DONConfig, don handlers.DON, legacyChains legacyevm.LegacyChainContainer, db *sqlx.DB, qcfg pg.QConfig, lggr logger.Logger) (handlers.Handler, error) { +func NewFunctionsHandlerFromConfig(handlerConfig json.RawMessage, donConfig *config.DONConfig, don handlers.DON, legacyChains legacyevm.LegacyChainContainer, ds sqlutil.DataSource, lggr logger.Logger) (handlers.Handler, error) { var cfg FunctionsHandlerConfig err := json.Unmarshal(handlerConfig, &cfg) if err != nil { @@ -114,7 +113,7 @@ func NewFunctionsHandlerFromConfig(handlerConfig json.RawMessage, donConfig *con return nil, err2 } - orm, err2 := fallow.NewORM(db, lggr, cfg.OnchainAllowlist.ContractAddress) + orm, err2 := fallow.NewORM(ds, lggr, cfg.OnchainAllowlist.ContractAddress) if err2 != nil { return nil, err2 } @@ -143,7 +142,7 @@ func NewFunctionsHandlerFromConfig(handlerConfig json.RawMessage, donConfig *con return nil, err2 } - orm, err2 := fsub.NewORM(db, lggr, cfg.OnchainSubscriptions.ContractAddress) + orm, err2 := fsub.NewORM(ds, lggr, cfg.OnchainSubscriptions.ContractAddress) if err2 != nil { return nil, err2 } diff --git a/core/services/gateway/handlers/functions/handler.functions_test.go b/core/services/gateway/handlers/functions/handler.functions_test.go index 2e2c1c77caf..b7abeed8a99 100644 --- a/core/services/gateway/handlers/functions/handler.functions_test.go +++ b/core/services/gateway/handlers/functions/handler.functions_test.go @@ -84,7 +84,7 @@ func sendNodeReponses(t *testing.T, handler handlers.Handler, userRequestMsg api func TestFunctionsHandler_Minimal(t *testing.T) { t.Parallel() - handler, err := functions.NewFunctionsHandlerFromConfig(json.RawMessage("{}"), &config.DONConfig{}, nil, nil, nil, nil, logger.TestLogger(t)) + handler, err := functions.NewFunctionsHandlerFromConfig(json.RawMessage("{}"), &config.DONConfig{}, nil, nil, nil, logger.TestLogger(t)) require.NoError(t, err) // empty message should always error out @@ -96,7 +96,7 @@ func TestFunctionsHandler_Minimal(t *testing.T) { func TestFunctionsHandler_CleanStartAndClose(t *testing.T) { t.Parallel() - handler, err := functions.NewFunctionsHandlerFromConfig(json.RawMessage("{}"), &config.DONConfig{}, nil, nil, nil, nil, logger.TestLogger(t)) + handler, err := functions.NewFunctionsHandlerFromConfig(json.RawMessage("{}"), &config.DONConfig{}, nil, nil, nil, logger.TestLogger(t)) require.NoError(t, err) servicetest.Run(t, handler) diff --git a/core/services/gateway/integration_tests/gateway_integration_test.go b/core/services/gateway/integration_tests/gateway_integration_test.go index 7f4a2ab58fa..38a6b6ebbca 100644 --- a/core/services/gateway/integration_tests/gateway_integration_test.go +++ b/core/services/gateway/integration_tests/gateway_integration_test.go @@ -143,7 +143,7 @@ func TestIntegration_Gateway_NoFullNodes_BasicConnectionAndMessage(t *testing.T) // Launch Gateway lggr := logger.TestLogger(t) gatewayConfig := fmt.Sprintf(gatewayConfigTemplate, nodeKeys.Address) - gateway, err := gateway.NewGatewayFromConfig(parseGatewayConfig(t, gatewayConfig), gateway.NewHandlerFactory(nil, nil, nil, lggr), lggr) + gateway, err := gateway.NewGatewayFromConfig(parseGatewayConfig(t, gatewayConfig), gateway.NewHandlerFactory(nil, nil, lggr), lggr) require.NoError(t, err) servicetest.Run(t, gateway) userPort, nodePort := gateway.GetUserPort(), gateway.GetNodePort() diff --git a/core/services/job/common.go b/core/services/job/common.go index 58b1754cbf5..055195440b0 100644 --- a/core/services/job/common.go +++ b/core/services/job/common.go @@ -3,8 +3,6 @@ package job import ( "context" "net/url" - - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) //go:generate mockery --quiet --name ServiceCtx --output ./mocks/ --case=underscore @@ -22,7 +20,6 @@ type ServiceCtx interface { type Config interface { URL() url.URL - pg.QConfig } // ServiceAdapter is a helper introduced for transitioning from Service to ServiceCtx. diff --git a/core/services/job/helpers_test.go b/core/services/job/helpers_test.go index 22e1b0bef63..7120fe4200c 100644 --- a/core/services/job/helpers_test.go +++ b/core/services/job/helpers_test.go @@ -268,8 +268,7 @@ func makeOCRJobSpecFromToml(t *testing.T, jobSpecToml string) *job.Job { return &jb } -func makeOCR2VRFJobSpec(t testing.TB, ks keystore.Master, cfg chainlink.GeneralConfig, - transmitter common.Address, chainID *big.Int, fromBlock uint64) *job.Job { +func makeOCR2VRFJobSpec(t testing.TB, ks keystore.Master, transmitter common.Address, chainID *big.Int, fromBlock uint64) *job.Job { t.Helper() ctx := testutils.Context(t) diff --git a/core/services/job/job_orm_test.go b/core/services/job/job_orm_test.go index ffbd02c512b..f07b68d9987 100644 --- a/core/services/job/job_orm_test.go +++ b/core/services/job/job_orm_test.go @@ -73,20 +73,21 @@ serverPubKey = '8fa807463ad73f9ee855cfd60ba406dcf98a2855b3dd8af613107b0f6890a707 func TestORM(t *testing.T) { t.Parallel() - ctx := testutils.Context(t) + config := configtest.NewTestGeneralConfig(t) db := pgtest.NewSqlxDB(t) keyStore := cltest.NewKeyStore(t, db) ethKeyStore := keyStore.Eth() - require.NoError(t, keyStore.OCR().Add(ctx, cltest.DefaultOCRKey)) - require.NoError(t, keyStore.P2P().Add(ctx, cltest.DefaultP2PKey)) + func() { + ctx := testutils.Context(t) + require.NoError(t, keyStore.OCR().Add(ctx, cltest.DefaultOCRKey)) + require.NoError(t, keyStore.P2P().Add(ctx, cltest.DefaultP2PKey)) + }() pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns()) - bridgesORM := bridges.NewORM(db) - - orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database()) borm := bridges.NewORM(db) + orm := NewTestORM(t, db, pipelineORM, borm, keyStore) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}) _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}) @@ -94,7 +95,7 @@ func TestORM(t *testing.T) { jb := makeOCRJobSpec(t, address, bridge.Name.String(), bridge2.Name.String()) t.Run("it creates job specs", func(t *testing.T) { - err := orm.CreateJob(jb) + err := orm.CreateJob(testutils.Context(t), jb) require.NoError(t, err) var returnedSpec job.Job @@ -109,8 +110,9 @@ func TestORM(t *testing.T) { }) t.Run("it correctly mark job_pipeline_specs as primary when creating a job", func(t *testing.T) { + ctx := testutils.Context(t) jb2 := makeOCRJobSpec(t, address, bridge.Name.String(), bridge2.Name.String()) - err := orm.CreateJob(jb2) + err := orm.CreateJob(ctx, jb2) require.NoError(t, err) var pipelineSpec pipeline.Spec @@ -128,7 +130,7 @@ func TestORM(t *testing.T) { t.Run("autogenerates external job ID if missing", func(t *testing.T) { jb2 := makeOCRJobSpec(t, address, bridge.Name.String(), bridge2.Name.String()) jb2.ExternalJobID = uuid.UUID{} - err := orm.CreateJob(jb2) + err := orm.CreateJob(testutils.Context(t), jb2) require.NoError(t, err) var returnedSpec job.Job @@ -145,7 +147,7 @@ func TestORM(t *testing.T) { require.NoError(t, err) require.Len(t, dbSpecs, 3) - err = orm.DeleteJob(jb.ID) + err = orm.DeleteJob(testutils.Context(t), jb.ID) require.NoError(t, err) dbSpecs = []job.Job{} @@ -155,8 +157,9 @@ func TestORM(t *testing.T) { }) t.Run("increase job spec error occurrence", func(t *testing.T) { + ctx := testutils.Context(t) jb3 := makeOCRJobSpec(t, address, bridge.Name.String(), bridge2.Name.String()) - err := orm.CreateJob(jb3) + err := orm.CreateJob(ctx, jb3) require.NoError(t, err) var jobSpec job.Job err = db.Get(&jobSpec, "SELECT * FROM jobs") @@ -164,9 +167,9 @@ func TestORM(t *testing.T) { ocrSpecError1 := "ocr spec 1 errored" ocrSpecError2 := "ocr spec 2 errored" - require.NoError(t, orm.RecordError(jobSpec.ID, ocrSpecError1)) - require.NoError(t, orm.RecordError(jobSpec.ID, ocrSpecError1)) - require.NoError(t, orm.RecordError(jobSpec.ID, ocrSpecError2)) + require.NoError(t, orm.RecordError(ctx, jobSpec.ID, ocrSpecError1)) + require.NoError(t, orm.RecordError(ctx, jobSpec.ID, ocrSpecError1)) + require.NoError(t, orm.RecordError(ctx, jobSpec.ID, ocrSpecError2)) var specErrors []job.SpecError err = db.Select(&specErrors, "SELECT * FROM job_spec_errors") @@ -193,8 +196,9 @@ func TestORM(t *testing.T) { }) t.Run("finds job spec error by ID", func(t *testing.T) { + ctx := testutils.Context(t) jb3 := makeOCRJobSpec(t, address, bridge.Name.String(), bridge2.Name.String()) - err := orm.CreateJob(jb3) + err := orm.CreateJob(ctx, jb3) require.NoError(t, err) var jobSpec job.Job err = db.Get(&jobSpec, "SELECT * FROM jobs") @@ -207,8 +211,8 @@ func TestORM(t *testing.T) { ocrSpecError1 := "ocr spec 3 errored" ocrSpecError2 := "ocr spec 4 errored" - require.NoError(t, orm.RecordError(jobSpec.ID, ocrSpecError1)) - require.NoError(t, orm.RecordError(jobSpec.ID, ocrSpecError2)) + require.NoError(t, orm.RecordError(ctx, jobSpec.ID, ocrSpecError1)) + require.NoError(t, orm.RecordError(ctx, jobSpec.ID, ocrSpecError2)) var updatedSpecError []job.SpecError @@ -221,9 +225,9 @@ func TestORM(t *testing.T) { assert.Equal(t, ocrSpecError1, updatedSpecError[2].Description) assert.Equal(t, ocrSpecError2, updatedSpecError[3].Description) - dbSpecErr1, err := orm.FindSpecError(updatedSpecError[2].ID) + dbSpecErr1, err := orm.FindSpecError(ctx, updatedSpecError[2].ID) require.NoError(t, err) - dbSpecErr2, err := orm.FindSpecError(updatedSpecError[3].ID) + dbSpecErr2, err := orm.FindSpecError(ctx, updatedSpecError[3].ID) require.NoError(t, err) assert.Equal(t, uint(1), dbSpecErr1.Occurrences) @@ -251,11 +255,12 @@ func TestORM(t *testing.T) { drJob, err := directrequest.ValidatedDirectRequestSpec(drSpec) require.NoError(t, err) - err = orm.CreateJob(&drJob) + err = orm.CreateJob(testutils.Context(t), &drJob) require.NoError(t, err) }) t.Run("creates webhook specs along with external_initiator_webhook_specs", func(t *testing.T) { + ctx := testutils.Context(t) eiFoo := cltest.MustInsertExternalInitiator(t, borm) eiBar := cltest.MustInsertExternalInitiator(t, borm) @@ -263,22 +268,23 @@ func TestORM(t *testing.T) { {Name: eiFoo.Name, Spec: cltest.JSONFromString(t, `{}`)}, {Name: eiBar.Name, Spec: cltest.JSONFromString(t, `{"bar": 1}`)}, } - eim := webhook.NewExternalInitiatorManager(db, nil, logger.TestLogger(t), config.Database()) - jb, err := webhook.ValidatedWebhookSpec(testspecs.GenerateWebhookSpec(testspecs.WebhookSpecParams{ExternalInitiators: eiWS}).Toml(), eim) + eim := webhook.NewExternalInitiatorManager(db, nil) + jb, err := webhook.ValidatedWebhookSpec(ctx, testspecs.GenerateWebhookSpec(testspecs.WebhookSpecParams{ExternalInitiators: eiWS}).Toml(), eim) require.NoError(t, err) - err = orm.CreateJob(&jb) + err = orm.CreateJob(testutils.Context(t), &jb) require.NoError(t, err) cltest.AssertCount(t, db, "external_initiator_webhook_specs", 2) }) t.Run("it creates and deletes records for blockhash store jobs", func(t *testing.T) { + ctx := testutils.Context(t) bhsJob, err := blockhashstore.ValidatedSpec( testspecs.GenerateBlockhashStoreSpec(testspecs.BlockhashStoreSpecParams{}).Toml()) require.NoError(t, err) - err = orm.CreateJob(&bhsJob) + err = orm.CreateJob(ctx, &bhsJob) require.NoError(t, err) savedJob, err := orm.FindJob(testutils.Context(t), bhsJob.ID) require.NoError(t, err) @@ -298,18 +304,19 @@ func TestORM(t *testing.T) { require.Equal(t, bhsJob.BlockhashStoreSpec.RunTimeout, savedJob.BlockhashStoreSpec.RunTimeout) require.Equal(t, bhsJob.BlockhashStoreSpec.EVMChainID, savedJob.BlockhashStoreSpec.EVMChainID) require.Equal(t, bhsJob.BlockhashStoreSpec.FromAddresses, savedJob.BlockhashStoreSpec.FromAddresses) - err = orm.DeleteJob(bhsJob.ID) + err = orm.DeleteJob(ctx, bhsJob.ID) require.NoError(t, err) _, err = orm.FindJob(testutils.Context(t), bhsJob.ID) require.Error(t, err) }) t.Run("it creates and deletes records for blockheaderfeeder jobs", func(t *testing.T) { + ctx := testutils.Context(t) bhsJob, err := blockheaderfeeder.ValidatedSpec( testspecs.GenerateBlockHeaderFeederSpec(testspecs.BlockHeaderFeederSpecParams{}).Toml()) require.NoError(t, err) - err = orm.CreateJob(&bhsJob) + err = orm.CreateJob(ctx, &bhsJob) require.NoError(t, err) savedJob, err := orm.FindJob(testutils.Context(t), bhsJob.ID) require.NoError(t, err) @@ -329,7 +336,7 @@ func TestORM(t *testing.T) { require.Equal(t, bhsJob.BlockHeaderFeederSpec.FromAddresses, savedJob.BlockHeaderFeederSpec.FromAddresses) require.Equal(t, bhsJob.BlockHeaderFeederSpec.GetBlockhashesBatchSize, savedJob.BlockHeaderFeederSpec.GetBlockhashesBatchSize) require.Equal(t, bhsJob.BlockHeaderFeederSpec.StoreBlockhashesBatchSize, savedJob.BlockHeaderFeederSpec.StoreBlockhashesBatchSize) - err = orm.DeleteJob(bhsJob.ID) + err = orm.DeleteJob(ctx, bhsJob.ID) require.NoError(t, err) _, err = orm.FindJob(testutils.Context(t), bhsJob.ID) require.Error(t, err) @@ -349,10 +356,11 @@ func TestORM_DeleteJob_DeletesAssociatedRecords(t *testing.T) { lggr := logger.TestLogger(t) pipelineORM := pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db) - jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database()) + jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore) korm := keeper.NewORM(db, logger.TestLogger(t)) t.Run("it deletes records for offchainreporting jobs", func(t *testing.T) { + ctx := testutils.Context(t) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}) _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}) @@ -366,13 +374,13 @@ func TestORM_DeleteJob_DeletesAssociatedRecords(t *testing.T) { }).Toml()) require.NoError(t, err) - err = jobORM.CreateJob(&jb) + err = jobORM.CreateJob(ctx, &jb) require.NoError(t, err) cltest.AssertCount(t, db, "ocr_oracle_specs", 1) cltest.AssertCount(t, db, "pipeline_specs", 1) - err = jobORM.DeleteJob(jb.ID) + err = jobORM.DeleteJob(ctx, jb.ID) require.NoError(t, err) cltest.AssertCount(t, db, "ocr_oracle_specs", 0) cltest.AssertCount(t, db, "pipeline_specs", 0) @@ -380,6 +388,7 @@ func TestORM_DeleteJob_DeletesAssociatedRecords(t *testing.T) { }) t.Run("it deletes records for keeper jobs", func(t *testing.T) { + ctx := testutils.Context(t) registry, keeperJob := cltest.MustInsertKeeperRegistry(t, db, korm, keyStore.Eth(), 0, 1, 20) cltest.MustInsertUpkeepForRegistry(t, db, registry) @@ -387,7 +396,7 @@ func TestORM_DeleteJob_DeletesAssociatedRecords(t *testing.T) { cltest.AssertCount(t, db, "keeper_registries", 1) cltest.AssertCount(t, db, "upkeep_registrations", 1) - err := jobORM.DeleteJob(keeperJob.ID) + err := jobORM.DeleteJob(ctx, keeperJob.ID) require.NoError(t, err) cltest.AssertCount(t, db, "keeper_specs", 0) cltest.AssertCount(t, db, "keeper_registries", 0) @@ -396,29 +405,31 @@ func TestORM_DeleteJob_DeletesAssociatedRecords(t *testing.T) { }) t.Run("it creates and deletes records for vrf jobs", func(t *testing.T) { - key, err := keyStore.VRF().Create(testutils.Context(t)) + ctx := testutils.Context(t) + key, err := keyStore.VRF().Create(ctx) require.NoError(t, err) pk := key.PublicKey jb, err := vrfcommon.ValidatedVRFSpec(testspecs.GenerateVRFSpec(testspecs.VRFSpecParams{PublicKey: pk.String()}).Toml()) require.NoError(t, err) - err = jobORM.CreateJob(&jb) + err = jobORM.CreateJob(ctx, &jb) require.NoError(t, err) cltest.AssertCount(t, db, "vrf_specs", 1) cltest.AssertCount(t, db, "jobs", 1) - err = jobORM.DeleteJob(jb.ID) + err = jobORM.DeleteJob(ctx, jb.ID) require.NoError(t, err) cltest.AssertCount(t, db, "vrf_specs", 0) cltest.AssertCount(t, db, "jobs", 0) }) t.Run("it deletes records for webhook jobs", func(t *testing.T) { + ctx := testutils.Context(t) ei := cltest.MustInsertExternalInitiator(t, bridges.NewORM(db)) jb, webhookSpec := cltest.MustInsertWebhookSpec(t, db) _, err := db.Exec(`INSERT INTO external_initiator_webhook_specs (external_initiator_id, webhook_spec_id, spec) VALUES ($1,$2,$3)`, ei.ID, webhookSpec.ID, `{"ei": "foo", "name": "webhookSpecTwoEIs"}`) require.NoError(t, err) - err = jobORM.DeleteJob(jb.ID) + err = jobORM.DeleteJob(ctx, jb.ID) require.NoError(t, err) cltest.AssertCount(t, db, "webhook_specs", 0) cltest.AssertCount(t, db, "external_initiator_webhook_specs", 0) @@ -449,7 +460,7 @@ func TestORM_CreateJob_VRFV2(t *testing.T) { pipelineORM := pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db) - jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database()) + jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore) fromAddresses := []string{cltest.NewEIP55Address().String(), cltest.NewEIP55Address().String()} jb, err := vrfcommon.ValidatedVRFSpec(testspecs.GenerateVRFSpec( @@ -465,7 +476,7 @@ func TestORM_CreateJob_VRFV2(t *testing.T) { Toml()) require.NoError(t, err) - require.NoError(t, jobORM.CreateJob(&jb)) + require.NoError(t, jobORM.CreateJob(ctx, &jb)) cltest.AssertCount(t, db, "vrf_specs", 1) cltest.AssertCount(t, db, "jobs", 1) var requestedConfsDelay int64 @@ -505,20 +516,20 @@ func TestORM_CreateJob_VRFV2(t *testing.T) { var vrfOwnerAddress evmtypes.EIP55Address require.NoError(t, db.Get(&vrfOwnerAddress, `SELECT vrf_owner_address FROM vrf_specs LIMIT 1`)) require.Equal(t, "0x32891BD79647DC9136Fc0a59AAB48c7825eb624c", vrfOwnerAddress.Address().String()) - require.NoError(t, jobORM.DeleteJob(jb.ID)) + require.NoError(t, jobORM.DeleteJob(ctx, jb.ID)) cltest.AssertCount(t, db, "vrf_specs", 0) cltest.AssertCount(t, db, "jobs", 0) jb, err = vrfcommon.ValidatedVRFSpec(testspecs.GenerateVRFSpec(testspecs.VRFSpecParams{RequestTimeout: 1 * time.Hour}).Toml()) require.NoError(t, err) - require.NoError(t, jobORM.CreateJob(&jb)) + require.NoError(t, jobORM.CreateJob(ctx, &jb)) cltest.AssertCount(t, db, "vrf_specs", 1) cltest.AssertCount(t, db, "jobs", 1) require.NoError(t, db.Get(&requestedConfsDelay, `SELECT requested_confs_delay FROM vrf_specs LIMIT 1`)) require.Equal(t, int64(0), requestedConfsDelay) require.NoError(t, db.Get(&requestTimeout, `SELECT request_timeout FROM vrf_specs LIMIT 1`)) require.Equal(t, 1*time.Hour, requestTimeout) - require.NoError(t, jobORM.DeleteJob(jb.ID)) + require.NoError(t, jobORM.DeleteJob(ctx, jb.ID)) cltest.AssertCount(t, db, "vrf_specs", 0) cltest.AssertCount(t, db, "jobs", 0) } @@ -533,7 +544,7 @@ func TestORM_CreateJob_VRFV2Plus(t *testing.T) { lggr := logger.TestLogger(t) pipelineORM := pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db) - jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database()) + jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore) fromAddresses := []string{cltest.NewEIP55Address().String(), cltest.NewEIP55Address().String()} jb, err := vrfcommon.ValidatedVRFSpec(testspecs.GenerateVRFSpec( @@ -550,7 +561,7 @@ func TestORM_CreateJob_VRFV2Plus(t *testing.T) { Toml()) require.NoError(t, err) - require.NoError(t, jobORM.CreateJob(&jb)) + require.NoError(t, jobORM.CreateJob(ctx, &jb)) cltest.AssertCount(t, db, "vrf_specs", 1) cltest.AssertCount(t, db, "jobs", 1) var requestedConfsDelay int64 @@ -589,7 +600,7 @@ func TestORM_CreateJob_VRFV2Plus(t *testing.T) { require.ElementsMatch(t, fromAddresses, actual) var vrfOwnerAddress evmtypes.EIP55Address require.Error(t, db.Get(&vrfOwnerAddress, `SELECT vrf_owner_address FROM vrf_specs LIMIT 1`)) - require.NoError(t, jobORM.DeleteJob(jb.ID)) + require.NoError(t, jobORM.DeleteJob(ctx, jb.ID)) cltest.AssertCount(t, db, "vrf_specs", 0) cltest.AssertCount(t, db, "jobs", 0) @@ -599,14 +610,14 @@ func TestORM_CreateJob_VRFV2Plus(t *testing.T) { FromAddresses: fromAddresses, }).Toml()) require.NoError(t, err) - require.NoError(t, jobORM.CreateJob(&jb)) + require.NoError(t, jobORM.CreateJob(ctx, &jb)) cltest.AssertCount(t, db, "vrf_specs", 1) cltest.AssertCount(t, db, "jobs", 1) require.NoError(t, db.Get(&requestedConfsDelay, `SELECT requested_confs_delay FROM vrf_specs LIMIT 1`)) require.Equal(t, int64(0), requestedConfsDelay) require.NoError(t, db.Get(&requestTimeout, `SELECT request_timeout FROM vrf_specs LIMIT 1`)) require.Equal(t, 1*time.Hour, requestTimeout) - require.NoError(t, jobORM.DeleteJob(jb.ID)) + require.NoError(t, jobORM.DeleteJob(ctx, jb.ID)) cltest.AssertCount(t, db, "vrf_specs", 0) cltest.AssertCount(t, db, "jobs", 0) } @@ -621,12 +632,12 @@ func TestORM_CreateJob_OCRBootstrap(t *testing.T) { lggr := logger.TestLogger(t) pipelineORM := pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db) - jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database()) + jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore) jb, err := ocrbootstrap.ValidatedBootstrapSpecToml(testspecs.GetOCRBootstrapSpec()) require.NoError(t, err) - err = jobORM.CreateJob(&jb) + err = jobORM.CreateJob(ctx, &jb) require.NoError(t, err) cltest.AssertCount(t, db, "bootstrap_specs", 1) cltest.AssertCount(t, db, "jobs", 1) @@ -634,7 +645,7 @@ func TestORM_CreateJob_OCRBootstrap(t *testing.T) { require.NoError(t, db.Get(&relay, `SELECT relay FROM bootstrap_specs LIMIT 1`)) require.Equal(t, "evm", relay) - require.NoError(t, jobORM.DeleteJob(jb.ID)) + require.NoError(t, jobORM.DeleteJob(ctx, jb.ID)) cltest.AssertCount(t, db, "bootstrap_specs", 0) cltest.AssertCount(t, db, "jobs", 0) } @@ -648,14 +659,14 @@ func TestORM_CreateJob_EVMChainID_Validation(t *testing.T) { pipelineORM := pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db) - jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database()) + jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore) t.Run("evm chain id validation for ocr works", func(t *testing.T) { jb := job.Job{ Type: job.OffchainReporting, OCROracleSpec: &job.OCROracleSpec{}, } - assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(&jb).Error()) + assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(testutils.Context(t), &jb).Error()) }) t.Run("evm chain id validation for direct request works", func(t *testing.T) { @@ -663,7 +674,7 @@ func TestORM_CreateJob_EVMChainID_Validation(t *testing.T) { Type: job.DirectRequest, DirectRequestSpec: &job.DirectRequestSpec{}, } - assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(&jb).Error()) + assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(testutils.Context(t), &jb).Error()) }) t.Run("evm chain id validation for flux monitor works", func(t *testing.T) { @@ -671,7 +682,7 @@ func TestORM_CreateJob_EVMChainID_Validation(t *testing.T) { Type: job.FluxMonitor, FluxMonitorSpec: &job.FluxMonitorSpec{}, } - assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(&jb).Error()) + assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(testutils.Context(t), &jb).Error()) }) t.Run("evm chain id validation for keepers works", func(t *testing.T) { @@ -679,7 +690,7 @@ func TestORM_CreateJob_EVMChainID_Validation(t *testing.T) { Type: job.Keeper, KeeperSpec: &job.KeeperSpec{}, } - assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(&jb).Error()) + assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(testutils.Context(t), &jb).Error()) }) t.Run("evm chain id validation for vrf works", func(t *testing.T) { @@ -687,7 +698,7 @@ func TestORM_CreateJob_EVMChainID_Validation(t *testing.T) { Type: job.VRF, VRFSpec: &job.VRFSpec{}, } - assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(&jb).Error()) + assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(testutils.Context(t), &jb).Error()) }) t.Run("evm chain id validation for block hash store works", func(t *testing.T) { @@ -695,7 +706,7 @@ func TestORM_CreateJob_EVMChainID_Validation(t *testing.T) { Type: job.BlockhashStore, BlockhashStoreSpec: &job.BlockhashStoreSpec{}, } - assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(&jb).Error()) + assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(testutils.Context(t), &jb).Error()) }) t.Run("evm chain id validation for block header feeder works", func(t *testing.T) { @@ -703,7 +714,7 @@ func TestORM_CreateJob_EVMChainID_Validation(t *testing.T) { Type: job.BlockHeaderFeeder, BlockHeaderFeederSpec: &job.BlockHeaderFeederSpec{}, } - assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(&jb).Error()) + assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(testutils.Context(t), &jb).Error()) }) t.Run("evm chain id validation for legacy gas station server spec works", func(t *testing.T) { @@ -711,7 +722,7 @@ func TestORM_CreateJob_EVMChainID_Validation(t *testing.T) { Type: job.LegacyGasStationServer, LegacyGasStationServerSpec: &job.LegacyGasStationServerSpec{}, } - assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(&jb).Error()) + assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(testutils.Context(t), &jb).Error()) }) t.Run("evm chain id validation for legacy gas station sidecar spec works", func(t *testing.T) { @@ -719,7 +730,7 @@ func TestORM_CreateJob_EVMChainID_Validation(t *testing.T) { Type: job.LegacyGasStationSidecar, LegacyGasStationSidecarSpec: &job.LegacyGasStationSidecarSpec{}, } - assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(&jb).Error()) + assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(testutils.Context(t), &jb).Error()) }) } @@ -744,7 +755,7 @@ func TestORM_CreateJob_OCR_DuplicatedContractAddress(t *testing.T) { pipelineORM := pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db) - jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database()) + jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore) // defaultChainID is deprecated defaultChainID := customChainID @@ -768,7 +779,8 @@ func TestORM_CreateJob_OCR_DuplicatedContractAddress(t *testing.T) { require.NoError(t, err) t.Run("with a set chain id", func(t *testing.T) { - err = jobORM.CreateJob(&jb) // Add job with custom chain id + ctx := testutils.Context(t) + err = jobORM.CreateJob(ctx, &jb) // Add job with custom chain id require.NoError(t, err) cltest.AssertCount(t, db, "ocr_oracle_specs", 1) @@ -778,7 +790,7 @@ func TestORM_CreateJob_OCR_DuplicatedContractAddress(t *testing.T) { spec.JobID = externalJobID.UUID.String() jba, err := ocr.ValidatedOracleSpecToml(config, legacyChains, spec.Toml()) require.NoError(t, err) - err = jobORM.CreateJob(&jba) // Try to add duplicate job with default id + err = jobORM.CreateJob(ctx, &jba) // Try to add duplicate job with default id require.Error(t, err) assert.Equal(t, fmt.Sprintf("CreateJobFailed: a job with contract address %s already exists for chain ID %s", jb.OCROracleSpec.ContractAddress, defaultChainID.String()), err.Error()) @@ -787,7 +799,7 @@ func TestORM_CreateJob_OCR_DuplicatedContractAddress(t *testing.T) { jb2, err := ocr.ValidatedOracleSpecToml(config, legacyChains, spec.Toml()) require.NoError(t, err) - err = jobORM.CreateJob(&jb2) // Try to add duplicate job with custom id + err = jobORM.CreateJob(ctx, &jb2) // Try to add duplicate job with custom id require.Error(t, err) assert.Equal(t, fmt.Sprintf("CreateJobFailed: a job with contract address %s already exists for chain ID %s", jb2.OCROracleSpec.ContractAddress, customChainID), err.Error()) }) @@ -814,7 +826,7 @@ func TestORM_CreateJob_OCR2_DuplicatedContractAddress(t *testing.T) { pipelineORM := pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db) - jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database()) + jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore) _, address := cltest.MustInsertRandomKey(t, keyStore.Eth()) @@ -831,7 +843,7 @@ func TestORM_CreateJob_OCR2_DuplicatedContractAddress(t *testing.T) { jb.OCR2OracleSpec.TransmitterID = null.StringFrom(address.String()) jb.OCR2OracleSpec.PluginConfig["juelsPerFeeCoinSource"] = juelsPerFeeCoinSource - err = jobORM.CreateJob(&jb) + err = jobORM.CreateJob(ctx, &jb) require.NoError(t, err) jb2, err := ocr2validate.ValidatedOracleSpecToml(testutils.Context(t), config.OCR2(), config.Insecure(), testspecs.GetOCR2EVMSpecMinimal(), nil) @@ -841,7 +853,7 @@ func TestORM_CreateJob_OCR2_DuplicatedContractAddress(t *testing.T) { jb2.OCR2OracleSpec.TransmitterID = null.StringFrom(address.String()) jb.OCR2OracleSpec.PluginConfig["juelsPerFeeCoinSource"] = juelsPerFeeCoinSource - err = jobORM.CreateJob(&jb2) + err = jobORM.CreateJob(ctx, &jb2) require.Error(t, err) jb3, err := ocr2validate.ValidatedOracleSpecToml(testutils.Context(t), config.OCR2(), config.Insecure(), testspecs.GetOCR2EVMSpecMinimal(), nil) @@ -851,7 +863,7 @@ func TestORM_CreateJob_OCR2_DuplicatedContractAddress(t *testing.T) { jb3.OCR2OracleSpec.RelayConfig["chainID"] = customChainID.Int64() jb.OCR2OracleSpec.PluginConfig["juelsPerFeeCoinSource"] = juelsPerFeeCoinSource - err = jobORM.CreateJob(&jb3) + err = jobORM.CreateJob(ctx, &jb3) require.Error(t, err) } @@ -876,37 +888,41 @@ func TestORM_CreateJob_OCR2_Sending_Keys_Transmitter_Keys_Validations(t *testing pipelineORM := pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db) - jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database()) + jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore) jb, err := ocr2validate.ValidatedOracleSpecToml(testutils.Context(t), config.OCR2(), config.Insecure(), testspecs.GetOCR2EVMSpecMinimal(), nil) require.NoError(t, err) t.Run("sending keys or transmitterID must be defined", func(t *testing.T) { + ctx := testutils.Context(t) jb.OCR2OracleSpec.TransmitterID = null.String{} - assert.Equal(t, "CreateJobFailed: neither sending keys nor transmitter ID is defined", jobORM.CreateJob(&jb).Error()) + assert.Equal(t, "CreateJobFailed: neither sending keys nor transmitter ID is defined", jobORM.CreateJob(ctx, &jb).Error()) }) _, address := cltest.MustInsertRandomKey(t, keyStore.Eth()) t.Run("sending keys validation works properly", func(t *testing.T) { + ctx := testutils.Context(t) jb.OCR2OracleSpec.TransmitterID = null.String{} _, address2 := cltest.MustInsertRandomKey(t, keyStore.Eth()) jb.OCR2OracleSpec.RelayConfig["sendingKeys"] = interface{}([]any{address.String(), address2.String(), common.HexToAddress("0X0").String()}) - assert.Equal(t, "CreateJobFailed: no EVM key matching: \"0x0000000000000000000000000000000000000000\": no such sending key exists", jobORM.CreateJob(&jb).Error()) + assert.Equal(t, "CreateJobFailed: no EVM key matching: \"0x0000000000000000000000000000000000000000\": no such sending key exists", jobORM.CreateJob(ctx, &jb).Error()) jb.OCR2OracleSpec.RelayConfig["sendingKeys"] = interface{}([]any{1, 2, 3}) - assert.Equal(t, "CreateJobFailed: sending keys are of wrong type", jobORM.CreateJob(&jb).Error()) + assert.Equal(t, "CreateJobFailed: sending keys are of wrong type", jobORM.CreateJob(ctx, &jb).Error()) }) t.Run("sending keys and transmitter ID can't both be defined", func(t *testing.T) { + ctx := testutils.Context(t) jb.OCR2OracleSpec.TransmitterID = null.StringFrom(address.String()) jb.OCR2OracleSpec.RelayConfig["sendingKeys"] = interface{}([]any{address.String()}) - assert.Equal(t, "CreateJobFailed: sending keys and transmitter ID can't both be defined", jobORM.CreateJob(&jb).Error()) + assert.Equal(t, "CreateJobFailed: sending keys and transmitter ID can't both be defined", jobORM.CreateJob(ctx, &jb).Error()) }) t.Run("transmitter validation works", func(t *testing.T) { + ctx := testutils.Context(t) jb.OCR2OracleSpec.TransmitterID = null.StringFrom("transmitterID that doesn't have a match in key store") jb.OCR2OracleSpec.RelayConfig["sendingKeys"] = nil - assert.Equal(t, "CreateJobFailed: no EVM key matching: \"transmitterID that doesn't have a match in key store\": no such transmitter key exists", jobORM.CreateJob(&jb).Error()) + assert.Equal(t, "CreateJobFailed: no EVM key matching: \"transmitterID that doesn't have a match in key store\": no such transmitter key exists", jobORM.CreateJob(ctx, &jb).Error()) }) } @@ -998,7 +1014,7 @@ func Test_FindJobs(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db) - orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database()) + orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}) _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}) @@ -1016,7 +1032,7 @@ func Test_FindJobs(t *testing.T) { ) require.NoError(t, err) - err = orm.CreateJob(&jb1) + err = orm.CreateJob(ctx, &jb1) require.NoError(t, err) jb2, err := directrequest.ValidatedDirectRequestSpec( @@ -1024,11 +1040,11 @@ func Test_FindJobs(t *testing.T) { ) require.NoError(t, err) - err = orm.CreateJob(&jb2) + err = orm.CreateJob(ctx, &jb2) require.NoError(t, err) t.Run("jobs are ordered by latest first", func(t *testing.T) { - jobs, count, err2 := orm.FindJobs(0, 2) + jobs, count, err2 := orm.FindJobs(testutils.Context(t), 0, 2) require.NoError(t, err2) require.Len(t, jobs, 2) assert.Equal(t, count, 2) @@ -1041,7 +1057,7 @@ func Test_FindJobs(t *testing.T) { }) t.Run("jobs respect pagination", func(t *testing.T) { - jobs, count, err2 := orm.FindJobs(0, 1) + jobs, count, err2 := orm.FindJobs(testutils.Context(t), 0, 1) require.NoError(t, err2) require.Len(t, jobs, 1) assert.Equal(t, count, 2) @@ -1080,7 +1096,7 @@ func Test_FindJob(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db) - orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database()) + orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}) _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}) @@ -1148,20 +1164,20 @@ func Test_FindJob(t *testing.T) { jobOCR2WithFeedID2.Name = null.StringFrom("new name") require.NoError(t, err) - err = orm.CreateJob(&job) + err = orm.CreateJob(ctx, &job) require.NoError(t, err) - err = orm.CreateJob(&jobSameAddress) + err = orm.CreateJob(ctx, &jobSameAddress) require.NoError(t, err) - err = orm.CreateJob(&jobOCR2) + err = orm.CreateJob(ctx, &jobOCR2) require.NoError(t, err) - err = orm.CreateJob(&jobOCR2WithFeedID1) + err = orm.CreateJob(ctx, &jobOCR2WithFeedID1) require.NoError(t, err) // second ocr2 job with same contract id but different feed id - err = orm.CreateJob(&jobOCR2WithFeedID2) + err = orm.CreateJob(ctx, &jobOCR2WithFeedID2) require.NoError(t, err) t.Run("by id", func(t *testing.T) { @@ -1180,7 +1196,8 @@ func Test_FindJob(t *testing.T) { }) t.Run("by external job id", func(t *testing.T) { - jb, err2 := orm.FindJobByExternalJobID(externalJobID) + ctx := testutils.Context(t) + jb, err2 := orm.FindJobByExternalJobID(ctx, externalJobID) require.NoError(t, err2) assert.Equal(t, jb.ID, job.ID) @@ -1193,59 +1210,64 @@ func Test_FindJob(t *testing.T) { }) t.Run("by address", func(t *testing.T) { - jbID, err2 := orm.FindJobIDByAddress(job.OCROracleSpec.ContractAddress, job.OCROracleSpec.EVMChainID) + ctx := testutils.Context(t) + jbID, err2 := orm.FindJobIDByAddress(ctx, job.OCROracleSpec.ContractAddress, job.OCROracleSpec.EVMChainID) require.NoError(t, err2) assert.Equal(t, job.ID, jbID) - _, err2 = orm.FindJobIDByAddress("not-existing", big.NewI(0)) + _, err2 = orm.FindJobIDByAddress(ctx, "not-existing", big.NewI(0)) require.Error(t, err2) require.ErrorIs(t, err2, sql.ErrNoRows) }) t.Run("by address yet chain scoped", func(t *testing.T) { + ctx := testutils.Context(t) commonAddr := jobSameAddress.OCROracleSpec.ContractAddress // Find job ID for job on chain 1337 with common address. - jbID, err2 := orm.FindJobIDByAddress(commonAddr, jobSameAddress.OCROracleSpec.EVMChainID) + jbID, err2 := orm.FindJobIDByAddress(ctx, commonAddr, jobSameAddress.OCROracleSpec.EVMChainID) require.NoError(t, err2) assert.Equal(t, jobSameAddress.ID, jbID) // Find job ID for job on default evm chain with common address. - jbID, err2 = orm.FindJobIDByAddress(commonAddr, job.OCROracleSpec.EVMChainID) + jbID, err2 = orm.FindJobIDByAddress(ctx, commonAddr, job.OCROracleSpec.EVMChainID) require.NoError(t, err2) assert.Equal(t, job.ID, jbID) }) t.Run("by contract id without feed id", func(t *testing.T) { + ctx := testutils.Context(t) contractID := "0x613a38AC1659769640aaE063C651F48E0250454C" // Find job ID for ocr2 job without feedID. - jbID, err2 := orm.FindOCR2JobIDByAddress(contractID, nil) + jbID, err2 := orm.FindOCR2JobIDByAddress(ctx, contractID, nil) require.NoError(t, err2) assert.Equal(t, jobOCR2.ID, jbID) }) t.Run("by contract id with valid feed id", func(t *testing.T) { + ctx := testutils.Context(t) contractID := "0x0000000000000000000000000000000000000006" feedID := common.HexToHash(ocr2WithFeedID1) // Find job ID for ocr2 job with feed ID - jbID, err2 := orm.FindOCR2JobIDByAddress(contractID, &feedID) + jbID, err2 := orm.FindOCR2JobIDByAddress(ctx, contractID, &feedID) require.NoError(t, err2) assert.Equal(t, jobOCR2WithFeedID1.ID, jbID) }) t.Run("with duplicate contract id but different feed id", func(t *testing.T) { + ctx := testutils.Context(t) contractID := "0x0000000000000000000000000000000000000006" feedID := common.HexToHash(ocr2WithFeedID2) // Find job ID for ocr2 job with feed ID - jbID, err2 := orm.FindOCR2JobIDByAddress(contractID, &feedID) + jbID, err2 := orm.FindOCR2JobIDByAddress(ctx, contractID, &feedID) require.NoError(t, err2) assert.Equal(t, jobOCR2WithFeedID2.ID, jbID) @@ -1263,17 +1285,18 @@ func Test_FindJobsByPipelineSpecIDs(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db) - orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database()) + orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore) jb, err := directrequest.ValidatedDirectRequestSpec(testspecs.GetDirectRequestSpec()) require.NoError(t, err) jb.DirectRequestSpec.EVMChainID = big.NewI(0) - err = orm.CreateJob(&jb) + err = orm.CreateJob(testutils.Context(t), &jb) require.NoError(t, err) t.Run("with jobs", func(t *testing.T) { - jbs, err2 := orm.FindJobsByPipelineSpecIDs([]int32{jb.PipelineSpecID}) + ctx := testutils.Context(t) + jbs, err2 := orm.FindJobsByPipelineSpecIDs(ctx, []int32{jb.PipelineSpecID}) require.NoError(t, err2) assert.Len(t, jbs, 1) @@ -1286,15 +1309,17 @@ func Test_FindJobsByPipelineSpecIDs(t *testing.T) { }) t.Run("without jobs", func(t *testing.T) { - jbs, err2 := orm.FindJobsByPipelineSpecIDs([]int32{-1}) + ctx := testutils.Context(t) + jbs, err2 := orm.FindJobsByPipelineSpecIDs(ctx, []int32{-1}) require.NoError(t, err2) assert.Len(t, jbs, 0) }) t.Run("with chainID disabled", func(t *testing.T) { - orm2 := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database()) + ctx := testutils.Context(t) + orm2 := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore) - jbs, err2 := orm2.FindJobsByPipelineSpecIDs([]int32{jb.PipelineSpecID}) + jbs, err2 := orm2.FindJobsByPipelineSpecIDs(ctx, []int32{jb.PipelineSpecID}) require.NoError(t, err2) assert.Len(t, jbs, 1) }) @@ -1314,7 +1339,7 @@ func Test_FindPipelineRuns(t *testing.T) { bridgesORM := bridges.NewORM(db) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database()) + orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}) _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}) @@ -1331,20 +1356,22 @@ func Test_FindPipelineRuns(t *testing.T) { ) require.NoError(t, err) - err = orm.CreateJob(&jb) + err = orm.CreateJob(testutils.Context(t), &jb) require.NoError(t, err) t.Run("with no pipeline runs", func(t *testing.T) { - runs, count, err2 := orm.PipelineRuns(nil, 0, 10) + ctx := testutils.Context(t) + runs, count, err2 := orm.PipelineRuns(ctx, nil, 0, 10) require.NoError(t, err2) assert.Equal(t, count, 0) assert.Empty(t, runs) }) t.Run("with a pipeline run", func(t *testing.T) { + ctx := testutils.Context(t) run := mustInsertPipelineRun(t, pipelineORM, jb) - runs, count, err2 := orm.PipelineRuns(nil, 0, 10) + runs, count, err2 := orm.PipelineRuns(ctx, nil, 0, 10) require.NoError(t, err2) assert.Equal(t, count, 1) @@ -1376,7 +1403,7 @@ func Test_PipelineRunsByJobID(t *testing.T) { bridgesORM := bridges.NewORM(db) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database()) + orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}) _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}) @@ -1393,20 +1420,22 @@ func Test_PipelineRunsByJobID(t *testing.T) { ) require.NoError(t, err) - err = orm.CreateJob(&jb) + err = orm.CreateJob(testutils.Context(t), &jb) require.NoError(t, err) t.Run("with no pipeline runs", func(t *testing.T) { - runs, count, err2 := orm.PipelineRuns(&jb.ID, 0, 10) + ctx := testutils.Context(t) + runs, count, err2 := orm.PipelineRuns(ctx, &jb.ID, 0, 10) require.NoError(t, err2) assert.Equal(t, count, 0) assert.Empty(t, runs) }) t.Run("with a pipeline run", func(t *testing.T) { + ctx := testutils.Context(t) run := mustInsertPipelineRun(t, pipelineORM, jb) - runs, count, err2 := orm.PipelineRuns(&jb.ID, 0, 10) + runs, count, err2 := orm.PipelineRuns(ctx, &jb.ID, 0, 10) require.NoError(t, err2) assert.Equal(t, 1, count) @@ -1437,7 +1466,7 @@ func Test_FindPipelineRunIDsByJobID(t *testing.T) { bridgesORM := bridges.NewORM(db) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database()) + orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore) _, address := cltest.MustInsertRandomKey(t, keyStore.Eth()) @@ -1461,7 +1490,7 @@ func Test_FindPipelineRunIDsByJobID(t *testing.T) { require.NoError(t, err) - err = orm.CreateJob(&jb) + err = orm.CreateJob(testutils.Context(t), &jb) require.NoError(t, err) jobs[j] = jb } @@ -1475,15 +1504,17 @@ func Test_FindPipelineRunIDsByJobID(t *testing.T) { } t.Run("with no pipeline runs", func(t *testing.T) { - runIDs, err := orm.FindPipelineRunIDsByJobID(jb.ID, 0, 10) + ctx := testutils.Context(t) + runIDs, err := orm.FindPipelineRunIDsByJobID(ctx, jb.ID, 0, 10) require.NoError(t, err) assert.Empty(t, runIDs) }) t.Run("with a pipeline run", func(t *testing.T) { + ctx := testutils.Context(t) run := mustInsertPipelineRun(t, pipelineORM, jb) - runIDs, err := orm.FindPipelineRunIDsByJobID(jb.ID, 0, 10) + runIDs, err := orm.FindPipelineRunIDsByJobID(ctx, jb.ID, 0, 10) require.NoError(t, err) require.Len(t, runIDs, 1) @@ -1493,7 +1524,8 @@ func Test_FindPipelineRunIDsByJobID(t *testing.T) { // Internally these queries are batched by 1000, this tests case requiring concatenation // of more than 1 batch t.Run("with batch concatenation limit 10", func(t *testing.T) { - runIDs, err := orm.FindPipelineRunIDsByJobID(jobs[3].ID, 95, 10) + ctx := testutils.Context(t) + runIDs, err := orm.FindPipelineRunIDsByJobID(ctx, jobs[3].ID, 95, 10) require.NoError(t, err) require.Len(t, runIDs, 10) assert.Equal(t, int64(4*(len(jobs)-1)), runIDs[3]-runIDs[7]) @@ -1502,7 +1534,8 @@ func Test_FindPipelineRunIDsByJobID(t *testing.T) { // Internally these queries are batched by 1000, this tests case requiring concatenation // of more than 1 batch t.Run("with batch concatenation limit 100", func(t *testing.T) { - runIDs, err := orm.FindPipelineRunIDsByJobID(jobs[3].ID, 95, 100) + ctx := testutils.Context(t) + runIDs, err := orm.FindPipelineRunIDsByJobID(ctx, jobs[3].ID, 95, 100) require.NoError(t, err) require.Len(t, runIDs, 100) assert.Equal(t, int64(67*(len(jobs)-1)), runIDs[12]-runIDs[79]) @@ -1516,7 +1549,8 @@ func Test_FindPipelineRunIDsByJobID(t *testing.T) { // returns empty. This can happen if the job id being requested hasn't run in a while, // but many other jobs have run since. t.Run("with first batch empty, over limit", func(t *testing.T) { - runIDs, err := orm.FindPipelineRunIDsByJobID(jobs[3].ID, 0, 25) + ctx := testutils.Context(t) + runIDs, err := orm.FindPipelineRunIDsByJobID(ctx, jobs[3].ID, 0, 25) require.NoError(t, err) require.Len(t, runIDs, 25) assert.Equal(t, int64(16*(len(jobs)-1)), runIDs[7]-runIDs[23]) @@ -1524,7 +1558,8 @@ func Test_FindPipelineRunIDsByJobID(t *testing.T) { // Same as previous, but where there are fewer matching jobs than the limit t.Run("with first batch empty, under limit", func(t *testing.T) { - runIDs, err := orm.FindPipelineRunIDsByJobID(jobs[3].ID, 143, 190) + ctx := testutils.Context(t) + runIDs, err := orm.FindPipelineRunIDsByJobID(ctx, jobs[3].ID, 143, 190) require.NoError(t, err) require.Len(t, runIDs, 107) assert.Equal(t, int64(16*(len(jobs)-1)), runIDs[7]-runIDs[23]) @@ -1546,7 +1581,7 @@ func Test_FindPipelineRunsByIDs(t *testing.T) { bridgesORM := bridges.NewORM(db) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database()) + orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}) _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}) @@ -1563,19 +1598,21 @@ func Test_FindPipelineRunsByIDs(t *testing.T) { ) require.NoError(t, err) - err = orm.CreateJob(&jb) + err = orm.CreateJob(testutils.Context(t), &jb) require.NoError(t, err) t.Run("with no pipeline runs", func(t *testing.T) { - runs, err2 := orm.FindPipelineRunsByIDs([]int64{-1}) + ctx := testutils.Context(t) + runs, err2 := orm.FindPipelineRunsByIDs(ctx, []int64{-1}) require.NoError(t, err2) assert.Empty(t, runs) }) t.Run("with a pipeline run", func(t *testing.T) { + ctx := testutils.Context(t) run := mustInsertPipelineRun(t, pipelineORM, jb) - actual, err2 := orm.FindPipelineRunsByIDs([]int64{run.ID}) + actual, err2 := orm.FindPipelineRunsByIDs(ctx, []int64{run.ID}) require.NoError(t, err2) require.Len(t, actual, 1) @@ -1603,24 +1640,26 @@ func Test_FindPipelineRunByID(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db) - orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database()) + orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore) jb, err := directrequest.ValidatedDirectRequestSpec(testspecs.GetDirectRequestSpec()) require.NoError(t, err) - err = orm.CreateJob(&jb) + err = orm.CreateJob(testutils.Context(t), &jb) require.NoError(t, err) t.Run("with no pipeline run", func(t *testing.T) { - run, err2 := orm.FindPipelineRunByID(-1) + ctx := testutils.Context(t) + run, err2 := orm.FindPipelineRunByID(ctx, -1) assert.Equal(t, run, pipeline.Run{}) require.ErrorIs(t, err2, sql.ErrNoRows) }) t.Run("with a pipeline run", func(t *testing.T) { + ctx := testutils.Context(t) run := mustInsertPipelineRun(t, pipelineORM, jb) - actual, err2 := orm.FindPipelineRunByID(run.ID) + actual, err2 := orm.FindPipelineRunByID(ctx, run.ID) require.NoError(t, err2) actualRun := actual @@ -1647,12 +1686,12 @@ func Test_FindJobWithoutSpecErrors(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db) - orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database()) + orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore) jb, err := directrequest.ValidatedDirectRequestSpec(testspecs.GetDirectRequestSpec()) require.NoError(t, err) - err = orm.CreateJob(&jb) + err = orm.CreateJob(ctx, &jb) require.NoError(t, err) var jobSpec job.Job err = db.Get(&jobSpec, "SELECT * FROM jobs") @@ -1660,10 +1699,10 @@ func Test_FindJobWithoutSpecErrors(t *testing.T) { ocrSpecError1 := "ocr spec 1 errored" ocrSpecError2 := "ocr spec 2 errored" - require.NoError(t, orm.RecordError(jobSpec.ID, ocrSpecError1)) - require.NoError(t, orm.RecordError(jobSpec.ID, ocrSpecError2)) + require.NoError(t, orm.RecordError(ctx, jobSpec.ID, ocrSpecError1)) + require.NoError(t, orm.RecordError(ctx, jobSpec.ID, ocrSpecError2)) - jb, err = orm.FindJobWithoutSpecErrors(jobSpec.ID) + jb, err = orm.FindJobWithoutSpecErrors(ctx, jobSpec.ID) require.NoError(t, err) jbWithErrors, err := orm.FindJobTx(testutils.Context(t), jobSpec.ID) require.NoError(t, err) @@ -1685,12 +1724,12 @@ func Test_FindSpecErrorsByJobIDs(t *testing.T) { pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db) - orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database()) + orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore) jb, err := directrequest.ValidatedDirectRequestSpec(testspecs.GetDirectRequestSpec()) require.NoError(t, err) - err = orm.CreateJob(&jb) + err = orm.CreateJob(ctx, &jb) require.NoError(t, err) var jobSpec job.Job err = db.Get(&jobSpec, "SELECT * FROM jobs") @@ -1698,10 +1737,10 @@ func Test_FindSpecErrorsByJobIDs(t *testing.T) { ocrSpecError1 := "ocr spec 1 errored" ocrSpecError2 := "ocr spec 2 errored" - require.NoError(t, orm.RecordError(jobSpec.ID, ocrSpecError1)) - require.NoError(t, orm.RecordError(jobSpec.ID, ocrSpecError2)) + require.NoError(t, orm.RecordError(ctx, jobSpec.ID, ocrSpecError1)) + require.NoError(t, orm.RecordError(ctx, jobSpec.ID, ocrSpecError2)) - specErrs, err := orm.FindSpecErrorsByJobIDs([]int32{jobSpec.ID}) + specErrs, err := orm.FindSpecErrorsByJobIDs(ctx, []int32{jobSpec.ID}) require.NoError(t, err) assert.Equal(t, len(specErrs), 2) @@ -1722,7 +1761,7 @@ func Test_CountPipelineRunsByJobID(t *testing.T) { bridgesORM := bridges.NewORM(db) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()}) legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore, config.Database()) + orm := NewTestORM(t, db, pipelineORM, bridgesORM, keyStore) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}) _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}) @@ -1739,19 +1778,21 @@ func Test_CountPipelineRunsByJobID(t *testing.T) { ) require.NoError(t, err) - err = orm.CreateJob(&jb) + err = orm.CreateJob(testutils.Context(t), &jb) require.NoError(t, err) t.Run("with no pipeline runs", func(t *testing.T) { - count, err2 := orm.CountPipelineRunsByJobID(jb.ID) + ctx := testutils.Context(t) + count, err2 := orm.CountPipelineRunsByJobID(ctx, jb.ID) require.NoError(t, err2) assert.Equal(t, int32(0), count) }) t.Run("with a pipeline run", func(t *testing.T) { + ctx := testutils.Context(t) mustInsertPipelineRun(t, pipelineORM, jb) - count, err2 := orm.CountPipelineRunsByJobID(jb.ID) + count, err2 := orm.CountPipelineRunsByJobID(ctx, jb.ID) require.NoError(t, err2) require.Equal(t, int32(1), count) }) diff --git a/core/services/job/job_pipeline_orm_integration_test.go b/core/services/job/job_pipeline_orm_integration_test.go index 33ee6dc306c..f8a43bca34d 100644 --- a/core/services/job/job_pipeline_orm_integration_test.go +++ b/core/services/job/job_pipeline_orm_integration_test.go @@ -135,7 +135,7 @@ func TestPipelineORM_Integration(t *testing.T) { p, err := pipeline.Parse(DotStr) require.NoError(t, err) - specID, err = orm.CreateSpec(ctx, nil, *p, models.Interval(0)) + specID, err = orm.CreateSpec(ctx, *p, models.Interval(0)) require.NoError(t, err) var pipelineSpecs []pipeline.Spec @@ -160,12 +160,12 @@ func TestPipelineORM_Integration(t *testing.T) { legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) runner := pipeline.NewRunner(orm, btORM, config.JobPipeline(), cfg.WebServer(), legacyChains, nil, nil, lggr, nil, nil) - jobORM := NewTestORM(t, db, orm, btORM, keyStore, cfg.Database()) + jobORM := NewTestORM(t, db, orm, btORM, keyStore) dbSpec := makeVoterTurnoutOCRJobSpec(t, transmitterAddress, bridge.Name.String(), bridge2.Name.String()) // Need a job in order to create a run - require.NoError(t, jobORM.CreateJob(dbSpec)) + require.NoError(t, jobORM.CreateJob(testutils.Context(t), dbSpec)) var pipelineSpecs []pipeline.Spec sql := `SELECT pipeline_specs.*, job_pipeline_specs.job_id FROM pipeline_specs JOIN job_pipeline_specs ON (pipeline_specs.id = job_pipeline_specs.pipeline_spec_id);` diff --git a/core/services/job/kv_orm.go b/core/services/job/kv_orm.go index 6108c123a62..63384efc25b 100644 --- a/core/services/job/kv_orm.go +++ b/core/services/job/kv_orm.go @@ -5,10 +5,8 @@ import ( "fmt" "time" - "github.com/jmoiron/sqlx" - + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) // KVStore is a simple KV store that can store and retrieve serializable data. @@ -21,17 +19,17 @@ type KVStore interface { type kVStore struct { jobID int32 - q pg.Q + ds sqlutil.DataSource lggr logger.SugaredLogger } var _ KVStore = (*kVStore)(nil) -func NewKVStore(jobID int32, db *sqlx.DB, cfg pg.QConfig, lggr logger.Logger) kVStore { +func NewKVStore(jobID int32, ds sqlutil.DataSource, lggr logger.Logger) kVStore { namedLogger := logger.Sugared(lggr.Named("JobORM")) return kVStore{ jobID: jobID, - q: pg.NewQ(db, namedLogger, cfg), + ds: ds, lggr: namedLogger, } } @@ -45,7 +43,7 @@ func (kv kVStore) Store(ctx context.Context, key string, val []byte) error { val_bytea = EXCLUDED.val_bytea, updated_at = $4;` - if _, err := kv.q.ExecContext(ctx, sql, kv.jobID, key, val, time.Now()); err != nil { + if _, err := kv.ds.ExecContext(ctx, sql, kv.jobID, key, val, time.Now()); err != nil { return fmt.Errorf("failed to store value: %s for key: %s for jobID: %d : %w", string(val), key, kv.jobID, err) } return nil @@ -55,7 +53,7 @@ func (kv kVStore) Store(ctx context.Context, key string, val []byte) error { func (kv kVStore) Get(ctx context.Context, key string) ([]byte, error) { var val []byte sql := "SELECT val_bytea FROM job_kv_store WHERE job_id = $1 AND key = $2" - if err := kv.q.GetContext(ctx, &val, sql, kv.jobID, key); err != nil { + if err := kv.ds.GetContext(ctx, &val, sql, kv.jobID, key); err != nil { return nil, fmt.Errorf("failed to get value by key: %s for jobID: %d : %w", key, kv.jobID, err) } diff --git a/core/services/job/kv_orm_test.go b/core/services/job/kv_orm_test.go index 156779ffb4d..0f229f09d88 100644 --- a/core/services/job/kv_orm_test.go +++ b/core/services/job/kv_orm_test.go @@ -11,6 +11,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -33,13 +34,13 @@ func TestJobKVStore(t *testing.T) { bridgesORM := bridges.NewORM(db) jobID := int32(1337) - kvStore := job.NewKVStore(jobID, db, config.Database(), lggr) - jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, cltest.NewKeyStore(t, db), config.Database()) + kvStore := job.NewKVStore(jobID, db, lggr) + jobORM := NewTestORM(t, db, pipelineORM, bridgesORM, cltest.NewKeyStore(t, db)) jb, err := directrequest.ValidatedDirectRequestSpec(testspecs.GetDirectRequestSpec()) require.NoError(t, err) jb.ID = jobID - require.NoError(t, jobORM.CreateJob(&jb)) + require.NoError(t, jobORM.CreateJob(testutils.Context(t), &jb)) var values = [][]byte{ []byte("Hello"), @@ -72,5 +73,5 @@ func TestJobKVStore(t *testing.T) { require.NoError(t, err) require.Equal(t, td2, fetchedBytes) - require.NoError(t, jobORM.DeleteJob(jobID)) + require.NoError(t, jobORM.DeleteJob(ctx, jobID)) } diff --git a/core/services/job/mocks/orm.go b/core/services/job/mocks/orm.go index b8534b9d688..ec60137de93 100644 --- a/core/services/job/mocks/orm.go +++ b/core/services/job/mocks/orm.go @@ -12,10 +12,10 @@ import ( mock "github.com/stretchr/testify/mock" - pg "github.com/smartcontractkit/chainlink/v2/core/services/pg" - pipeline "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" + sqlutil "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + types "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" uuid "github.com/google/uuid" @@ -62,9 +62,9 @@ func (_m *ORM) Close() error { return r0 } -// CountPipelineRunsByJobID provides a mock function with given fields: jobID -func (_m *ORM) CountPipelineRunsByJobID(jobID int32) (int32, error) { - ret := _m.Called(jobID) +// CountPipelineRunsByJobID provides a mock function with given fields: ctx, jobID +func (_m *ORM) CountPipelineRunsByJobID(ctx context.Context, jobID int32) (int32, error) { + ret := _m.Called(ctx, jobID) if len(ret) == 0 { panic("no return value specified for CountPipelineRunsByJobID") @@ -72,17 +72,17 @@ func (_m *ORM) CountPipelineRunsByJobID(jobID int32) (int32, error) { var r0 int32 var r1 error - if rf, ok := ret.Get(0).(func(int32) (int32, error)); ok { - return rf(jobID) + if rf, ok := ret.Get(0).(func(context.Context, int32) (int32, error)); ok { + return rf(ctx, jobID) } - if rf, ok := ret.Get(0).(func(int32) int32); ok { - r0 = rf(jobID) + if rf, ok := ret.Get(0).(func(context.Context, int32) int32); ok { + r0 = rf(ctx, jobID) } else { r0 = ret.Get(0).(int32) } - if rf, ok := ret.Get(1).(func(int32) error); ok { - r1 = rf(jobID) + if rf, ok := ret.Get(1).(func(context.Context, int32) error); ok { + r1 = rf(ctx, jobID) } else { r1 = ret.Error(1) } @@ -90,24 +90,17 @@ func (_m *ORM) CountPipelineRunsByJobID(jobID int32) (int32, error) { return r0, r1 } -// CreateJob provides a mock function with given fields: jb, qopts -func (_m *ORM) CreateJob(jb *job.Job, qopts ...pg.QOpt) error { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, jb) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// CreateJob provides a mock function with given fields: ctx, jb +func (_m *ORM) CreateJob(ctx context.Context, jb *job.Job) error { + ret := _m.Called(ctx, jb) if len(ret) == 0 { panic("no return value specified for CreateJob") } var r0 error - if rf, ok := ret.Get(0).(func(*job.Job, ...pg.QOpt) error); ok { - r0 = rf(jb, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, *job.Job) error); ok { + r0 = rf(ctx, jb) } else { r0 = ret.Error(0) } @@ -115,24 +108,37 @@ func (_m *ORM) CreateJob(jb *job.Job, qopts ...pg.QOpt) error { return r0 } -// DeleteJob provides a mock function with given fields: id, qopts -func (_m *ORM) DeleteJob(id int32, qopts ...pg.QOpt) error { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] +// DataSource provides a mock function with given fields: +func (_m *ORM) DataSource() sqlutil.DataSource { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for DataSource") + } + + var r0 sqlutil.DataSource + if rf, ok := ret.Get(0).(func() sqlutil.DataSource); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(sqlutil.DataSource) + } } - var _ca []interface{} - _ca = append(_ca, id) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) + + return r0 +} + +// DeleteJob provides a mock function with given fields: ctx, id +func (_m *ORM) DeleteJob(ctx context.Context, id int32) error { + ret := _m.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for DeleteJob") } var r0 error - if rf, ok := ret.Get(0).(func(int32, ...pg.QOpt) error); ok { - r0 = rf(id, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int32) error); ok { + r0 = rf(ctx, id) } else { r0 = ret.Error(0) } @@ -186,16 +192,9 @@ func (_m *ORM) FindJob(ctx context.Context, id int32) (job.Job, error) { return r0, r1 } -// FindJobByExternalJobID provides a mock function with given fields: _a0, qopts -func (_m *ORM) FindJobByExternalJobID(_a0 uuid.UUID, qopts ...pg.QOpt) (job.Job, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, _a0) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// FindJobByExternalJobID provides a mock function with given fields: ctx, _a1 +func (_m *ORM) FindJobByExternalJobID(ctx context.Context, _a1 uuid.UUID) (job.Job, error) { + ret := _m.Called(ctx, _a1) if len(ret) == 0 { panic("no return value specified for FindJobByExternalJobID") @@ -203,17 +202,17 @@ func (_m *ORM) FindJobByExternalJobID(_a0 uuid.UUID, qopts ...pg.QOpt) (job.Job, var r0 job.Job var r1 error - if rf, ok := ret.Get(0).(func(uuid.UUID, ...pg.QOpt) (job.Job, error)); ok { - return rf(_a0, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID) (job.Job, error)); ok { + return rf(ctx, _a1) } - if rf, ok := ret.Get(0).(func(uuid.UUID, ...pg.QOpt) job.Job); ok { - r0 = rf(_a0, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID) job.Job); ok { + r0 = rf(ctx, _a1) } else { r0 = ret.Get(0).(job.Job) } - if rf, ok := ret.Get(1).(func(uuid.UUID, ...pg.QOpt) error); ok { - r1 = rf(_a0, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { + r1 = rf(ctx, _a1) } else { r1 = ret.Error(1) } @@ -221,16 +220,9 @@ func (_m *ORM) FindJobByExternalJobID(_a0 uuid.UUID, qopts ...pg.QOpt) (job.Job, return r0, r1 } -// FindJobIDByAddress provides a mock function with given fields: address, evmChainID, qopts -func (_m *ORM) FindJobIDByAddress(address types.EIP55Address, evmChainID *big.Big, qopts ...pg.QOpt) (int32, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, address, evmChainID) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// FindJobIDByAddress provides a mock function with given fields: ctx, address, evmChainID +func (_m *ORM) FindJobIDByAddress(ctx context.Context, address types.EIP55Address, evmChainID *big.Big) (int32, error) { + ret := _m.Called(ctx, address, evmChainID) if len(ret) == 0 { panic("no return value specified for FindJobIDByAddress") @@ -238,17 +230,17 @@ func (_m *ORM) FindJobIDByAddress(address types.EIP55Address, evmChainID *big.Bi var r0 int32 var r1 error - if rf, ok := ret.Get(0).(func(types.EIP55Address, *big.Big, ...pg.QOpt) (int32, error)); ok { - return rf(address, evmChainID, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, types.EIP55Address, *big.Big) (int32, error)); ok { + return rf(ctx, address, evmChainID) } - if rf, ok := ret.Get(0).(func(types.EIP55Address, *big.Big, ...pg.QOpt) int32); ok { - r0 = rf(address, evmChainID, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, types.EIP55Address, *big.Big) int32); ok { + r0 = rf(ctx, address, evmChainID) } else { r0 = ret.Get(0).(int32) } - if rf, ok := ret.Get(1).(func(types.EIP55Address, *big.Big, ...pg.QOpt) error); ok { - r1 = rf(address, evmChainID, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, types.EIP55Address, *big.Big) error); ok { + r1 = rf(ctx, address, evmChainID) } else { r1 = ret.Error(1) } @@ -256,9 +248,9 @@ func (_m *ORM) FindJobIDByAddress(address types.EIP55Address, evmChainID *big.Bi return r0, r1 } -// FindJobIDsWithBridge provides a mock function with given fields: name -func (_m *ORM) FindJobIDsWithBridge(name string) ([]int32, error) { - ret := _m.Called(name) +// FindJobIDsWithBridge provides a mock function with given fields: ctx, name +func (_m *ORM) FindJobIDsWithBridge(ctx context.Context, name string) ([]int32, error) { + ret := _m.Called(ctx, name) if len(ret) == 0 { panic("no return value specified for FindJobIDsWithBridge") @@ -266,19 +258,19 @@ func (_m *ORM) FindJobIDsWithBridge(name string) ([]int32, error) { var r0 []int32 var r1 error - if rf, ok := ret.Get(0).(func(string) ([]int32, error)); ok { - return rf(name) + if rf, ok := ret.Get(0).(func(context.Context, string) ([]int32, error)); ok { + return rf(ctx, name) } - if rf, ok := ret.Get(0).(func(string) []int32); ok { - r0 = rf(name) + if rf, ok := ret.Get(0).(func(context.Context, string) []int32); ok { + r0 = rf(ctx, name) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]int32) } } - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(name) + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, name) } else { r1 = ret.Error(1) } @@ -314,9 +306,9 @@ func (_m *ORM) FindJobTx(ctx context.Context, id int32) (job.Job, error) { return r0, r1 } -// FindJobWithoutSpecErrors provides a mock function with given fields: id -func (_m *ORM) FindJobWithoutSpecErrors(id int32) (job.Job, error) { - ret := _m.Called(id) +// FindJobWithoutSpecErrors provides a mock function with given fields: ctx, id +func (_m *ORM) FindJobWithoutSpecErrors(ctx context.Context, id int32) (job.Job, error) { + ret := _m.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for FindJobWithoutSpecErrors") @@ -324,17 +316,17 @@ func (_m *ORM) FindJobWithoutSpecErrors(id int32) (job.Job, error) { var r0 job.Job var r1 error - if rf, ok := ret.Get(0).(func(int32) (job.Job, error)); ok { - return rf(id) + if rf, ok := ret.Get(0).(func(context.Context, int32) (job.Job, error)); ok { + return rf(ctx, id) } - if rf, ok := ret.Get(0).(func(int32) job.Job); ok { - r0 = rf(id) + if rf, ok := ret.Get(0).(func(context.Context, int32) job.Job); ok { + r0 = rf(ctx, id) } else { r0 = ret.Get(0).(job.Job) } - if rf, ok := ret.Get(1).(func(int32) error); ok { - r1 = rf(id) + if rf, ok := ret.Get(1).(func(context.Context, int32) error); ok { + r1 = rf(ctx, id) } else { r1 = ret.Error(1) } @@ -342,9 +334,9 @@ func (_m *ORM) FindJobWithoutSpecErrors(id int32) (job.Job, error) { return r0, r1 } -// FindJobs provides a mock function with given fields: offset, limit -func (_m *ORM) FindJobs(offset int, limit int) ([]job.Job, int, error) { - ret := _m.Called(offset, limit) +// FindJobs provides a mock function with given fields: ctx, offset, limit +func (_m *ORM) FindJobs(ctx context.Context, offset int, limit int) ([]job.Job, int, error) { + ret := _m.Called(ctx, offset, limit) if len(ret) == 0 { panic("no return value specified for FindJobs") @@ -353,25 +345,25 @@ func (_m *ORM) FindJobs(offset int, limit int) ([]job.Job, int, error) { var r0 []job.Job var r1 int var r2 error - if rf, ok := ret.Get(0).(func(int, int) ([]job.Job, int, error)); ok { - return rf(offset, limit) + if rf, ok := ret.Get(0).(func(context.Context, int, int) ([]job.Job, int, error)); ok { + return rf(ctx, offset, limit) } - if rf, ok := ret.Get(0).(func(int, int) []job.Job); ok { - r0 = rf(offset, limit) + if rf, ok := ret.Get(0).(func(context.Context, int, int) []job.Job); ok { + r0 = rf(ctx, offset, limit) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]job.Job) } } - if rf, ok := ret.Get(1).(func(int, int) int); ok { - r1 = rf(offset, limit) + if rf, ok := ret.Get(1).(func(context.Context, int, int) int); ok { + r1 = rf(ctx, offset, limit) } else { r1 = ret.Get(1).(int) } - if rf, ok := ret.Get(2).(func(int, int) error); ok { - r2 = rf(offset, limit) + if rf, ok := ret.Get(2).(func(context.Context, int, int) error); ok { + r2 = rf(ctx, offset, limit) } else { r2 = ret.Error(2) } @@ -379,9 +371,9 @@ func (_m *ORM) FindJobs(offset int, limit int) ([]job.Job, int, error) { return r0, r1, r2 } -// FindJobsByPipelineSpecIDs provides a mock function with given fields: ids -func (_m *ORM) FindJobsByPipelineSpecIDs(ids []int32) ([]job.Job, error) { - ret := _m.Called(ids) +// FindJobsByPipelineSpecIDs provides a mock function with given fields: ctx, ids +func (_m *ORM) FindJobsByPipelineSpecIDs(ctx context.Context, ids []int32) ([]job.Job, error) { + ret := _m.Called(ctx, ids) if len(ret) == 0 { panic("no return value specified for FindJobsByPipelineSpecIDs") @@ -389,19 +381,19 @@ func (_m *ORM) FindJobsByPipelineSpecIDs(ids []int32) ([]job.Job, error) { var r0 []job.Job var r1 error - if rf, ok := ret.Get(0).(func([]int32) ([]job.Job, error)); ok { - return rf(ids) + if rf, ok := ret.Get(0).(func(context.Context, []int32) ([]job.Job, error)); ok { + return rf(ctx, ids) } - if rf, ok := ret.Get(0).(func([]int32) []job.Job); ok { - r0 = rf(ids) + if rf, ok := ret.Get(0).(func(context.Context, []int32) []job.Job); ok { + r0 = rf(ctx, ids) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]job.Job) } } - if rf, ok := ret.Get(1).(func([]int32) error); ok { - r1 = rf(ids) + if rf, ok := ret.Get(1).(func(context.Context, []int32) error); ok { + r1 = rf(ctx, ids) } else { r1 = ret.Error(1) } @@ -409,16 +401,9 @@ func (_m *ORM) FindJobsByPipelineSpecIDs(ids []int32) ([]job.Job, error) { return r0, r1 } -// FindOCR2JobIDByAddress provides a mock function with given fields: contractID, feedID, qopts -func (_m *ORM) FindOCR2JobIDByAddress(contractID string, feedID *common.Hash, qopts ...pg.QOpt) (int32, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, contractID, feedID) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// FindOCR2JobIDByAddress provides a mock function with given fields: ctx, contractID, feedID +func (_m *ORM) FindOCR2JobIDByAddress(ctx context.Context, contractID string, feedID *common.Hash) (int32, error) { + ret := _m.Called(ctx, contractID, feedID) if len(ret) == 0 { panic("no return value specified for FindOCR2JobIDByAddress") @@ -426,17 +411,17 @@ func (_m *ORM) FindOCR2JobIDByAddress(contractID string, feedID *common.Hash, qo var r0 int32 var r1 error - if rf, ok := ret.Get(0).(func(string, *common.Hash, ...pg.QOpt) (int32, error)); ok { - return rf(contractID, feedID, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, string, *common.Hash) (int32, error)); ok { + return rf(ctx, contractID, feedID) } - if rf, ok := ret.Get(0).(func(string, *common.Hash, ...pg.QOpt) int32); ok { - r0 = rf(contractID, feedID, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, string, *common.Hash) int32); ok { + r0 = rf(ctx, contractID, feedID) } else { r0 = ret.Get(0).(int32) } - if rf, ok := ret.Get(1).(func(string, *common.Hash, ...pg.QOpt) error); ok { - r1 = rf(contractID, feedID, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, string, *common.Hash) error); ok { + r1 = rf(ctx, contractID, feedID) } else { r1 = ret.Error(1) } @@ -444,9 +429,9 @@ func (_m *ORM) FindOCR2JobIDByAddress(contractID string, feedID *common.Hash, qo return r0, r1 } -// FindPipelineRunByID provides a mock function with given fields: id -func (_m *ORM) FindPipelineRunByID(id int64) (pipeline.Run, error) { - ret := _m.Called(id) +// FindPipelineRunByID provides a mock function with given fields: ctx, id +func (_m *ORM) FindPipelineRunByID(ctx context.Context, id int64) (pipeline.Run, error) { + ret := _m.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for FindPipelineRunByID") @@ -454,17 +439,17 @@ func (_m *ORM) FindPipelineRunByID(id int64) (pipeline.Run, error) { var r0 pipeline.Run var r1 error - if rf, ok := ret.Get(0).(func(int64) (pipeline.Run, error)); ok { - return rf(id) + if rf, ok := ret.Get(0).(func(context.Context, int64) (pipeline.Run, error)); ok { + return rf(ctx, id) } - if rf, ok := ret.Get(0).(func(int64) pipeline.Run); ok { - r0 = rf(id) + if rf, ok := ret.Get(0).(func(context.Context, int64) pipeline.Run); ok { + r0 = rf(ctx, id) } else { r0 = ret.Get(0).(pipeline.Run) } - if rf, ok := ret.Get(1).(func(int64) error); ok { - r1 = rf(id) + if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok { + r1 = rf(ctx, id) } else { r1 = ret.Error(1) } @@ -472,9 +457,9 @@ func (_m *ORM) FindPipelineRunByID(id int64) (pipeline.Run, error) { return r0, r1 } -// FindPipelineRunIDsByJobID provides a mock function with given fields: jobID, offset, limit -func (_m *ORM) FindPipelineRunIDsByJobID(jobID int32, offset int, limit int) ([]int64, error) { - ret := _m.Called(jobID, offset, limit) +// FindPipelineRunIDsByJobID provides a mock function with given fields: ctx, jobID, offset, limit +func (_m *ORM) FindPipelineRunIDsByJobID(ctx context.Context, jobID int32, offset int, limit int) ([]int64, error) { + ret := _m.Called(ctx, jobID, offset, limit) if len(ret) == 0 { panic("no return value specified for FindPipelineRunIDsByJobID") @@ -482,19 +467,19 @@ func (_m *ORM) FindPipelineRunIDsByJobID(jobID int32, offset int, limit int) ([] var r0 []int64 var r1 error - if rf, ok := ret.Get(0).(func(int32, int, int) ([]int64, error)); ok { - return rf(jobID, offset, limit) + if rf, ok := ret.Get(0).(func(context.Context, int32, int, int) ([]int64, error)); ok { + return rf(ctx, jobID, offset, limit) } - if rf, ok := ret.Get(0).(func(int32, int, int) []int64); ok { - r0 = rf(jobID, offset, limit) + if rf, ok := ret.Get(0).(func(context.Context, int32, int, int) []int64); ok { + r0 = rf(ctx, jobID, offset, limit) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]int64) } } - if rf, ok := ret.Get(1).(func(int32, int, int) error); ok { - r1 = rf(jobID, offset, limit) + if rf, ok := ret.Get(1).(func(context.Context, int32, int, int) error); ok { + r1 = rf(ctx, jobID, offset, limit) } else { r1 = ret.Error(1) } @@ -502,9 +487,9 @@ func (_m *ORM) FindPipelineRunIDsByJobID(jobID int32, offset int, limit int) ([] return r0, r1 } -// FindPipelineRunsByIDs provides a mock function with given fields: ids -func (_m *ORM) FindPipelineRunsByIDs(ids []int64) ([]pipeline.Run, error) { - ret := _m.Called(ids) +// FindPipelineRunsByIDs provides a mock function with given fields: ctx, ids +func (_m *ORM) FindPipelineRunsByIDs(ctx context.Context, ids []int64) ([]pipeline.Run, error) { + ret := _m.Called(ctx, ids) if len(ret) == 0 { panic("no return value specified for FindPipelineRunsByIDs") @@ -512,19 +497,19 @@ func (_m *ORM) FindPipelineRunsByIDs(ids []int64) ([]pipeline.Run, error) { var r0 []pipeline.Run var r1 error - if rf, ok := ret.Get(0).(func([]int64) ([]pipeline.Run, error)); ok { - return rf(ids) + if rf, ok := ret.Get(0).(func(context.Context, []int64) ([]pipeline.Run, error)); ok { + return rf(ctx, ids) } - if rf, ok := ret.Get(0).(func([]int64) []pipeline.Run); ok { - r0 = rf(ids) + if rf, ok := ret.Get(0).(func(context.Context, []int64) []pipeline.Run); ok { + r0 = rf(ctx, ids) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]pipeline.Run) } } - if rf, ok := ret.Get(1).(func([]int64) error); ok { - r1 = rf(ids) + if rf, ok := ret.Get(1).(func(context.Context, []int64) error); ok { + r1 = rf(ctx, ids) } else { r1 = ret.Error(1) } @@ -532,16 +517,9 @@ func (_m *ORM) FindPipelineRunsByIDs(ids []int64) ([]pipeline.Run, error) { return r0, r1 } -// FindSpecError provides a mock function with given fields: id, qopts -func (_m *ORM) FindSpecError(id int64, qopts ...pg.QOpt) (job.SpecError, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, id) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// FindSpecError provides a mock function with given fields: ctx, id +func (_m *ORM) FindSpecError(ctx context.Context, id int64) (job.SpecError, error) { + ret := _m.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for FindSpecError") @@ -549,17 +527,17 @@ func (_m *ORM) FindSpecError(id int64, qopts ...pg.QOpt) (job.SpecError, error) var r0 job.SpecError var r1 error - if rf, ok := ret.Get(0).(func(int64, ...pg.QOpt) (job.SpecError, error)); ok { - return rf(id, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64) (job.SpecError, error)); ok { + return rf(ctx, id) } - if rf, ok := ret.Get(0).(func(int64, ...pg.QOpt) job.SpecError); ok { - r0 = rf(id, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64) job.SpecError); ok { + r0 = rf(ctx, id) } else { r0 = ret.Get(0).(job.SpecError) } - if rf, ok := ret.Get(1).(func(int64, ...pg.QOpt) error); ok { - r1 = rf(id, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok { + r1 = rf(ctx, id) } else { r1 = ret.Error(1) } @@ -567,16 +545,9 @@ func (_m *ORM) FindSpecError(id int64, qopts ...pg.QOpt) (job.SpecError, error) return r0, r1 } -// FindSpecErrorsByJobIDs provides a mock function with given fields: ids, qopts -func (_m *ORM) FindSpecErrorsByJobIDs(ids []int32, qopts ...pg.QOpt) ([]job.SpecError, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, ids) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// FindSpecErrorsByJobIDs provides a mock function with given fields: ctx, ids +func (_m *ORM) FindSpecErrorsByJobIDs(ctx context.Context, ids []int32) ([]job.SpecError, error) { + ret := _m.Called(ctx, ids) if len(ret) == 0 { panic("no return value specified for FindSpecErrorsByJobIDs") @@ -584,19 +555,19 @@ func (_m *ORM) FindSpecErrorsByJobIDs(ids []int32, qopts ...pg.QOpt) ([]job.Spec var r0 []job.SpecError var r1 error - if rf, ok := ret.Get(0).(func([]int32, ...pg.QOpt) ([]job.SpecError, error)); ok { - return rf(ids, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, []int32) ([]job.SpecError, error)); ok { + return rf(ctx, ids) } - if rf, ok := ret.Get(0).(func([]int32, ...pg.QOpt) []job.SpecError); ok { - r0 = rf(ids, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, []int32) []job.SpecError); ok { + r0 = rf(ctx, ids) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]job.SpecError) } } - if rf, ok := ret.Get(1).(func([]int32, ...pg.QOpt) error); ok { - r1 = rf(ids, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, []int32) error); ok { + r1 = rf(ctx, ids) } else { r1 = ret.Error(1) } @@ -604,16 +575,9 @@ func (_m *ORM) FindSpecErrorsByJobIDs(ids []int32, qopts ...pg.QOpt) ([]job.Spec return r0, r1 } -// FindTaskResultByRunIDAndTaskName provides a mock function with given fields: runID, taskName, qopts -func (_m *ORM) FindTaskResultByRunIDAndTaskName(runID int64, taskName string, qopts ...pg.QOpt) ([]byte, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, runID, taskName) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// FindTaskResultByRunIDAndTaskName provides a mock function with given fields: ctx, runID, taskName +func (_m *ORM) FindTaskResultByRunIDAndTaskName(ctx context.Context, runID int64, taskName string) ([]byte, error) { + ret := _m.Called(ctx, runID, taskName) if len(ret) == 0 { panic("no return value specified for FindTaskResultByRunIDAndTaskName") @@ -621,19 +585,19 @@ func (_m *ORM) FindTaskResultByRunIDAndTaskName(runID int64, taskName string, qo var r0 []byte var r1 error - if rf, ok := ret.Get(0).(func(int64, string, ...pg.QOpt) ([]byte, error)); ok { - return rf(runID, taskName, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64, string) ([]byte, error)); ok { + return rf(ctx, runID, taskName) } - if rf, ok := ret.Get(0).(func(int64, string, ...pg.QOpt) []byte); ok { - r0 = rf(runID, taskName, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int64, string) []byte); ok { + r0 = rf(ctx, runID, taskName) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]byte) } } - if rf, ok := ret.Get(1).(func(int64, string, ...pg.QOpt) error); ok { - r1 = rf(runID, taskName, qopts...) + if rf, ok := ret.Get(1).(func(context.Context, int64, string) error); ok { + r1 = rf(ctx, runID, taskName) } else { r1 = ret.Error(1) } @@ -641,24 +605,17 @@ func (_m *ORM) FindTaskResultByRunIDAndTaskName(runID int64, taskName string, qo return r0, r1 } -// InsertJob provides a mock function with given fields: _a0, qopts -func (_m *ORM) InsertJob(_a0 *job.Job, qopts ...pg.QOpt) error { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, _a0) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// InsertJob provides a mock function with given fields: ctx, _a1 +func (_m *ORM) InsertJob(ctx context.Context, _a1 *job.Job) error { + ret := _m.Called(ctx, _a1) if len(ret) == 0 { panic("no return value specified for InsertJob") } var r0 error - if rf, ok := ret.Get(0).(func(*job.Job, ...pg.QOpt) error); ok { - r0 = rf(_a0, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, *job.Job) error); ok { + r0 = rf(ctx, _a1) } else { r0 = ret.Error(0) } @@ -666,24 +623,17 @@ func (_m *ORM) InsertJob(_a0 *job.Job, qopts ...pg.QOpt) error { return r0 } -// InsertWebhookSpec provides a mock function with given fields: webhookSpec, qopts -func (_m *ORM) InsertWebhookSpec(webhookSpec *job.WebhookSpec, qopts ...pg.QOpt) error { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, webhookSpec) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// InsertWebhookSpec provides a mock function with given fields: ctx, webhookSpec +func (_m *ORM) InsertWebhookSpec(ctx context.Context, webhookSpec *job.WebhookSpec) error { + ret := _m.Called(ctx, webhookSpec) if len(ret) == 0 { panic("no return value specified for InsertWebhookSpec") } var r0 error - if rf, ok := ret.Get(0).(func(*job.WebhookSpec, ...pg.QOpt) error); ok { - r0 = rf(webhookSpec, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, *job.WebhookSpec) error); ok { + r0 = rf(ctx, webhookSpec) } else { r0 = ret.Error(0) } @@ -691,9 +641,9 @@ func (_m *ORM) InsertWebhookSpec(webhookSpec *job.WebhookSpec, qopts ...pg.QOpt) return r0 } -// PipelineRuns provides a mock function with given fields: jobID, offset, size -func (_m *ORM) PipelineRuns(jobID *int32, offset int, size int) ([]pipeline.Run, int, error) { - ret := _m.Called(jobID, offset, size) +// PipelineRuns provides a mock function with given fields: ctx, jobID, offset, size +func (_m *ORM) PipelineRuns(ctx context.Context, jobID *int32, offset int, size int) ([]pipeline.Run, int, error) { + ret := _m.Called(ctx, jobID, offset, size) if len(ret) == 0 { panic("no return value specified for PipelineRuns") @@ -702,25 +652,25 @@ func (_m *ORM) PipelineRuns(jobID *int32, offset int, size int) ([]pipeline.Run, var r0 []pipeline.Run var r1 int var r2 error - if rf, ok := ret.Get(0).(func(*int32, int, int) ([]pipeline.Run, int, error)); ok { - return rf(jobID, offset, size) + if rf, ok := ret.Get(0).(func(context.Context, *int32, int, int) ([]pipeline.Run, int, error)); ok { + return rf(ctx, jobID, offset, size) } - if rf, ok := ret.Get(0).(func(*int32, int, int) []pipeline.Run); ok { - r0 = rf(jobID, offset, size) + if rf, ok := ret.Get(0).(func(context.Context, *int32, int, int) []pipeline.Run); ok { + r0 = rf(ctx, jobID, offset, size) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]pipeline.Run) } } - if rf, ok := ret.Get(1).(func(*int32, int, int) int); ok { - r1 = rf(jobID, offset, size) + if rf, ok := ret.Get(1).(func(context.Context, *int32, int, int) int); ok { + r1 = rf(ctx, jobID, offset, size) } else { r1 = ret.Get(1).(int) } - if rf, ok := ret.Get(2).(func(*int32, int, int) error); ok { - r2 = rf(jobID, offset, size) + if rf, ok := ret.Get(2).(func(context.Context, *int32, int, int) error); ok { + r2 = rf(ctx, jobID, offset, size) } else { r2 = ret.Error(2) } @@ -728,24 +678,17 @@ func (_m *ORM) PipelineRuns(jobID *int32, offset int, size int) ([]pipeline.Run, return r0, r1, r2 } -// RecordError provides a mock function with given fields: jobID, description, qopts -func (_m *ORM) RecordError(jobID int32, description string, qopts ...pg.QOpt) error { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, jobID, description) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// RecordError provides a mock function with given fields: ctx, jobID, description +func (_m *ORM) RecordError(ctx context.Context, jobID int32, description string) error { + ret := _m.Called(ctx, jobID, description) if len(ret) == 0 { panic("no return value specified for RecordError") } var r0 error - if rf, ok := ret.Get(0).(func(int32, string, ...pg.QOpt) error); ok { - r0 = rf(jobID, description, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, int32, string) error); ok { + r0 = rf(ctx, jobID, description) } else { r0 = ret.Error(0) } @@ -753,16 +696,29 @@ func (_m *ORM) RecordError(jobID int32, description string, qopts ...pg.QOpt) er return r0 } -// TryRecordError provides a mock function with given fields: jobID, description, qopts -func (_m *ORM) TryRecordError(jobID int32, description string, qopts ...pg.QOpt) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] +// TryRecordError provides a mock function with given fields: ctx, jobID, description +func (_m *ORM) TryRecordError(ctx context.Context, jobID int32, description string) { + _m.Called(ctx, jobID, description) +} + +// WithDataSource provides a mock function with given fields: source +func (_m *ORM) WithDataSource(source sqlutil.DataSource) job.ORM { + ret := _m.Called(source) + + if len(ret) == 0 { + panic("no return value specified for WithDataSource") } - var _ca []interface{} - _ca = append(_ca, jobID, description) - _ca = append(_ca, _va...) - _m.Called(_ca...) + + var r0 job.ORM + if rf, ok := ret.Get(0).(func(sqlutil.DataSource) job.ORM); ok { + r0 = rf(source) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(job.ORM) + } + } + + return r0 } // NewORM creates a new instance of ORM. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. diff --git a/core/services/job/mocks/spawner.go b/core/services/job/mocks/spawner.go index 37e883ef3c5..7127636cdbb 100644 --- a/core/services/job/mocks/spawner.go +++ b/core/services/job/mocks/spawner.go @@ -8,7 +8,7 @@ import ( job "github.com/smartcontractkit/chainlink/v2/core/services/job" mock "github.com/stretchr/testify/mock" - pg "github.com/smartcontractkit/chainlink/v2/core/services/pg" + sqlutil "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" ) // Spawner is an autogenerated mock type for the Spawner type @@ -54,24 +54,17 @@ func (_m *Spawner) Close() error { return r0 } -// CreateJob provides a mock function with given fields: jb, qopts -func (_m *Spawner) CreateJob(jb *job.Job, qopts ...pg.QOpt) error { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, jb) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// CreateJob provides a mock function with given fields: ctx, ds, jb +func (_m *Spawner) CreateJob(ctx context.Context, ds sqlutil.DataSource, jb *job.Job) error { + ret := _m.Called(ctx, ds, jb) if len(ret) == 0 { panic("no return value specified for CreateJob") } var r0 error - if rf, ok := ret.Get(0).(func(*job.Job, ...pg.QOpt) error); ok { - r0 = rf(jb, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, sqlutil.DataSource, *job.Job) error); ok { + r0 = rf(ctx, ds, jb) } else { r0 = ret.Error(0) } @@ -79,24 +72,17 @@ func (_m *Spawner) CreateJob(jb *job.Job, qopts ...pg.QOpt) error { return r0 } -// DeleteJob provides a mock function with given fields: jobID, qopts -func (_m *Spawner) DeleteJob(jobID int32, qopts ...pg.QOpt) error { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, jobID) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// DeleteJob provides a mock function with given fields: ctx, ds, jobID +func (_m *Spawner) DeleteJob(ctx context.Context, ds sqlutil.DataSource, jobID int32) error { + ret := _m.Called(ctx, ds, jobID) if len(ret) == 0 { panic("no return value specified for DeleteJob") } var r0 error - if rf, ok := ret.Get(0).(func(int32, ...pg.QOpt) error); ok { - r0 = rf(jobID, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, sqlutil.DataSource, int32) error); ok { + r0 = rf(ctx, ds, jobID) } else { r0 = ret.Error(0) } @@ -178,24 +164,17 @@ func (_m *Spawner) Start(_a0 context.Context) error { return r0 } -// StartService provides a mock function with given fields: ctx, spec, qopts -func (_m *Spawner) StartService(ctx context.Context, spec job.Job, qopts ...pg.QOpt) error { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, spec) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// StartService provides a mock function with given fields: ctx, spec +func (_m *Spawner) StartService(ctx context.Context, spec job.Job) error { + ret := _m.Called(ctx, spec) if len(ret) == 0 { panic("no return value specified for StartService") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, job.Job, ...pg.QOpt) error); ok { - r0 = rf(ctx, spec, qopts...) + if rf, ok := ret.Get(0).(func(context.Context, job.Job) error); ok { + r0 = rf(ctx, spec) } else { r0 = ret.Error(0) } diff --git a/core/services/job/orm.go b/core/services/job/orm.go index f7238799634..2b2f73396dc 100644 --- a/core/services/job/orm.go +++ b/core/services/job/orm.go @@ -18,6 +18,7 @@ import ( "github.com/jmoiron/sqlx" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/bridges" @@ -29,7 +30,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/null" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" medianconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/median/config" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/store/models" ) @@ -44,37 +44,40 @@ var ( //go:generate mockery --quiet --name ORM --output ./mocks/ --case=underscore type ORM interface { - InsertWebhookSpec(webhookSpec *WebhookSpec, qopts ...pg.QOpt) error - InsertJob(job *Job, qopts ...pg.QOpt) error - CreateJob(jb *Job, qopts ...pg.QOpt) error - FindJobs(offset, limit int) ([]Job, int, error) + InsertWebhookSpec(ctx context.Context, webhookSpec *WebhookSpec) error + InsertJob(ctx context.Context, job *Job) error + CreateJob(ctx context.Context, jb *Job) error + FindJobs(ctx context.Context, offset, limit int) ([]Job, int, error) FindJobTx(ctx context.Context, id int32) (Job, error) FindJob(ctx context.Context, id int32) (Job, error) - FindJobByExternalJobID(uuid uuid.UUID, qopts ...pg.QOpt) (Job, error) - FindJobIDByAddress(address evmtypes.EIP55Address, evmChainID *big.Big, qopts ...pg.QOpt) (int32, error) - FindOCR2JobIDByAddress(contractID string, feedID *common.Hash, qopts ...pg.QOpt) (int32, error) - FindJobIDsWithBridge(name string) ([]int32, error) - DeleteJob(id int32, qopts ...pg.QOpt) error - RecordError(jobID int32, description string, qopts ...pg.QOpt) error + FindJobByExternalJobID(ctx context.Context, uuid uuid.UUID) (Job, error) + FindJobIDByAddress(ctx context.Context, address evmtypes.EIP55Address, evmChainID *big.Big) (int32, error) + FindOCR2JobIDByAddress(ctx context.Context, contractID string, feedID *common.Hash) (int32, error) + FindJobIDsWithBridge(ctx context.Context, name string) ([]int32, error) + DeleteJob(ctx context.Context, id int32) error + RecordError(ctx context.Context, jobID int32, description string) error // TryRecordError is a helper which calls RecordError and logs the returned error if present. - TryRecordError(jobID int32, description string, qopts ...pg.QOpt) + TryRecordError(ctx context.Context, jobID int32, description string) DismissError(ctx context.Context, errorID int64) error - FindSpecError(id int64, qopts ...pg.QOpt) (SpecError, error) + FindSpecError(ctx context.Context, id int64) (SpecError, error) Close() error - PipelineRuns(jobID *int32, offset, size int) ([]pipeline.Run, int, error) + PipelineRuns(ctx context.Context, jobID *int32, offset, size int) ([]pipeline.Run, int, error) - FindPipelineRunIDsByJobID(jobID int32, offset, limit int) (ids []int64, err error) - FindPipelineRunsByIDs(ids []int64) (runs []pipeline.Run, err error) - CountPipelineRunsByJobID(jobID int32) (count int32, err error) + FindPipelineRunIDsByJobID(ctx context.Context, jobID int32, offset, limit int) (ids []int64, err error) + FindPipelineRunsByIDs(ctx context.Context, ids []int64) (runs []pipeline.Run, err error) + CountPipelineRunsByJobID(ctx context.Context, jobID int32) (count int32, err error) - FindJobsByPipelineSpecIDs(ids []int32) ([]Job, error) - FindPipelineRunByID(id int64) (pipeline.Run, error) + FindJobsByPipelineSpecIDs(ctx context.Context, ids []int32) ([]Job, error) + FindPipelineRunByID(ctx context.Context, id int64) (pipeline.Run, error) - FindSpecErrorsByJobIDs(ids []int32, qopts ...pg.QOpt) ([]SpecError, error) - FindJobWithoutSpecErrors(id int32) (jb Job, err error) + FindSpecErrorsByJobIDs(ctx context.Context, ids []int32) ([]SpecError, error) + FindJobWithoutSpecErrors(ctx context.Context, id int32) (jb Job, err error) - FindTaskResultByRunIDAndTaskName(runID int64, taskName string, qopts ...pg.QOpt) ([]byte, error) + FindTaskResultByRunIDAndTaskName(ctx context.Context, runID int64, taskName string) ([]byte, error) AssertBridgesExist(ctx context.Context, p pipeline.Pipeline) error + + DataSource() sqlutil.DataSource + WithDataSource(source sqlutil.DataSource) ORM } type ORMConfig interface { @@ -82,31 +85,56 @@ type ORMConfig interface { } type orm struct { - q pg.Q + ds sqlutil.DataSource keyStore keystore.Master pipelineORM pipeline.ORM lggr logger.SugaredLogger - cfg pg.QConfig bridgeORM bridges.ORM } var _ ORM = (*orm)(nil) -func NewORM(db *sqlx.DB, pipelineORM pipeline.ORM, bridgeORM bridges.ORM, keyStore keystore.Master, lggr logger.Logger, cfg pg.QConfig) *orm { +func NewORM(ds sqlutil.DataSource, pipelineORM pipeline.ORM, bridgeORM bridges.ORM, keyStore keystore.Master, lggr logger.Logger) *orm { namedLogger := logger.Sugared(lggr.Named("JobORM")) return &orm{ - q: pg.NewQ(db, namedLogger, cfg), + ds: ds, keyStore: keyStore, pipelineORM: pipelineORM, bridgeORM: bridgeORM, lggr: namedLogger, - cfg: cfg, } } + func (o *orm) Close() error { return nil } +func (o *orm) DataSource() sqlutil.DataSource { + return o.ds +} + +func (o *orm) WithDataSource(ds sqlutil.DataSource) ORM { return o.withDataSource(ds) } + +func (o *orm) withDataSource(ds sqlutil.DataSource) *orm { + n := &orm{ + ds: ds, + lggr: o.lggr, + keyStore: o.keyStore, + } + if o.bridgeORM != nil { + n.bridgeORM = o.bridgeORM.WithDataSource(ds) + } + if o.pipelineORM != nil { + n.pipelineORM = o.pipelineORM.WithDataSource(ds) + } + return n +} + +func (o *orm) transact(ctx context.Context, readOnly bool, fn func(*orm) error) error { + opts := &sqlutil.TxOptions{TxOptions: sql.TxOptions{ReadOnly: readOnly}} + return sqlutil.Transact(ctx, o.withDataSource, o.ds, opts, fn) +} + func (o *orm) AssertBridgesExist(ctx context.Context, p pipeline.Pipeline) error { var bridgeNames = make(map[bridges.BridgeName]struct{}) var uniqueBridges []bridges.BridgeName @@ -137,16 +165,14 @@ func (o *orm) AssertBridgesExist(ctx context.Context, p pipeline.Pipeline) error // CreateJob creates the job, and it's associated spec record. // Expects an unmarshalled job spec as the jb argument i.e. output from ValidatedXX. // Scans all persisted records back into jb -func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { - q := o.q.WithOpts(qopts...) +func (o *orm) CreateJob(ctx context.Context, jb *Job) error { p := jb.Pipeline - ctx := context.TODO() // TODO https://smartcontract-it.atlassian.net/browse/BCF-2887 if err := o.AssertBridgesExist(ctx, p); err != nil { return err } var jobID int32 - err := q.Transaction(func(tx pg.Queryer) error { + err := o.transact(ctx, false, func(tx *orm) error { // Autogenerate a job ID if not specified if jb.ExternalJobID == (uuid.UUID{}) { jb.ExternalJobID = uuid.New() @@ -157,26 +183,18 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { if jb.DirectRequestSpec.EVMChainID == nil { return errors.New("evm chain id must be defined") } - var specID int32 - sql := `INSERT INTO direct_request_specs (contract_address, min_incoming_confirmations, requesters, min_contract_payment, evm_chain_id, created_at, updated_at) - VALUES (:contract_address, :min_incoming_confirmations, :requesters, :min_contract_payment, :evm_chain_id, now(), now()) - RETURNING id;` - if err := pg.PrepareQueryRowx(tx, sql, &specID, jb.DirectRequestSpec); err != nil { - return errors.Wrap(err, "failed to create DirectRequestSpec") + specID, err := tx.insertDirectRequestSpec(ctx, jb.DirectRequestSpec) + if err != nil { + return fmt.Errorf("failed to create DirectRequestSpec for jobSpec: %w", err) } jb.DirectRequestSpecID = &specID case FluxMonitor: if jb.FluxMonitorSpec.EVMChainID == nil { return errors.New("evm chain id must be defined") } - var specID int32 - sql := `INSERT INTO flux_monitor_specs (contract_address, threshold, absolute_threshold, poll_timer_period, poll_timer_disabled, idle_timer_period, idle_timer_disabled, - drumbeat_schedule, drumbeat_random_delay, drumbeat_enabled, min_payment, evm_chain_id, created_at, updated_at) - VALUES (:contract_address, :threshold, :absolute_threshold, :poll_timer_period, :poll_timer_disabled, :idle_timer_period, :idle_timer_disabled, - :drumbeat_schedule, :drumbeat_random_delay, :drumbeat_enabled, :min_payment, :evm_chain_id, NOW(), NOW()) - RETURNING id;` - if err := pg.PrepareQueryRowx(tx, sql, &specID, jb.FluxMonitorSpec); err != nil { - return errors.Wrap(err, "failed to create FluxMonitorSpec") + specID, err := tx.insertFluxMonitorSpec(ctx, jb.FluxMonitorSpec) + if err != nil { + return fmt.Errorf("failed to create FluxMonitorSpec for jobSpec: %w", err) } jb.FluxMonitorSpecID = &specID case OffchainReporting: @@ -184,15 +202,14 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { return errors.New("evm chain id must be defined") } - var specID int32 if jb.OCROracleSpec.EncryptedOCRKeyBundleID != nil { - _, err := o.keyStore.OCR().Get(jb.OCROracleSpec.EncryptedOCRKeyBundleID.String()) + _, err := tx.keyStore.OCR().Get(jb.OCROracleSpec.EncryptedOCRKeyBundleID.String()) if err != nil { return errors.Wrapf(ErrNoSuchKeyBundle, "no key bundle with id: %x", jb.OCROracleSpec.EncryptedOCRKeyBundleID) } } if jb.OCROracleSpec.TransmitterAddress != nil { - _, err := o.keyStore.Eth().Get(q.ParentCtx, jb.OCROracleSpec.TransmitterAddress.Hex()) + _, err := tx.keyStore.Eth().Get(ctx, jb.OCROracleSpec.TransmitterAddress.Hex()) if err != nil { return errors.Wrapf(ErrNoSuchTransmitterKey, "no key matching transmitter address: %s", jb.OCROracleSpec.TransmitterAddress.Hex()) } @@ -200,7 +217,7 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { newChainID := jb.OCROracleSpec.EVMChainID existingSpec := new(OCROracleSpec) - err := tx.Get(existingSpec, `SELECT * FROM ocr_oracle_specs WHERE contract_address = $1 and (evm_chain_id = $2 or evm_chain_id IS NULL) LIMIT 1;`, + err := tx.ds.GetContext(ctx, existingSpec, `SELECT * FROM ocr_oracle_specs WHERE contract_address = $1 and (evm_chain_id = $2 or evm_chain_id IS NULL) LIMIT 1;`, jb.OCROracleSpec.ContractAddress, newChainID, ) @@ -212,23 +229,14 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { return errors.Errorf("a job with contract address %s already exists for chain ID %s", jb.OCROracleSpec.ContractAddress, newChainID) } - sql := `INSERT INTO ocr_oracle_specs (contract_address, p2pv2_bootstrappers, is_bootstrap_peer, encrypted_ocr_key_bundle_id, transmitter_address, - observation_timeout, blockchain_timeout, contract_config_tracker_subscribe_interval, contract_config_tracker_poll_interval, contract_config_confirmations, evm_chain_id, - created_at, updated_at, database_timeout, observation_grace_period, contract_transmitter_transmit_timeout) - VALUES (:contract_address, :p2pv2_bootstrappers, :is_bootstrap_peer, :encrypted_ocr_key_bundle_id, :transmitter_address, - :observation_timeout, :blockchain_timeout, :contract_config_tracker_subscribe_interval, :contract_config_tracker_poll_interval, :contract_config_confirmations, :evm_chain_id, - NOW(), NOW(), :database_timeout, :observation_grace_period, :contract_transmitter_transmit_timeout) - RETURNING id;` - err = pg.PrepareQueryRowx(tx, sql, &specID, jb.OCROracleSpec) + specID, err := tx.insertOCROracleSpec(ctx, jb.OCROracleSpec) if err != nil { - return errors.Wrap(err, "failed to create OffchainreportingOracleSpec") + return fmt.Errorf("failed to create OCROracleSpec for jobSpec: %w", err) } jb.OCROracleSpecID = &specID case OffchainReporting2: - var specID int32 - if jb.OCR2OracleSpec.OCRKeyBundleID.Valid { - _, err := o.keyStore.OCR2().Get(jb.OCR2OracleSpec.OCRKeyBundleID.String) + _, err := tx.keyStore.OCR2().Get(jb.OCR2OracleSpec.OCRKeyBundleID.String) if err != nil { return errors.Wrapf(ErrNoSuchKeyBundle, "no key bundle with id: %q", jb.OCR2OracleSpec.OCRKeyBundleID.ValueOrZero()) } @@ -239,7 +247,7 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { } // checks if they are present and if they are valid - sendingKeysDefined, err := areSendingKeysDefined(q.ParentCtx, jb, o.keyStore) + sendingKeysDefined, err := areSendingKeysDefined(ctx, jb, tx.keyStore) if err != nil { return err } @@ -249,7 +257,7 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { } if !sendingKeysDefined { - if err = ValidateKeyStoreMatch(q.ParentCtx, jb.OCR2OracleSpec, o.keyStore, jb.OCR2OracleSpec.TransmitterID.String); err != nil { + if err = ValidateKeyStoreMatch(ctx, jb.OCR2OracleSpec, tx.keyStore, jb.OCR2OracleSpec.TransmitterID.String); err != nil { return errors.Wrap(ErrNoSuchTransmitterKey, err.Error()) } } @@ -278,66 +286,36 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { if err2 != nil { return err2 } - if err2 = o.AssertBridgesExist(ctx, *feePipeline); err2 != nil { + if err2 = tx.AssertBridgesExist(ctx, *feePipeline); err2 != nil { return err2 } } - sql := `INSERT INTO ocr2_oracle_specs (contract_id, feed_id, relay, relay_config, plugin_type, plugin_config, p2pv2_bootstrappers, ocr_key_bundle_id, transmitter_id, - blockchain_timeout, contract_config_tracker_poll_interval, contract_config_confirmations, - created_at, updated_at) - VALUES (:contract_id, :feed_id, :relay, :relay_config, :plugin_type, :plugin_config, :p2pv2_bootstrappers, :ocr_key_bundle_id, :transmitter_id, - :blockchain_timeout, :contract_config_tracker_poll_interval, :contract_config_confirmations, - NOW(), NOW()) - RETURNING id;` - err = pg.PrepareQueryRowx(tx, sql, &specID, jb.OCR2OracleSpec) + specID, err := tx.insertOCR2OracleSpec(ctx, jb.OCR2OracleSpec) if err != nil { - return errors.Wrap(err, "failed to create Offchainreporting2OracleSpec") + return fmt.Errorf("failed to create OCR2OracleSpec for jobSpec: %w", err) } jb.OCR2OracleSpecID = &specID case Keeper: if jb.KeeperSpec.EVMChainID == nil { return errors.New("evm chain id must be defined") } - var specID int32 - sql := `INSERT INTO keeper_specs (contract_address, from_address, evm_chain_id, created_at, updated_at) - VALUES (:contract_address, :from_address, :evm_chain_id, NOW(), NOW()) - RETURNING id;` - if err := pg.PrepareQueryRowx(tx, sql, &specID, jb.KeeperSpec); err != nil { - return errors.Wrap(err, "failed to create KeeperSpec") + specID, err := tx.insertKeeperSpec(ctx, jb.KeeperSpec) + if err != nil { + return fmt.Errorf("failed to create KeeperSpec for jobSpec: %w", err) } jb.KeeperSpecID = &specID case Cron: - var specID int32 - sql := `INSERT INTO cron_specs (cron_schedule, created_at, updated_at) - VALUES (:cron_schedule, NOW(), NOW()) - RETURNING id;` - if err := pg.PrepareQueryRowx(tx, sql, &specID, jb.CronSpec); err != nil { - return errors.Wrap(err, "failed to create CronSpec") + specID, err := tx.insertCronSpec(ctx, jb.CronSpec) + if err != nil { + return fmt.Errorf("failed to create CronSpec for jobSpec: %w", err) } jb.CronSpecID = &specID case VRF: if jb.VRFSpec.EVMChainID == nil { return errors.New("evm chain id must be defined") } - var specID int32 - sql := `INSERT INTO vrf_specs ( - coordinator_address, public_key, min_incoming_confirmations, - evm_chain_id, from_addresses, poll_period, requested_confs_delay, - request_timeout, chunk_size, batch_coordinator_address, batch_fulfillment_enabled, - batch_fulfillment_gas_multiplier, backoff_initial_delay, backoff_max_delay, gas_lane_price, - vrf_owner_address, custom_reverts_pipeline_enabled, - created_at, updated_at) - VALUES ( - :coordinator_address, :public_key, :min_incoming_confirmations, - :evm_chain_id, :from_addresses, :poll_period, :requested_confs_delay, - :request_timeout, :chunk_size, :batch_coordinator_address, :batch_fulfillment_enabled, - :batch_fulfillment_gas_multiplier, :backoff_initial_delay, :backoff_max_delay, :gas_lane_price, - :vrf_owner_address, :custom_reverts_pipeline_enabled, - NOW(), NOW()) - RETURNING id;` - - err := pg.PrepareQueryRowx(tx, sql, &specID, toVRFSpecRow(jb.VRFSpec)) + specID, err := tx.insertVRFSpec(ctx, jb.VRFSpec) var pqErr *pgconn.PgError ok := errors.As(err, &pqErr) if err != nil && ok && pqErr.Code == "23503" { @@ -346,11 +324,11 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { } } if err != nil { - return errors.Wrap(err, "failed to create VRFSpec") + return fmt.Errorf("failed to create VRFSpec for jobSpec: %w", err) } jb.VRFSpecID = &specID case Webhook: - err := o.InsertWebhookSpec(jb.WebhookSpec, pg.WithQueryer(tx)) + err := tx.InsertWebhookSpec(ctx, jb.WebhookSpec) if err != nil { return errors.Wrap(err, "failed to create WebhookSpec") } @@ -362,11 +340,7 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { } sql := `INSERT INTO external_initiator_webhook_specs (external_initiator_id, webhook_spec_id, spec) VALUES (:external_initiator_id, :webhook_spec_id, :spec);` - query, args, err := tx.BindNamed(sql, jb.WebhookSpec.ExternalInitiatorWebhookSpecs) - if err != nil { - return errors.Wrap(err, "failed to bindquery for ExternalInitiatorWebhookSpecs") - } - if _, err = tx.Exec(query, args...); err != nil { + if _, err := tx.ds.NamedExecContext(ctx, sql, jb.WebhookSpec.ExternalInitiatorWebhookSpecs); err != nil { return errors.Wrap(err, "failed to create ExternalInitiatorWebhookSpecs") } } @@ -374,80 +348,58 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { if jb.BlockhashStoreSpec.EVMChainID == nil { return errors.New("evm chain id must be defined") } - var specID int32 - sql := `INSERT INTO blockhash_store_specs (coordinator_v1_address, coordinator_v2_address, coordinator_v2_plus_address, trusted_blockhash_store_address, trusted_blockhash_store_batch_size, wait_blocks, lookback_blocks, heartbeat_period, blockhash_store_address, poll_period, run_timeout, evm_chain_id, from_addresses, created_at, updated_at) - VALUES (:coordinator_v1_address, :coordinator_v2_address, :coordinator_v2_plus_address, :trusted_blockhash_store_address, :trusted_blockhash_store_batch_size, :wait_blocks, :lookback_blocks, :heartbeat_period, :blockhash_store_address, :poll_period, :run_timeout, :evm_chain_id, :from_addresses, NOW(), NOW()) - RETURNING id;` - if err := pg.PrepareQueryRowx(tx, sql, &specID, toBlockhashStoreSpecRow(jb.BlockhashStoreSpec)); err != nil { - return errors.Wrap(err, "failed to create BlockhashStore spec") + specID, err := tx.insertBlockhashStoreSpec(ctx, jb.BlockhashStoreSpec) + if err != nil { + return fmt.Errorf("failed to create BlockhashStoreSpec for jobSpec: %w", err) } jb.BlockhashStoreSpecID = &specID case BlockHeaderFeeder: if jb.BlockHeaderFeederSpec.EVMChainID == nil { return errors.New("evm chain id must be defined") } - var specID int32 - sql := `INSERT INTO block_header_feeder_specs (coordinator_v1_address, coordinator_v2_address, coordinator_v2_plus_address, wait_blocks, lookback_blocks, blockhash_store_address, batch_blockhash_store_address, poll_period, run_timeout, evm_chain_id, from_addresses, get_blockhashes_batch_size, store_blockhashes_batch_size, created_at, updated_at) - VALUES (:coordinator_v1_address, :coordinator_v2_address, :coordinator_v2_plus_address, :wait_blocks, :lookback_blocks, :blockhash_store_address, :batch_blockhash_store_address, :poll_period, :run_timeout, :evm_chain_id, :from_addresses, :get_blockhashes_batch_size, :store_blockhashes_batch_size, NOW(), NOW()) - RETURNING id;` - if err := pg.PrepareQueryRowx(tx, sql, &specID, toBlockHeaderFeederSpecRow(jb.BlockHeaderFeederSpec)); err != nil { - return errors.Wrap(err, "failed to create BlockHeaderFeeder spec") + specID, err := tx.insertBlockHeaderFeederSpec(ctx, jb.BlockHeaderFeederSpec) + if err != nil { + return fmt.Errorf("failed to create BlockHeaderFeederSpec for jobSpec: %w", err) } jb.BlockHeaderFeederSpecID = &specID case LegacyGasStationServer: if jb.LegacyGasStationServerSpec.EVMChainID == nil { return errors.New("evm chain id must be defined") } - var specID int32 - sql := `INSERT INTO legacy_gas_station_server_specs (forwarder_address, evm_chain_id, ccip_chain_selector, from_addresses, created_at, updated_at) - VALUES (:forwarder_address, :evm_chain_id, :ccip_chain_selector, :from_addresses, NOW(), NOW()) - RETURNING id;` - if err := pg.PrepareQueryRowx(tx, sql, &specID, toLegacyGasStationServerSpecRow(jb.LegacyGasStationServerSpec)); err != nil { - return errors.Wrap(err, "failed to create LegacyGasStationServer spec") + specID, err := tx.insertLegacyGasStationServerSpec(ctx, jb.LegacyGasStationServerSpec) + if err != nil { + return fmt.Errorf("failed to create LegacyGasStationServerSpec for jobSpec: %w", err) } jb.LegacyGasStationServerSpecID = &specID case LegacyGasStationSidecar: if jb.LegacyGasStationSidecarSpec.EVMChainID == nil { return errors.New("evm chain id must be defined") } - var specID int32 - sql := `INSERT INTO legacy_gas_station_sidecar_specs (forwarder_address, off_ramp_address, lookback_blocks, poll_period, run_timeout, evm_chain_id, ccip_chain_selector, created_at, updated_at) - VALUES (:forwarder_address, :off_ramp_address, :lookback_blocks, :poll_period, :run_timeout, :evm_chain_id, :ccip_chain_selector, NOW(), NOW()) - RETURNING id;` - if err := pg.PrepareQueryRowx(tx, sql, &specID, jb.LegacyGasStationSidecarSpec); err != nil { - return errors.Wrap(err, "failed to create LegacyGasStationSidecar spec") + specID, err := tx.insertLegacyGasStationSidecarSpec(ctx, jb.LegacyGasStationSidecarSpec) + if err != nil { + return fmt.Errorf("failed to create LegacyGasStationSidecarSpec for jobSpec: %w", err) } jb.LegacyGasStationSidecarSpecID = &specID case Bootstrap: - var specID int32 - sql := `INSERT INTO bootstrap_specs (contract_id, feed_id, relay, relay_config, monitoring_endpoint, - blockchain_timeout, contract_config_tracker_poll_interval, - contract_config_confirmations, created_at, updated_at) - VALUES (:contract_id, :feed_id, :relay, :relay_config, :monitoring_endpoint, - :blockchain_timeout, :contract_config_tracker_poll_interval, - :contract_config_confirmations, NOW(), NOW()) - RETURNING id;` - if err := pg.PrepareQueryRowx(tx, sql, &specID, jb.BootstrapSpec); err != nil { - return errors.Wrap(err, "failed to create BootstrapSpec for jobSpec") + specID, err := tx.insertBootstrapSpec(ctx, jb.BootstrapSpec) + if err != nil { + return fmt.Errorf("failed to create BootstrapSpec for jobSpec: %w", err) } jb.BootstrapSpecID = &specID case Gateway: - var specID int32 - sql := `INSERT INTO gateway_specs (gateway_config, created_at, updated_at) - VALUES (:gateway_config, NOW(), NOW()) - RETURNING id;` - if err := pg.PrepareQueryRowx(tx, sql, &specID, jb.GatewaySpec); err != nil { - return errors.Wrap(err, "failed to create GatewaySpec for jobSpec") + specID, err := tx.insertGatewaySpec(ctx, jb.GatewaySpec) + if err != nil { + return fmt.Errorf("failed to create GatewaySpec for jobSpec: %w", err) } jb.GatewaySpecID = &specID case Stream: // 'stream' type has no associated spec, nothing to do here case Workflow: - var specID int32 sql := `INSERT INTO workflow_specs (workflow, workflow_id, workflow_owner, created_at, updated_at) VALUES (:workflow, :workflow_id, :workflow_owner, NOW(), NOW()) RETURNING id;` - if err := pg.PrepareQueryRowx(tx, sql, &specID, jb.WorkflowSpec); err != nil { + specID, err := tx.prepareQuerySpecID(ctx, sql, jb.WorkflowSpec) + if err != nil { return errors.Wrap(err, "failed to create WorkflowSpec for jobSpec") } jb.WorkflowSpecID = &specID @@ -455,14 +407,14 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { o.lggr.Panicf("Unsupported jb.Type: %v", jb.Type) } - pipelineSpecID, err := o.pipelineORM.CreateSpec(ctx, tx, p, jb.MaxTaskDuration) + pipelineSpecID, err := tx.pipelineORM.CreateSpec(ctx, p, jb.MaxTaskDuration) if err != nil { return errors.Wrap(err, "failed to create pipeline spec") } jb.PipelineSpecID = pipelineSpecID - err = o.InsertJob(jb, pg.WithQueryer(tx)) + err = tx.InsertJob(ctx, jb) jobID = jb.ID return errors.Wrap(err, "failed to insert job") }) @@ -470,7 +422,122 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { return errors.Wrap(err, "CreateJobFailed") } - return o.findJob(jb, "id", jobID, qopts...) + return o.findJob(ctx, jb, "id", jobID) +} + +func (o *orm) prepareQuerySpecID(ctx context.Context, sql string, arg any) (specID int32, err error) { + var stmt *sqlx.NamedStmt + stmt, err = o.ds.PrepareNamedContext(ctx, sql) + if err != nil { + return + } + defer stmt.Close() + err = stmt.QueryRowxContext(ctx, arg).Scan(&specID) + return +} + +func (o *orm) insertDirectRequestSpec(ctx context.Context, spec *DirectRequestSpec) (specID int32, err error) { + return o.prepareQuerySpecID(ctx, `INSERT INTO direct_request_specs (contract_address, min_incoming_confirmations, requesters, min_contract_payment, evm_chain_id, created_at, updated_at) + VALUES (:contract_address, :min_incoming_confirmations, :requesters, :min_contract_payment, :evm_chain_id, now(), now()) + RETURNING id;`, spec) +} + +func (o *orm) insertFluxMonitorSpec(ctx context.Context, spec *FluxMonitorSpec) (specID int32, err error) { + return o.prepareQuerySpecID(ctx, `INSERT INTO flux_monitor_specs (contract_address, threshold, absolute_threshold, poll_timer_period, poll_timer_disabled, idle_timer_period, idle_timer_disabled, + drumbeat_schedule, drumbeat_random_delay, drumbeat_enabled, min_payment, evm_chain_id, created_at, updated_at) + VALUES (:contract_address, :threshold, :absolute_threshold, :poll_timer_period, :poll_timer_disabled, :idle_timer_period, :idle_timer_disabled, + :drumbeat_schedule, :drumbeat_random_delay, :drumbeat_enabled, :min_payment, :evm_chain_id, NOW(), NOW()) + RETURNING id;`, spec) +} + +func (o *orm) insertOCROracleSpec(ctx context.Context, spec *OCROracleSpec) (specID int32, err error) { + return o.prepareQuerySpecID(ctx, `INSERT INTO ocr_oracle_specs (contract_address, p2pv2_bootstrappers, is_bootstrap_peer, encrypted_ocr_key_bundle_id, transmitter_address, + observation_timeout, blockchain_timeout, contract_config_tracker_subscribe_interval, contract_config_tracker_poll_interval, contract_config_confirmations, evm_chain_id, + created_at, updated_at, database_timeout, observation_grace_period, contract_transmitter_transmit_timeout) + VALUES (:contract_address, :p2pv2_bootstrappers, :is_bootstrap_peer, :encrypted_ocr_key_bundle_id, :transmitter_address, + :observation_timeout, :blockchain_timeout, :contract_config_tracker_subscribe_interval, :contract_config_tracker_poll_interval, :contract_config_confirmations, :evm_chain_id, + NOW(), NOW(), :database_timeout, :observation_grace_period, :contract_transmitter_transmit_timeout) + RETURNING id;`, spec) +} + +func (o *orm) insertOCR2OracleSpec(ctx context.Context, spec *OCR2OracleSpec) (specID int32, err error) { + return o.prepareQuerySpecID(ctx, `INSERT INTO ocr2_oracle_specs (contract_id, feed_id, relay, relay_config, plugin_type, plugin_config, p2pv2_bootstrappers, ocr_key_bundle_id, transmitter_id, + blockchain_timeout, contract_config_tracker_poll_interval, contract_config_confirmations, + created_at, updated_at) + VALUES (:contract_id, :feed_id, :relay, :relay_config, :plugin_type, :plugin_config, :p2pv2_bootstrappers, :ocr_key_bundle_id, :transmitter_id, + :blockchain_timeout, :contract_config_tracker_poll_interval, :contract_config_confirmations, + NOW(), NOW()) + RETURNING id;`, spec) +} + +func (o *orm) insertKeeperSpec(ctx context.Context, spec *KeeperSpec) (specID int32, err error) { + return o.prepareQuerySpecID(ctx, `INSERT INTO keeper_specs (contract_address, from_address, evm_chain_id, created_at, updated_at) + VALUES (:contract_address, :from_address, :evm_chain_id, NOW(), NOW()) + RETURNING id;`, spec) +} + +func (o *orm) insertCronSpec(ctx context.Context, spec *CronSpec) (specID int32, err error) { + return o.prepareQuerySpecID(ctx, `INSERT INTO cron_specs (cron_schedule, created_at, updated_at) + VALUES (:cron_schedule, NOW(), NOW()) + RETURNING id;`, spec) +} + +func (o *orm) insertVRFSpec(ctx context.Context, spec *VRFSpec) (specID int32, err error) { + return o.prepareQuerySpecID(ctx, `INSERT INTO vrf_specs ( + coordinator_address, public_key, min_incoming_confirmations, + evm_chain_id, from_addresses, poll_period, requested_confs_delay, + request_timeout, chunk_size, batch_coordinator_address, batch_fulfillment_enabled, + batch_fulfillment_gas_multiplier, backoff_initial_delay, backoff_max_delay, gas_lane_price, + vrf_owner_address, custom_reverts_pipeline_enabled, + created_at, updated_at) + VALUES ( + :coordinator_address, :public_key, :min_incoming_confirmations, + :evm_chain_id, :from_addresses, :poll_period, :requested_confs_delay, + :request_timeout, :chunk_size, :batch_coordinator_address, :batch_fulfillment_enabled, + :batch_fulfillment_gas_multiplier, :backoff_initial_delay, :backoff_max_delay, :gas_lane_price, + :vrf_owner_address, :custom_reverts_pipeline_enabled, + NOW(), NOW()) + RETURNING id;`, toVRFSpecRow(spec)) +} + +func (o *orm) insertBlockhashStoreSpec(ctx context.Context, spec *BlockhashStoreSpec) (specID int32, err error) { + return o.prepareQuerySpecID(ctx, `INSERT INTO blockhash_store_specs (coordinator_v1_address, coordinator_v2_address, coordinator_v2_plus_address, trusted_blockhash_store_address, trusted_blockhash_store_batch_size, wait_blocks, lookback_blocks, heartbeat_period, blockhash_store_address, poll_period, run_timeout, evm_chain_id, from_addresses, created_at, updated_at) + VALUES (:coordinator_v1_address, :coordinator_v2_address, :coordinator_v2_plus_address, :trusted_blockhash_store_address, :trusted_blockhash_store_batch_size, :wait_blocks, :lookback_blocks, :heartbeat_period, :blockhash_store_address, :poll_period, :run_timeout, :evm_chain_id, :from_addresses, NOW(), NOW()) + RETURNING id;`, toBlockhashStoreSpecRow(spec)) +} + +func (o *orm) insertBlockHeaderFeederSpec(ctx context.Context, spec *BlockHeaderFeederSpec) (specID int32, err error) { + return o.prepareQuerySpecID(ctx, `INSERT INTO block_header_feeder_specs (coordinator_v1_address, coordinator_v2_address, coordinator_v2_plus_address, wait_blocks, lookback_blocks, blockhash_store_address, batch_blockhash_store_address, poll_period, run_timeout, evm_chain_id, from_addresses, get_blockhashes_batch_size, store_blockhashes_batch_size, created_at, updated_at) + VALUES (:coordinator_v1_address, :coordinator_v2_address, :coordinator_v2_plus_address, :wait_blocks, :lookback_blocks, :blockhash_store_address, :batch_blockhash_store_address, :poll_period, :run_timeout, :evm_chain_id, :from_addresses, :get_blockhashes_batch_size, :store_blockhashes_batch_size, NOW(), NOW()) + RETURNING id;`, toBlockHeaderFeederSpecRow(spec)) +} + +func (o *orm) insertLegacyGasStationServerSpec(ctx context.Context, spec *LegacyGasStationServerSpec) (specID int32, err error) { + return o.prepareQuerySpecID(ctx, `INSERT INTO legacy_gas_station_server_specs (forwarder_address, evm_chain_id, ccip_chain_selector, from_addresses, created_at, updated_at) + VALUES (:forwarder_address, :evm_chain_id, :ccip_chain_selector, :from_addresses, NOW(), NOW()) + RETURNING id;`, toLegacyGasStationServerSpecRow(spec)) +} + +func (o *orm) insertLegacyGasStationSidecarSpec(ctx context.Context, spec *LegacyGasStationSidecarSpec) (specID int32, err error) { + return o.prepareQuerySpecID(ctx, `INSERT INTO legacy_gas_station_sidecar_specs (forwarder_address, off_ramp_address, lookback_blocks, poll_period, run_timeout, evm_chain_id, ccip_chain_selector, created_at, updated_at) + VALUES (:forwarder_address, :off_ramp_address, :lookback_blocks, :poll_period, :run_timeout, :evm_chain_id, :ccip_chain_selector, NOW(), NOW()) + RETURNING id;`, spec) +} + +func (o *orm) insertBootstrapSpec(ctx context.Context, spec *BootstrapSpec) (specID int32, err error) { + return o.prepareQuerySpecID(ctx, `INSERT INTO bootstrap_specs (contract_id, feed_id, relay, relay_config, monitoring_endpoint, + blockchain_timeout, contract_config_tracker_poll_interval, + contract_config_confirmations, created_at, updated_at) + VALUES (:contract_id, :feed_id, :relay, :relay_config, :monitoring_endpoint, + :blockchain_timeout, :contract_config_tracker_poll_interval, + :contract_config_confirmations, NOW(), NOW()) + RETURNING id;`, spec) +} + +func (o *orm) insertGatewaySpec(ctx context.Context, spec *GatewaySpec) (specID int32, err error) { + return o.prepareQuerySpecID(ctx, `INSERT INTO gateway_specs (gateway_config, created_at, updated_at) + VALUES (:gateway_config, NOW(), NOW()) + RETURNING id;`, spec) } // ValidateKeyStoreMatch confirms that the key has a valid match in the keystore @@ -531,17 +598,18 @@ func areSendingKeysDefined(ctx context.Context, jb *Job, keystore keystore.Maste return false, nil } -func (o *orm) InsertWebhookSpec(webhookSpec *WebhookSpec, qopts ...pg.QOpt) error { - q := o.q.WithOpts(qopts...) - query := `INSERT INTO webhook_specs (created_at, updated_at) +func (o *orm) InsertWebhookSpec(ctx context.Context, webhookSpec *WebhookSpec) error { + query, args, err := o.ds.BindNamed(`INSERT INTO webhook_specs (created_at, updated_at) VALUES (NOW(), NOW()) - RETURNING *;` - return q.GetNamed(query, webhookSpec, webhookSpec) + RETURNING *;`, webhookSpec) + if err != nil { + return fmt.Errorf("error binding arg: %w", err) + } + return o.ds.GetContext(ctx, webhookSpec, query, args...) } -func (o *orm) InsertJob(job *Job, qopts ...pg.QOpt) error { - q := o.q.WithOpts(qopts...) - return q.Transaction(func(querier pg.Queryer) error { +func (o *orm) InsertJob(ctx context.Context, job *Job) error { + return o.transact(ctx, false, func(tx *orm) error { var query string // if job has id, emplace otherwise insert with a new id. @@ -562,26 +630,30 @@ func (o *orm) InsertJob(job *Job, qopts ...pg.QOpt) error { :legacy_gas_station_server_spec_id, :legacy_gas_station_sidecar_spec_id, :workflow_spec_id, :external_job_id, :gas_limit, :forwarding_allowed, NOW()) RETURNING *;` } - err := q.GetNamed(query, job, job) + query, args, err := tx.ds.BindNamed(query, job) + if err != nil { + return fmt.Errorf("error binding arg: %w", err) + } + err = tx.ds.GetContext(ctx, job, query, args...) if err != nil { return err } // Always inserts the `job_pipeline_specs` record as primary, since this is the first one for the job. sqlStmt := `INSERT INTO job_pipeline_specs (job_id, pipeline_spec_id, is_primary) VALUES ($1, $2, true)` - _, err = q.Exec(sqlStmt, job.ID, job.PipelineSpecID) + _, err = tx.ds.ExecContext(ctx, sqlStmt, job.ID, job.PipelineSpecID) return errors.Wrap(err, "failed to insert job_pipeline_specs relationship") }) } // DeleteJob removes a job -func (o *orm) DeleteJob(id int32, qopts ...pg.QOpt) error { +func (o *orm) DeleteJob(ctx context.Context, id int32) error { o.lggr.Debugw("Deleting job", "jobID", id) // Added a 1-minute timeout to this query since this can take a long time as data increases. // This was added specifically due to an issue with a database that had a million of pipeline_runs and pipeline_task_runs // and this query was taking ~40secs. - qopts = append(qopts, pg.WithLongQueryTimeout()) - q := o.q.WithOpts(qopts...) + ctx, cancel := context.WithTimeout(sqlutil.WithoutDefaultTimeout(ctx), time.Minute) + defer cancel() query := ` WITH deleted_jobs AS ( DELETE FROM jobs WHERE id = $1 RETURNING @@ -643,8 +715,7 @@ func (o *orm) DeleteJob(id int32, qopts ...pg.QOpt) error { DELETE FROM job_pipeline_specs WHERE job_id IN (SELECT id FROM deleted_jobs) RETURNING pipeline_spec_id ) DELETE FROM pipeline_specs WHERE id IN (SELECT pipeline_spec_id FROM deleted_job_pipeline_specs)` - res, cancel, err := q.ExecQIter(query, id) - defer cancel() + res, err := o.ds.ExecContext(ctx, query, id) if err != nil { return errors.Wrap(err, "DeleteJob failed to delete job") } @@ -659,14 +730,13 @@ func (o *orm) DeleteJob(id int32, qopts ...pg.QOpt) error { return nil } -func (o *orm) RecordError(jobID int32, description string, qopts ...pg.QOpt) error { - q := o.q.WithOpts(qopts...) +func (o *orm) RecordError(ctx context.Context, jobID int32, description string) error { sql := `INSERT INTO job_spec_errors (job_id, description, occurrences, created_at, updated_at) VALUES ($1, $2, 1, $3, $3) ON CONFLICT (job_id, description) DO UPDATE SET occurrences = job_spec_errors.occurrences + 1, updated_at = excluded.updated_at` - err := q.ExecQ(sql, jobID, description, time.Now()) + _, err := o.ds.ExecContext(ctx, sql, jobID, description, time.Now()) // Noop if the job has been deleted. var pqErr *pgconn.PgError ok := errors.As(err, &pqErr) @@ -677,15 +747,13 @@ func (o *orm) RecordError(jobID int32, description string, qopts ...pg.QOpt) err } return err } -func (o *orm) TryRecordError(jobID int32, description string, qopts ...pg.QOpt) { - err := o.RecordError(jobID, description, qopts...) +func (o *orm) TryRecordError(ctx context.Context, jobID int32, description string) { + err := o.RecordError(ctx, jobID, description) o.lggr.ErrorIf(err, fmt.Sprintf("Error creating SpecError %v", description)) } func (o *orm) DismissError(ctx context.Context, ID int64) error { - q := o.q.WithOpts(pg.WithParentCtx(ctx)) - res, cancel, err := q.ExecQIter("DELETE FROM job_spec_errors WHERE id = $1", ID) - defer cancel() + res, err := o.ds.ExecContext(ctx, "DELETE FROM job_spec_errors WHERE id = $1", ID) if err != nil { return errors.Wrap(err, "failed to dismiss error") } @@ -699,35 +767,35 @@ func (o *orm) DismissError(ctx context.Context, ID int64) error { return nil } -func (o *orm) FindSpecError(id int64, qopts ...pg.QOpt) (SpecError, error) { +func (o *orm) FindSpecError(ctx context.Context, id int64) (SpecError, error) { stmt := `SELECT * FROM job_spec_errors WHERE id = $1;` specErr := new(SpecError) - err := o.q.WithOpts(qopts...).Get(specErr, stmt, id) + err := o.ds.GetContext(ctx, specErr, stmt, id) return *specErr, errors.Wrap(err, "FindSpecError failed") } -func (o *orm) FindJobs(offset, limit int) (jobs []Job, count int, err error) { - err = o.q.Transaction(func(tx pg.Queryer) error { +func (o *orm) FindJobs(ctx context.Context, offset, limit int) (jobs []Job, count int, err error) { + err = o.transact(ctx, false, func(tx *orm) error { sql := `SELECT count(*) FROM jobs;` - err = tx.QueryRowx(sql).Scan(&count) + err = tx.ds.QueryRowxContext(ctx, sql).Scan(&count) if err != nil { - return err + return fmt.Errorf("failed to query jobs count: %w", err) } sql = `SELECT jobs.*, job_pipeline_specs.pipeline_spec_id as pipeline_spec_id FROM jobs JOIN job_pipeline_specs ON (jobs.id = job_pipeline_specs.job_id) ORDER BY jobs.created_at DESC, jobs.id DESC OFFSET $1 LIMIT $2;` - err = tx.Select(&jobs, sql, offset, limit) + err = tx.ds.SelectContext(ctx, &jobs, sql, offset, limit) if err != nil { - return err + return fmt.Errorf("failed to select jobs: %w", err) } - err = LoadAllJobsTypes(tx, jobs) + err = tx.loadAllJobsTypes(ctx, jobs) if err != nil { - return err + return fmt.Errorf("failed to load job types: %w", err) } return nil @@ -820,32 +888,30 @@ func LoadConfigVarsOCR(evmOcrCfg evmconfig.OCR, ocrCfg OCRConfig, os OCROracleSp } func (o *orm) FindJobTx(ctx context.Context, id int32) (Job, error) { - ctx, cancel := context.WithTimeout(ctx, o.cfg.DefaultQueryTimeout()) - defer cancel() return o.FindJob(ctx, id) } // FindJob returns job by ID, with all relations preloaded func (o *orm) FindJob(ctx context.Context, id int32) (jb Job, err error) { - err = o.findJob(&jb, "id", id, pg.WithParentCtx(ctx)) + err = o.findJob(ctx, &jb, "id", id) return } // FindJobWithoutSpecErrors returns a job by ID, without loading Spec Errors preloaded -func (o *orm) FindJobWithoutSpecErrors(id int32) (jb Job, err error) { - err = o.q.Transaction(func(tx pg.Queryer) error { +func (o *orm) FindJobWithoutSpecErrors(ctx context.Context, id int32) (jb Job, err error) { + err = o.transact(ctx, true, func(tx *orm) error { stmt := "SELECT jobs.*, job_pipeline_specs.pipeline_spec_id as pipeline_spec_id FROM jobs JOIN job_pipeline_specs ON (jobs.id = job_pipeline_specs.job_id) WHERE jobs.id = $1 LIMIT 1" - err = tx.Get(&jb, stmt, id) + err = tx.ds.GetContext(ctx, &jb, stmt, id) if err != nil { return errors.Wrap(err, "failed to load job") } - if err = LoadAllJobTypes(tx, &jb); err != nil { + if err = tx.loadAllJobTypes(ctx, &jb); err != nil { return errors.Wrap(err, "failed to load job types") } return nil - }, pg.OptReadOnlyTx()) + }) if err != nil { return jb, errors.Wrap(err, "FindJobWithoutSpecErrors failed") } @@ -854,87 +920,76 @@ func (o *orm) FindJobWithoutSpecErrors(id int32) (jb Job, err error) { } // FindSpecErrorsByJobIDs returns all jobs spec errors by jobs IDs -func (o *orm) FindSpecErrorsByJobIDs(ids []int32, qopts ...pg.QOpt) ([]SpecError, error) { +func (o *orm) FindSpecErrorsByJobIDs(ctx context.Context, ids []int32) ([]SpecError, error) { stmt := `SELECT * FROM job_spec_errors WHERE job_id = ANY($1);` var specErrs []SpecError - err := o.q.WithOpts(qopts...).Select(&specErrs, stmt, ids) + err := o.ds.SelectContext(ctx, &specErrs, stmt, ids) return specErrs, errors.Wrap(err, "FindSpecErrorsByJobIDs failed") } -func (o *orm) FindJobByExternalJobID(externalJobID uuid.UUID, qopts ...pg.QOpt) (jb Job, err error) { - err = o.findJob(&jb, "external_job_id", externalJobID, qopts...) +func (o *orm) FindJobByExternalJobID(ctx context.Context, externalJobID uuid.UUID) (jb Job, err error) { + err = o.findJob(ctx, &jb, "external_job_id", externalJobID) return } // FindJobIDByAddress - finds a job id by contract address. Currently only OCR and FM jobs are supported -func (o *orm) FindJobIDByAddress(address evmtypes.EIP55Address, evmChainID *big.Big, qopts ...pg.QOpt) (jobID int32, err error) { - q := o.q.WithOpts(qopts...) - err = q.Transaction(func(tx pg.Queryer) error { - stmt := ` +func (o *orm) FindJobIDByAddress(ctx context.Context, address evmtypes.EIP55Address, evmChainID *big.Big) (jobID int32, err error) { + stmt := ` SELECT jobs.id FROM jobs LEFT JOIN ocr_oracle_specs ocrspec on ocrspec.contract_address = $1 AND (ocrspec.evm_chain_id = $2 OR ocrspec.evm_chain_id IS NULL) AND ocrspec.id = jobs.ocr_oracle_spec_id LEFT JOIN flux_monitor_specs fmspec on fmspec.contract_address = $1 AND (fmspec.evm_chain_id = $2 OR fmspec.evm_chain_id IS NULL) AND fmspec.id = jobs.flux_monitor_spec_id WHERE ocrspec.id IS NOT NULL OR fmspec.id IS NOT NULL ` - err = tx.Get(&jobID, stmt, address, evmChainID) - + err = o.ds.GetContext(ctx, &jobID, stmt, address, evmChainID) + if err != nil { if !errors.Is(err, sql.ErrNoRows) { - if err != nil { - return errors.Wrap(err, "error searching for job by contract address") - } - return nil + err = errors.Wrap(err, "error searching for job by contract address") } + err = errors.Wrap(err, "FindJobIDByAddress failed") + return + } - return err - }) - - return jobID, errors.Wrap(err, "FindJobIDByAddress failed") + return } -func (o *orm) FindOCR2JobIDByAddress(contractID string, feedID *common.Hash, qopts ...pg.QOpt) (jobID int32, err error) { - q := o.q.WithOpts(qopts...) - err = q.Transaction(func(tx pg.Queryer) error { - // NOTE: We want to explicitly match on NULL feed_id hence usage of `IS - // NOT DISTINCT FROM` instead of `=` - stmt := ` +func (o *orm) FindOCR2JobIDByAddress(ctx context.Context, contractID string, feedID *common.Hash) (jobID int32, err error) { + // NOTE: We want to explicitly match on NULL feed_id hence usage of `IS + // NOT DISTINCT FROM` instead of `=` + stmt := ` SELECT jobs.id FROM jobs LEFT JOIN ocr2_oracle_specs ocr2spec on ocr2spec.contract_id = $1 AND ocr2spec.feed_id IS NOT DISTINCT FROM $2 AND ocr2spec.id = jobs.ocr2_oracle_spec_id LEFT JOIN bootstrap_specs bs on bs.contract_id = $1 AND bs.feed_id IS NOT DISTINCT FROM $2 AND bs.id = jobs.bootstrap_spec_id WHERE ocr2spec.id IS NOT NULL OR bs.id IS NOT NULL ` - err = tx.Get(&jobID, stmt, contractID, feedID) - + err = o.ds.GetContext(ctx, &jobID, stmt, contractID, feedID) + if err != nil { if !errors.Is(err, sql.ErrNoRows) { - if err != nil { - return errors.Wrapf(err, "error searching for job by contract id=%s and feed id=%s", contractID, feedID) - } - return nil + err = errors.Wrapf(err, "error searching for job by contract id=%s and feed id=%s", contractID, feedID) } + err = errors.Wrap(err, "FindOCR2JobIDByAddress failed") + return + } - return err - }) - - return jobID, errors.Wrap(err, "FindOCR2JobIDByAddress failed") + return } -func (o *orm) findJob(jb *Job, col string, arg interface{}, qopts ...pg.QOpt) error { - q := o.q.WithOpts(qopts...) - err := q.Transaction(func(tx pg.Queryer) error { +func (o *orm) findJob(ctx context.Context, jb *Job, col string, arg interface{}) error { + err := o.transact(ctx, false, func(tx *orm) error { sql := fmt.Sprintf(`SELECT jobs.*, job_pipeline_specs.pipeline_spec_id FROM jobs JOIN job_pipeline_specs ON (jobs.id = job_pipeline_specs.job_id) WHERE jobs.%s = $1 AND job_pipeline_specs.is_primary = true LIMIT 1`, col) - err := tx.Get(jb, sql, arg) + err := tx.ds.GetContext(ctx, jb, sql, arg) if err != nil { return errors.Wrap(err, "failed to load job") } - if err = LoadAllJobTypes(tx, jb); err != nil { + if err = tx.loadAllJobTypes(ctx, jb); err != nil { return err } - return loadJobSpecErrors(tx, jb) + return tx.loadJobSpecErrors(ctx, jb) }) if err != nil { return errors.Wrap(err, "findJob failed") @@ -942,62 +997,62 @@ func (o *orm) findJob(jb *Job, col string, arg interface{}, qopts ...pg.QOpt) er return nil } -func (o *orm) FindJobIDsWithBridge(name string) (jids []int32, err error) { - err = o.q.Transaction(func(tx pg.Queryer) error { - query := `SELECT +func (o *orm) FindJobIDsWithBridge(ctx context.Context, name string) (jids []int32, err error) { + query := `SELECT jobs.id, pipeline_specs.dot_dag_source FROM jobs JOIN job_pipeline_specs ON job_pipeline_specs.job_id = jobs.id JOIN pipeline_specs ON pipeline_specs.id = job_pipeline_specs.pipeline_spec_id WHERE pipeline_specs.dot_dag_source ILIKE '%' || $1 || '%' ORDER BY id` + var rows *sqlx.Rows + rows, err = o.ds.QueryxContext(ctx, query, name) + if err != nil { + return + } + defer rows.Close() + var ids []int32 + var sources []string + for rows.Next() { + var id int32 + var source string + if err = rows.Scan(&id, &source); err != nil { + return + } + ids = append(jids, id) + sources = append(sources, source) + } + if err = rows.Err(); err != nil { + return + } - var rows *sqlx.Rows - rows, err = tx.Queryx(query, name) + for i, id := range ids { + var p *pipeline.Pipeline + p, err = pipeline.Parse(sources[i]) if err != nil { - return err + return nil, errors.Wrapf(err, "could not parse dag for job %d", id) } - defer rows.Close() - var ids []int32 - var sources []string - for rows.Next() { - var id int32 - var source string - if err = rows.Scan(&id, &source); err != nil { - return err - } - ids = append(jids, id) - sources = append(sources, source) - } - - for i, id := range ids { - var p *pipeline.Pipeline - p, err = pipeline.Parse(sources[i]) - if err != nil { - return errors.Wrapf(err, "could not parse dag for job %d", id) - } - for _, task := range p.Tasks { - if task.Type() == pipeline.TaskTypeBridge { - if task.(*pipeline.BridgeTask).Name == name { - jids = append(jids, id) - } + for _, task := range p.Tasks { + if task.Type() == pipeline.TaskTypeBridge { + if task.(*pipeline.BridgeTask).Name == name { + jids = append(jids, id) } } } - return nil - }) - return jids, errors.Wrap(err, "FindJobIDsWithBridge failed") + } + + return } // PipelineRunsByJobsIDs returns pipeline runs for multiple jobs, not preloading data -func (o *orm) PipelineRunsByJobsIDs(ids []int32) (runs []pipeline.Run, err error) { - err = o.q.Transaction(func(tx pg.Queryer) error { +func (o *orm) PipelineRunsByJobsIDs(ctx context.Context, ids []int32) (runs []pipeline.Run, err error) { + err = o.transact(ctx, false, func(tx *orm) error { stmt := `SELECT pipeline_runs.* FROM pipeline_runs INNER JOIN job_pipeline_specs ON pipeline_runs.pipeline_spec_id = job_pipeline_specs.pipeline_spec_id WHERE jobs.id = ANY($1) ORDER BY pipeline_runs.created_at DESC, pipeline_runs.id DESC;` - if err = tx.Select(&runs, stmt, ids); err != nil { + if err = tx.ds.SelectContext(ctx, &runs, stmt, ids); err != nil { return errors.Wrap(err, "error loading runs") } - runs, err = o.loadPipelineRunsRelations(runs, tx) + runs, err = tx.loadPipelineRunsRelations(ctx, runs) return err }) @@ -1005,11 +1060,11 @@ func (o *orm) PipelineRunsByJobsIDs(ids []int32) (runs []pipeline.Run, err error return runs, errors.Wrap(err, "PipelineRunsByJobsIDs failed") } -func (o *orm) loadPipelineRunIDs(jobID *int32, offset, limit int, tx pg.Queryer) (ids []int64, err error) { +func (o *orm) loadPipelineRunIDs(ctx context.Context, jobID *int32, offset, limit int) (ids []int64, err error) { lggr := logger.Sugared(o.lggr) var res sql.NullInt64 - if err = tx.Get(&res, "SELECT MAX(id) FROM pipeline_runs"); err != nil { + if err = o.ds.GetContext(ctx, &res, "SELECT MAX(id) FROM pipeline_runs"); err != nil { err = errors.Wrap(err, "error while loading runs") return } else if !res.Valid { @@ -1037,7 +1092,7 @@ func (o *orm) loadPipelineRunIDs(jobID *int32, offset, limit int, tx pg.Queryer) for n := int64(1000); maxID > 0 && len(ids) < limit; n *= 2 { var batch []int64 minID := maxID - n - if err = tx.Select(&batch, stmt, offset, limit-len(ids), minID, maxID); err != nil { + if err = o.ds.SelectContext(ctx, &batch, stmt, offset, limit-len(ids), minID, maxID); err != nil { err = errors.Wrap(err, "error loading runs") return } @@ -1050,7 +1105,7 @@ func (o *orm) loadPipelineRunIDs(jobID *int32, offset, limit int, tx pg.Queryer) var skipped int // If no rows were returned, we need to know whether there were any ids skipped // in this batch due to the offset, and reduce it for the next batch - err = tx.Get(&skipped, + err = o.ds.GetContext(ctx, &skipped, fmt.Sprintf( `SELECT COUNT(p.id) FROM pipeline_runs AS p %s p.id >= $1 AND p.id <= $2`, filter, ), minID, maxID, @@ -1074,63 +1129,60 @@ func (o *orm) loadPipelineRunIDs(jobID *int32, offset, limit int, tx pg.Queryer) return } -func (o *orm) FindTaskResultByRunIDAndTaskName(runID int64, taskName string, qopts ...pg.QOpt) (result []byte, err error) { - q := o.q.WithOpts(qopts...) - err = q.Transaction(func(tx pg.Queryer) error { - stmt := fmt.Sprintf("SELECT * FROM pipeline_task_runs WHERE pipeline_run_id = $1 AND dot_id = '%s';", taskName) +func (o *orm) FindTaskResultByRunIDAndTaskName(ctx context.Context, runID int64, taskName string) (result []byte, err error) { + stmt := fmt.Sprintf("SELECT * FROM pipeline_task_runs WHERE pipeline_run_id = $1 AND dot_id = '%s';", taskName) - var taskRuns []pipeline.TaskRun - if errB := tx.Select(&taskRuns, stmt, runID); errB != nil { - return errB - } - if len(taskRuns) == 0 { - return fmt.Errorf("can't find task run with id: %v, taskName: %v", runID, taskName) - } - if len(taskRuns) > 1 { - o.lggr.Errorf("found multiple task runs with id: %v, taskName: %v. Using the first one.", runID, taskName) - } - taskRun := taskRuns[0] - if !taskRun.Error.IsZero() { - return errors.New(taskRun.Error.ValueOrZero()) - } - resBytes, errB := taskRun.Output.MarshalJSON() - if errB != nil { - return errB - } - result = resBytes - return nil - }) - return result, errors.Wrap(err, "failed") + var taskRuns []pipeline.TaskRun + if errB := o.ds.SelectContext(ctx, &taskRuns, stmt, runID); errB != nil { + return nil, errB + } + if len(taskRuns) == 0 { + return nil, fmt.Errorf("can't find task run with id: %v, taskName: %v", runID, taskName) + } + if len(taskRuns) > 1 { + o.lggr.Errorf("found multiple task runs with id: %v, taskName: %v. Using the first one.", runID, taskName) + } + taskRun := taskRuns[0] + if !taskRun.Error.IsZero() { + return nil, errors.New(taskRun.Error.ValueOrZero()) + } + resBytes, errB := taskRun.Output.MarshalJSON() + if errB != nil { + return + } + result = resBytes + + return } // FindPipelineRunIDsByJobID fetches the ids of pipeline runs for a job. -func (o *orm) FindPipelineRunIDsByJobID(jobID int32, offset, limit int) (ids []int64, err error) { - err = o.q.Transaction(func(tx pg.Queryer) error { - ids, err = o.loadPipelineRunIDs(&jobID, offset, limit, tx) +func (o *orm) FindPipelineRunIDsByJobID(ctx context.Context, jobID int32, offset, limit int) (ids []int64, err error) { + err = o.transact(ctx, false, func(tx *orm) error { + ids, err = tx.loadPipelineRunIDs(ctx, &jobID, offset, limit) return err }) return ids, errors.Wrap(err, "FindPipelineRunIDsByJobID failed") } -func (o *orm) loadPipelineRunsByID(ids []int64, tx pg.Queryer) (runs []pipeline.Run, err error) { +func (o *orm) loadPipelineRunsByID(ctx context.Context, ids []int64) (runs []pipeline.Run, err error) { stmt := ` SELECT pipeline_runs.* FROM pipeline_runs WHERE id = ANY($1) ORDER BY created_at DESC, id DESC ` - if err = tx.Select(&runs, stmt, ids); err != nil { + if err = o.ds.SelectContext(ctx, &runs, stmt, ids); err != nil { err = errors.Wrap(err, "error loading runs") return } - return o.loadPipelineRunsRelations(runs, tx) + return o.loadPipelineRunsRelations(ctx, runs) } // FindPipelineRunsByIDs returns pipeline runs with the ids. -func (o *orm) FindPipelineRunsByIDs(ids []int64) (runs []pipeline.Run, err error) { - err = o.q.Transaction(func(tx pg.Queryer) error { - runs, err = o.loadPipelineRunsByID(ids, tx) +func (o *orm) FindPipelineRunsByIDs(ctx context.Context, ids []int64) (runs []pipeline.Run, err error) { + err = o.transact(ctx, false, func(tx *orm) error { + runs, err = tx.loadPipelineRunsByID(ctx, ids) return err }) @@ -1138,21 +1190,21 @@ func (o *orm) FindPipelineRunsByIDs(ids []int64) (runs []pipeline.Run, err error } // FindPipelineRunByID returns pipeline run with the id. -func (o *orm) FindPipelineRunByID(id int64) (pipeline.Run, error) { +func (o *orm) FindPipelineRunByID(ctx context.Context, id int64) (pipeline.Run, error) { var run pipeline.Run - err := o.q.Transaction(func(tx pg.Queryer) error { + err := o.transact(ctx, false, func(tx *orm) error { stmt := ` SELECT pipeline_runs.* FROM pipeline_runs WHERE id = $1 ` - if err := tx.Get(&run, stmt, id); err != nil { + if err := tx.ds.GetContext(ctx, &run, stmt, id); err != nil { return errors.Wrap(err, "error loading run") } - runs, err := o.loadPipelineRunsRelations([]pipeline.Run{run}, tx) + runs, err := tx.loadPipelineRunsRelations(ctx, []pipeline.Run{run}) run = runs[0] @@ -1163,30 +1215,24 @@ WHERE id = $1 } // CountPipelineRunsByJobID returns the total number of pipeline runs for a job. -func (o *orm) CountPipelineRunsByJobID(jobID int32) (count int32, err error) { - err = o.q.Transaction(func(tx pg.Queryer) error { - stmt := "SELECT COUNT(*) FROM pipeline_runs JOIN job_pipeline_specs USING (pipeline_spec_id) WHERE job_pipeline_specs.job_id = $1" - if err = tx.Get(&count, stmt, jobID); err != nil { - return errors.Wrap(err, "error counting runs") - } - - return err - }) +func (o *orm) CountPipelineRunsByJobID(ctx context.Context, jobID int32) (count int32, err error) { + stmt := "SELECT COUNT(*) FROM pipeline_runs JOIN job_pipeline_specs USING (pipeline_spec_id) WHERE job_pipeline_specs.job_id = $1" + err = o.ds.GetContext(ctx, &count, stmt, jobID) return count, errors.Wrap(err, "CountPipelineRunsByJobID failed") } -func (o *orm) FindJobsByPipelineSpecIDs(ids []int32) ([]Job, error) { +func (o *orm) FindJobsByPipelineSpecIDs(ctx context.Context, ids []int32) ([]Job, error) { var jbs []Job - err := o.q.Transaction(func(tx pg.Queryer) error { + err := o.transact(ctx, false, func(tx *orm) error { stmt := `SELECT jobs.*, job_pipeline_specs.pipeline_spec_id FROM jobs JOIN job_pipeline_specs ON (jobs.id = job_pipeline_specs.job_id) WHERE job_pipeline_specs.pipeline_spec_id = ANY($1) ORDER BY jobs.id ASC ` - if err := tx.Select(&jbs, stmt, ids); err != nil { + if err := tx.ds.SelectContext(ctx, &jbs, stmt, ids); err != nil { return errors.Wrap(err, "error fetching jobs by pipeline spec IDs") } - err := LoadAllJobsTypes(tx, jbs) + err := tx.loadAllJobsTypes(ctx, jbs) if err != nil { return err } @@ -1199,20 +1245,20 @@ func (o *orm) FindJobsByPipelineSpecIDs(ids []int32) ([]Job, error) { // PipelineRuns returns pipeline runs for a job, with spec and taskruns loaded, latest first // If jobID is nil, returns all pipeline runs -func (o *orm) PipelineRuns(jobID *int32, offset, size int) (runs []pipeline.Run, count int, err error) { +func (o *orm) PipelineRuns(ctx context.Context, jobID *int32, offset, size int) (runs []pipeline.Run, count int, err error) { var filter string if jobID != nil { filter = fmt.Sprintf("JOIN job_pipeline_specs USING(pipeline_spec_id) WHERE job_pipeline_specs.job_id = %d", *jobID) } - err = o.q.Transaction(func(tx pg.Queryer) error { + err = o.transact(ctx, false, func(tx *orm) error { sql := fmt.Sprintf(`SELECT count(*) FROM pipeline_runs %s`, filter) - if err = tx.QueryRowx(sql).Scan(&count); err != nil { + if err = tx.ds.QueryRowxContext(ctx, sql).Scan(&count); err != nil { return errors.Wrap(err, "error counting runs") } var ids []int64 - ids, err = o.loadPipelineRunIDs(jobID, offset, size, tx) - runs, err = o.loadPipelineRunsByID(ids, tx) + ids, err = tx.loadPipelineRunIDs(ctx, jobID, offset, size) + runs, err = tx.loadPipelineRunsByID(ctx, ids) return err }) @@ -1220,7 +1266,7 @@ func (o *orm) PipelineRuns(jobID *int32, offset, size int) (runs []pipeline.Run, return runs, count, errors.Wrap(err, "PipelineRuns failed") } -func (o *orm) loadPipelineRunsRelations(runs []pipeline.Run, tx pg.Queryer) ([]pipeline.Run, error) { +func (o *orm) loadPipelineRunsRelations(ctx context.Context, runs []pipeline.Run) ([]pipeline.Run, error) { // Postload PipelineSpecs // TODO: We should pull this out into a generic preload function once go has generics specM := make(map[int32]pipeline.Spec) @@ -1235,7 +1281,7 @@ func (o *orm) loadPipelineRunsRelations(runs []pipeline.Run, tx pg.Queryer) ([]p } stmt := `SELECT pipeline_specs.*, job_pipeline_specs.job_id AS job_id FROM pipeline_specs JOIN job_pipeline_specs ON pipeline_specs.id = job_pipeline_specs.pipeline_spec_id WHERE pipeline_specs.id = ANY($1);` var specs []pipeline.Spec - if err := o.q.Select(&specs, stmt, specIDs); err != nil { + if err := o.ds.SelectContext(ctx, &specs, stmt, specIDs); err != nil { return nil, errors.Wrap(err, "error loading specs") } for _, spec := range specs { @@ -1254,7 +1300,7 @@ func (o *orm) loadPipelineRunsRelations(runs []pipeline.Run, tx pg.Queryer) ([]p } var taskRuns []pipeline.TaskRun stmt = `SELECT * FROM pipeline_task_runs WHERE pipeline_run_id = ANY($1) ORDER BY pipeline_run_id, created_at, id;` - if err := tx.Select(&taskRuns, stmt, runIDs); err != nil { + if err := o.ds.SelectContext(ctx, &taskRuns, stmt, runIDs); err != nil { return nil, errors.Wrap(err, "error loading pipeline_task_runs") } for _, taskRun := range taskRuns { @@ -1268,9 +1314,9 @@ func (o *orm) loadPipelineRunsRelations(runs []pipeline.Run, tx pg.Queryer) ([]p // NOTE: N+1 query, be careful of performance // This is not easily fixable without complicating the logic a lot, since we // only use it in the GUI it's probably acceptable -func LoadAllJobsTypes(tx pg.Queryer, jobs []Job) error { +func (o *orm) loadAllJobsTypes(ctx context.Context, jobs []Job) error { for i := range jobs { - err := LoadAllJobTypes(tx, &jobs[i]) + err := o.loadAllJobTypes(ctx, &jobs[i]) if err != nil { return err } @@ -1278,28 +1324,28 @@ func LoadAllJobsTypes(tx pg.Queryer, jobs []Job) error { return nil } -func LoadAllJobTypes(tx pg.Queryer, job *Job) error { +func (o *orm) loadAllJobTypes(ctx context.Context, job *Job) error { return multierr.Combine( - loadJobPipelineSpec(tx, job, &job.PipelineSpecID), - loadJobType(tx, job, "FluxMonitorSpec", "flux_monitor_specs", job.FluxMonitorSpecID), - loadJobType(tx, job, "DirectRequestSpec", "direct_request_specs", job.DirectRequestSpecID), - loadJobType(tx, job, "OCROracleSpec", "ocr_oracle_specs", job.OCROracleSpecID), - loadJobType(tx, job, "OCR2OracleSpec", "ocr2_oracle_specs", job.OCR2OracleSpecID), - loadJobType(tx, job, "KeeperSpec", "keeper_specs", job.KeeperSpecID), - loadJobType(tx, job, "CronSpec", "cron_specs", job.CronSpecID), - loadJobType(tx, job, "WebhookSpec", "webhook_specs", job.WebhookSpecID), - loadVRFJob(tx, job, job.VRFSpecID), - loadBlockhashStoreJob(tx, job, job.BlockhashStoreSpecID), - loadBlockHeaderFeederJob(tx, job, job.BlockHeaderFeederSpecID), - loadLegacyGasStationServerJob(tx, job, job.LegacyGasStationServerSpecID), - loadJobType(tx, job, "LegacyGasStationSidecarSpec", "legacy_gas_station_sidecar_specs", job.LegacyGasStationSidecarSpecID), - loadJobType(tx, job, "BootstrapSpec", "bootstrap_specs", job.BootstrapSpecID), - loadJobType(tx, job, "GatewaySpec", "gateway_specs", job.GatewaySpecID), - loadJobType(tx, job, "WorkflowSpec", "workflow_specs", job.WorkflowSpecID), + o.loadJobPipelineSpec(ctx, job, &job.PipelineSpecID), + o.loadJobType(ctx, job, "FluxMonitorSpec", "flux_monitor_specs", job.FluxMonitorSpecID), + o.loadJobType(ctx, job, "DirectRequestSpec", "direct_request_specs", job.DirectRequestSpecID), + o.loadJobType(ctx, job, "OCROracleSpec", "ocr_oracle_specs", job.OCROracleSpecID), + o.loadJobType(ctx, job, "OCR2OracleSpec", "ocr2_oracle_specs", job.OCR2OracleSpecID), + o.loadJobType(ctx, job, "KeeperSpec", "keeper_specs", job.KeeperSpecID), + o.loadJobType(ctx, job, "CronSpec", "cron_specs", job.CronSpecID), + o.loadJobType(ctx, job, "WebhookSpec", "webhook_specs", job.WebhookSpecID), + o.loadVRFJob(ctx, job, job.VRFSpecID), + o.loadBlockhashStoreJob(ctx, job, job.BlockhashStoreSpecID), + o.loadBlockHeaderFeederJob(ctx, job, job.BlockHeaderFeederSpecID), + o.loadLegacyGasStationServerJob(ctx, job, job.LegacyGasStationServerSpecID), + o.loadJobType(ctx, job, "LegacyGasStationSidecarSpec", "legacy_gas_station_sidecar_specs", job.LegacyGasStationSidecarSpecID), + o.loadJobType(ctx, job, "BootstrapSpec", "bootstrap_specs", job.BootstrapSpecID), + o.loadJobType(ctx, job, "GatewaySpec", "gateway_specs", job.GatewaySpecID), + o.loadJobType(ctx, job, "WorkflowSpec", "workflow_specs", job.WorkflowSpecID), ) } -func loadJobType(tx pg.Queryer, job *Job, field, table string, id *int32) error { +func (o *orm) loadJobType(ctx context.Context, job *Job, field, table string, id *int32) error { if id == nil { return nil } @@ -1312,7 +1358,7 @@ func loadJobType(tx pg.Queryer, job *Job, field, table string, id *int32) error destVal := reflect.New(t) dest := destVal.Interface() - err := tx.Get(dest, fmt.Sprintf(`SELECT * FROM %s WHERE id = $1`, table), *id) + err := o.ds.GetContext(ctx, dest, fmt.Sprintf(`SELECT * FROM %s WHERE id = $1`, table), *id) if err != nil { return errors.Wrapf(err, "failed to load job type %s with id %d", table, *id) @@ -1321,7 +1367,7 @@ func loadJobType(tx pg.Queryer, job *Job, field, table string, id *int32) error return nil } -func loadJobPipelineSpec(tx pg.Queryer, job *Job, id *int32) error { +func (o *orm) loadJobPipelineSpec(ctx context.Context, job *Job, id *int32) error { if id == nil { return nil } @@ -1329,7 +1375,8 @@ func loadJobPipelineSpec(tx pg.Queryer, job *Job, id *int32) error { if job.PipelineSpec != nil { pipelineSpecRow = job.PipelineSpec } - err := tx.Get( + err := o.ds.GetContext( + ctx, pipelineSpecRow, `SELECT pipeline_specs.*, job_pipeline_specs.job_id as job_id FROM pipeline_specs @@ -1344,13 +1391,13 @@ func loadJobPipelineSpec(tx pg.Queryer, job *Job, id *int32) error { return nil } -func loadVRFJob(tx pg.Queryer, job *Job, id *int32) error { +func (o *orm) loadVRFJob(ctx context.Context, job *Job, id *int32) error { if id == nil { return nil } var row vrfSpecRow - err := tx.Get(&row, `SELECT * FROM vrf_specs WHERE id = $1`, *id) + err := o.ds.GetContext(ctx, &row, `SELECT * FROM vrf_specs WHERE id = $1`, *id) if err != nil { return errors.Wrapf(err, `failed to load job type VRFSpec with id %d`, *id) } @@ -1383,13 +1430,13 @@ func (r vrfSpecRow) toVRFSpec() *VRFSpec { return r.VRFSpec } -func loadBlockhashStoreJob(tx pg.Queryer, job *Job, id *int32) error { +func (o *orm) loadBlockhashStoreJob(ctx context.Context, job *Job, id *int32) error { if id == nil { return nil } var row blockhashStoreSpecRow - err := tx.Get(&row, `SELECT * FROM blockhash_store_specs WHERE id = $1`, *id) + err := o.ds.GetContext(ctx, &row, `SELECT * FROM blockhash_store_specs WHERE id = $1`, *id) if err != nil { return errors.Wrapf(err, `failed to load job type BlockhashStoreSpec with id %d`, *id) } @@ -1422,13 +1469,13 @@ func (r blockhashStoreSpecRow) toBlockhashStoreSpec() *BlockhashStoreSpec { return r.BlockhashStoreSpec } -func loadBlockHeaderFeederJob(tx pg.Queryer, job *Job, id *int32) error { +func (o *orm) loadBlockHeaderFeederJob(ctx context.Context, job *Job, id *int32) error { if id == nil { return nil } var row blockHeaderFeederSpecRow - err := tx.Get(&row, `SELECT * FROM block_header_feeder_specs WHERE id = $1`, *id) + err := o.ds.GetContext(ctx, &row, `SELECT * FROM block_header_feeder_specs WHERE id = $1`, *id) if err != nil { return errors.Wrapf(err, `failed to load job type BlockHeaderFeederSpec with id %d`, *id) } @@ -1461,13 +1508,13 @@ func (r blockHeaderFeederSpecRow) toBlockHeaderFeederSpec() *BlockHeaderFeederSp return r.BlockHeaderFeederSpec } -func loadLegacyGasStationServerJob(tx pg.Queryer, job *Job, id *int32) error { +func (o *orm) loadLegacyGasStationServerJob(ctx context.Context, job *Job, id *int32) error { if id == nil { return nil } var row legacyGasStationServerSpecRow - err := tx.Get(&row, `SELECT * FROM legacy_gas_station_server_specs WHERE id = $1`, *id) + err := o.ds.GetContext(ctx, &row, `SELECT * FROM legacy_gas_station_server_specs WHERE id = $1`, *id) if err != nil { return errors.Wrapf(err, `failed to load job type LegacyGasStationServerSpec with id %d`, *id) } @@ -1500,6 +1547,6 @@ func (r legacyGasStationServerSpecRow) toLegacyGasStationServerSpec() *LegacyGas return r.LegacyGasStationServerSpec } -func loadJobSpecErrors(tx pg.Queryer, jb *Job) error { - return errors.Wrapf(tx.Select(&jb.JobSpecErrors, `SELECT * FROM job_spec_errors WHERE job_id = $1`, jb.ID), "failed to load job spec errors for job %d", jb.ID) +func (o *orm) loadJobSpecErrors(ctx context.Context, jb *Job) error { + return errors.Wrapf(o.ds.SelectContext(ctx, &jb.JobSpecErrors, `SELECT * FROM job_spec_errors WHERE job_id = $1`, jb.ID), "failed to load job spec errors for job %d", jb.ID) } diff --git a/core/services/job/orm_test.go b/core/services/job/orm_test.go index fb0e846b9d2..11f3e94f2d4 100644 --- a/core/services/job/orm_test.go +++ b/core/services/job/orm_test.go @@ -6,8 +6,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/jmoiron/sqlx" - + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" @@ -16,13 +15,12 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/store/models" ) -func NewTestORM(t *testing.T, db *sqlx.DB, pipelineORM pipeline.ORM, bridgeORM bridges.ORM, keyStore keystore.Master, cfg pg.QConfig) job.ORM { - o := job.NewORM(db, pipelineORM, bridgeORM, keyStore, logger.TestLogger(t), cfg) +func NewTestORM(t *testing.T, ds sqlutil.DataSource, pipelineORM pipeline.ORM, bridgeORM bridges.ORM, keyStore keystore.Master) job.ORM { + o := job.NewORM(ds, pipelineORM, bridgeORM, keyStore, logger.TestLogger(t)) t.Cleanup(func() { assert.NoError(t, o.Close()) }) return o } diff --git a/core/services/job/runner_integration_test.go b/core/services/job/runner_integration_test.go index 26a78a8624e..cdfe39dd17f 100644 --- a/core/services/job/runner_integration_test.go +++ b/core/services/job/runner_integration_test.go @@ -89,7 +89,7 @@ func TestRunner(t *testing.T) { c := clhttptest.NewTestLocalOnlyHTTPClient() runner := pipeline.NewRunner(pipelineORM, btORM, config.JobPipeline(), config.WebServer(), legacyChains, nil, nil, logger.TestLogger(t), c, c) - jobORM := NewTestORM(t, db, pipelineORM, btORM, keyStore, config.Database()) + jobORM := NewTestORM(t, db, pipelineORM, btORM, keyStore) t.Cleanup(func() { assert.NoError(t, jobORM.Close()) }) _, placeHolderAddress := cltest.MustInsertRandomKey(t, keyStore.Eth()) @@ -121,8 +121,9 @@ func TestRunner(t *testing.T) { // Need a job in order to create a run jb := MakeVoterTurnoutOCRJobSpecWithHTTPURL(t, transmitterAddress, httpURL, bridgeVT.Name.String(), bridgeER.Name.String()) - require.NoError(t, jobORM.CreateJob(jb)) + require.NoError(t, jobORM.CreateJob(testutils.Context(t), jb)) require.NotNil(t, jb.PipelineSpec) + require.NotZero(t, jb.PipelineSpec.JobID) m, err := bridges.MarshalBridgeMetaData(big.NewInt(10), big.NewInt(100)) require.NoError(t, err) @@ -169,6 +170,7 @@ func TestRunner(t *testing.T) { }) t.Run("must delete job before deleting bridge", func(t *testing.T) { + ctx := testutils.Context(t) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}) jb := makeOCRJobSpecFromToml(t, fmt.Sprintf(` type = "offchainreporting" @@ -178,20 +180,21 @@ func TestRunner(t *testing.T) { ds1 [type=bridge name="%s"]; """ `, bridge.Name.String())) - require.NoError(t, jobORM.CreateJob(jb)) + require.NoError(t, jobORM.CreateJob(ctx, jb)) // Should not be able to delete a bridge in use. - jids, err := jobORM.FindJobIDsWithBridge(bridge.Name.String()) + jids, err := jobORM.FindJobIDsWithBridge(ctx, bridge.Name.String()) require.NoError(t, err) require.Equal(t, 1, len(jids)) // But if we delete the job, then we can. - require.NoError(t, jobORM.DeleteJob(jb.ID)) - jids, err = jobORM.FindJobIDsWithBridge(bridge.Name.String()) + require.NoError(t, jobORM.DeleteJob(ctx, jb.ID)) + jids, err = jobORM.FindJobIDsWithBridge(ctx, bridge.Name.String()) require.NoError(t, err) require.Equal(t, 0, len(jids)) }) t.Run("referencing a non-existent bridge should error", func(t *testing.T) { + ctx := testutils.Context(t) // Create a random bridge name _, b := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}) @@ -223,7 +226,7 @@ func TestRunner(t *testing.T) { `, placeHolderAddress.String())) require.NoError(t, err) // Should error creating it - err = jobORM.CreateJob(&jb) + err = jobORM.CreateJob(ctx, &jb) require.Error(t, err) assert.Contains(t, err.Error(), "not all bridges exist") @@ -258,7 +261,7 @@ answer1 [type=median index=0]; `, placeHolderAddress.String(), b.Name.String()), nil) require.NoError(t, err) // Should error creating it because of the juels per fee coin non-existent bridge - err = jobORM.CreateJob(&jb2) + err = jobORM.CreateJob(ctx, &jb2) require.Error(t, err) assert.Contains(t, err.Error(), "not all bridges exist") @@ -297,11 +300,12 @@ answer1 [type=median index=0]; `, placeHolderAddress, b.Name.String(), b.Name.String(), b.Name.String()), nil) require.NoError(t, err) // Should not error with duplicate bridges - err = jobORM.CreateJob(&jb3) + err = jobORM.CreateJob(ctx, &jb3) require.NoError(t, err) }) t.Run("handles the case where the parsed value is literally null", func(t *testing.T) { + ctx := testutils.Context(t) var httpURL string resp := `{"USD": null}` { @@ -311,7 +315,7 @@ answer1 [type=median index=0]; // Need a job in order to create a run jb := makeSimpleFetchOCRJobSpecWithHTTPURL(t, transmitterAddress, httpURL, false) - err := jobORM.CreateJob(jb) + err := jobORM.CreateJob(ctx, jb) require.NoError(t, err) runID, taskResults, err := runner.ExecuteAndInsertFinishedRun(testutils.Context(t), *jb.PipelineSpec, pipeline.NewVarsFrom(nil), logger.TestLogger(t), true) @@ -357,7 +361,7 @@ answer1 [type=median index=0]; // Need a job in order to create a run jb := makeSimpleFetchOCRJobSpecWithHTTPURL(t, transmitterAddress, httpURL, false) - err := jobORM.CreateJob(jb) + err := jobORM.CreateJob(testutils.Context(t), jb) require.NoError(t, err) runID, taskResults, err := runner.ExecuteAndInsertFinishedRun(testutils.Context(t), *jb.PipelineSpec, pipeline.NewVarsFrom(nil), logger.TestLogger(t), true) @@ -402,7 +406,7 @@ answer1 [type=median index=0]; // Need a job in order to create a run jb := makeSimpleFetchOCRJobSpecWithHTTPURL(t, transmitterAddress, httpURL, true) - err := jobORM.CreateJob(jb) + err := jobORM.CreateJob(testutils.Context(t), jb) require.NoError(t, err) runID, taskResults, err := runner.ExecuteAndInsertFinishedRun(testutils.Context(t), *jb.PipelineSpec, pipeline.NewVarsFrom(nil), logger.TestLogger(t), true) @@ -451,13 +455,13 @@ answer1 [type=median index=0]; err = toml.Unmarshal([]byte(s), &jb) require.NoError(t, err) jb.MaxTaskDuration = models.Interval(cltest.MustParseDuration(t, "1s")) - err = jobORM.CreateJob(&jb) + err = jobORM.CreateJob(testutils.Context(t), &jb) require.NoError(t, err) lggr := logger.TestLogger(t) _, err = keyStore.P2P().Create(ctx) assert.NoError(t, err) - pw := ocrcommon.NewSingletonPeerWrapper(keyStore, config.P2P(), config.OCR(), config.Database(), db, lggr) + pw := ocrcommon.NewSingletonPeerWrapper(keyStore, config.P2P(), config.OCR(), db, lggr) servicetest.Run(t, pw) sd := ocr.NewDelegate( db, @@ -487,12 +491,12 @@ answer1 [type=median index=0]; require.NoError(t, err) jb.MaxTaskDuration = models.Interval(cltest.MustParseDuration(t, "1s")) - err = jobORM.CreateJob(&jb) + err = jobORM.CreateJob(testutils.Context(t), &jb) require.NoError(t, err) assert.Equal(t, jb.MaxTaskDuration, models.Interval(cltest.MustParseDuration(t, "1s"))) lggr := logger.TestLogger(t) - pw := ocrcommon.NewSingletonPeerWrapper(keyStore, config.P2P(), config.OCR(), config.Database(), db, lggr) + pw := ocrcommon.NewSingletonPeerWrapper(keyStore, config.P2P(), config.OCR(), db, lggr) servicetest.Run(t, pw) sd := ocr.NewDelegate( db, @@ -516,11 +520,11 @@ answer1 [type=median index=0]; require.NoError(t, err) err = toml.Unmarshal([]byte(s), &jb) require.NoError(t, err) - err = jobORM.CreateJob(&jb) + err = jobORM.CreateJob(testutils.Context(t), &jb) require.NoError(t, err) lggr := logger.TestLogger(t) - pw := ocrcommon.NewSingletonPeerWrapper(keyStore, config.P2P(), config.OCR(), config.Database(), db, lggr) + pw := ocrcommon.NewSingletonPeerWrapper(keyStore, config.P2P(), config.OCR(), db, lggr) servicetest.Run(t, pw) sd := ocr.NewDelegate( db, @@ -571,12 +575,12 @@ answer1 [type=median index=0]; require.NoError(t, err) jb.MaxTaskDuration = models.Interval(cltest.MustParseDuration(t, "1s")) - err = jobORM.CreateJob(&jb) + err = jobORM.CreateJob(testutils.Context(t), &jb) require.NoError(t, err) assert.Equal(t, jb.MaxTaskDuration, models.Interval(cltest.MustParseDuration(t, "1s"))) lggr := logger.TestLogger(t) - pw := ocrcommon.NewSingletonPeerWrapper(keyStore, config.P2P(), config.OCR(), config.Database(), db, lggr) + pw := ocrcommon.NewSingletonPeerWrapper(keyStore, config.P2P(), config.OCR(), db, lggr) servicetest.Run(t, pw) sd := ocr.NewDelegate( db, @@ -617,11 +621,11 @@ answer1 [type=median index=0]; jb := makeOCRJobSpecFromToml(t, spec) // Create an OCR job - err = jobORM.CreateJob(jb) + err = jobORM.CreateJob(ctx, jb) require.NoError(t, err) lggr := logger.TestLogger(t) - pw := ocrcommon.NewSingletonPeerWrapper(keyStore, config.P2P(), config.OCR(), config.Database(), db, lggr) + pw := ocrcommon.NewSingletonPeerWrapper(keyStore, config.P2P(), config.OCR(), db, lggr) servicetest.Run(t, pw) sd := ocr.NewDelegate( db, @@ -640,6 +644,7 @@ answer1 [type=median index=0]; // Return an error getting the contract code. ethClient.On("CodeAt", mock.Anything, mock.Anything, mock.Anything).Return(nil, errors.New("no such code")) + for _, s := range services { err = s.Start(ctx) require.NoError(t, err) @@ -659,7 +664,7 @@ answer1 [type=median index=0]; } // Ensure we can delete an errored - err = jobORM.DeleteJob(jb.ID) + err = jobORM.DeleteJob(ctx, jb.ID) require.NoError(t, err) se = []job.SpecError{} err = db.Select(&se, `SELECT * FROM job_spec_errors`) @@ -675,6 +680,7 @@ answer1 [type=median index=0]; }) t.Run("timeouts", func(t *testing.T) { + ctx := testutils.Context(t) // There are 4 timeouts: // - ObservationTimeout = how long the whole OCR time needs to run, or it fails (default 10 seconds) // - config.JobPipelineMaxTaskDuration() = node level maximum time for a pipeline task (default 10 minutes) @@ -689,7 +695,7 @@ answer1 [type=median index=0]; defer serv.Close() jb := makeMinimalHTTPOracleSpec(t, db, config, cltest.NewEIP55Address().String(), transmitterAddress.Hex(), cltest.DefaultOCRKeyBundleID, serv.URL, `timeout="1ns"`) - err := jobORM.CreateJob(jb) + err := jobORM.CreateJob(ctx, jb) require.NoError(t, err) _, taskResults, err := runner.ExecuteAndInsertFinishedRun(testutils.Context(t), *jb.PipelineSpec, pipeline.NewVarsFrom(nil), logger.TestLogger(t), true) @@ -700,7 +706,7 @@ answer1 [type=median index=0]; // No task timeout should succeed. jb = makeMinimalHTTPOracleSpec(t, db, config, cltest.NewEIP55Address().String(), transmitterAddress.Hex(), cltest.DefaultOCRKeyBundleID, serv.URL, "") jb.Name = null.NewString("a job 2", true) - err = jobORM.CreateJob(jb) + err = jobORM.CreateJob(ctx, jb) require.NoError(t, err) _, taskResults, err = runner.ExecuteAndInsertFinishedRun(testutils.Context(t), *jb.PipelineSpec, pipeline.NewVarsFrom(nil), logger.TestLogger(t), true) require.NoError(t, err) @@ -712,7 +718,7 @@ answer1 [type=median index=0]; jb = makeMinimalHTTPOracleSpec(t, db, config, cltest.NewEIP55Address().String(), transmitterAddress.Hex(), cltest.DefaultOCRKeyBundleID, serv.URL, "") jb.MaxTaskDuration = models.Interval(time.Duration(1)) jb.Name = null.NewString("a job 3", true) - err = jobORM.CreateJob(jb) + err = jobORM.CreateJob(ctx, jb) require.NoError(t, err) _, taskResults, err = runner.ExecuteAndInsertFinishedRun(testutils.Context(t), *jb.PipelineSpec, pipeline.NewVarsFrom(nil), logger.TestLogger(t), true) @@ -722,6 +728,7 @@ answer1 [type=median index=0]; }) t.Run("deleting jobs", func(t *testing.T) { + ctx := testutils.Context(t) var httpURL string { resp := `{"USD": 42.42}` @@ -731,7 +738,7 @@ answer1 [type=median index=0]; // Need a job in order to create a run jb := makeSimpleFetchOCRJobSpecWithHTTPURL(t, transmitterAddress, httpURL, false) - err := jobORM.CreateJob(jb) + err := jobORM.CreateJob(ctx, jb) require.NoError(t, err) _, taskResults, err := runner.ExecuteAndInsertFinishedRun(testutils.Context(t), *jb.PipelineSpec, pipeline.NewVarsFrom(nil), logger.TestLogger(t), true) @@ -742,7 +749,7 @@ answer1 [type=median index=0]; assert.Equal(t, "4242", results.Values[0].(decimal.Decimal).String()) // Delete the job - err = jobORM.DeleteJob(jb.ID) + err = jobORM.DeleteJob(ctx, jb.ID) require.NoError(t, err) // Create another run, it should fail @@ -849,7 +856,7 @@ func TestRunner_Success_Callback_AsyncJob(t *testing.T) { require.NoError(t, err) bridgeCalled <- struct{}{} })) - _, bridge := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{URL: bridgeServer.URL}) + _, bridge := cltest.MustCreateBridge(t, app.GetDB(), cltest.BridgeOpts{URL: bridgeServer.URL}) bridgeName = bridge.Name.String() defer bridgeServer.Close() } @@ -879,7 +886,7 @@ func TestRunner_Success_Callback_AsyncJob(t *testing.T) { """ `, jobUUID, eiName, cltest.MustJSONMarshal(t, eiSpec), bridgeName) - _, err := webhook.ValidatedWebhookSpec(tomlSpec, app.GetExternalInitiatorManager()) + _, err := webhook.ValidatedWebhookSpec(testutils.Context(t), tomlSpec, app.GetExternalInitiatorManager()) require.NoError(t, err) job := cltest.CreateJobViaWeb(t, app, []byte(cltest.MustJSONMarshal(t, web.CreateJobRequest{TOML: tomlSpec}))) jobID = job.ID @@ -891,9 +898,9 @@ func TestRunner_Success_Callback_AsyncJob(t *testing.T) { _ = cltest.CreateJobRunViaExternalInitiatorV2(t, app, jobUUID, *eia, cltest.MustJSONMarshal(t, eiRequest)) - pipelineORM := pipeline.NewORM(app.GetSqlxDB(), logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns()) - bridgesORM := bridges.NewORM(app.GetSqlxDB()) - jobORM := NewTestORM(t, app.GetSqlxDB(), pipelineORM, bridgesORM, app.KeyStore, cfg.Database()) + pipelineORM := pipeline.NewORM(app.GetDB(), logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns()) + bridgesORM := bridges.NewORM(app.GetDB()) + jobORM := NewTestORM(t, app.GetDB(), pipelineORM, bridgesORM, app.KeyStore) // Trigger v2/resume select { @@ -1028,7 +1035,7 @@ func TestRunner_Error_Callback_AsyncJob(t *testing.T) { require.NoError(t, err) bridgeCalled <- struct{}{} })) - _, bridge := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{URL: bridgeServer.URL}) + _, bridge := cltest.MustCreateBridge(t, app.GetDB(), cltest.BridgeOpts{URL: bridgeServer.URL}) bridgeName = bridge.Name.String() defer bridgeServer.Close() } @@ -1058,19 +1065,20 @@ func TestRunner_Error_Callback_AsyncJob(t *testing.T) { """ `, jobUUID, eiName, cltest.MustJSONMarshal(t, eiSpec), bridgeName) - _, err := webhook.ValidatedWebhookSpec(tomlSpec, app.GetExternalInitiatorManager()) + _, err := webhook.ValidatedWebhookSpec(testutils.Context(t), tomlSpec, app.GetExternalInitiatorManager()) require.NoError(t, err) job := cltest.CreateJobViaWeb(t, app, []byte(cltest.MustJSONMarshal(t, web.CreateJobRequest{TOML: tomlSpec}))) jobID = job.ID require.Eventually(t, func() bool { return eiNotifiedOfCreate }, 5*time.Second, 10*time.Millisecond, "expected external initiator to be notified of new job") } + t.Run("simulate request from EI -> Core node with erroring callback", func(t *testing.T) { _ = cltest.CreateJobRunViaExternalInitiatorV2(t, app, jobUUID, *eia, cltest.MustJSONMarshal(t, eiRequest)) - pipelineORM := pipeline.NewORM(app.GetSqlxDB(), logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns()) - bridgesORM := bridges.NewORM(app.GetSqlxDB()) - jobORM := NewTestORM(t, app.GetSqlxDB(), pipelineORM, bridgesORM, app.KeyStore, cfg.Database()) + pipelineORM := pipeline.NewORM(app.GetDB(), logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns()) + bridgesORM := bridges.NewORM(app.GetDB()) + jobORM := NewTestORM(t, app.GetDB(), pipelineORM, bridgesORM, app.KeyStore) // Trigger v2/resume select { diff --git a/core/services/job/spawner.go b/core/services/job/spawner.go index 8024424226c..6bb2cdbf76b 100644 --- a/core/services/job/spawner.go +++ b/core/services/job/spawner.go @@ -9,13 +9,11 @@ import ( pkgerrors "github.com/pkg/errors" - "github.com/jmoiron/sqlx" - "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) //go:generate mockery --quiet --name Spawner --output ./mocks/ --case=underscore @@ -29,16 +27,16 @@ type ( // CreateJob creates a new job and starts services. // All services must start without errors for the job to be active. - CreateJob(jb *Job, qopts ...pg.QOpt) (err error) + CreateJob(ctx context.Context, ds sqlutil.DataSource, jb *Job) (err error) // DeleteJob deletes a job and stops any active services. - DeleteJob(jobID int32, qopts ...pg.QOpt) error + DeleteJob(ctx context.Context, ds sqlutil.DataSource, jobID int32) error // ActiveJobs returns a map of jobs with active services (started without error). ActiveJobs() map[int32]Job // StartService starts services for the given job spec. // NOTE: Prefer to use CreateJob, this is only publicly exposed for use in tests // to start a job that was previously manually inserted into DB - StartService(ctx context.Context, spec Job, qopts ...pg.QOpt) error + StartService(ctx context.Context, spec Job) error } Checker interface { @@ -54,7 +52,6 @@ type ( jobTypeDelegates map[Type]Delegate activeJobs map[int32]activeJob activeJobsMu sync.RWMutex - q pg.Q lggr logger.Logger chStop services.StopChan @@ -90,14 +87,13 @@ type ( var _ Spawner = (*spawner)(nil) -func NewSpawner(orm ORM, config Config, checker Checker, jobTypeDelegates map[Type]Delegate, db *sqlx.DB, lggr logger.Logger, lbDependentAwaiters []utils.DependentAwaiter) *spawner { +func NewSpawner(orm ORM, config Config, checker Checker, jobTypeDelegates map[Type]Delegate, lggr logger.Logger, lbDependentAwaiters []utils.DependentAwaiter) *spawner { namedLogger := lggr.Named("JobSpawner") s := &spawner{ orm: orm, config: config, checker: checker, jobTypeDelegates: jobTypeDelegates, - q: pg.NewQ(db, namedLogger, config), lggr: namedLogger, activeJobs: make(map[int32]activeJob), chStop: make(services.StopChan), @@ -134,7 +130,7 @@ func (js *spawner) HealthReport() map[string]error { func (js *spawner) startAllServices(ctx context.Context) { // TODO: rename to find AllJobs - specs, _, err := js.orm.FindJobs(0, math.MaxUint32) + specs, _, err := js.orm.FindJobs(ctx, 0, math.MaxUint32) if err != nil { werr := fmt.Errorf("couldn't fetch unclaimed jobs: %v", err) js.lggr.Critical(werr.Error()) @@ -191,7 +187,7 @@ func (js *spawner) stopService(jobID int32) { delete(js.activeJobs, jobID) } -func (js *spawner) StartService(ctx context.Context, jb Job, qopts ...pg.QOpt) error { +func (js *spawner) StartService(ctx context.Context, jb Job) error { lggr := js.lggr.With("jobID", jb.ID) js.activeJobsMu.Lock() defer js.activeJobsMu.Unlock() @@ -220,7 +216,7 @@ func (js *spawner) StartService(ctx context.Context, jb Job, qopts ...pg.QOpt) e lggr.Errorw("Error creating services for job", "err", err) cctx, cancel := js.chStop.NewCtx() defer cancel() - js.orm.TryRecordError(jb.ID, err.Error(), pg.WithParentCtx(cctx)) + js.orm.TryRecordError(cctx, jb.ID, err.Error()) js.activeJobs[jb.ID] = aj return pkgerrors.Wrapf(err, "failed to create services for job: %d", jb.ID) } @@ -249,7 +245,11 @@ func (js *spawner) StartService(ctx context.Context, jb Job, qopts ...pg.QOpt) e } // Should not get called before Start() -func (js *spawner) CreateJob(jb *Job, qopts ...pg.QOpt) (err error) { +func (js *spawner) CreateJob(ctx context.Context, ds sqlutil.DataSource, jb *Job) (err error) { + orm := js.orm + if ds != nil { + orm = orm.WithDataSource(ds) + } delegate, exists := js.jobTypeDelegates[jb.Type] if !exists { js.lggr.Errorf("job type '%s' has not been registered with the job.Spawner", jb.Type) @@ -257,15 +257,7 @@ func (js *spawner) CreateJob(jb *Job, qopts ...pg.QOpt) (err error) { return } - q := js.q.WithOpts(qopts...) - pctx, cancel := js.chStop.Ctx(q.ParentCtx) - defer cancel() - q.ParentCtx = pctx - - ctx, cancel := q.Context() - defer cancel() - - err = js.orm.CreateJob(jb, pg.WithQueryer(q.Queryer), pg.WithParentCtx(ctx)) + err = orm.CreateJob(ctx, jb) if err != nil { js.lggr.Errorw("Error creating job", "type", jb.Type, "err", err) return @@ -273,7 +265,7 @@ func (js *spawner) CreateJob(jb *Job, qopts ...pg.QOpt) (err error) { js.lggr.Infow("Created job", "type", jb.Type, "jobID", jb.ID) delegate.BeforeJobCreated(*jb) - err = js.StartService(pctx, *jb, pg.WithQueryer(q.Queryer)) + err = js.StartService(ctx, *jb) if err != nil { js.lggr.Errorw("Error starting job services", "type", jb.Type, "jobID", jb.ID, "err", err) } else { @@ -286,7 +278,10 @@ func (js *spawner) CreateJob(jb *Job, qopts ...pg.QOpt) (err error) { } // Should not get called before Start() -func (js *spawner) DeleteJob(jobID int32, qopts ...pg.QOpt) error { +func (js *spawner) DeleteJob(ctx context.Context, ds sqlutil.DataSource, jobID int32) error { + if ds == nil { + ds = js.orm.DataSource() + } if jobID == 0 { return pkgerrors.New("will not delete job with 0 ID") } @@ -302,15 +297,8 @@ func (js *spawner) DeleteJob(jobID int32, qopts ...pg.QOpt) error { aj, exists = js.activeJobs[jobID] }() - q := js.q.WithOpts(qopts...) - pctx, cancel := js.chStop.Ctx(q.ParentCtx) - defer cancel() - q.ParentCtx = pctx - ctx, cancel := q.Context() - defer cancel() - if !exists { // inactive, so look up the spec and delegate - jb, err := js.orm.FindJob(ctx, jobID) + jb, err := js.orm.WithDataSource(ds).FindJob(ctx, jobID) if err != nil { return pkgerrors.Wrapf(err, "job %d not found", jobID) } @@ -330,8 +318,8 @@ func (js *spawner) DeleteJob(jobID int32, qopts ...pg.QOpt) error { aj.delegate.BeforeJobDeleted(aj.spec) lggr.Debugw("Callback: BeforeDeleteJob done") - err := q.Transaction(func(tx pg.Queryer) error { - err := js.orm.DeleteJob(jobID, pg.WithQueryer(tx)) + err := sqlutil.Transact(ctx, js.orm.WithDataSource, ds, nil, func(tx ORM) error { + err := tx.DeleteJob(ctx, jobID) if err != nil { js.lggr.Errorw("Error deleting job", "jobID", jobID, "err", err) return err diff --git a/core/services/job/spawner_test.go b/core/services/job/spawner_test.go index ae8ffaa2161..7b4ab138e7c 100644 --- a/core/services/job/spawner_test.go +++ b/core/services/job/spawner_test.go @@ -101,10 +101,10 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) t.Run("should respect its dependents", func(t *testing.T) { lggr := logger.TestLogger(t) - orm := NewTestORM(t, db, pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db), keyStore, config.Database()) + orm := NewTestORM(t, db, pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db), keyStore) a := utils.NewDependentAwaiter() a.AddDependents(1) - spawner := job.NewSpawner(orm, config.Database(), noopChecker{}, map[job.Type]job.Delegate{}, db, lggr, []utils.DependentAwaiter{a}) + spawner := job.NewSpawner(orm, config.Database(), noopChecker{}, map[job.Type]job.Delegate{}, lggr, []utils.DependentAwaiter{a}) // Starting the spawner should signal to the dependents result := make(chan bool) go func() { @@ -124,7 +124,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { jobB := makeOCRJobSpec(t, address, bridge.Name.String(), bridge2.Name.String()) lggr := logger.TestLogger(t) - orm := NewTestORM(t, db, pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db), keyStore, config.Database()) + orm := NewTestORM(t, db, pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db), keyStore) eventuallyA := cltest.NewAwaiter() serviceA1 := mocks.NewServiceCtx(t) @@ -146,9 +146,10 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { spawner := job.NewSpawner(orm, config.Database(), noopChecker{}, map[job.Type]job.Delegate{ jobA.Type: delegateA, jobB.Type: delegateB, - }, db, lggr, nil) - require.NoError(t, spawner.Start(testutils.Context(t))) - err := spawner.CreateJob(jobA) + }, lggr, nil) + ctx := testutils.Context(t) + require.NoError(t, spawner.Start(ctx)) + err := spawner.CreateJob(ctx, nil, jobA) require.NoError(t, err) jobSpecIDA := jobA.ID delegateA.jobID = jobSpecIDA @@ -156,7 +157,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { eventuallyA.AwaitOrFail(t, 20*time.Second) - err = spawner.CreateJob(jobB) + err = spawner.CreateJob(ctx, nil, jobB) require.NoError(t, err) jobSpecIDB := jobB.ID delegateB.jobID = jobSpecIDB @@ -166,12 +167,12 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { serviceA1.On("Close").Return(nil).Once() serviceA2.On("Close").Return(nil).Once() - err = spawner.DeleteJob(jobSpecIDA) + err = spawner.DeleteJob(ctx, nil, jobSpecIDA) require.NoError(t, err) serviceB1.On("Close").Return(nil).Once() serviceB2.On("Close").Return(nil).Once() - err = spawner.DeleteJob(jobSpecIDB) + err = spawner.DeleteJob(ctx, nil, jobSpecIDB) require.NoError(t, err) require.NoError(t, spawner.Close()) @@ -189,19 +190,20 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { serviceA2.On("Start", mock.Anything).Return(nil).Once().Run(func(mock.Arguments) { eventually.ItHappened() }) lggr := logger.TestLogger(t) - orm := NewTestORM(t, db, pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db), keyStore, config.Database()) + orm := NewTestORM(t, db, pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db), keyStore) mailMon := servicetest.Run(t, mailboxtest.NewMonitor(t)) d := ocr.NewDelegate(nil, orm, nil, nil, nil, monitoringEndpoint, legacyChains, logger.TestLogger(t), config, mailMon) delegateA := &delegate{jobA.Type, []job.ServiceCtx{serviceA1, serviceA2}, 0, nil, d} spawner := job.NewSpawner(orm, config.Database(), noopChecker{}, map[job.Type]job.Delegate{ jobA.Type: delegateA, - }, db, lggr, nil) + }, lggr, nil) - err := orm.CreateJob(jobA) + ctx := testutils.Context(t) + err := orm.CreateJob(ctx, jobA) require.NoError(t, err) delegateA.jobID = jobA.ID - require.NoError(t, spawner.Start(testutils.Context(t))) + require.NoError(t, spawner.Start(ctx)) eventually.AwaitOrFail(t) @@ -223,20 +225,21 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { serviceA2.On("Start", mock.Anything).Return(nil).Once().Run(func(mock.Arguments) { eventuallyStart.ItHappened() }) lggr := logger.TestLogger(t) - orm := NewTestORM(t, db, pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db), keyStore, config.Database()) + orm := NewTestORM(t, db, pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db), keyStore) mailMon := servicetest.Run(t, mailboxtest.NewMonitor(t)) d := ocr.NewDelegate(nil, orm, nil, nil, nil, monitoringEndpoint, legacyChains, logger.TestLogger(t), config, mailMon) delegateA := &delegate{jobA.Type, []job.ServiceCtx{serviceA1, serviceA2}, 0, nil, d} spawner := job.NewSpawner(orm, config.Database(), noopChecker{}, map[job.Type]job.Delegate{ jobA.Type: delegateA, - }, db, lggr, nil) + }, lggr, nil) - err := orm.CreateJob(jobA) + ctx := testutils.Context(t) + err := orm.CreateJob(ctx, jobA) require.NoError(t, err) jobSpecIDA := jobA.ID delegateA.jobID = jobSpecIDA - require.NoError(t, spawner.Start(testutils.Context(t))) + require.NoError(t, spawner.Start(ctx)) defer func() { assert.NoError(t, spawner.Close()) }() eventuallyStart.AwaitOrFail(t) @@ -252,7 +255,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { serviceA1.On("Close").Return(nil).Once() serviceA2.On("Close").Return(nil).Once().Run(func(mock.Arguments) { eventuallyClose.ItHappened() }) - err = spawner.DeleteJob(jobSpecIDA) + err = spawner.DeleteJob(ctx, nil, jobSpecIDA) require.NoError(t, err) eventuallyClose.AwaitOrFail(t) @@ -287,9 +290,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { chain := evmtest.MustGetDefaultChain(t, legacyChains) evmRelayer, err := evmrelayer.NewRelayer(lggr, chain, evmrelayer.RelayerOpts{ - DB: db, DS: db, - QConfig: testopts.GeneralConfig.Database(), CSAETHKeystore: keyStore, }) assert.NoError(t, err) @@ -299,23 +300,24 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { r: evmRelayer, } - jobOCR2VRF := makeOCR2VRFJobSpec(t, keyStore, config, address, chain.ID(), 2) + jobOCR2VRF := makeOCR2VRFJobSpec(t, keyStore, address, chain.ID(), 2) - orm := NewTestORM(t, db, pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db), keyStore, config.Database()) + orm := NewTestORM(t, db, pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db), keyStore) mailMon := servicetest.Run(t, mailboxtest.NewMonitor(t)) processConfig := plugins.NewRegistrarConfig(loop.GRPCOpts{}, func(name string) (*plugins.RegisteredLoop, error) { return nil, nil }, func(loopId string) {}) - ocr2DelegateConfig := ocr2.NewDelegateConfig(config.OCR2(), config.Mercury(), config.Threshold(), config.Insecure(), config.JobPipeline(), config.Database(), processConfig) + ocr2DelegateConfig := ocr2.NewDelegateConfig(config.OCR2(), config.Mercury(), config.Threshold(), config.Insecure(), config.JobPipeline(), processConfig) - d := ocr2.NewDelegate(nil, nil, orm, nil, nil, nil, nil, nil, monitoringEndpoint, legacyChains, lggr, ocr2DelegateConfig, + d := ocr2.NewDelegate(nil, orm, nil, nil, nil, nil, nil, monitoringEndpoint, legacyChains, lggr, ocr2DelegateConfig, keyStore.OCR2(), keyStore.DKGSign(), keyStore.DKGEncrypt(), ethKeyStore, testRelayGetter, mailMon, capabilities.NewRegistry(lggr)) delegateOCR2 := &delegate{jobOCR2VRF.Type, []job.ServiceCtx{}, 0, nil, d} spawner := job.NewSpawner(orm, config.Database(), noopChecker{}, map[job.Type]job.Delegate{ jobOCR2VRF.Type: delegateOCR2, - }, db, lggr, nil) + }, lggr, nil) - err = spawner.CreateJob(jobOCR2VRF) + ctx := testutils.Context(t) + err = spawner.CreateJob(ctx, nil, jobOCR2VRF) require.NoError(t, err) jobSpecID := jobOCR2VRF.ID delegateOCR2.jobID = jobOCR2VRF.ID @@ -324,7 +326,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { lggr.Debugf("Got here, with args %v", args) }) - err = spawner.DeleteJob(jobSpecID) + err = spawner.DeleteJob(ctx, nil, jobSpecID) require.NoError(t, err) lp.AssertNumberOfCalls(t, "UnregisterFilter", 3) diff --git a/core/services/keeper/delegate.go b/core/services/keeper/delegate.go index 184a61e1e1a..71a0c5c43a9 100644 --- a/core/services/keeper/delegate.go +++ b/core/services/keeper/delegate.go @@ -5,8 +5,7 @@ import ( "github.com/pkg/errors" - "github.com/jmoiron/sqlx" - + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/config" @@ -25,7 +24,7 @@ type DelegateConfig interface { type Delegate struct { cfg DelegateConfig logger logger.Logger - db *sqlx.DB + ds sqlutil.DataSource jrm job.ORM pr pipeline.Runner legacyChains legacyevm.LegacyChainContainer @@ -35,7 +34,7 @@ type Delegate struct { // NewDelegate is the constructor of Delegate func NewDelegate( cfg DelegateConfig, - db *sqlx.DB, + ds sqlutil.DataSource, jrm job.ORM, pr pipeline.Runner, logger logger.Logger, @@ -45,7 +44,7 @@ func NewDelegate( return &Delegate{ cfg: cfg, logger: logger, - db: db, + ds: ds, jrm: jrm, pr: pr, legacyChains: legacyChains, @@ -58,10 +57,10 @@ func (d *Delegate) JobType() job.Type { return job.Keeper } -func (d *Delegate) BeforeJobCreated(spec job.Job) {} -func (d *Delegate) AfterJobCreated(spec job.Job) {} -func (d *Delegate) BeforeJobDeleted(spec job.Job) {} -func (d *Delegate) OnDeleteJob(context.Context, job.Job) error { return nil } +func (d *Delegate) BeforeJobCreated(spec job.Job) {} +func (d *Delegate) AfterJobCreated(spec job.Job) {} +func (d *Delegate) BeforeJobDeleted(spec job.Job) {} +func (d *Delegate) OnDeleteJob(ctx context.Context, spec job.Job) error { return nil } // ServicesForSpec satisfies the job.Delegate interface. func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) (services []job.ServiceCtx, err error) { @@ -73,7 +72,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) (services return nil, err } registryAddress := spec.KeeperSpec.ContractAddress - orm := NewORM(d.db, d.logger) + orm := NewORM(d.ds, d.logger) svcLogger := d.logger.With( "jobID", spec.ID, "registryAddress", registryAddress.Hex(), diff --git a/core/services/keeper/helpers_test.go b/core/services/keeper/helpers_test.go index 3fb9d7760a4..a10c3a48aff 100644 --- a/core/services/keeper/helpers_test.go +++ b/core/services/keeper/helpers_test.go @@ -12,6 +12,10 @@ func (rs *RegistrySynchronizer) ExportedFullSync(ctx context.Context) { rs.fullSync(ctx) } +func (rs *RegistrySynchronizer) ExportedProcessLogs(ctx context.Context) { + rs.processLogs(ctx) +} + func (rw *RegistryWrapper) GetUpkeepIdFromRawRegistrationLog(rawLog types.Log) (*big.Int, error) { switch rw.Version { case RegistryVersion_1_0, RegistryVersion_1_1: diff --git a/core/services/keeper/integration_test.go b/core/services/keeper/integration_test.go index 08699d3d835..9e4cf5f9041 100644 --- a/core/services/keeper/integration_test.go +++ b/core/services/keeper/integration_test.go @@ -284,7 +284,7 @@ func TestKeeperEthIntegration(t *testing.T) { require.NoError(t, err) backend.Commit() - cltest.WaitForCount(t, app.GetSqlxDB(), "upkeep_registrations", 0) + cltest.WaitForCount(t, app.GetDB(), "upkeep_registrations", 0) // add new upkeep (same target contract) registrationTx, err = registryWrapper.RegisterUpkeep(steve, upkeepAddr, 2_500_000, carrol.From, []byte{}) @@ -308,8 +308,8 @@ func TestKeeperEthIntegration(t *testing.T) { require.NoError(t, err) var registry keeper.Registry - require.NoError(t, app.GetSqlxDB().Get(®istry, `SELECT * FROM keeper_registries`)) - cltest.AssertRecordEventually(t, app.GetSqlxDB(), ®istry, fmt.Sprintf("SELECT * FROM keeper_registries WHERE id = %d", registry.ID), func() bool { + require.NoError(t, app.GetDB().GetContext(ctx, ®istry, `SELECT * FROM keeper_registries`)) + cltest.AssertRecordEventually(t, app.GetDB(), ®istry, fmt.Sprintf("SELECT * FROM keeper_registries WHERE id = %d", registry.ID), func() bool { return registry.KeeperIndex == -1 }) runs, err := app.PipelineORM().GetAllRuns(ctx) @@ -435,7 +435,7 @@ func TestKeeperForwarderEthIntegration(t *testing.T) { SchemaVersion: 1, ForwardingAllowed: true, } - err = app.JobORM().CreateJob(&jb) + err = app.JobORM().CreateJob(testutils.Context(t), &jb) require.NoError(t, err) registry := keeper.Registry{ diff --git a/core/services/keeper/registry_synchronizer_helper_test.go b/core/services/keeper/registry_synchronizer_helper_test.go index 2726c9a754d..73a3cb88166 100644 --- a/core/services/keeper/registry_synchronizer_helper_test.go +++ b/core/services/keeper/registry_synchronizer_helper_test.go @@ -46,7 +46,7 @@ func setupRegistrySync(t *testing.T, version keeper.RegistryVersion) ( j := cltest.MustInsertKeeperJob(t, db, korm, cltest.NewEIP55Address(), cltest.NewEIP55Address()) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, Client: ethClient, LogBroadcaster: lbMock, GeneralConfig: cfg, KeyStore: keyStore.Eth()}) legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - jpv2 := cltest.NewJobPipelineV2(t, cfg.WebServer(), cfg.JobPipeline(), cfg.Database(), legacyChains, db, keyStore, nil, nil) + jpv2 := cltest.NewJobPipelineV2(t, cfg.WebServer(), cfg.JobPipeline(), legacyChains, db, keyStore, nil, nil) contractAddress := j.KeeperSpec.ContractAddress.Address() switch version { diff --git a/core/services/keeper/registry_synchronizer_process_logs.go b/core/services/keeper/registry_synchronizer_process_logs.go index a1bdcd8db0b..5aaddb6f1e4 100644 --- a/core/services/keeper/registry_synchronizer_process_logs.go +++ b/core/services/keeper/registry_synchronizer_process_logs.go @@ -82,6 +82,9 @@ func (rs *RegistrySynchronizer) processLogs(ctx context.Context) { } if err != nil { + if ctx.Err() != nil { + return + } rs.logger.Error(err) } diff --git a/core/services/keeper/registry_synchronizer_sync.go b/core/services/keeper/registry_synchronizer_sync.go index 6c0e12d844b..6615d376e2b 100644 --- a/core/services/keeper/registry_synchronizer_sync.go +++ b/core/services/keeper/registry_synchronizer_sync.go @@ -30,7 +30,7 @@ func (rs *RegistrySynchronizer) fullSync(ctx context.Context) { } func (rs *RegistrySynchronizer) syncRegistry(ctx context.Context) (Registry, error) { - registry, err := rs.newRegistryFromChain() + registry, err := rs.newRegistryFromChain(ctx) if err != nil { return Registry{}, errors.Wrap(err, "failed to get new registry from chain") } @@ -138,13 +138,13 @@ func (rs *RegistrySynchronizer) syncUpkeep(ctx context.Context, getter upkeepGet } // newRegistryFromChain returns a Registry struct with fields synched from those on chain -func (rs *RegistrySynchronizer) newRegistryFromChain() (Registry, error) { +func (rs *RegistrySynchronizer) newRegistryFromChain(ctx context.Context) (Registry, error) { fromAddress := rs.effectiveKeeperAddress contractAddress := rs.job.KeeperSpec.ContractAddress registryConfig, err := rs.registryWrapper.GetConfig(nil) if err != nil { - rs.jrm.TryRecordError(rs.job.ID, err.Error()) + rs.jrm.TryRecordError(ctx, rs.job.ID, err.Error()) return Registry{}, errors.Wrap(err, "failed to get contract config") } diff --git a/core/services/keeper/upkeep_executer_test.go b/core/services/keeper/upkeep_executer_test.go index ec23331f904..cd02fc27d11 100644 --- a/core/services/keeper/upkeep_executer_test.go +++ b/core/services/keeper/upkeep_executer_test.go @@ -83,7 +83,7 @@ func setup(t *testing.T, estimator gas.EvmFeeEstimator, overrideFn func(c *chain txm := txmmocks.NewMockEvmTxManager(t) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{TxManager: txm, DB: db, Client: ethClient, KeyStore: keyStore.Eth(), GeneralConfig: cfg, GasEstimator: estimator}) legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) - jpv2 := cltest.NewJobPipelineV2(t, cfg.WebServer(), cfg.JobPipeline(), cfg.Database(), legacyChains, db, keyStore, nil, nil) + jpv2 := cltest.NewJobPipelineV2(t, cfg.WebServer(), cfg.JobPipeline(), legacyChains, db, keyStore, nil, nil) ch := evmtest.MustGetDefaultChain(t, legacyChains) orm := keeper.NewORM(db, logger.TestLogger(t)) registry, jb := cltest.MustInsertKeeperRegistry(t, db, orm, keyStore.Eth(), 0, 1, 20) diff --git a/core/services/keystore/eth_test.go b/core/services/keystore/eth_test.go index 07a41599f7d..4a9c8a952ff 100644 --- a/core/services/keystore/eth_test.go +++ b/core/services/keystore/eth_test.go @@ -13,8 +13,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-common/pkg/logger" - "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" commonutils "github.com/smartcontractkit/chainlink-common/pkg/utils" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" @@ -29,9 +27,7 @@ import ( func Test_EthKeyStore(t *testing.T) { t.Parallel() - db := sqlutil.WrapDataSource(pgtest.NewSqlxDB(t), logger.Test(t), sqlutil.TimeoutHook(func() time.Duration { - return 5 * time.Minute - }), sqlutil.MonitorHook(func() bool { return true })) + db := pgtest.NewSqlxDB(t) keyStore := keystore.ExposedNewMaster(t, db) err := keyStore.Unlock(testutils.Context(t), cltest.Password) diff --git a/core/services/llo/delegate.go b/core/services/llo/delegate.go index 2bab0ab12a2..6cdad6290fc 100644 --- a/core/services/llo/delegate.go +++ b/core/services/llo/delegate.go @@ -13,13 +13,13 @@ import ( "gopkg.in/guregu/null.v4" "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" "github.com/smartcontractkit/chainlink-data-streams/llo" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/llo/evm" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/streams" ) @@ -43,11 +43,11 @@ type delegate struct { } type DelegateConfig struct { - Logger logger.Logger - Queryer pg.Queryer - Runner streams.Runner - Registry Registry - JobName null.String + Logger logger.Logger + DataSource sqlutil.DataSource + Runner streams.Runner + Registry Registry + JobName null.String // LLO ChannelDefinitionCache llotypes.ChannelDefinitionCache @@ -67,8 +67,8 @@ type DelegateConfig struct { } func NewDelegate(cfg DelegateConfig) (job.ServiceCtx, error) { - if cfg.Queryer == nil { - return nil, errors.New("Queryer must not be nil") + if cfg.DataSource == nil { + return nil, errors.New("DataSource must not be nil") } if cfg.Runner == nil { return nil, errors.New("Runner must not be nil") diff --git a/core/services/ocr/contract_tracker.go b/core/services/ocr/contract_tracker.go index 5746f97cd38..f7c7a9940b5 100644 --- a/core/services/ocr/contract_tracker.go +++ b/core/services/ocr/contract_tracker.go @@ -90,8 +90,9 @@ type ( } OCRContractTrackerDB interface { - SaveLatestRoundRequested(ctx context.Context, tx sqlutil.DataSource, rr offchainaggregator.OffchainAggregatorRoundRequested) error + SaveLatestRoundRequested(ctx context.Context, rr offchainaggregator.OffchainAggregatorRoundRequested) error LoadLatestRoundRequested(ctx context.Context) (rr offchainaggregator.OffchainAggregatorRoundRequested, err error) + WithDataSource(sqlutil.DataSource) OCRContractTrackerDB } ) @@ -293,7 +294,7 @@ func (t *OCRContractTracker) HandleLog(ctx context.Context, lb log.Broadcast) { } if IsLaterThan(raw, t.latestRoundRequested.Raw) { err = sqlutil.TransactDataSource(ctx, t.ds, nil, func(tx sqlutil.DataSource) error { - if err = t.ocrDB.SaveLatestRoundRequested(ctx, tx, *rr); err != nil { + if err = t.ocrDB.WithDataSource(tx).SaveLatestRoundRequested(ctx, *rr); err != nil { return err } return t.logBroadcaster.MarkConsumed(ctx, tx, lb) diff --git a/core/services/ocr/contract_tracker_test.go b/core/services/ocr/contract_tracker_test.go index 6f8b05c6436..d8fd8a01a11 100644 --- a/core/services/ocr/contract_tracker_test.go +++ b/core/services/ocr/contract_tracker_test.go @@ -224,9 +224,10 @@ func Test_OCRContractTracker_HandleLog_OCRContractLatestRoundRequested(t *testin uni.lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil) uni.lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil) - uni.db.On("SaveLatestRoundRequested", mock.Anything, mock.Anything, mock.MatchedBy(func(rr offchainaggregator.OffchainAggregatorRoundRequested) bool { + uni.db.On("SaveLatestRoundRequested", mock.Anything, mock.MatchedBy(func(rr offchainaggregator.OffchainAggregatorRoundRequested) bool { return rr.Epoch == 1 && rr.Round == 1 })).Return(nil) + uni.db.On("WithDataSource", mock.Anything).Return(uni.db) uni.tracker.HandleLog(testutils.Context(t), logBroadcast) @@ -244,7 +245,7 @@ func Test_OCRContractTracker_HandleLog_OCRContractLatestRoundRequested(t *testin uni.lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil) uni.lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil) - uni.db.On("SaveLatestRoundRequested", mock.Anything, mock.Anything, mock.MatchedBy(func(rr offchainaggregator.OffchainAggregatorRoundRequested) bool { + uni.db.On("SaveLatestRoundRequested", mock.Anything, mock.MatchedBy(func(rr offchainaggregator.OffchainAggregatorRoundRequested) bool { return rr.Epoch == 1 && rr.Round == 9 })).Return(nil) @@ -273,7 +274,7 @@ func Test_OCRContractTracker_HandleLog_OCRContractLatestRoundRequested(t *testin uni.lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil) uni.lb.On("MarkConsumed", mock.Anything, mock.Anything, mock.Anything).Return(nil) - uni.db.On("SaveLatestRoundRequested", mock.Anything, mock.Anything, mock.MatchedBy(func(rr offchainaggregator.OffchainAggregatorRoundRequested) bool { + uni.db.On("SaveLatestRoundRequested", mock.Anything, mock.MatchedBy(func(rr offchainaggregator.OffchainAggregatorRoundRequested) bool { return rr.Epoch == 2 && rr.Round == 1 })).Return(nil) @@ -295,7 +296,8 @@ func Test_OCRContractTracker_HandleLog_OCRContractLatestRoundRequested(t *testin logBroadcast.On("String").Return("").Maybe() uni.lb.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil) - uni.db.On("SaveLatestRoundRequested", mock.Anything, mock.Anything, mock.Anything).Return(errors.New("something exploded")) + uni.db.On("SaveLatestRoundRequested", mock.Anything, mock.Anything).Return(errors.New("something exploded")) + uni.db.On("WithDataSource", mock.Anything).Return(uni.db) uni.tracker.HandleLog(testutils.Context(t), logBroadcast) diff --git a/core/services/ocr/database.go b/core/services/ocr/database.go index 95993de9d5c..b5f890565f1 100644 --- a/core/services/ocr/database.go +++ b/core/services/ocr/database.go @@ -38,6 +38,9 @@ func NewDB(ds sqlutil.DataSource, oracleSpecID int32, lggr logger.Logger) *db { lggr: logger.Sugared(lggr), } } +func (d *db) WithDataSource(ds sqlutil.DataSource) OCRContractTrackerDB { + return NewDB(ds, d.oracleSpecID, d.lggr) +} func (d *db) ReadState(ctx context.Context, cd ocrtypes.ConfigDigest) (ps *ocrtypes.PersistentState, err error) { stmt := ` @@ -293,12 +296,12 @@ WHERE ocr_oracle_spec_id = $1 AND time < $2 return } -func (d *db) SaveLatestRoundRequested(ctx context.Context, tx sqlutil.DataSource, rr offchainaggregator.OffchainAggregatorRoundRequested) error { +func (d *db) SaveLatestRoundRequested(ctx context.Context, rr offchainaggregator.OffchainAggregatorRoundRequested) error { rawLog, err := json.Marshal(rr.Raw) if err != nil { return errors.Wrap(err, "could not marshal log as JSON") } - _, err = tx.ExecContext(ctx, ` + _, err = d.ds.ExecContext(ctx, ` INSERT INTO ocr_latest_round_requested (ocr_oracle_spec_id, requester, config_digest, epoch, round, raw) VALUES ($1,$2,$3,$4,$5,$6) ON CONFLICT (ocr_oracle_spec_id) DO UPDATE SET requester = EXCLUDED.requester, diff --git a/core/services/ocr/database_test.go b/core/services/ocr/database_test.go index a2559ca2a87..12f9309450c 100644 --- a/core/services/ocr/database_test.go +++ b/core/services/ocr/database_test.go @@ -407,7 +407,7 @@ func Test_DB_LatestRoundRequested(t *testing.T) { t.Run("saves latest round requested", func(t *testing.T) { ctx := testutils.Context(t) - err := odb.SaveLatestRoundRequested(ctx, sqlDB, rr) + err := odb.SaveLatestRoundRequested(ctx, rr) require.NoError(t, err) rawLog.Index = 42 @@ -421,7 +421,7 @@ func Test_DB_LatestRoundRequested(t *testing.T) { Raw: rawLog, } - err = odb.SaveLatestRoundRequested(ctx, sqlDB, rr) + err = odb.SaveLatestRoundRequested(ctx, rr) require.NoError(t, err) }) diff --git a/core/services/ocr/delegate.go b/core/services/ocr/delegate.go index 88561bd1c3a..690e9ad7c71 100644 --- a/core/services/ocr/delegate.go +++ b/core/services/ocr/delegate.go @@ -10,13 +10,12 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" - "github.com/jmoiron/sqlx" - "github.com/smartcontractkit/libocr/gethwrappers/offchainaggregator" ocr "github.com/smartcontractkit/libocr/offchainreporting" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting/types" commonlogger "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" @@ -35,7 +34,7 @@ import ( ) type Delegate struct { - db *sqlx.DB + ds sqlutil.DataSource jobORM job.ORM keyStore keystore.Master pipelineRunner pipeline.Runner @@ -52,7 +51,7 @@ var _ job.Delegate = (*Delegate)(nil) const ConfigOverriderPollInterval = 30 * time.Second func NewDelegate( - db *sqlx.DB, + ds sqlutil.DataSource, jobORM job.ORM, keyStore keystore.Master, pipelineRunner pipeline.Runner, @@ -64,7 +63,7 @@ func NewDelegate( mailMon *mailbox.Monitor, ) *Delegate { return &Delegate{ - db: db, + ds: ds, jobORM: jobORM, keyStore: keyStore, pipelineRunner: pipelineRunner, @@ -120,7 +119,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) (services [] return nil, errors.Wrap(err, "could not instantiate NewOffchainAggregatorCaller") } - ocrDB := NewDB(d.db, concreteSpec.ID, lggr) + ocrDB := NewDB(d.ds, concreteSpec.ID, lggr) tracker := NewOCRContractTracker( contract, @@ -130,7 +129,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) (services [] chain.LogBroadcaster(), jb.ID, lggr, - d.db, + d.ds, ocrDB, chain.Config().EVM(), chain.HeadBroadcaster(), @@ -157,7 +156,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) (services [] } ocrLogger := commonlogger.NewOCRWrapper(lggr, d.cfg.OCR().TraceLogging(), func(msg string) { - d.jobORM.TryRecordError(jb.ID, msg) + d.jobORM.TryRecordError(ctx, jb.ID, msg) }) lc := toLocalConfig(chain.Config().EVM(), chain.Config().EVM().OCR(), d.cfg.Insecure(), *concreteSpec, d.cfg.OCR()) diff --git a/core/services/ocr/helpers_internal_test.go b/core/services/ocr/helpers_internal_test.go index c6a3d1ac401..a8c656f636c 100644 --- a/core/services/ocr/helpers_internal_test.go +++ b/core/services/ocr/helpers_internal_test.go @@ -3,8 +3,7 @@ package ocr import ( "testing" - "github.com/jmoiron/sqlx" - + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink/v2/core/logger" ) @@ -12,6 +11,6 @@ func (c *ConfigOverriderImpl) ExportedUpdateFlagsStatus() error { return c.updateFlagsStatus() } -func NewTestDB(t *testing.T, sqldb *sqlx.DB, oracleSpecID int32) *db { - return NewDB(sqldb, oracleSpecID, logger.TestLogger(t)) +func NewTestDB(t *testing.T, ds sqlutil.DataSource, oracleSpecID int32) *db { + return NewDB(ds, oracleSpecID, logger.TestLogger(t)) } diff --git a/core/services/ocr/mocks/ocr_contract_tracker_db.go b/core/services/ocr/mocks/ocr_contract_tracker_db.go index ed47d87cd1e..d3dcce2641b 100644 --- a/core/services/ocr/mocks/ocr_contract_tracker_db.go +++ b/core/services/ocr/mocks/ocr_contract_tracker_db.go @@ -5,6 +5,7 @@ package mocks import ( context "context" + ocr "github.com/smartcontractkit/chainlink/v2/core/services/ocr" mock "github.com/stretchr/testify/mock" offchainaggregator "github.com/smartcontractkit/libocr/gethwrappers/offchainaggregator" @@ -45,17 +46,17 @@ func (_m *OCRContractTrackerDB) LoadLatestRoundRequested(ctx context.Context) (o return r0, r1 } -// SaveLatestRoundRequested provides a mock function with given fields: ctx, tx, rr -func (_m *OCRContractTrackerDB) SaveLatestRoundRequested(ctx context.Context, tx sqlutil.DataSource, rr offchainaggregator.OffchainAggregatorRoundRequested) error { - ret := _m.Called(ctx, tx, rr) +// SaveLatestRoundRequested provides a mock function with given fields: ctx, rr +func (_m *OCRContractTrackerDB) SaveLatestRoundRequested(ctx context.Context, rr offchainaggregator.OffchainAggregatorRoundRequested) error { + ret := _m.Called(ctx, rr) if len(ret) == 0 { panic("no return value specified for SaveLatestRoundRequested") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, sqlutil.DataSource, offchainaggregator.OffchainAggregatorRoundRequested) error); ok { - r0 = rf(ctx, tx, rr) + if rf, ok := ret.Get(0).(func(context.Context, offchainaggregator.OffchainAggregatorRoundRequested) error); ok { + r0 = rf(ctx, rr) } else { r0 = ret.Error(0) } @@ -63,6 +64,26 @@ func (_m *OCRContractTrackerDB) SaveLatestRoundRequested(ctx context.Context, tx return r0 } +// WithDataSource provides a mock function with given fields: _a0 +func (_m *OCRContractTrackerDB) WithDataSource(_a0 sqlutil.DataSource) ocr.OCRContractTrackerDB { + ret := _m.Called(_a0) + + if len(ret) == 0 { + panic("no return value specified for WithDataSource") + } + + var r0 ocr.OCRContractTrackerDB + if rf, ok := ret.Get(0).(func(sqlutil.DataSource) ocr.OCRContractTrackerDB); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(ocr.OCRContractTrackerDB) + } + } + + return r0 +} + // NewOCRContractTrackerDB creates a new instance of OCRContractTrackerDB. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewOCRContractTrackerDB(t interface { diff --git a/core/services/ocr2/database.go b/core/services/ocr2/database.go index 1d449047578..83ee3240a46 100644 --- a/core/services/ocr2/database.go +++ b/core/services/ocr2/database.go @@ -6,18 +6,17 @@ import ( "encoding/binary" "time" - "github.com/jmoiron/sqlx" "github.com/lib/pq" "github.com/pkg/errors" ocrcommon "github.com/smartcontractkit/libocr/commontypes" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) type db struct { - q pg.Q + ds sqlutil.DataSource oracleSpecID int32 pluginID int32 lggr logger.SugaredLogger @@ -28,11 +27,9 @@ var ( ) // NewDB returns a new DB scoped to this oracleSpecID -func NewDB(sqlxDB *sqlx.DB, oracleSpecID int32, pluginID int32, lggr logger.Logger, cfg pg.QConfig) *db { - namedLogger := lggr.Named("OCR2.DB") - +func NewDB(ds sqlutil.DataSource, oracleSpecID int32, pluginID int32, lggr logger.Logger) *db { return &db{ - q: pg.NewQ(sqlxDB, namedLogger, cfg), + ds: ds, oracleSpecID: oracleSpecID, pluginID: pluginID, lggr: logger.Sugared(lggr), @@ -51,7 +48,7 @@ func (d *db) ReadState(ctx context.Context, cd ocrtypes.ConfigDigest) (ps *ocrty var tmp []int64 var highestSentEpochTmp int64 - err = d.q.QueryRowxContext(ctx, stmt, d.oracleSpecID, cd).Scan(&ps.Epoch, &highestSentEpochTmp, pq.Array(&tmp)) + err = d.ds.QueryRowxContext(ctx, stmt, d.oracleSpecID, cd).Scan(&ps.Epoch, &highestSentEpochTmp, pq.Array(&tmp)) if errors.Is(err, sql.ErrNoRows) { return nil, nil } @@ -98,7 +95,9 @@ func (d *db) WriteState(ctx context.Context, cd ocrtypes.ConfigDigest, state ocr NOW() )` - _, err := d.q.WithOpts(pg.WithLongQueryTimeout()).ExecContext( + ctx, cancel := context.WithTimeout(sqlutil.WithoutDefaultTimeout(ctx), time.Minute) + defer cancel() + _, err := d.ds.ExecContext( ctx, stmt, d.oracleSpecID, cd, state.Epoch, state.HighestSentEpoch, pq.Array(&highestReceivedEpoch), ) @@ -126,7 +125,7 @@ func (d *db) ReadConfig(ctx context.Context) (c *ocrtypes.ContractConfig, err er signers := [][]byte{} transmitters := [][]byte{} - err = d.q.QueryRowx(stmt, d.oracleSpecID, d.pluginID).Scan( + err = d.ds.QueryRowxContext(ctx, stmt, d.oracleSpecID, d.pluginID).Scan( &digest, &c.ConfigCount, (*pq.ByteaArray)(&signers), @@ -191,7 +190,7 @@ func (d *db) WriteConfig(ctx context.Context, c ocrtypes.ContractConfig) error { offchain_config = EXCLUDED.offchain_config, updated_at = NOW() ` - _, err := d.q.ExecContext(ctx, stmt, + _, err := d.ds.ExecContext(ctx, stmt, d.oracleSpecID, d.pluginID, c.ConfigDigest, @@ -252,7 +251,7 @@ func (d *db) StorePendingTransmission(ctx context.Context, t ocrtypes.ReportTime updated_at = NOW() ` - _, err := d.q.ExecContext(ctx, stmt, + _, err := d.ds.ExecContext(ctx, stmt, d.oracleSpecID, digest, t.Epoch, @@ -279,7 +278,7 @@ func (d *db) PendingTransmissionsWithConfigDigest(ctx context.Context, cd ocrtyp FROM ocr2_pending_transmissions WHERE ocr2_oracle_spec_id = $1 AND config_digest = $2 ` - rows, err := d.q.QueryxContext(ctx, stmt, d.oracleSpecID, cd) //nolint sqlclosecheck false positive + rows, err := d.ds.QueryxContext(ctx, stmt, d.oracleSpecID, cd) //nolint sqlclosecheck false positive if err != nil { return nil, errors.Wrap(err, "PendingTransmissionsWithConfigDigest failed to query rows") } @@ -325,7 +324,9 @@ func (d *db) PendingTransmissionsWithConfigDigest(ctx context.Context, cd ocrtyp } func (d *db) DeletePendingTransmission(ctx context.Context, t ocrtypes.ReportTimestamp) (err error) { - _, err = d.q.WithOpts(pg.WithLongQueryTimeout()).ExecContext(ctx, ` + ctx, cancel := context.WithTimeout(sqlutil.WithoutDefaultTimeout(ctx), time.Minute) + defer cancel() + _, err = d.ds.ExecContext(ctx, ` DELETE FROM ocr2_pending_transmissions WHERE ocr2_oracle_spec_id = $1 AND config_digest = $2 AND epoch = $3 AND round = $4 `, d.oracleSpecID, t.ConfigDigest, t.Epoch, t.Round) @@ -336,7 +337,9 @@ WHERE ocr2_oracle_spec_id = $1 AND config_digest = $2 AND epoch = $3 AND round } func (d *db) DeletePendingTransmissionsOlderThan(ctx context.Context, t time.Time) (err error) { - _, err = d.q.WithOpts(pg.WithLongQueryTimeout()).ExecContext(ctx, ` + ctx, cancel := context.WithTimeout(sqlutil.WithoutDefaultTimeout(ctx), time.Minute) + defer cancel() + _, err = d.ds.ExecContext(ctx, ` DELETE FROM ocr2_pending_transmissions WHERE ocr2_oracle_spec_id = $1 AND time < $2 `, d.oracleSpecID, t) @@ -347,7 +350,7 @@ WHERE ocr2_oracle_spec_id = $1 AND time < $2 } func (d *db) ReadProtocolState(ctx context.Context, configDigest ocrtypes.ConfigDigest, key string) (value []byte, err error) { - err = d.q.GetContext(ctx, &value, ` + err = d.ds.GetContext(ctx, &value, ` SELECT value FROM ocr_protocol_states WHERE config_digest = $1 AND key = $2; `, configDigest, key) @@ -363,9 +366,9 @@ WHERE config_digest = $1 AND key = $2; func (d *db) WriteProtocolState(ctx context.Context, configDigest ocrtypes.ConfigDigest, key string, value []byte) (err error) { if value == nil { - _, err = d.q.ExecContext(ctx, `DELETE FROM ocr_protocol_states WHERE config_digest = $1 AND key = $2;`, configDigest, key) + _, err = d.ds.ExecContext(ctx, `DELETE FROM ocr_protocol_states WHERE config_digest = $1 AND key = $2;`, configDigest, key) } else { - _, err = d.q.ExecContext(ctx, ` + _, err = d.ds.ExecContext(ctx, ` INSERT INTO ocr_protocol_states (config_digest, key, value) VALUES ($1, $2, $3) ON CONFLICT (config_digest, key) DO UPDATE SET value = $3;`, configDigest, key, value) } diff --git a/core/services/ocr2/database_test.go b/core/services/ocr2/database_test.go index 6e4f8f5dd66..3e78249d087 100644 --- a/core/services/ocr2/database_test.go +++ b/core/services/ocr2/database_test.go @@ -16,7 +16,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" @@ -60,14 +59,13 @@ func Test_DB_ReadWriteState(t *testing.T) { sqlDB := setupDB(t) configDigest := testhelpers.MakeConfigDigest(t) - cfg := configtest.NewTestGeneralConfig(t) ethKeyStore := cltest.NewKeyStore(t, sqlDB).Eth() key, _ := cltest.MustInsertRandomKey(t, ethKeyStore) spec := MustInsertOCROracleSpec(t, sqlDB, key.EIP55Address) lggr := logger.TestLogger(t) t.Run("reads and writes state", func(t *testing.T) { - db := ocr2.NewDB(sqlDB, spec.ID, defaultPluginID, lggr, cfg.Database()) + db := ocr2.NewDB(sqlDB, spec.ID, defaultPluginID, lggr) state := ocrtypes.PersistentState{ Epoch: 1, HighestSentEpoch: 2, @@ -84,7 +82,7 @@ func Test_DB_ReadWriteState(t *testing.T) { }) t.Run("updates state", func(t *testing.T) { - db := ocr2.NewDB(sqlDB, spec.ID, defaultPluginID, lggr, cfg.Database()) + db := ocr2.NewDB(sqlDB, spec.ID, defaultPluginID, lggr) newState := ocrtypes.PersistentState{ Epoch: 2, HighestSentEpoch: 3, @@ -101,7 +99,7 @@ func Test_DB_ReadWriteState(t *testing.T) { }) t.Run("does not return result for wrong spec", func(t *testing.T) { - db := ocr2.NewDB(sqlDB, spec.ID, defaultPluginID, lggr, cfg.Database()) + db := ocr2.NewDB(sqlDB, spec.ID, defaultPluginID, lggr) state := ocrtypes.PersistentState{ Epoch: 3, HighestSentEpoch: 4, @@ -112,7 +110,7 @@ func Test_DB_ReadWriteState(t *testing.T) { require.NoError(t, err) // odb with different spec - db = ocr2.NewDB(sqlDB, -1, defaultPluginID, lggr, cfg.Database()) + db = ocr2.NewDB(sqlDB, -1, defaultPluginID, lggr) readState, err := db.ReadState(testutils.Context(t), configDigest) require.NoError(t, err) @@ -121,7 +119,7 @@ func Test_DB_ReadWriteState(t *testing.T) { }) t.Run("does not return result for wrong config digest", func(t *testing.T) { - db := ocr2.NewDB(sqlDB, spec.ID, defaultPluginID, lggr, cfg.Database()) + db := ocr2.NewDB(sqlDB, spec.ID, defaultPluginID, lggr) state := ocrtypes.PersistentState{ Epoch: 4, HighestSentEpoch: 5, @@ -151,14 +149,13 @@ func Test_DB_ReadWriteConfig(t *testing.T) { OffchainConfigVersion: 111, OffchainConfig: []byte{0x03, 0x04}, } - cfg := configtest.NewTestGeneralConfig(t) ethKeyStore := cltest.NewKeyStore(t, sqlDB).Eth() key, _ := cltest.MustInsertRandomKey(t, ethKeyStore) spec := MustInsertOCROracleSpec(t, sqlDB, key.EIP55Address) lggr := logger.TestLogger(t) t.Run("reads and writes config", func(t *testing.T) { - db := ocr2.NewDB(sqlDB, spec.ID, defaultPluginID, lggr, cfg.Database()) + db := ocr2.NewDB(sqlDB, spec.ID, defaultPluginID, lggr) err := db.WriteConfig(testutils.Context(t), config) require.NoError(t, err) @@ -170,7 +167,7 @@ func Test_DB_ReadWriteConfig(t *testing.T) { }) t.Run("updates config", func(t *testing.T) { - db := ocr2.NewDB(sqlDB, spec.ID, defaultPluginID, lggr, cfg.Database()) + db := ocr2.NewDB(sqlDB, spec.ID, defaultPluginID, lggr) newConfig := ocrtypes.ContractConfig{ ConfigDigest: testhelpers.MakeConfigDigest(t), @@ -188,12 +185,12 @@ func Test_DB_ReadWriteConfig(t *testing.T) { }) t.Run("does not return result for wrong spec", func(t *testing.T) { - db := ocr2.NewDB(sqlDB, spec.ID, defaultPluginID, lggr, cfg.Database()) + db := ocr2.NewDB(sqlDB, spec.ID, defaultPluginID, lggr) err := db.WriteConfig(testutils.Context(t), config) require.NoError(t, err) - db = ocr2.NewDB(sqlDB, -1, defaultPluginID, lggr, cfg.Database()) + db = ocr2.NewDB(sqlDB, -1, defaultPluginID, lggr) readConfig, err := db.ReadConfig(testutils.Context(t)) require.NoError(t, err) @@ -203,8 +200,8 @@ func Test_DB_ReadWriteConfig(t *testing.T) { t.Run("reads and writes config for multiple plugins", func(t *testing.T) { otherPluginID := int32(2) - db1 := ocr2.NewDB(sqlDB, spec.ID, defaultPluginID, lggr, cfg.Database()) - db2 := ocr2.NewDB(sqlDB, spec.ID, otherPluginID, lggr, cfg.Database()) + db1 := ocr2.NewDB(sqlDB, spec.ID, defaultPluginID, lggr) + db2 := ocr2.NewDB(sqlDB, spec.ID, otherPluginID, lggr) otherConfig := ocrtypes.ContractConfig{ ConfigDigest: testhelpers.MakeConfigDigest(t), @@ -238,15 +235,14 @@ func assertPendingTransmissionEqual(t *testing.T, pt1, pt2 ocrtypes.PendingTrans func Test_DB_PendingTransmissions(t *testing.T) { sqlDB := setupDB(t) - cfg := configtest.NewTestGeneralConfig(t) ethKeyStore := cltest.NewKeyStore(t, sqlDB).Eth() key, _ := cltest.MustInsertRandomKey(t, ethKeyStore) lggr := logger.TestLogger(t) spec := MustInsertOCROracleSpec(t, sqlDB, key.EIP55Address) spec2 := MustInsertOCROracleSpec(t, sqlDB, key.EIP55Address) - db := ocr2.NewDB(sqlDB, spec.ID, defaultPluginID, lggr, cfg.Database()) - db2 := ocr2.NewDB(sqlDB, spec2.ID, defaultPluginID, lggr, cfg.Database()) + db := ocr2.NewDB(sqlDB, spec.ID, defaultPluginID, lggr) + db2 := ocr2.NewDB(sqlDB, spec2.ID, defaultPluginID, lggr) configDigest := testhelpers.MakeConfigDigest(t) k := ocrtypes.ReportTimestamp{ @@ -436,7 +432,7 @@ func Test_DB_PendingTransmissions(t *testing.T) { require.Len(t, m, 1) // Didn't affect other oracleSpecIDs - db = ocr2.NewDB(sqlDB, spec2.ID, defaultPluginID, lggr, cfg.Database()) + db = ocr2.NewDB(sqlDB, spec2.ID, defaultPluginID, lggr) m, err = db.PendingTransmissionsWithConfigDigest(testutils.Context(t), configDigest) require.NoError(t, err) require.Len(t, m, 1) @@ -446,10 +442,8 @@ func Test_DB_PendingTransmissions(t *testing.T) { func Test_DB_ReadWriteProtocolState(t *testing.T) { sqlDB := setupDB(t) - cfg := configtest.NewTestGeneralConfig(t) - lggr := logger.TestLogger(t) - db := ocr2.NewDB(sqlDB, 0, defaultPluginID, lggr, cfg.Database()) + db := ocr2.NewDB(sqlDB, 0, defaultPluginID, lggr) cd1 := testhelpers.MakeConfigDigest(t) cd2 := testhelpers.MakeConfigDigest(t) ctx := testutils.Context(t) diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index 7a2ef532fd2..6c76b0ff9c9 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -9,7 +9,6 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - "github.com/jmoiron/sqlx" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "google.golang.org/grpc" @@ -70,7 +69,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/promwrapper" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/services/relay" evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" @@ -111,7 +109,6 @@ type RelayGetter interface { Get(id types.RelayID) (loop.Relayer, error) } type Delegate struct { - db *sqlx.DB // legacy: prefer to use ds instead ds sqlutil.DataSource jobORM job.ORM bridgeORM bridges.ORM @@ -138,7 +135,6 @@ type DelegateConfig interface { plugins.RegistrarConfig OCR2() ocr2Config JobPipeline() jobPipelineConfig - Database() pg.QConfig Insecure() insecureConfig Mercury() coreconfig.Mercury Threshold() coreconfig.Threshold @@ -149,7 +145,6 @@ type delegateConfig struct { plugins.RegistrarConfig ocr2 ocr2Config jobPipeline jobPipelineConfig - database pg.QConfig insecure insecureConfig mercury mercuryConfig threshold thresholdConfig @@ -159,10 +154,6 @@ func (d *delegateConfig) JobPipeline() jobPipelineConfig { return d.jobPipeline } -func (d *delegateConfig) Database() pg.QConfig { - return d.database -} - func (d *delegateConfig) Insecure() insecureConfig { return d.insecure } @@ -212,12 +203,11 @@ type thresholdConfig interface { ThresholdKeyShare() string } -func NewDelegateConfig(ocr2Cfg ocr2Config, m coreconfig.Mercury, t coreconfig.Threshold, i insecureConfig, jp jobPipelineConfig, qconf pg.QConfig, pluginProcessCfg plugins.RegistrarConfig) DelegateConfig { +func NewDelegateConfig(ocr2Cfg ocr2Config, m coreconfig.Mercury, t coreconfig.Threshold, i insecureConfig, jp jobPipelineConfig, pluginProcessCfg plugins.RegistrarConfig) DelegateConfig { return &delegateConfig{ ocr2: ocr2Cfg, RegistrarConfig: pluginProcessCfg, jobPipeline: jp, - database: qconf, insecure: i, mercury: m, threshold: t, @@ -227,7 +217,6 @@ func NewDelegateConfig(ocr2Cfg ocr2Config, m coreconfig.Mercury, t coreconfig.Th var _ job.Delegate = (*Delegate)(nil) func NewDelegate( - db *sqlx.DB, ds sqlutil.DataSource, jobORM job.ORM, bridgeORM bridges.ORM, @@ -248,7 +237,6 @@ func NewDelegate( capabilitiesRegistry core.CapabilitiesRegistry, ) *Delegate { return &Delegate{ - db: db, ds: ds, jobORM: jobORM, bridgeORM: bridgeORM, @@ -382,7 +370,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) ([]job.Servi } lggr := logger.Sugared(d.lggr.Named(jb.ExternalJobID.String()).With(lggrCtx.Args()...)) - kvStore := job.NewKVStore(jb.ID, d.db, d.cfg.Database(), lggr) + kvStore := job.NewKVStore(jb.ID, d.ds, lggr) rid, err := spec.RelayID() if err != nil { @@ -404,7 +392,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) ([]job.Servi spec.RelayConfig["effectiveTransmitterID"] = effectiveTransmitterID spec.RelayConfig.ApplyDefaultsOCR2(d.cfg.OCR2()) - ocrDB := NewDB(d.db, spec.ID, 0, lggr, d.cfg.Database()) + ocrDB := NewDB(d.ds, spec.ID, 0, lggr) if d.peerWrapper == nil { return nil, errors.New("cannot setup OCR2 job service, libp2p peer was missing") } else if !d.peerWrapper.IsStarted() { @@ -412,7 +400,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) ([]job.Servi } ocrLogger := commonlogger.NewOCRWrapper(lggr, d.cfg.OCR2().TraceLogging(), func(msg string) { - lggr.ErrorIf(d.jobORM.RecordError(jb.ID, msg), "unable to record error") + lggr.ErrorIf(d.jobORM.RecordError(ctx, jb.ID, msg), "unable to record error") }) lc, err := validate.ToLocalConfig(d.cfg.OCR2(), d.cfg.Insecure(), *spec) @@ -475,8 +463,8 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) ([]job.Servi thresholdPluginId s4PluginId ) - thresholdPluginDB := NewDB(d.db, spec.ID, thresholdPluginId, lggr, d.cfg.Database()) - s4PluginDB := NewDB(d.db, spec.ID, s4PluginId, lggr, d.cfg.Database()) + thresholdPluginDB := NewDB(d.ds, spec.ID, thresholdPluginId, lggr) + s4PluginDB := NewDB(d.ds, spec.ID, s4PluginId, lggr) return d.newServicesOCR2Functions(ctx, lggr, jb, bootstrapPeers, kb, ocrDB, thresholdPluginDB, s4PluginDB, lc, ocrLogger) case types.GenericPlugin: @@ -904,10 +892,10 @@ func (d *Delegate) newServicesLLO( kr := llo.NewOnchainKeyring(lggr, kbm) cfg := llo.DelegateConfig{ - Logger: lggr, - Queryer: pg.NewQ(d.db, lggr, d.cfg.Database()), - Runner: d.pipelineRunner, - Registry: d.streamRegistry, + Logger: lggr, + DataSource: d.ds, + Runner: d.pipelineRunner, + Registry: d.streamRegistry, JobName: jb.Name, @@ -1010,7 +998,7 @@ func (d *Delegate) newServicesDKG( if err2 != nil { return nil, fmt.Errorf("DKG services: failed to get chain %s: %w", rid.ChainID, err2) } - ocr2vrfRelayer := evmrelay.NewOCR2VRFRelayer(d.db, chain, lggr.Named("OCR2VRFRelayer"), d.ethKs) + ocr2vrfRelayer := evmrelay.NewOCR2VRFRelayer(chain, lggr.Named("OCR2VRFRelayer"), d.ethKs) dkgProvider, err2 := ocr2vrfRelayer.NewDKGProvider( types.RelayArgs{ ExternalJobID: jb.ExternalJobID, @@ -1041,20 +1029,7 @@ func (d *Delegate) newServicesDKG( OnchainKeyring: kb, MetricsRegisterer: prometheus.WrapRegistererWith(map[string]string{"job_name": jb.Name.ValueOrZero()}, prometheus.DefaultRegisterer), } - return dkg.NewDKGServices( - jb, - dkgProvider, - lggr, - ocrLogger, - d.dkgSignKs, - d.dkgEncryptKs, - chain.Client(), - oracleArgsNoPlugin, - d.db, - d.cfg.Database(), - chain.ID(), - spec.Relay, - ) + return dkg.NewDKGServices(jb, dkgProvider, lggr, ocrLogger, d.dkgSignKs, d.dkgEncryptKs, chain.Client(), oracleArgsNoPlugin, d.ds, chain.ID(), spec.Relay) } func (d *Delegate) newServicesOCR2VRF( @@ -1094,7 +1069,7 @@ func (d *Delegate) newServicesOCR2VRF( return nil, errors.Wrap(err2, "validate ocr2vrf plugin config") } - ocr2vrfRelayer := evmrelay.NewOCR2VRFRelayer(d.db, chain, lggr.Named("OCR2VRFRelayer"), d.ethKs) + ocr2vrfRelayer := evmrelay.NewOCR2VRFRelayer(chain, lggr.Named("OCR2VRFRelayer"), d.ethKs) transmitterID := spec.TransmitterID.String vrfProvider, err2 := ocr2vrfRelayer.NewOCR2VRFProvider( @@ -1179,11 +1154,11 @@ func (d *Delegate) newServicesOCR2VRF( ) vrfLogger := commonlogger.NewOCRWrapper(l.With( "vrfContractID", spec.ContractID), d.cfg.OCR2().TraceLogging(), func(msg string) { - lggr.ErrorIf(d.jobORM.RecordError(jb.ID, msg), "unable to record error") + lggr.ErrorIf(d.jobORM.RecordError(ctx, jb.ID, msg), "unable to record error") }) dkgLogger := commonlogger.NewOCRWrapper(l.With( "dkgContractID", cfg.DKGContractAddress), d.cfg.OCR2().TraceLogging(), func(msg string) { - lggr.ErrorIf(d.jobORM.RecordError(jb.ID, msg), "unable to record error") + lggr.ErrorIf(d.jobORM.RecordError(ctx, jb.ID, msg), "unable to record error") }) dkgReportingPluginFactoryDecorator := func(wrapped ocrtypes.ReportingPluginFactory) ocrtypes.ReportingPluginFactory { return promwrapper.NewPromFactory(wrapped, "DKG", string(types.NetworkEVM), chain.ID()) @@ -1222,7 +1197,7 @@ func (d *Delegate) newServicesOCR2VRF( KeyID: keyID, DKGReportingPluginFactoryDecorator: dkgReportingPluginFactoryDecorator, VRFReportingPluginFactoryDecorator: vrfReportingPluginFactoryDecorator, - DKGSharePersistence: persistence.NewShareDB(d.db, lggr.Named("DKGShareDB"), d.cfg.Database(), chain.ID(), spec.Relay), + DKGSharePersistence: persistence.NewShareDB(d.ds, lggr.Named("DKGShareDB"), chain.ID(), spec.Relay), }) if err2 != nil { return nil, errors.Wrap(err2, "new ocr2vrf") @@ -1449,7 +1424,7 @@ func (d *Delegate) newServicesOCR2Keepers20( return nil, fmt.Errorf("keepers2.0 services: failed to get chain (%s): %w", rid.ChainID, err2) } - keeperProvider, rgstry, encoder, logProvider, err2 := ocr2keeper.EVMDependencies20(ctx, jb, d.db, lggr, chain, d.ethKs, d.cfg.Database()) + keeperProvider, rgstry, encoder, logProvider, err2 := ocr2keeper.EVMDependencies20(ctx, jb, d.ds, lggr, chain, d.ethKs) if err2 != nil { return nil, errors.Wrap(err2, "could not build dependencies for ocr2 keepers") } @@ -1699,11 +1674,11 @@ func (d *Delegate) newServicesOCR2Functions( // errorLog implements [loop.ErrorLog] type errorLog struct { jobID int32 - recordError func(jobID int32, description string, qopts ...pg.QOpt) error + recordError func(ctx context.Context, jobID int32, description string) error } func (l *errorLog) SaveError(ctx context.Context, msg string) error { - return l.recordError(l.jobID, msg) + return l.recordError(ctx, l.jobID, msg) } type logWriter struct { diff --git a/core/services/ocr2/plugins/dkg/persistence/db.go b/core/services/ocr2/plugins/dkg/persistence/db.go index b8ecfbaceb4..07dad494ed7 100644 --- a/core/services/ocr2/plugins/dkg/persistence/db.go +++ b/core/services/ocr2/plugins/dkg/persistence/db.go @@ -16,11 +16,11 @@ import ( ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" ocr2vrftypes "github.com/smartcontractkit/chainlink-vrf/types" "github.com/smartcontractkit/chainlink-vrf/types/hash" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) var ( @@ -52,16 +52,16 @@ var ( ) type shareDB struct { - q pg.Q + ds sqlutil.DataSource lggr logger.Logger chainID *big.Int chainType string } // NewShareDB creates a new DKG share database. -func NewShareDB(db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig, chainID *big.Int, chainType string) ocr2vrftypes.DKGSharePersistence { +func NewShareDB(ds sqlutil.DataSource, lggr logger.Logger, chainID *big.Int, chainType string) ocr2vrftypes.DKGSharePersistence { return &shareDB{ - q: pg.NewQ(db, lggr, cfg), + ds: ds, lggr: lggr, chainID: chainID, chainType: chainType, @@ -134,13 +134,13 @@ func (s *shareDB) WriteShareRecords( // Always upsert because we want the number of rows in the table to match // the number of members of the committee. - query := ` + _, err := s.ds.NamedExecContext(ctx, ` INSERT INTO dkg_shares (config_digest, key_id, dealer, marshaled_share_record, record_hash) VALUES (:config_digest, :key_id, :dealer, :marshaled_share_record, :record_hash) ON CONFLICT ON CONSTRAINT dkg_shares_pkey DO UPDATE SET marshaled_share_record = EXCLUDED.marshaled_share_record, record_hash = EXCLUDED.record_hash -` - return s.q.ExecQNamed(query, named[:]) +`, named[:]) + return err } // ReadShareRecords retrieves any share records in the database that correspond @@ -152,6 +152,7 @@ func (s *shareDB) ReadShareRecords( retrievedShares []ocr2vrftypes.PersistentShareSetRecord, err error, ) { + ctx := context.Background() //TODO https://smartcontract-it.atlassian.net/browse/BCF-2887 lggr := s.lggr.With( "configDigest", hexutil.Encode(cfgDgst[:]), "keyID", hexutil.Encode(keyID[:])) @@ -177,9 +178,9 @@ WHERE config_digest = :config_digest if err != nil { return nil, errors.Wrap(err, "sqlx Named") } - query = s.q.Rebind(query) + query = s.ds.Rebind(query) var dkgShares []dkgShare - err = s.q.Select(&dkgShares, query, args...) + err = s.ds.SelectContext(ctx, &dkgShares, query, args...) if errors.Is(err, sql.ErrNoRows) { return nil, nil } diff --git a/core/services/ocr2/plugins/dkg/persistence/db_test.go b/core/services/ocr2/plugins/dkg/persistence/db_test.go index a3949ea70dc..dbc400a3468 100644 --- a/core/services/ocr2/plugins/dkg/persistence/db_test.go +++ b/core/services/ocr2/plugins/dkg/persistence/db_test.go @@ -22,7 +22,7 @@ import ( func setup(t testing.TB) (ocr2vrftypes.DKGSharePersistence, *sqlx.DB) { db := pgtest.NewSqlxDB(t) lggr := logger.TestLogger(t) - return NewShareDB(db, lggr, pgtest.NewQConfig(true), big.NewInt(1337), types.NetworkEVM), db + return NewShareDB(db, lggr, big.NewInt(1337), types.NetworkEVM), db } func TestShareDB_WriteShareRecords(t *testing.T) { diff --git a/core/services/ocr2/plugins/dkg/plugin.go b/core/services/ocr2/plugins/dkg/plugin.go index 65216ac1115..0364c5d9ab0 100644 --- a/core/services/ocr2/plugins/dkg/plugin.go +++ b/core/services/ocr2/plugins/dkg/plugin.go @@ -6,12 +6,12 @@ import ( "fmt" "math/big" - "github.com/jmoiron/sqlx" "github.com/pkg/errors" "github.com/smartcontractkit/libocr/commontypes" libocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-vrf/altbn_128" "github.com/smartcontractkit/chainlink-vrf/dkg" @@ -21,7 +21,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/dkg/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/dkg/persistence" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" ) @@ -34,8 +33,7 @@ func NewDKGServices( dkgEncryptKs keystore.DKGEncrypt, ethClient evmclient.Client, oracleArgsNoPlugin libocr2.OCR2OracleArgs, - db *sqlx.DB, - qConfig pg.QConfig, + ds sqlutil.DataSource, chainID *big.Int, network string, ) ([]job.ServiceCtx, error) { @@ -68,7 +66,7 @@ func NewDKGServices( if err != nil { return nil, errors.Wrap(err, "decode key ID") } - shareDB := persistence.NewShareDB(db, lggr.Named("DKGShareDB"), qConfig, chainID, network) + shareDB := persistence.NewShareDB(ds, lggr.Named("DKGShareDB"), chainID, network) oracleArgsNoPlugin.ReportingPluginFactory = dkg.NewReportingPluginFactory( encryptKey.KyberScalar(), signKey.KyberScalar(), diff --git a/core/services/ocr2/plugins/generic/pipeline_runner_adapter_test.go b/core/services/ocr2/plugins/generic/pipeline_runner_adapter_test.go index 0d6bc02e198..a33ab2a1bd2 100644 --- a/core/services/ocr2/plugins/generic/pipeline_runner_adapter_test.go +++ b/core/services/ocr2/plugins/generic/pipeline_runner_adapter_test.go @@ -47,7 +47,7 @@ func TestAdapter_Integration(t *testing.T) { keystore := keystore.NewInMemory(db, utils.FastScryptParams, logger) pipelineORM := pipeline.NewORM(db, logger, cfg.JobPipeline().MaxSuccessfulRuns()) bridgesORM := bridges.NewORM(db) - jobORM := job.NewORM(db, pipelineORM, bridgesORM, keystore, logger, cfg.Database()) + jobORM := job.NewORM(db, pipelineORM, bridgesORM, keystore, logger) pr := pipeline.NewRunner( pipelineORM, bridgesORM, @@ -75,7 +75,7 @@ func TestAdapter_Integration(t *testing.T) { jb.Name = null.StringFrom("Job 1") jb.OCR2OracleSpec.TransmitterID = null.StringFrom(address.String()) jb.OCR2OracleSpec.PluginConfig["juelsPerFeeCoinSource"] = juelsPerFeeCoinSource - err = jobORM.CreateJob(&jb) + err = jobORM.CreateJob(ctx, &jb) require.NoError(t, err) pra := generic.NewPipelineRunnerAdapter(logger, jb, pr) results, err := pra.ExecuteRun(testutils.Context(t), spec, core.Vars{Vars: map[string]interface{}{"val": 1}}, core.Options{}) diff --git a/core/services/ocr2/plugins/ocr2keeper/util.go b/core/services/ocr2/plugins/ocr2keeper/util.go index 35bd62eeed8..339d8a89dfb 100644 --- a/core/services/ocr2/plugins/ocr2keeper/util.go +++ b/core/services/ocr2/plugins/ocr2keeper/util.go @@ -4,12 +4,11 @@ import ( "context" "fmt" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" - "github.com/jmoiron/sqlx" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ocr2keepers20 "github.com/smartcontractkit/chainlink-automation/pkg/v2" @@ -25,7 +24,6 @@ import ( evmregistry20 "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v20" evmregistry21 "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21" evmregistry21transmit "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/transmit" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) type Encoder20 interface { @@ -44,9 +42,9 @@ var ( ErrNoChainFromSpec = fmt.Errorf("could not create chain from spec") ) -func EVMProvider(db *sqlx.DB, chain legacyevm.Chain, lggr logger.Logger, spec job.Job, ethKeystore keystore.Eth, dbCfg pg.QConfig) (evmrelay.OCR2KeeperProvider, error) { +func EVMProvider(ds sqlutil.DataSource, chain legacyevm.Chain, lggr logger.Logger, spec job.Job, ethKeystore keystore.Eth) (evmrelay.OCR2KeeperProvider, error) { oSpec := spec.OCR2OracleSpec - ocr2keeperRelayer := evmrelay.NewOCR2KeeperRelayer(db, chain, lggr.Named("OCR2KeeperRelayer"), ethKeystore, dbCfg) + ocr2keeperRelayer := evmrelay.NewOCR2KeeperRelayer(ds, chain, lggr.Named("OCR2KeeperRelayer"), ethKeystore) keeperProvider, err := ocr2keeperRelayer.NewOCR2KeeperProvider( types.RelayArgs{ @@ -70,11 +68,10 @@ func EVMProvider(db *sqlx.DB, chain legacyevm.Chain, lggr logger.Logger, spec jo func EVMDependencies20( ctx context.Context, spec job.Job, - db *sqlx.DB, + ds sqlutil.DataSource, lggr logger.Logger, chain legacyevm.Chain, ethKeystore keystore.Eth, - dbCfg pg.QConfig, ) (evmrelay.OCR2KeeperProvider, *evmregistry20.EvmRegistry, Encoder20, *evmregistry20.LogProvider, error) { var err error @@ -82,7 +79,7 @@ func EVMDependencies20( var registry *evmregistry20.EvmRegistry // the provider will be returned as a dependency - if keeperProvider, err = EVMProvider(db, chain, lggr, spec, ethKeystore, dbCfg); err != nil { + if keeperProvider, err = EVMProvider(ds, chain, lggr, spec, ethKeystore); err != nil { return nil, nil, nil, nil, err } diff --git a/core/services/ocrbootstrap/database.go b/core/services/ocrbootstrap/database.go index 86ade39a05d..ef63b75dd39 100644 --- a/core/services/ocrbootstrap/database.go +++ b/core/services/ocrbootstrap/database.go @@ -8,11 +8,12 @@ import ( "github.com/pkg/errors" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink/v2/core/logger" ) type db struct { - *sql.DB + ds sqlutil.DataSource oracleSpecID int32 lggr logger.Logger } @@ -20,12 +21,12 @@ type db struct { var _ ocrtypes.ConfigDatabase = &db{} // NewDB returns a new DB scoped to this oracleSpecID -func NewDB(sqldb *sql.DB, bootstrapSpecID int32, lggr logger.Logger) *db { - return &db{sqldb, bootstrapSpecID, lggr} +func NewDB(ds sqlutil.DataSource, bootstrapSpecID int32, lggr logger.Logger) *db { + return &db{ds, bootstrapSpecID, lggr} } func (d *db) ReadConfig(ctx context.Context) (c *ocrtypes.ContractConfig, err error) { - q := d.QueryRowContext(ctx, ` + q := d.ds.QueryRowxContext(ctx, ` SELECT config_digest, config_count, @@ -82,7 +83,7 @@ func (d *db) WriteConfig(ctx context.Context, c ocrtypes.ContractConfig) error { for _, s := range c.Signers { signers = append(signers, []byte(s)) } - _, err := d.ExecContext(ctx, ` + _, err := d.ds.ExecContext(ctx, ` INSERT INTO bootstrap_contract_configs ( bootstrap_spec_id, config_digest, diff --git a/core/services/ocrbootstrap/database_test.go b/core/services/ocrbootstrap/database_test.go index e00e318c69c..eaad863c88b 100644 --- a/core/services/ocrbootstrap/database_test.go +++ b/core/services/ocrbootstrap/database_test.go @@ -52,7 +52,7 @@ func Test_DB_ReadWriteConfig(t *testing.T) { lggr := logger.TestLogger(t) t.Run("reads and writes config", func(t *testing.T) { - db := ocrbootstrap.NewDB(sqlDB.DB, spec.ID, lggr) + db := ocrbootstrap.NewDB(sqlDB, spec.ID, lggr) err := db.WriteConfig(testutils.Context(t), config) require.NoError(t, err) @@ -64,7 +64,7 @@ func Test_DB_ReadWriteConfig(t *testing.T) { }) t.Run("updates config", func(t *testing.T) { - db := ocrbootstrap.NewDB(sqlDB.DB, spec.ID, lggr) + db := ocrbootstrap.NewDB(sqlDB, spec.ID, lggr) newConfig := ocrtypes.ContractConfig{ ConfigDigest: testhelpers.MakeConfigDigest(t), @@ -82,12 +82,12 @@ func Test_DB_ReadWriteConfig(t *testing.T) { }) t.Run("does not return result for wrong spec", func(t *testing.T) { - db := ocrbootstrap.NewDB(sqlDB.DB, spec.ID, lggr) + db := ocrbootstrap.NewDB(sqlDB, spec.ID, lggr) err := db.WriteConfig(testutils.Context(t), config) require.NoError(t, err) - db = ocrbootstrap.NewDB(sqlDB.DB, -1, lggr) + db = ocrbootstrap.NewDB(sqlDB, -1, lggr) readConfig, err := db.ReadConfig(testutils.Context(t)) require.NoError(t, err) diff --git a/core/services/ocrbootstrap/delegate.go b/core/services/ocrbootstrap/delegate.go index 84f473088bb..0bb7a0ca2ba 100644 --- a/core/services/ocrbootstrap/delegate.go +++ b/core/services/ocrbootstrap/delegate.go @@ -7,12 +7,11 @@ import ( "github.com/pkg/errors" - "github.com/jmoiron/sqlx" - ocr "github.com/smartcontractkit/libocr/offchainreporting2plus" commonlogger "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -27,7 +26,7 @@ type RelayGetter interface { // Delegate creates Bootstrap jobs type Delegate struct { - db *sqlx.DB + ds sqlutil.DataSource jobORM job.ORM peerWrapper *ocrcommon.SingletonPeerWrapper ocr2Cfg validate.OCR2Config @@ -48,7 +47,7 @@ type relayConfig struct { // NewDelegateBootstrap creates a new Delegate func NewDelegateBootstrap( - db *sqlx.DB, + ds sqlutil.DataSource, jobORM job.ORM, peerWrapper *ocrcommon.SingletonPeerWrapper, lggr logger.Logger, @@ -57,7 +56,7 @@ func NewDelegateBootstrap( relayers RelayGetter, ) *Delegate { return &Delegate{ - db: db, + ds: ds, jobORM: jobORM, peerWrapper: peerWrapper, lggr: logger.Sugared(lggr), @@ -166,10 +165,10 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) (services [] bootstrapNodeArgs := ocr.BootstrapperArgs{ BootstrapperFactory: d.peerWrapper.Peer2, ContractConfigTracker: configProvider.ContractConfigTracker(), - Database: NewDB(d.db.DB, spec.ID, lggr), + Database: NewDB(d.ds, spec.ID, lggr), LocalConfig: lc, Logger: commonlogger.NewOCRWrapper(lggr.Named("OCRBootstrap"), d.ocr2Cfg.TraceLogging(), func(msg string) { - logger.Sugared(lggr).ErrorIf(d.jobORM.RecordError(jb.ID, msg), "unable to record error") + logger.Sugared(lggr).ErrorIf(d.jobORM.RecordError(ctx, jb.ID, msg), "unable to record error") }), OffchainConfigDigester: configProvider.OffchainConfigDigester(), } diff --git a/core/services/ocrcommon/discoverer_database.go b/core/services/ocrcommon/discoverer_database.go index 9413b11ad07..ea75f9e6d21 100644 --- a/core/services/ocrcommon/discoverer_database.go +++ b/core/services/ocrcommon/discoverer_database.go @@ -2,25 +2,26 @@ package ocrcommon import ( "context" - "database/sql" "github.com/lib/pq" "github.com/pkg/errors" "go.uber.org/multierr" ocrnetworking "github.com/smartcontractkit/libocr/networking/types" + + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" ) var _ ocrnetworking.DiscovererDatabase = &DiscovererDatabase{} type DiscovererDatabase struct { - db *sql.DB + ds sqlutil.DataSource peerID string } -func NewDiscovererDatabase(db *sql.DB, peerID string) *DiscovererDatabase { +func NewDiscovererDatabase(ds sqlutil.DataSource, peerID string) *DiscovererDatabase { return &DiscovererDatabase{ - db, + ds, peerID, } } @@ -28,7 +29,7 @@ func NewDiscovererDatabase(db *sql.DB, peerID string) *DiscovererDatabase { // StoreAnnouncement has key-value-store semantics and stores a peerID (key) and an associated serialized // announcement (value). func (d *DiscovererDatabase) StoreAnnouncement(ctx context.Context, peerID string, ann []byte) error { - _, err := d.db.ExecContext(ctx, ` + _, err := d.ds.ExecContext(ctx, ` INSERT INTO ocr_discoverer_announcements (local_peer_id, remote_peer_id, ann, created_at, updated_at) VALUES ($1,$2,$3,NOW(),NOW()) ON CONFLICT (local_peer_id, remote_peer_id) DO UPDATE SET ann = EXCLUDED.ann, @@ -40,7 +41,7 @@ updated_at = EXCLUDED.updated_at // ReadAnnouncements returns one serialized announcement (if available) for each of the peerIDs in the form of a map // keyed by each announcement's corresponding peer ID. func (d *DiscovererDatabase) ReadAnnouncements(ctx context.Context, peerIDs []string) (results map[string][]byte, err error) { - rows, err := d.db.QueryContext(ctx, ` + rows, err := d.ds.QueryContext(ctx, ` SELECT remote_peer_id, ann FROM ocr_discoverer_announcements WHERE remote_peer_id = ANY($1) AND local_peer_id = $2`, pq.Array(peerIDs), d.peerID) if err != nil { return nil, errors.Wrap(err, "DiscovererDatabase failed to ReadAnnouncements") diff --git a/core/services/ocrcommon/discoverer_database_test.go b/core/services/ocrcommon/discoverer_database_test.go index b7a79e92bce..23d5ad661a4 100644 --- a/core/services/ocrcommon/discoverer_database_test.go +++ b/core/services/ocrcommon/discoverer_database_test.go @@ -16,7 +16,7 @@ import ( ) func Test_DiscovererDatabase(t *testing.T) { - db := pgtest.NewSqlDB(t) + db := pgtest.NewSqlxDB(t) localPeerID1 := mustRandomP2PPeerID(t) localPeerID2 := mustRandomP2PPeerID(t) diff --git a/core/services/ocrcommon/peer_wrapper.go b/core/services/ocrcommon/peer_wrapper.go index 02bdd9cee7d..97c429f9a5f 100644 --- a/core/services/ocrcommon/peer_wrapper.go +++ b/core/services/ocrcommon/peer_wrapper.go @@ -4,7 +4,6 @@ import ( "context" "io" - "github.com/jmoiron/sqlx" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" @@ -14,12 +13,12 @@ import ( commonlogger "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink/v2/core/config" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) type PeerWrapperOCRConfig interface { @@ -43,8 +42,7 @@ type ( keyStore keystore.Master p2pCfg config.P2P ocrCfg PeerWrapperOCRConfig - dbConfig pg.QConfig - db *sqlx.DB + ds sqlutil.DataSource lggr logger.Logger PeerID p2pkey.PeerID @@ -69,13 +67,12 @@ func ValidatePeerWrapperConfig(config config.P2P) error { // NewSingletonPeerWrapper creates a new peer based on the p2p keys in the keystore // It currently only supports one peerID/key // It should be fairly easy to modify it to support multiple peerIDs/keys using e.g. a map -func NewSingletonPeerWrapper(keyStore keystore.Master, p2pCfg config.P2P, ocrCfg PeerWrapperOCRConfig, dbConfig pg.QConfig, db *sqlx.DB, lggr logger.Logger) *SingletonPeerWrapper { +func NewSingletonPeerWrapper(keyStore keystore.Master, p2pCfg config.P2P, ocrCfg PeerWrapperOCRConfig, ds sqlutil.DataSource, lggr logger.Logger) *SingletonPeerWrapper { return &SingletonPeerWrapper{ keyStore: keyStore, p2pCfg: p2pCfg, ocrCfg: ocrCfg, - dbConfig: dbConfig, - db: db, + ds: ds, lggr: lggr.Named("SingletonPeerWrapper"), } } @@ -120,7 +117,7 @@ func (p *SingletonPeerWrapper) peerConfig() (ocrnetworking.PeerConfig, error) { } p.PeerID = key.PeerID() - discovererDB := NewDiscovererDatabase(p.db.DB, p.PeerID.Raw()) + discovererDB := NewDiscovererDatabase(p.ds, p.PeerID.Raw()) config := p.p2pCfg peerConfig := ocrnetworking.PeerConfig{ diff --git a/core/services/ocrcommon/peer_wrapper_test.go b/core/services/ocrcommon/peer_wrapper_test.go index e87f211fd21..a47ed19ec56 100644 --- a/core/services/ocrcommon/peer_wrapper_test.go +++ b/core/services/ocrcommon/peer_wrapper_test.go @@ -34,7 +34,7 @@ func Test_SingletonPeerWrapper_Start(t *testing.T) { c.P2P.V2.Enabled = ptr(true) }) keyStore := cltest.NewKeyStore(t, db) - pw := ocrcommon.NewSingletonPeerWrapper(keyStore, cfg.P2P(), cfg.OCR(), cfg.Database(), db, logger.TestLogger(t)) + pw := ocrcommon.NewSingletonPeerWrapper(keyStore, cfg.P2P(), cfg.OCR(), db, logger.TestLogger(t)) require.Contains(t, pw.Start(testutils.Context(t)).Error(), "No P2P keys found in keystore. Peer wrapper will not be fully initialized") }) @@ -49,7 +49,7 @@ func Test_SingletonPeerWrapper_Start(t *testing.T) { c.P2P.V2.ListenAddresses = &[]string{fmt.Sprintf("127.0.0.1:%d", freeport.GetOne(t))} c.P2P.PeerID = ptr(k.PeerID()) }) - pw := ocrcommon.NewSingletonPeerWrapper(keyStore, cfg.P2P(), cfg.OCR(), cfg.Database(), db, logger.TestLogger(t)) + pw := ocrcommon.NewSingletonPeerWrapper(keyStore, cfg.P2P(), cfg.OCR(), db, logger.TestLogger(t)) servicetest.Run(t, pw) require.Equal(t, k.PeerID(), pw.PeerID) @@ -66,7 +66,7 @@ func Test_SingletonPeerWrapper_Start(t *testing.T) { _, err := keyStore.P2P().Create(ctx) require.NoError(t, err) - pw := ocrcommon.NewSingletonPeerWrapper(keyStore, cfg.P2P(), cfg.OCR(), cfg.Database(), db, logger.TestLogger(t)) + pw := ocrcommon.NewSingletonPeerWrapper(keyStore, cfg.P2P(), cfg.OCR(), db, logger.TestLogger(t)) require.Contains(t, pw.Start(testutils.Context(t)).Error(), "unable to find P2P key with id") }) @@ -83,7 +83,7 @@ func Test_SingletonPeerWrapper_Start(t *testing.T) { c.P2P.PeerID = ptr(k2.PeerID()) }) - pw := ocrcommon.NewSingletonPeerWrapper(keyStore, cfg.P2P(), cfg.OCR(), cfg.Database(), db, logger.TestLogger(t)) + pw := ocrcommon.NewSingletonPeerWrapper(keyStore, cfg.P2P(), cfg.OCR(), db, logger.TestLogger(t)) servicetest.Run(t, pw) require.Equal(t, k2.PeerID(), pw.PeerID) @@ -101,7 +101,7 @@ func Test_SingletonPeerWrapper_Start(t *testing.T) { _, err := keyStore.P2P().Create(ctx) require.NoError(t, err) - pw := ocrcommon.NewSingletonPeerWrapper(keyStore, cfg.P2P(), cfg.OCR(), cfg.Database(), db, logger.TestLogger(t)) + pw := ocrcommon.NewSingletonPeerWrapper(keyStore, cfg.P2P(), cfg.OCR(), db, logger.TestLogger(t)) require.Contains(t, pw.Start(testutils.Context(t)).Error(), "unable to find P2P key with id") }) @@ -131,7 +131,7 @@ func Test_SingletonPeerWrapper_Close(t *testing.T) { }) - pw := ocrcommon.NewSingletonPeerWrapper(keyStore, cfg.P2P(), cfg.OCR(), cfg.Database(), db, logger.TestLogger(t)) + pw := ocrcommon.NewSingletonPeerWrapper(keyStore, cfg.P2P(), cfg.OCR(), db, logger.TestLogger(t)) require.NoError(t, pw.Start(testutils.Context(t))) require.True(t, pw.IsStarted(), "Should have started successfully") @@ -139,7 +139,7 @@ func Test_SingletonPeerWrapper_Close(t *testing.T) { /* If peer is still stuck in listenLoop, we will get a bind error trying to start on the same port */ require.False(t, pw.IsStarted()) - pw = ocrcommon.NewSingletonPeerWrapper(keyStore, cfg.P2P(), cfg.OCR(), cfg.Database(), db, logger.TestLogger(t)) + pw = ocrcommon.NewSingletonPeerWrapper(keyStore, cfg.P2P(), cfg.OCR(), db, logger.TestLogger(t)) require.NoError(t, pw.Start(testutils.Context(t)), "Should have shut down gracefully, and be able to re-use same port") require.True(t, pw.IsStarted(), "Should have started successfully") require.NoError(t, pw.Close()) diff --git a/core/services/pg/connection.go b/core/services/pg/connection.go index 79d74c6e610..e8b6f3af429 100644 --- a/core/services/pg/connection.go +++ b/core/services/pg/connection.go @@ -1,6 +1,7 @@ package pg import ( + "database/sql" "fmt" "log" "os" @@ -18,6 +19,10 @@ import ( "github.com/XSAM/otelsql" ) +// NOTE: This is the default level in Postgres anyway, we just make it +// explicit here +const defaultIsolation = sql.LevelReadCommitted + var MinRequiredPGVersion = 110000 func init() { diff --git a/core/services/pg/lease_lock.go b/core/services/pg/lease_lock.go index 58ec2781245..885115d26c7 100644 --- a/core/services/pg/lease_lock.go +++ b/core/services/pg/lease_lock.go @@ -12,6 +12,7 @@ import ( "github.com/pkg/errors" "go.uber.org/multierr" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink/v2/core/logger" ) @@ -248,10 +249,12 @@ func (l *leaseLock) getLease(ctx context.Context, isInitial bool) (gotLease bool // NOTE: Uses database time for all calculations since it's conceivable // that node local times might be skewed compared to each other - err = sqlxTransactionQ(ctx, l.conn, l.logger, func(tx Queryer) error { + err = sqlutil.TransactConn(ctx, func(ds sqlutil.DataSource) sqlutil.DataSource { + return ds + }, l.conn, nil, func(tx sqlutil.DataSource) error { if isInitial { for _, query := range initialSQL { - if _, err = tx.Exec(query); err != nil { + if _, err = tx.ExecContext(ctx, query); err != nil { return errors.Wrap(err, "failed to create initial lease_lock table") } } @@ -259,7 +262,7 @@ func (l *leaseLock) getLease(ctx context.Context, isInitial bool) (gotLease bool // Upsert the lease_lock, only overwriting an existing one if the existing one has expired var res sql.Result - res, err = tx.Exec(` + res, err = tx.ExecContext(ctx, ` INSERT INTO lease_lock (client_id, expires_at) VALUES ($1, NOW()+$2::interval) ON CONFLICT ((client_id IS NOT NULL)) DO UPDATE SET client_id = EXCLUDED.client_id, expires_at = EXCLUDED.expires_at diff --git a/core/services/pg/q.go b/core/services/pg/q.go deleted file mode 100644 index 433023ddbc9..00000000000 --- a/core/services/pg/q.go +++ /dev/null @@ -1,384 +0,0 @@ -package pg - -import ( - "context" - "database/sql" - "fmt" - "strconv" - "strings" - "sync" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/jmoiron/sqlx" - "github.com/lib/pq" - "github.com/pkg/errors" - - "github.com/smartcontractkit/chainlink-common/pkg/logger" - "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" -) - -// QOpt is deprecated. Use [sqlutil.DataSource] with [sqlutil.QueryHook]s instead. -// -// QOpt pattern for ORM methods aims to clarify usage and remove some common footguns, notably: -// -// 1. It should be easy and obvious how to pass a parent context or a transaction into an ORM method -// 2. Simple queries should not be cluttered -// 3. It should have compile-time safety and be explicit -// 4. It should enforce some sort of context deadline on all queries by default -// 5. It should optimise for clarity and readability -// 6. It should mandate using sqlx everywhere, gorm is forbidden in new code -// 7. It should make using sqlx a little more convenient by wrapping certain methods -// 8. It allows easier mocking of DB calls (Queryer is an interface) -// -// The two main concepts introduced are: -// -// A `Q` struct that wraps a `sqlx.DB` or `sqlx.Tx` and implements the `pg.Queryer` interface. -// -// This struct is initialised with `QOpts` which define how the queryer should behave. `QOpts` can define a parent context, an open transaction or other options to configure the Queryer. -// -// A sample ORM method looks like this: -// -// func (o *orm) GetFoo(id int64, qopts ...pg.QOpt) (Foo, error) { -// q := pg.NewQ(q, qopts...) -// return q.Exec(...) -// } -// -// Now you can call it like so: -// -// orm.GetFoo(1) // will automatically have default query timeout context set -// orm.GetFoo(1, pg.WithParentCtx(ctx)) // will wrap the supplied parent context with the default query context -// orm.GetFoo(1, pg.WithQueryer(tx)) // allows to pass in a running transaction or anything else that implements Queryer -// orm.GetFoo(q, pg.WithQueryer(tx), pg.WithParentCtx(ctx)) // options can be combined -type QOpt func(*Q) - -// WithQueryer sets the queryer -func WithQueryer(queryer Queryer) QOpt { - return func(q *Q) { - if q.Queryer != nil { - panic("queryer already set") - } - q.Queryer = queryer - } -} - -// WithParentCtx sets or overwrites the parent ctx -func WithParentCtx(ctx context.Context) QOpt { - return func(q *Q) { - q.ParentCtx = ctx - } -} - -// If the parent has a timeout, just use that instead of DefaultTimeout -func WithParentCtxInheritTimeout(ctx context.Context) QOpt { - return func(q *Q) { - q.ParentCtx = ctx - deadline, ok := q.ParentCtx.Deadline() - if ok { - q.QueryTimeout = time.Until(deadline) - } - } -} - -// WithLongQueryTimeout prevents the usage of the `DefaultQueryTimeout` duration and uses `OneMinuteQueryTimeout` instead -// Some queries need to take longer when operating over big chunks of data, like deleting jobs, but we need to keep some upper bound timeout -func WithLongQueryTimeout() QOpt { - return func(q *Q) { - q.QueryTimeout = longQueryTimeout - } -} - -var _ Queryer = Q{} - -type QConfig interface { - LogSQL() bool - DefaultQueryTimeout() time.Duration -} - -// Q wraps an underlying queryer (either a *sqlx.DB or a *sqlx.Tx) -// -// It is designed to make handling *sqlx.Tx or *sqlx.DB a little bit safer by -// preventing footguns such as having no deadline on contexts. -// -// It also handles nesting transactions. -// -// It automatically adds the default context deadline to all non-context -// queries (if you _really_ want to issue a query without a context, use the -// underlying Queryer) -// -// This is not the prettiest construct but without macros its about the best we -// can do. -// Deprecated: Use a `sqlutil.DataSource` with `sqlutil.QueryHook`s instead -type Q struct { - Queryer - ParentCtx context.Context - db *sqlx.DB - logger logger.SugaredLogger - config QConfig - QueryTimeout time.Duration -} - -func NewQ(db *sqlx.DB, lggr logger.Logger, config QConfig, qopts ...QOpt) (q Q) { - for _, opt := range qopts { - opt(&q) - } - - q.db = db - // skip two levels since we use internal helpers and also want to point up the stack to the caller of the Q method. - q.logger = logger.Sugared(logger.Helper(lggr, 2)) - q.config = config - - if q.Queryer == nil { - q.Queryer = db - } - if q.ParentCtx == nil { - q.ParentCtx = context.Background() - } - if q.QueryTimeout <= 0 { - q.QueryTimeout = q.config.DefaultQueryTimeout() - } - return -} - -func (q Q) originalLogger() logger.Logger { - return logger.Helper(q.logger, -2) -} - -func PrepareQueryRowx(q Queryer, sql string, dest interface{}, arg interface{}) error { - stmt, err := q.PrepareNamed(sql) - if err != nil { - return errors.Wrap(err, "error preparing named statement") - } - defer stmt.Close() - return errors.Wrap(stmt.QueryRowx(arg).Scan(dest), "error querying row") -} - -func (q Q) WithOpts(qopts ...QOpt) Q { - return NewQ(q.db, q.originalLogger(), q.config, qopts...) -} - -func (q Q) Context() (context.Context, context.CancelFunc) { - return context.WithTimeout(q.ParentCtx, q.QueryTimeout) -} - -func (q Q) Transaction(fc func(q Queryer) error, txOpts ...TxOption) error { - ctx, cancel := q.Context() - defer cancel() - return SqlxTransaction(ctx, q.Queryer, q.originalLogger(), fc, txOpts...) -} - -// CAUTION: A subtle problem lurks here, because the following code is buggy: -// -// ctx, cancel := context.WithCancel(context.Background()) -// rows, err := db.QueryContext(ctx, "SELECT foo") -// cancel() // canceling here "poisons" the scan below -// for rows.Next() { -// rows.Scan(...) -// } -// -// We must cancel the context only after we have completely finished using the -// returned rows or result from the query/exec -// -// For this reasons, the following functions return a context.CancelFunc and it -// is up to the caller to ensure that cancel is called after it has finished -// -// Generally speaking, it makes more sense to use Get/Select in most cases, -// which avoids this problem -func (q Q) ExecQIter(query string, args ...interface{}) (sql.Result, context.CancelFunc, error) { - ctx, cancel := q.Context() - - ql := q.newQueryLogger(query, args) - ql.logSqlQuery() - defer ql.postSqlLog(ctx, time.Now()) - - res, err := q.Queryer.ExecContext(ctx, query, args...) - return res, cancel, ql.withLogError(err) -} -func (q Q) ExecQWithRowsAffected(query string, args ...interface{}) (int64, error) { - res, cancel, err := q.ExecQIter(query, args...) - defer cancel() - if err != nil { - return 0, err - } - - rowsDeleted, err := res.RowsAffected() - return rowsDeleted, err -} -func (q Q) ExecQ(query string, args ...interface{}) error { - ctx, cancel := q.Context() - defer cancel() - - ql := q.newQueryLogger(query, args) - ql.logSqlQuery() - defer ql.postSqlLog(ctx, time.Now()) - - _, err := q.Queryer.ExecContext(ctx, query, args...) - return ql.withLogError(err) -} -func (q Q) ExecQNamed(query string, arg interface{}) (err error) { - query, args, err := q.BindNamed(query, arg) - if err != nil { - return errors.Wrap(err, "error binding arg") - } - ctx, cancel := q.Context() - defer cancel() - - ql := q.newQueryLogger(query, args) - ql.logSqlQuery() - defer ql.postSqlLog(ctx, time.Now()) - - _, err = q.Queryer.ExecContext(ctx, query, args...) - return ql.withLogError(err) -} - -// Select and Get are safe to wrap the context cancellation because the rows -// are entirely consumed within the call -func (q Q) Select(dest interface{}, query string, args ...interface{}) error { - ctx, cancel := q.Context() - defer cancel() - - ql := q.newQueryLogger(query, args) - ql.logSqlQuery() - defer ql.postSqlLog(ctx, time.Now()) - - return ql.withLogError(q.Queryer.SelectContext(ctx, dest, query, args...)) -} - -func (q Q) SelectNamed(dest interface{}, query string, arg interface{}) error { - query, args, err := q.BindNamed(query, arg) - if err != nil { - return errors.Wrap(err, "error binding arg") - } - return q.Select(dest, query, args...) -} - -func (q Q) Get(dest interface{}, query string, args ...interface{}) error { - ctx, cancel := q.Context() - defer cancel() - - ql := q.newQueryLogger(query, args) - ql.logSqlQuery() - defer ql.postSqlLog(ctx, time.Now()) - - return ql.withLogError(q.Queryer.GetContext(ctx, dest, query, args...)) -} - -func (q Q) GetNamed(sql string, dest interface{}, arg interface{}) error { - query, args, err := q.BindNamed(sql, arg) - if err != nil { - return errors.Wrap(err, "error binding arg") - } - ctx, cancel := q.Context() - defer cancel() - - ql := q.newQueryLogger(query, args) - ql.logSqlQuery() - defer ql.postSqlLog(ctx, time.Now()) - - return ql.withLogError(errors.Wrap(q.GetContext(ctx, dest, query, args...), "error in get query")) -} - -func (q Q) newQueryLogger(query string, args []interface{}) *queryLogger { - return &queryLogger{Q: q, query: query, args: args, str: sync.OnceValue(func() string { - return sprintQ(query, args) - })} -} - -// sprintQ formats the query with the given args and returns the resulting string. -func sprintQ(query string, args []interface{}) string { - if args == nil { - return query - } - var pairs []string - for i, arg := range args { - // We print by type so one can directly take the logged query string and execute it manually in pg. - // Annoyingly it seems as though the logger itself will add an extra \, so you still have to remove that. - switch v := arg.(type) { - case []byte: - pairs = append(pairs, fmt.Sprintf("$%d", i+1), fmt.Sprintf("'\\x%x'", v)) - case common.Address: - pairs = append(pairs, fmt.Sprintf("$%d", i+1), fmt.Sprintf("'\\x%x'", v.Bytes())) - case common.Hash: - pairs = append(pairs, fmt.Sprintf("$%d", i+1), fmt.Sprintf("'\\x%x'", v.Bytes())) - case pq.ByteaArray: - pairs = append(pairs, fmt.Sprintf("$%d", i+1)) - if v == nil { - pairs = append(pairs, "NULL") - continue - } - if len(v) == 0 { - pairs = append(pairs, "ARRAY[]") - continue - } - var s strings.Builder - fmt.Fprintf(&s, "ARRAY['\\x%x'", v[0]) - for j := 1; j < len(v); j++ { - fmt.Fprintf(&s, ",'\\x%x'", v[j]) - } - pairs = append(pairs, fmt.Sprintf("%s]", s.String())) - case string: - pairs = append(pairs, fmt.Sprintf("$%d", i+1), fmt.Sprintf("'%s'", v)) - default: - pairs = append(pairs, fmt.Sprintf("$%d", i+1), fmt.Sprintf("%v", v)) - } - } - replacer := strings.NewReplacer(pairs...) - queryWithVals := replacer.Replace(query) - return strings.ReplaceAll(strings.ReplaceAll(queryWithVals, "\n", " "), "\t", " ") -} - -// queryLogger extends Q with logging helpers for a particular query w/ args. -type queryLogger struct { - Q - - query string - args []interface{} - - str func() string -} - -func (q *queryLogger) String() string { - return q.str() -} - -func (q *queryLogger) logSqlQuery() { - if q.config != nil && q.config.LogSQL() { - q.logger.Debugw("SQL QUERY", "sql", q) - } -} - -func (q *queryLogger) withLogError(err error) error { - if err != nil && !errors.Is(err, sql.ErrNoRows) && q.config != nil && q.config.LogSQL() { - q.logger.Errorw("SQL ERROR", "err", err, "sql", q) - } - return err -} - -// postSqlLog logs about context cancellation and timing after a query returns. -// Queries which use their full timeout log critical level. More than 50% log error, and 10% warn. -func (q *queryLogger) postSqlLog(ctx context.Context, begin time.Time) { - elapsed := time.Since(begin) - if ctx.Err() != nil { - q.logger.Debugw("SQL CONTEXT CANCELLED", "ms", elapsed.Milliseconds(), "err", ctx.Err(), "sql", q) - } - - timeout := q.QueryTimeout - if timeout <= 0 { - timeout = DefaultQueryTimeout - } - - pct := float64(elapsed) / float64(timeout) - pct *= 100 - - kvs := []any{"ms", elapsed.Milliseconds(), "timeout", timeout.Milliseconds(), "percent", strconv.FormatFloat(pct, 'f', 1, 64), "sql", q} - - if elapsed >= timeout { - q.logger.Criticalw("SLOW SQL QUERY", kvs...) - } else if errThreshold := timeout / 5; errThreshold > 0 && elapsed > errThreshold { - q.logger.Errorw("SLOW SQL QUERY", kvs...) - } else if warnThreshold := timeout / 10; warnThreshold > 0 && elapsed > warnThreshold { - q.logger.Warnw("SLOW SQL QUERY", kvs...) - } - - sqlutil.PromSQLQueryTime.Observe(pct) -} diff --git a/core/services/pg/q_test.go b/core/services/pg/q_test.go deleted file mode 100644 index 81a883789df..00000000000 --- a/core/services/pg/q_test.go +++ /dev/null @@ -1,85 +0,0 @@ -package pg - -import ( - "testing" - - "github.com/google/uuid" - "github.com/jmoiron/sqlx" - "github.com/lib/pq" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/store/dialects" -) - -func Test_sprintQ(t *testing.T) { - for _, tt := range []struct { - name string - query string - args []interface{} - exp string - }{ - {"none", - "SELECT * FROM table;", - nil, - "SELECT * FROM table;"}, - {"one", - "SELECT $1 FROM table;", - []interface{}{"foo"}, - "SELECT 'foo' FROM table;"}, - {"two", - "SELECT $1 FROM table WHERE bar = $2;", - []interface{}{"foo", 1}, - "SELECT 'foo' FROM table WHERE bar = 1;"}, - {"limit", - "SELECT $1 FROM table LIMIT $2;", - []interface{}{"foo", Limit(10)}, - "SELECT 'foo' FROM table LIMIT 10;"}, - {"limit-all", - "SELECT $1 FROM table LIMIT $2;", - []interface{}{"foo", Limit(-1)}, - "SELECT 'foo' FROM table LIMIT NULL;"}, - {"bytea", - "SELECT $1 FROM table WHERE b = $2;", - []interface{}{"foo", []byte{0x0a}}, - "SELECT 'foo' FROM table WHERE b = '\\x0a';"}, - {"bytea[]", - "SELECT $1 FROM table WHERE b = $2;", - []interface{}{"foo", pq.ByteaArray([][]byte{{0xa}, {0xb}})}, - "SELECT 'foo' FROM table WHERE b = ARRAY['\\x0a','\\x0b'];"}, - } { - t.Run(tt.name, func(t *testing.T) { - got := sprintQ(tt.query, tt.args) - t.Log(tt.query, tt.args) - t.Log(got) - require.Equal(t, tt.exp, got) - }) - } -} - -func Test_ExecQWithRowsAffected(t *testing.T) { - testutils.SkipShortDB(t) - db, err := sqlx.Open(string(dialects.TransactionWrappedPostgres), uuid.New().String()) - require.NoError(t, err) - q := NewQ(db, logger.NullLogger, NewQConfig(false)) - - require.NoError(t, q.ExecQ("CREATE TABLE testtable (a TEXT, b TEXT)")) - - rows, err := q.ExecQWithRowsAffected("INSERT INTO testtable (a, b) VALUES ($1, $2)", "foo", "bar") - require.NoError(t, err) - assert.Equal(t, int64(1), rows) - - rows, err = q.ExecQWithRowsAffected("INSERT INTO testtable (a, b) VALUES ($1, $1), ($2, $2), ($1, $2)", "foo", "bar") - require.NoError(t, err) - assert.Equal(t, int64(3), rows) - - rows, err = q.ExecQWithRowsAffected("delete from testtable") - require.NoError(t, err) - assert.Equal(t, int64(4), rows) - - rows, err = q.ExecQWithRowsAffected("delete from testtable") - require.NoError(t, err) - assert.Equal(t, int64(0), rows) -} diff --git a/core/services/pg/sqlx.go b/core/services/pg/sqlx.go index 76eae792cbf..9c99142e5c9 100644 --- a/core/services/pg/sqlx.go +++ b/core/services/pg/sqlx.go @@ -4,12 +4,8 @@ import ( "context" "database/sql" - "github.com/pkg/errors" - mapper "github.com/scylladb/go-reflectx" - "github.com/jmoiron/sqlx" - - "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/scylladb/go-reflectx" ) // Queryer is deprecated. Use sqlutil.DataSource instead @@ -32,22 +28,6 @@ type Queryer interface { func WrapDbWithSqlx(rdb *sql.DB) *sqlx.DB { db := sqlx.NewDb(rdb, "postgres") - db.MapperFunc(mapper.CamelToSnakeASCII) + db.MapperFunc(reflectx.CamelToSnakeASCII) return db } - -func SqlxTransaction(ctx context.Context, q Queryer, lggr logger.Logger, fc func(q Queryer) error, txOpts ...TxOption) (err error) { - switch db := q.(type) { - case *sqlx.Tx: - // nested transaction: just use the outer transaction - err = fc(db) - case *sqlx.DB: - err = sqlxTransactionQ(ctx, db, lggr, fc, txOpts...) - case Q: - err = sqlxTransactionQ(ctx, db.db, lggr, fc, txOpts...) - default: - err = errors.Errorf("invalid db type: %T", q) - } - - return -} diff --git a/core/services/pg/transaction.go b/core/services/pg/transaction.go deleted file mode 100644 index d60270b4fe8..00000000000 --- a/core/services/pg/transaction.go +++ /dev/null @@ -1,95 +0,0 @@ -package pg - -import ( - "context" - "database/sql" - "fmt" - "time" - - "github.com/getsentry/sentry-go" - "github.com/jmoiron/sqlx" - "github.com/pkg/errors" - "go.uber.org/multierr" - - "github.com/smartcontractkit/chainlink-common/pkg/logger" - corelogger "github.com/smartcontractkit/chainlink/v2/core/logger" -) - -// NOTE: This is the default level in Postgres anyway, we just make it -// explicit here -const defaultIsolation = sql.LevelReadCommitted - -// TxOption is a functional option for SQL transactions. -type TxOption func(*sql.TxOptions) - -func OptReadOnlyTx() TxOption { - return func(opts *sql.TxOptions) { - opts.ReadOnly = true - } -} - -func SqlTransaction(ctx context.Context, rdb *sql.DB, lggr logger.Logger, fn func(tx *sqlx.Tx) error, opts ...TxOption) (err error) { - db := WrapDbWithSqlx(rdb) - wrapFn := func(q Queryer) error { - tx, ok := q.(*sqlx.Tx) - if !ok { - panic(fmt.Sprintf("expected q to be %T but got %T", tx, q)) - } - return fn(tx) - } - return sqlxTransactionQ(ctx, db, lggr, wrapFn, opts...) -} - -// txBeginner can be a db or a conn, anything that implements BeginTxx -type txBeginner interface { - BeginTxx(context.Context, *sql.TxOptions) (*sqlx.Tx, error) -} - -func sqlxTransactionQ(ctx context.Context, db txBeginner, lggr logger.Logger, fn func(q Queryer) error, opts ...TxOption) (err error) { - var txOpts sql.TxOptions - for _, o := range opts { - o(&txOpts) - } - - var tx *sqlx.Tx - tx, err = db.BeginTxx(ctx, &txOpts) - if err != nil { - return errors.Wrap(err, "failed to begin transaction") - } - - defer func() { - if p := recover(); p != nil { - sentry.CurrentHub().Recover(p) - sentry.Flush(corelogger.SentryFlushDeadline) - - // A panic occurred, rollback and repanic - lggr.Errorf("Panic in transaction, rolling back: %s", p) - done := make(chan struct{}) - go func() { - if rerr := tx.Rollback(); rerr != nil { - lggr.Errorf("Failed to rollback on panic: %s", rerr) - } - close(done) - }() - select { - case <-done: - panic(p) - case <-time.After(10 * time.Second): - panic(fmt.Sprintf("panic in transaction; aborting rollback that took longer than 10s: %s", p)) - } - } else if err != nil { - lggr.Warnf("Error in transaction, rolling back: %s", err) - // An error occurred, rollback and return error - if rerr := tx.Rollback(); rerr != nil { - err = multierr.Combine(err, errors.WithStack(rerr)) - } - } else { - // All good! Time to commit. - err = errors.WithStack(tx.Commit()) - } - }() - - err = fn(tx) - - return -} diff --git a/core/services/pg/utils.go b/core/services/pg/utils.go deleted file mode 100644 index eb53c261296..00000000000 --- a/core/services/pg/utils.go +++ /dev/null @@ -1,50 +0,0 @@ -package pg - -import ( - "database/sql/driver" - "strconv" - "time" -) - -const ( - // DefaultQueryTimeout is a reasonable upper bound for how long a SQL query should take. - // The configured value should be used instead of this if possible. - DefaultQueryTimeout = 10 * time.Second - // longQueryTimeout is a bigger upper bound for how long a SQL query should take - longQueryTimeout = 1 * time.Minute -) - -var _ driver.Valuer = Limit(-1) - -// Limit is a helper driver.Valuer for LIMIT queries which uses nil/NULL for negative values. -type Limit int - -func (l Limit) String() string { - if l < 0 { - return "NULL" - } - return strconv.Itoa(int(l)) -} - -func (l Limit) Value() (driver.Value, error) { - if l < 0 { - return nil, nil - } - return l, nil -} - -var _ QConfig = &qConfig{} - -// qConfig implements pg.QCOnfig -type qConfig struct { - logSQL bool - defaultQueryTimeout time.Duration -} - -func NewQConfig(logSQL bool) QConfig { - return &qConfig{logSQL, DefaultQueryTimeout} -} - -func (p *qConfig) LogSQL() bool { return p.logSQL } - -func (p *qConfig) DefaultQueryTimeout() time.Duration { return p.defaultQueryTimeout } diff --git a/core/services/pipeline/helpers_test.go b/core/services/pipeline/helpers_test.go index 0bbdef7a7f2..97d81f56f74 100644 --- a/core/services/pipeline/helpers_test.go +++ b/core/services/pipeline/helpers_test.go @@ -5,7 +5,6 @@ import ( "github.com/google/uuid" - "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" ) @@ -65,4 +64,4 @@ func (t *ETHTxTask) HelperSetDependencies(legacyChains legacyevm.LegacyChainCont t.jobType = jobType } -func (o *orm) Prune(ds sqlutil.DataSource, pipelineSpecID int32) { o.prune(ds, pipelineSpecID) } +func (o *orm) Prune(pipelineSpecID int32) { o.prune(o.ds, pipelineSpecID) } diff --git a/core/services/pipeline/mocks/orm.go b/core/services/pipeline/mocks/orm.go index 2fa6d8681e8..9bd5ddfbdea 100644 --- a/core/services/pipeline/mocks/orm.go +++ b/core/services/pipeline/mocks/orm.go @@ -58,9 +58,9 @@ func (_m *ORM) CreateRun(ctx context.Context, run *pipeline.Run) error { return r0 } -// CreateSpec provides a mock function with given fields: ctx, ds, _a2, maxTaskTimeout -func (_m *ORM) CreateSpec(ctx context.Context, ds pipeline.CreateDataSource, _a2 pipeline.Pipeline, maxTaskTimeout models.Interval) (int32, error) { - ret := _m.Called(ctx, ds, _a2, maxTaskTimeout) +// CreateSpec provides a mock function with given fields: ctx, _a1, maxTaskTimeout +func (_m *ORM) CreateSpec(ctx context.Context, _a1 pipeline.Pipeline, maxTaskTimeout models.Interval) (int32, error) { + ret := _m.Called(ctx, _a1, maxTaskTimeout) if len(ret) == 0 { panic("no return value specified for CreateSpec") @@ -68,17 +68,17 @@ func (_m *ORM) CreateSpec(ctx context.Context, ds pipeline.CreateDataSource, _a2 var r0 int32 var r1 error - if rf, ok := ret.Get(0).(func(context.Context, pipeline.CreateDataSource, pipeline.Pipeline, models.Interval) (int32, error)); ok { - return rf(ctx, ds, _a2, maxTaskTimeout) + if rf, ok := ret.Get(0).(func(context.Context, pipeline.Pipeline, models.Interval) (int32, error)); ok { + return rf(ctx, _a1, maxTaskTimeout) } - if rf, ok := ret.Get(0).(func(context.Context, pipeline.CreateDataSource, pipeline.Pipeline, models.Interval) int32); ok { - r0 = rf(ctx, ds, _a2, maxTaskTimeout) + if rf, ok := ret.Get(0).(func(context.Context, pipeline.Pipeline, models.Interval) int32); ok { + r0 = rf(ctx, _a1, maxTaskTimeout) } else { r0 = ret.Get(0).(int32) } - if rf, ok := ret.Get(1).(func(context.Context, pipeline.CreateDataSource, pipeline.Pipeline, models.Interval) error); ok { - r1 = rf(ctx, ds, _a2, maxTaskTimeout) + if rf, ok := ret.Get(1).(func(context.Context, pipeline.Pipeline, models.Interval) error); ok { + r1 = rf(ctx, _a1, maxTaskTimeout) } else { r1 = ret.Error(1) } diff --git a/core/services/pipeline/orm.go b/core/services/pipeline/orm.go index 3bebfb8cbad..0a96a7e08d5 100644 --- a/core/services/pipeline/orm.go +++ b/core/services/pipeline/orm.go @@ -11,8 +11,6 @@ import ( "github.com/google/uuid" "github.com/pkg/errors" - "github.com/jmoiron/sqlx" - "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" @@ -81,8 +79,7 @@ type CreateDataSource interface { type ORM interface { services.Service - // ds is optional and to be removed after completing https://smartcontract-it.atlassian.net/browse/BCF-2978 - CreateSpec(ctx context.Context, ds CreateDataSource, pipeline Pipeline, maxTaskTimeout models.Interval) (int32, error) + CreateSpec(ctx context.Context, pipeline Pipeline, maxTaskTimeout models.Interval) (int32, error) CreateRun(ctx context.Context, run *Run) (err error) InsertRun(ctx context.Context, run *Run) error DeleteRun(ctx context.Context, id int64) error @@ -163,6 +160,9 @@ func (o *orm) Transact(ctx context.Context, fn func(ORM) error) error { return sqlutil.Transact(ctx, func(tx sqlutil.DataSource) ORM { return o.withDataSource(tx) }, o.ds, nil, func(tx ORM) error { + if err := tx.Start(ctx); err != nil { + return fmt.Errorf("failed to start tx orm: %w", err) + } defer func() { if err := tx.Close(); err != nil { o.lggr.Warnw("Error closing temporary transactional ORM", "err", err) @@ -191,14 +191,11 @@ func (o *orm) transact(ctx context.Context, fn func(*orm) error) error { return sqlutil.Transact(ctx, o.withDataSource, o.ds, nil, fn) } -func (o *orm) CreateSpec(ctx context.Context, ds CreateDataSource, pipeline Pipeline, maxTaskDuration models.Interval) (id int32, err error) { +func (o *orm) CreateSpec(ctx context.Context, pipeline Pipeline, maxTaskDuration models.Interval) (id int32, err error) { sql := `INSERT INTO pipeline_specs (dot_dag_source, max_task_duration, created_at) VALUES ($1, $2, NOW()) RETURNING id;` - if ds == nil { - ds = o.ds - } - err = ds.GetContext(ctx, &id, sql, pipeline.Source, maxTaskDuration) + err = o.ds.GetContext(ctx, &id, sql, pipeline.Source, maxTaskDuration) return id, errors.WithStack(err) } @@ -254,13 +251,13 @@ func (o *orm) StoreRun(ctx context.Context, run *Run) (restart bool, err error) // Lock the current run. This prevents races with /v2/resume sql := `SELECT id FROM pipeline_runs WHERE id = $1 FOR UPDATE;` if _, err = tx.ds.ExecContext(ctx, sql, run.ID); err != nil { - return errors.Wrap(err, "StoreRun") + return fmt.Errorf("failed to select pipeline run %d: %w", run.ID, err) } taskRuns := []TaskRun{} // Reload task runs, we want to check for any changes while the run was ongoing if err = tx.ds.SelectContext(ctx, &taskRuns, `SELECT * FROM pipeline_task_runs WHERE pipeline_run_id = $1`, run.ID); err != nil { - return errors.Wrap(err, "StoreRun") + return fmt.Errorf("failed to select piepline task run %d: %w", run.ID, err) } // Construct a temporary run so we can use r.ByDotID @@ -287,17 +284,17 @@ func (o *orm) StoreRun(ctx context.Context, run *Run) (restart bool, err error) // Suspend the run run.State = RunStatusSuspended if _, err = tx.ds.NamedExecContext(ctx, `UPDATE pipeline_runs SET state = :state WHERE id = :id`, run); err != nil { - return errors.Wrap(err, "StoreRun") + return fmt.Errorf("failed to update pipeline run %d to %s: %w", run.ID, run.State, err) } } else { defer o.prune(tx.ds, run.PruningKey) // Simply finish the run, no need to do any sort of locking if run.Outputs.Val == nil || len(run.FatalErrors)+len(run.AllErrors) == 0 { - return errors.Errorf("run must have both Outputs and Errors, got Outputs: %#v, FatalErrors: %#v, AllErrors: %#v", run.Outputs.Val, run.FatalErrors, run.AllErrors) + return fmt.Errorf("run must have both Outputs and Errors, got Outputs: %#v, FatalErrors: %#v, AllErrors: %#v", run.Outputs.Val, run.FatalErrors, run.AllErrors) } sql := `UPDATE pipeline_runs SET state = :state, finished_at = :finished_at, all_errors= :all_errors, fatal_errors= :fatal_errors, outputs = :outputs WHERE id = :id` if _, err = tx.ds.NamedExecContext(ctx, sql, run); err != nil { - return errors.Wrap(err, "StoreRun") + return fmt.Errorf("failed to update pipeline run %d: %w", run.ID, err) } } @@ -309,18 +306,15 @@ func (o *orm) StoreRun(ctx context.Context, run *Run) (restart bool, err error) RETURNING *; ` - // NOTE: can't use Select() to auto scan because we're using NamedQuery, - // sqlx.Named + Select is possible but it's about the same amount of code - var rows *sqlx.Rows - rows, err = sqlx.NamedQueryContext(ctx, tx.ds, sql, run.PipelineTaskRuns) + taskRuns := []TaskRun{} + query, args, err := tx.ds.BindNamed(sql, run.PipelineTaskRuns) if err != nil { - return errors.Wrap(err, "StoreRun") + return fmt.Errorf("failed to prepare named query: %w", err) } - taskRuns := []TaskRun{} - if err = sqlx.StructScan(rows, &taskRuns); err != nil { - return errors.Wrap(err, "StoreRun") + err = tx.ds.SelectContext(ctx, &taskRuns, query, args...) + if err != nil { + return fmt.Errorf("failed to insert pipeline task runs: %w", err) } - // replace with new task run data run.PipelineTaskRuns = taskRuns return nil }) @@ -383,19 +377,18 @@ VALUES (:pipeline_spec_id, :pruning_key, :meta, :all_errors, :fatal_errors, :inputs, :outputs, :created_at, :finished_at, :state) RETURNING id ` - rows, errQ := sqlx.NamedQueryContext(ctx, tx.ds, pipelineRunsQuery, runs) - if errQ != nil { - return errors.Wrap(errQ, "inserting finished pipeline runs") - } - defer rows.Close() var runIDs []int64 - for rows.Next() { + err := sqlutil.NamedQueryContext(ctx, tx.ds, pipelineRunsQuery, runs, func(row sqlutil.RowScanner) error { var runID int64 - if errS := rows.Scan(&runID); errS != nil { + if errS := row.Scan(&runID); errS != nil { return errors.Wrap(errS, "scanning pipeline runs id row") } runIDs = append(runIDs, runID) + return nil + }) + if err != nil { + return errors.Wrap(err, "inserting finished pipeline runs") } pruningKeysm := make(map[int32]struct{}) @@ -717,13 +710,13 @@ const syncLimit = 1000 // // Note this does not guarantee the pipeline_runs table is kept to exactly the // max length, rather that it doesn't excessively larger than it. -func (o *orm) prune(ds sqlutil.DataSource, jobID int32) { +func (o *orm) prune(tx sqlutil.DataSource, jobID int32) { if jobID == 0 { o.lggr.Panic("expected a non-zero job ID") } // For small maxSuccessfulRuns its fast enough to prune every time if o.maxSuccessfulRuns < syncLimit { - o.execPrune(o.ctx, ds, jobID) + o.withDataSource(tx).execPrune(o.ctx, jobID) return } // for large maxSuccessfulRuns we do it async on a sampled basis @@ -736,11 +729,11 @@ func (o *orm) prune(ds sqlutil.DataSource, jobID int32) { go func() { o.lggr.Debugw("Pruning runs", "jobID", jobID, "count", val, "every", every, "maxSuccessfulRuns", o.maxSuccessfulRuns) defer o.wg.Done() - // Must not use ds here since it's async and the transaction - // could be stale ctx, cancel := context.WithTimeout(sqlutil.WithoutDefaultTimeout(o.ctx), time.Minute) defer cancel() - o.execPrune(ctx, o.ds, jobID) + + // Must not use tx here since it could be stale by the time we execute async. + o.execPrune(ctx, jobID) }() }) if !ok { @@ -750,8 +743,8 @@ func (o *orm) prune(ds sqlutil.DataSource, jobID int32) { } } -func (o *orm) execPrune(ctx context.Context, ds sqlutil.DataSource, jobID int32) { - res, err := ds.ExecContext(o.ctx, `DELETE FROM pipeline_runs WHERE pruning_key = $1 AND state = $2 AND id NOT IN ( +func (o *orm) execPrune(ctx context.Context, jobID int32) { + res, err := o.ds.ExecContext(o.ctx, `DELETE FROM pipeline_runs WHERE pruning_key = $1 AND state = $2 AND id NOT IN ( SELECT id FROM pipeline_runs WHERE pruning_key = $1 AND state = $2 ORDER BY id DESC @@ -769,7 +762,7 @@ LIMIT $3 if rowsAffected == 0 { // check the spec still exists and garbage collect if necessary var exists bool - if err := ds.GetContext(ctx, &exists, `SELECT EXISTS(SELECT ps.* FROM pipeline_specs ps JOIN job_pipeline_specs jps ON (ps.id=jps.pipeline_spec_id) WHERE jps.job_id = $1)`, jobID); err != nil { + if err := o.ds.GetContext(ctx, &exists, `SELECT EXISTS(SELECT ps.* FROM pipeline_specs ps JOIN job_pipeline_specs jps ON (ps.id=jps.pipeline_spec_id) WHERE jps.job_id = $1)`, jobID); err != nil { o.lggr.Errorw("Failed check existence of pipeline_spec while pruning runs", "err", err, "jobID", jobID) return } diff --git a/core/services/pipeline/orm_test.go b/core/services/pipeline/orm_test.go index bba928534ba..6ff32e15cc7 100644 --- a/core/services/pipeline/orm_test.go +++ b/core/services/pipeline/orm_test.go @@ -1,6 +1,7 @@ package pipeline_test import ( + "context" "testing" "time" @@ -12,6 +13,7 @@ import ( "github.com/jmoiron/sqlx" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/utils/hex" "github.com/smartcontractkit/chainlink-common/pkg/utils/jsonserializable" @@ -25,41 +27,34 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/store/models" ) -type ormconfig struct { - pg.QConfig -} - -func (ormconfig) JobPipelineMaxSuccessfulRuns() uint64 { return 123456 } - type testOnlyORM interface { pipeline.ORM - AddJobPipelineSpecWithoutConstraints(jobID, pipelineSpecID int32) error + AddJobPipelineSpecWithoutConstraints(ctx context.Context, jobID, pipelineSpecID int32) error } type testORM struct { pipeline.ORM - db *sqlx.DB + ds sqlutil.DataSource } -func (torm *testORM) AddJobPipelineSpecWithoutConstraints(jobID, pipelineSpecID int32) error { - _, err := torm.db.Exec(`SET CONSTRAINTS fk_job_pipeline_spec_job DEFERRED`) +func (torm *testORM) AddJobPipelineSpecWithoutConstraints(ctx context.Context, jobID, pipelineSpecID int32) error { + _, err := torm.ds.ExecContext(ctx, `SET CONSTRAINTS fk_job_pipeline_spec_job DEFERRED`) if err != nil { return err } - _, err = torm.db.Exec(`INSERT INTO job_pipeline_specs (job_id,pipeline_spec_id, is_primary) VALUES ($1, $2, false)`, jobID, pipelineSpecID) + _, err = torm.ds.ExecContext(ctx, `INSERT INTO job_pipeline_specs (job_id,pipeline_spec_id, is_primary) VALUES ($1, $2, false)`, jobID, pipelineSpecID) if err != nil { return err } return nil } -func newTestORM(orm pipeline.ORM, db *sqlx.DB) testOnlyORM { - return &testORM{ORM: orm, db: db} +func newTestORM(orm pipeline.ORM, ds sqlutil.DataSource) testOnlyORM { + return &testORM{ORM: orm, ds: ds} } func setupORM(t *testing.T, heavy bool) (db *sqlx.DB, orm pipeline.ORM, jorm job.ORM) { @@ -70,14 +65,12 @@ func setupORM(t *testing.T, heavy bool) (db *sqlx.DB, orm pipeline.ORM, jorm job } else { db = pgtest.NewSqlxDB(t) } - cfg := ormconfig{pgtest.NewQConfig(true)} - orm = pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipelineMaxSuccessfulRuns()) - config := configtest.NewTestGeneralConfig(t) + orm = pipeline.NewORM(db, logger.TestLogger(t), 123456) lggr := logger.TestLogger(t) keyStore := cltest.NewKeyStore(t, db) bridgeORM := bridges.NewORM(db) - jorm = job.NewORM(db, orm, bridgeORM, keyStore, lggr, config.Database()) + jorm = job.NewORM(db, orm, bridgeORM, keyStore, lggr) return } @@ -103,7 +96,7 @@ func Test_PipelineORM_CreateSpec(t *testing.T) { Source: source, } - id, err := orm.CreateSpec(ctx, nil, p, maxTaskDuration) + id, err := orm.CreateSpec(ctx, p, maxTaskDuration) require.NoError(t, err) actual := pipeline.Spec{} @@ -171,7 +164,7 @@ answer2 [type=bridge name=election_winner index=1]; DotDagSource: s, }, } - err := jobORM.CreateJob(&jb) + err := jobORM.CreateJob(ctx, &jb) require.NoError(t, err) run := &pipeline.Run{ @@ -274,7 +267,7 @@ answer2 [type=bridge name=election_winner index=1]; DotDagSource: s, }, } - err := jorm.CreateJob(&jb) + err := jorm.CreateJob(ctx, &jb) require.NoError(t, err) spec := pipeline.Spec{ DotDagSource: s, @@ -665,7 +658,7 @@ func Test_GetUnfinishedRuns_Keepers(t *testing.T) { porm := pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()) bridgeORM := bridges.NewORM(db) - jorm := job.NewORM(db, porm, bridgeORM, keyStore, lggr, config.Database()) + jorm := job.NewORM(db, porm, bridgeORM, keyStore, lggr) defer func() { assert.NoError(t, jorm.Close()) }() timestamp := time.Now() @@ -689,7 +682,7 @@ func Test_GetUnfinishedRuns_Keepers(t *testing.T) { MaxTaskDuration: models.Interval(1 * time.Minute), } - err := jorm.CreateJob(&keeperJob) + err := jorm.CreateJob(ctx, &keeperJob) require.NoError(t, err) require.Equal(t, job.Keeper, keeperJob.Type) @@ -768,7 +761,7 @@ func Test_GetUnfinishedRuns_DirectRequest(t *testing.T) { porm := pipeline.NewORM(db, lggr, config.JobPipeline().MaxSuccessfulRuns()) bridgeORM := bridges.NewORM(db) - jorm := job.NewORM(db, porm, bridgeORM, keyStore, lggr, config.Database()) + jorm := job.NewORM(db, porm, bridgeORM, keyStore, lggr) defer func() { assert.NoError(t, jorm.Close()) }() timestamp := time.Now() @@ -791,7 +784,7 @@ func Test_GetUnfinishedRuns_DirectRequest(t *testing.T) { MaxTaskDuration: models.Interval(1 * time.Minute), } - err := jorm.CreateJob(&drJob) + err := jorm.CreateJob(ctx, &drJob) require.NoError(t, err) require.Equal(t, job.DirectRequest, drJob.Type) @@ -865,13 +858,13 @@ func Test_Prune(t *testing.T) { ps1 := cltest.MustInsertPipelineSpec(t, db) // We need a job_pipeline_specs entry to test the pruning mechanism - err := torm.AddJobPipelineSpecWithoutConstraints(ps1.ID, ps1.ID) + err := torm.AddJobPipelineSpecWithoutConstraints(testutils.Context(t), ps1.ID, ps1.ID) require.NoError(t, err) jobID := ps1.ID t.Run("when there are no runs to prune, does nothing", func(t *testing.T) { - porm.Prune(db, jobID) + porm.Prune(jobID) // no error logs; it did nothing assert.Empty(t, observed.All()) @@ -907,7 +900,7 @@ func Test_Prune(t *testing.T) { cltest.MustInsertPipelineRunWithStatus(t, db, ps2.ID, pipeline.RunStatusSuspended, jobID2) } - porm.Prune(db, jobID2) + porm.Prune(jobID2) cnt := pgtest.MustCount(t, db, "SELECT count(*) FROM pipeline_runs WHERE pipeline_spec_id = $1 AND state = $2", ps1.ID, pipeline.RunStatusCompleted) assert.Equal(t, cnt, 20) diff --git a/core/services/pipeline/runner.go b/core/services/pipeline/runner.go index 862d2f49178..2de27b3d008 100644 --- a/core/services/pipeline/runner.go +++ b/core/services/pipeline/runner.go @@ -661,7 +661,7 @@ func (r *runner) Run(ctx context.Context, run *Run, l logger.Logger, saveSuccess } if err = r.orm.InsertFinishedRun(ctx, run, saveSuccessfulTaskRuns); err != nil { - return false, pkgerrors.Wrapf(err, "error storing run for spec ID %v", run.PipelineSpec.ID) + return false, pkgerrors.Wrapf(err, "error inserting finished run for spec ID %v", run.PipelineSpec.ID) } } diff --git a/core/services/pipeline/runner_test.go b/core/services/pipeline/runner_test.go index e086d5297ef..44d7acadd27 100644 --- a/core/services/pipeline/runner_test.go +++ b/core/services/pipeline/runner_test.go @@ -33,7 +33,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline/mocks" "github.com/smartcontractkit/chainlink/v2/core/utils" @@ -42,14 +41,10 @@ import ( ) func newRunner(t testing.TB, db *sqlx.DB, bridgeORM bridges.ORM, cfg chainlink.GeneralConfig) (pipeline.Runner, *mocks.ORM) { - lggr := logger.TestLogger(t) ethKeyStore := cltest.NewKeyStore(t, db).Eth() relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, KeyStore: ethKeyStore}) legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) orm := mocks.NewORM(t) - q := pg.NewQ(db, lggr, cfg.Database()) - - orm.On("GetQ").Return(q).Maybe() c := clhttptest.NewTestLocalOnlyHTTPClient() r := pipeline.NewRunner(orm, bridgeORM, cfg.JobPipeline(), cfg.WebServer(), legacyChains, ethKeyStore, nil, logger.TestLogger(t), c, c) return r, orm @@ -250,8 +245,7 @@ func Test_PipelineRunner_ExecuteTaskRunsWithVars(t *testing.T) { "times": "1000000000000000000", }, }, - }, - cfg.Database()) + }) defer ds1.Close() btORM.On("FindBridge", mock.Anything, bridge.Name).Return(bridge, nil).Once() @@ -269,7 +263,7 @@ func Test_PipelineRunner_ExecuteTaskRunsWithVars(t *testing.T) { defer ds4.Close() // 3. Setup final bridge task - submit, submitBt := makeBridge(t, db, expectedRequestSubmit, map[string]interface{}{"ok": true}, cfg.Database()) + submit, submitBt := makeBridge(t, db, expectedRequestSubmit, map[string]interface{}{"ok": true}) defer submit.Close() btORM.On("FindBridge", mock.Anything, submitBt.Name).Return(submitBt, nil).Once() @@ -419,10 +413,7 @@ func Test_PipelineRunner_HandleFaults(t *testing.T) { // but a sufficient number of them still complete within the desired time frame // and so we can still obtain a median. db := pgtest.NewSqlxDB(t) - orm := mocks.NewORM(t) - q := pg.NewQ(db, logger.TestLogger(t), configtest.NewTestGeneralConfig(t).Database()) - orm.On("GetQ").Return(q).Maybe() m1 := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { time.Sleep(100 * time.Millisecond) res.WriteHeader(http.StatusOK) @@ -472,8 +463,7 @@ func Test_PipelineRunner_HandleFaultsPersistRun(t *testing.T) { db := pgtest.NewSqlxDB(t) orm := mocks.NewORM(t) btORM := bridgesMocks.NewORM(t) - q := pg.NewQ(db, logger.TestLogger(t), configtest.NewTestGeneralConfig(t).Database()) - orm.On("GetQ").Return(q).Maybe() + orm.On("InsertFinishedRun", mock.Anything, mock.Anything, mock.Anything). Run(func(args mock.Arguments) { args.Get(1).(*pipeline.Run).ID = 1 @@ -513,8 +503,7 @@ func Test_PipelineRunner_ExecuteAndInsertFinishedRun_SavingTheSpec(t *testing.T) db := pgtest.NewSqlxDB(t) orm := mocks.NewORM(t) btORM := bridgesMocks.NewORM(t) - q := pg.NewQ(db, logger.TestLogger(t), configtest.NewTestGeneralConfig(t).Database()) - orm.On("GetQ").Return(q).Maybe() + orm.On("InsertFinishedRunWithSpec", mock.Anything, mock.Anything, mock.Anything). Run(func(args mock.Arguments) { args.Get(1).(*pipeline.Run).ID = 1 diff --git a/core/services/pipeline/task.bridge_test.go b/core/services/pipeline/task.bridge_test.go index 029c6c78ca8..e95aef4984c 100644 --- a/core/services/pipeline/task.bridge_test.go +++ b/core/services/pipeline/task.bridge_test.go @@ -29,7 +29,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline/internal/eautils" "github.com/smartcontractkit/chainlink/v2/core/store/models" @@ -217,7 +216,7 @@ func TestBridgeTask_Happy(t *testing.T) { } c := clhttptest.NewTestLocalOnlyHTTPClient() trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns()) - specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) + specID, err := trORM.CreateSpec(testutils.Context(t), pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) require.NoError(t, err) task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c) @@ -259,7 +258,7 @@ func TestBridgeTask_HandlesIntermittentFailure(t *testing.T) { } c := clhttptest.NewTestLocalOnlyHTTPClient() trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns()) - specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) + specID, err := trORM.CreateSpec(testutils.Context(t), pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) require.NoError(t, err) task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c) result, runInfo := task.Run(testutils.Context(t), logger.TestLogger(t), @@ -300,18 +299,19 @@ func TestBridgeTask_HandlesIntermittentFailure(t *testing.T) { func TestBridgeTask_DoesNotReturnStaleResults(t *testing.T) { t.Parallel() - db := pgtest.NewSqlxDB(t) + ctx := testutils.Context(t) cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { c.WebServer.BridgeCacheTTL = commonconfig.MustNewDuration(30 * time.Second) }) - queryer := pg.NewQ(db, logger.TestLogger(t), cfg.Database()) + s1 := httptest.NewServer(fakeIntermittentlyFailingPriceResponder(t, utils.MustUnmarshalToMap(btcUSDPairing), decimal.NewFromInt(9700), "", nil)) defer s1.Close() feedURL, err := url.ParseRequestURI(s1.URL) require.NoError(t, err) + db := pgtest.NewSqlxDB(t) orm := bridges.NewORM(db) _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{URL: feedURL.String()}) @@ -322,12 +322,12 @@ func TestBridgeTask_DoesNotReturnStaleResults(t *testing.T) { } c := clhttptest.NewTestLocalOnlyHTTPClient() trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns()) - specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) + specID, err := trORM.CreateSpec(testutils.Context(t), pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) require.NoError(t, err) task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c) // Insert entry 1m in the past, stale value, should not be used in case of EA failure. - err = queryer.ExecQ(`INSERT INTO bridge_last_value(dot_id, spec_id, value, finished_at) + _, err = db.ExecContext(ctx, `INSERT INTO bridge_last_value(dot_id, spec_id, value, finished_at) VALUES($1, $2, $3, $4) ON CONFLICT ON CONSTRAINT bridge_last_value_pkey DO UPDATE SET value = $3, finished_at = $4;`, task.DotID(), specID, big.NewInt(9700).Bytes(), time.Now().Add(-1*time.Minute)) require.NoError(t, err) @@ -348,7 +348,7 @@ func TestBridgeTask_DoesNotReturnStaleResults(t *testing.T) { require.Nil(t, result2.Value) // Insert entry 10s in the past, under 30 seconds and should be used in case of failure. - err = queryer.ExecQ(`INSERT INTO bridge_last_value(dot_id, spec_id, value, finished_at) + _, err = db.ExecContext(ctx, `INSERT INTO bridge_last_value(dot_id, spec_id, value, finished_at) VALUES($1, $2, $3, $4) ON CONFLICT ON CONSTRAINT bridge_last_value_pkey DO UPDATE SET value = $3, finished_at = $4;`, task.DotID(), specID, big.NewInt(9700).Bytes(), time.Now().Add(-10*time.Second)) require.NoError(t, err) @@ -398,7 +398,7 @@ func TestBridgeTask_DoesNotReturnStaleResults(t *testing.T) { task2.HelperSetDependencies(cfg2.JobPipeline(), cfg2.WebServer(), orm, specID, uuid.UUID{}, c) // Insert entry 32m in the past, under cacheTTL of 35m but more than stalenessCap of 30m. - err = queryer.ExecQ(`INSERT INTO bridge_last_value(dot_id, spec_id, value, finished_at) + _, err = db.ExecContext(ctx, `INSERT INTO bridge_last_value(dot_id, spec_id, value, finished_at) VALUES($1, $2, $3, $4) ON CONFLICT ON CONSTRAINT bridge_last_value_pkey DO UPDATE SET value = $3, finished_at = $4;`, task2.DotID(), specID, big.NewInt(9700).Bytes(), time.Now().Add(-32*time.Minute)) require.NoError(t, err) @@ -420,7 +420,7 @@ func TestBridgeTask_DoesNotReturnStaleResults(t *testing.T) { require.Nil(t, result2.Value) // Insert entry 25m in the past, under stalenessCap - err = queryer.ExecQ(`INSERT INTO bridge_last_value(dot_id, spec_id, value, finished_at) + _, err = db.ExecContext(ctx, `INSERT INTO bridge_last_value(dot_id, spec_id, value, finished_at) VALUES($1, $2, $3, $4) ON CONFLICT ON CONSTRAINT bridge_last_value_pkey DO UPDATE SET value = $3, finished_at = $4;`, task2.DotID(), specID, big.NewInt(9700).Bytes(), time.Now().Add(-25*time.Minute)) require.NoError(t, err) @@ -482,7 +482,7 @@ func TestBridgeTask_AsyncJobPendingState(t *testing.T) { } c := clhttptest.NewTestLocalOnlyHTTPClient() trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns()) - specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) + specID, err := trORM.CreateSpec(testutils.Context(t), pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) require.NoError(t, err) task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, id, c) @@ -660,7 +660,7 @@ func TestBridgeTask_Variables(t *testing.T) { } c := clhttptest.NewTestLocalOnlyHTTPClient() trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns()) - specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) + specID, err := trORM.CreateSpec(testutils.Context(t), pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) require.NoError(t, err) task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c) @@ -729,7 +729,7 @@ func TestBridgeTask_Meta(t *testing.T) { } c := clhttptest.NewTestLocalOnlyHTTPClient() trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns()) - specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) + specID, err := trORM.CreateSpec(testutils.Context(t), pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) require.NoError(t, err) task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c) @@ -783,7 +783,7 @@ func TestBridgeTask_IncludeInputAtKey(t *testing.T) { } c := clhttptest.NewTestLocalOnlyHTTPClient() trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns()) - specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) + specID, err := trORM.CreateSpec(testutils.Context(t), pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) require.NoError(t, err) task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c) @@ -839,7 +839,7 @@ func TestBridgeTask_ErrorMessage(t *testing.T) { } c := clhttptest.NewTestLocalOnlyHTTPClient() trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns()) - specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) + specID, err := trORM.CreateSpec(testutils.Context(t), pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) require.NoError(t, err) task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c) @@ -878,7 +878,7 @@ func TestBridgeTask_OnlyErrorMessage(t *testing.T) { } c := clhttptest.NewTestLocalOnlyHTTPClient() trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns()) - specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) + specID, err := trORM.CreateSpec(testutils.Context(t), pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) require.NoError(t, err) task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c) @@ -903,7 +903,7 @@ func TestBridgeTask_ErrorIfBridgeMissing(t *testing.T) { c := clhttptest.NewTestLocalOnlyHTTPClient() orm := bridges.NewORM(db) trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns()) - specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) + specID, err := trORM.CreateSpec(testutils.Context(t), pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) require.NoError(t, err) task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c) @@ -993,7 +993,7 @@ func TestBridgeTask_Headers(t *testing.T) { c := clhttptest.NewTestLocalOnlyHTTPClient() trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns()) - specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) + specID, err := trORM.CreateSpec(testutils.Context(t), pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) require.NoError(t, err) task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c) @@ -1015,7 +1015,7 @@ func TestBridgeTask_Headers(t *testing.T) { c := clhttptest.NewTestLocalOnlyHTTPClient() trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns()) - specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) + specID, err := trORM.CreateSpec(testutils.Context(t), pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) require.NoError(t, err) task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c) @@ -1037,7 +1037,7 @@ func TestBridgeTask_Headers(t *testing.T) { c := clhttptest.NewTestLocalOnlyHTTPClient() trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns()) - specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) + specID, err := trORM.CreateSpec(testutils.Context(t), pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) require.NoError(t, err) task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c) @@ -1052,6 +1052,7 @@ func TestBridgeTask_Headers(t *testing.T) { func TestBridgeTask_AdapterResponseStatusFailure(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) db := pgtest.NewSqlxDB(t) cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { @@ -1062,7 +1063,6 @@ func TestBridgeTask_AdapterResponseStatusFailure(t *testing.T) { Data: adapterResponseData{Result: &decimal.Zero}, } - queryer := pg.NewQ(db, logger.TestLogger(t), cfg.Database()) s1 := httptest.NewServer( http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { err := json.NewEncoder(w).Encode(testAdapterResponse) @@ -1083,12 +1083,12 @@ func TestBridgeTask_AdapterResponseStatusFailure(t *testing.T) { } c := clhttptest.NewTestLocalOnlyHTTPClient() trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns()) - specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) + specID, err := trORM.CreateSpec(ctx, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) require.NoError(t, err) task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c) // Insert entry 1m in the past, stale value, should not be used in case of EA failure. - err = queryer.ExecQ(`INSERT INTO bridge_last_value(dot_id, spec_id, value, finished_at) + _, err = db.ExecContext(ctx, `INSERT INTO bridge_last_value(dot_id, spec_id, value, finished_at) VALUES($1, $2, $3, $4) ON CONFLICT ON CONSTRAINT bridge_last_value_pkey DO UPDATE SET value = $3, finished_at = $4;`, task.DotID(), specID, big.NewInt(9700).Bytes(), time.Now()) require.NoError(t, err) @@ -1105,7 +1105,7 @@ func TestBridgeTask_AdapterResponseStatusFailure(t *testing.T) { // expect all external adapter response status failures to be served from the cache testAdapterResponse.SetStatusCode(http.StatusBadRequest) - result, runInfo := task.Run(testutils.Context(t), logger.TestLogger(t), vars, nil) + result, runInfo := task.Run(ctx, logger.TestLogger(t), vars, nil) require.NoError(t, result.Error) require.NotNil(t, result.Value) @@ -1114,7 +1114,7 @@ func TestBridgeTask_AdapterResponseStatusFailure(t *testing.T) { testAdapterResponse.SetStatusCode(http.StatusOK) testAdapterResponse.SetProviderStatusCode(http.StatusBadRequest) - result, runInfo = task.Run(testutils.Context(t), logger.TestLogger(t), vars, nil) + result, runInfo = task.Run(ctx, logger.TestLogger(t), vars, nil) require.NoError(t, result.Error) require.NotNil(t, result.Value) @@ -1124,7 +1124,7 @@ func TestBridgeTask_AdapterResponseStatusFailure(t *testing.T) { testAdapterResponse.SetStatusCode(http.StatusOK) testAdapterResponse.SetProviderStatusCode(http.StatusOK) testAdapterResponse.SetError("some error") - result, runInfo = task.Run(testutils.Context(t), logger.TestLogger(t), vars, nil) + result, runInfo = task.Run(ctx, logger.TestLogger(t), vars, nil) require.NoError(t, result.Error) require.NotNil(t, result.Value) @@ -1132,7 +1132,7 @@ func TestBridgeTask_AdapterResponseStatusFailure(t *testing.T) { require.False(t, runInfo.IsPending) testAdapterResponse.SetStatusCode(http.StatusInternalServerError) - result, runInfo = task.Run(testutils.Context(t), logger.TestLogger(t), vars, nil) + result, runInfo = task.Run(ctx, logger.TestLogger(t), vars, nil) require.NoError(t, result.Error) require.NotNil(t, result.Value) diff --git a/core/services/pipeline/task.http_test.go b/core/services/pipeline/task.http_test.go index 6264d1e591b..4098ce50d2a 100644 --- a/core/services/pipeline/task.http_test.go +++ b/core/services/pipeline/task.http_test.go @@ -177,7 +177,7 @@ func TestHTTPTask_Variables(t *testing.T) { } c := clhttptest.NewTestLocalOnlyHTTPClient() trORM := pipeline.NewORM(db, logger.TestLogger(t), cfg.JobPipeline().MaxSuccessfulRuns()) - specID, err := trORM.CreateSpec(testutils.Context(t), nil, pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) + specID, err := trORM.CreateSpec(testutils.Context(t), pipeline.Pipeline{}, *models.NewInterval(5 * time.Minute)) require.NoError(t, err) task.HelperSetDependencies(cfg.JobPipeline(), cfg.WebServer(), orm, specID, uuid.UUID{}, c) diff --git a/core/services/pipeline/test_helpers_test.go b/core/services/pipeline/test_helpers_test.go index fc87942e073..d890afc33df 100644 --- a/core/services/pipeline/test_helpers_test.go +++ b/core/services/pipeline/test_helpers_test.go @@ -13,7 +13,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/jmoiron/sqlx" @@ -39,7 +38,7 @@ func fakeExternalAdapter(t *testing.T, expectedRequest, response interface{}) ht }) } -func makeBridge(t *testing.T, db *sqlx.DB, expectedRequest, response interface{}, cfg pg.QConfig) (*httptest.Server, bridges.BridgeType) { +func makeBridge(t *testing.T, db *sqlx.DB, expectedRequest, response interface{}) (*httptest.Server, bridges.BridgeType) { t.Helper() server := httptest.NewServer(fakeExternalAdapter(t, expectedRequest, response)) diff --git a/core/services/promreporter/prom_reporter.go b/core/services/promreporter/prom_reporter.go index a302a6fa220..92e674aac44 100644 --- a/core/services/promreporter/prom_reporter.go +++ b/core/services/promreporter/prom_reporter.go @@ -2,12 +2,12 @@ package promreporter import ( "context" - "database/sql" "fmt" "math/big" "sync" "time" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" @@ -28,7 +28,7 @@ import ( type ( promReporter struct { services.StateMachine - db *sql.DB + ds sqlutil.DataSource chains legacyevm.LegacyChainContainer lggr logger.Logger backend PrometheusBackend @@ -92,7 +92,7 @@ func (defaultBackend) SetPipelineTaskRunsQueued(n int) { promPipelineRunsQueued.Set(float64(n)) } -func NewPromReporter(db *sql.DB, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, opts ...interface{}) *promReporter { +func NewPromReporter(ds sqlutil.DataSource, chainContainer legacyevm.LegacyChainContainer, lggr logger.Logger, opts ...interface{}) *promReporter { var backend PrometheusBackend = defaultBackend{} period := 15 * time.Second for _, opt := range opts { @@ -106,7 +106,7 @@ func NewPromReporter(db *sql.DB, chainContainer legacyevm.LegacyChainContainer, chStop := make(chan struct{}) return &promReporter{ - db: db, + ds: ds, chains: chainContainer, lggr: lggr.Named("PromReporter"), backend: backend, @@ -242,7 +242,7 @@ func (pr *promReporter) reportMaxUnconfirmedBlocks(ctx context.Context, head *ev } func (pr *promReporter) reportPipelineRunStats(ctx context.Context) (err error) { - rows, err := pr.db.QueryContext(ctx, ` + rows, err := pr.ds.QueryContext(ctx, ` SELECT pipeline_run_id FROM pipeline_task_runs WHERE finished_at IS NULL `) if err != nil { diff --git a/core/services/promreporter/prom_reporter_test.go b/core/services/promreporter/prom_reporter_test.go index bb09b86df95..f17b4aafed2 100644 --- a/core/services/promreporter/prom_reporter_test.go +++ b/core/services/promreporter/prom_reporter_test.go @@ -48,7 +48,6 @@ func newLegacyChainContainer(t *testing.T, db *sqlx.DB) legacyevm.LegacyChainCon lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.FixtureChainID, db, lggr), ethClient, lggr, lpOpts) txm, err := txmgr.NewTxm( - db, db, evmConfig, evmConfig.GasEstimator(), @@ -72,7 +71,7 @@ func Test_PromReporter_OnNewLongestChain(t *testing.T) { db := pgtest.NewSqlxDB(t) backend := mocks.NewPrometheusBackend(t) - reporter := promreporter.NewPromReporter(db.DB, newLegacyChainContainer(t, db), logger.TestLogger(t), backend, 10*time.Millisecond) + reporter := promreporter.NewPromReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend, 10*time.Millisecond) var subscribeCalls atomic.Int32 @@ -114,7 +113,7 @@ func Test_PromReporter_OnNewLongestChain(t *testing.T) { subscribeCalls.Add(1) }). Return() - reporter := promreporter.NewPromReporter(db.DB, newLegacyChainContainer(t, db), logger.TestLogger(t), backend, 10*time.Millisecond) + reporter := promreporter.NewPromReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend, 10*time.Millisecond) servicetest.Run(t, reporter) etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 0, fromAddress) @@ -133,7 +132,7 @@ func Test_PromReporter_OnNewLongestChain(t *testing.T) { pgtest.MustExec(t, db, `SET CONSTRAINTS pipeline_task_runs_pipeline_run_id_fkey DEFERRED`) backend := mocks.NewPrometheusBackend(t) - reporter := promreporter.NewPromReporter(db.DB, newLegacyChainContainer(t, db), logger.TestLogger(t), backend, 10*time.Millisecond) + reporter := promreporter.NewPromReporter(db, newLegacyChainContainer(t, db), logger.TestLogger(t), backend, 10*time.Millisecond) cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 1) cltest.MustInsertUnfinishedPipelineTaskRun(t, db, 1) diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index e9aaa7e0a8e..2f30d40e28d 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -11,7 +11,6 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/google/uuid" - "github.com/jmoiron/sqlx" pkgerrors "github.com/pkg/errors" "golang.org/x/exp/maps" @@ -35,7 +34,6 @@ import ( lloconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/llo/config" mercuryconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/mercury/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/functions" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils" @@ -71,13 +69,11 @@ func init() { var _ commontypes.Relayer = &Relayer{} //nolint:staticcheck type Relayer struct { - db *sqlx.DB // legacy: prefer to use ds instead ds sqlutil.DataSource chain legacyevm.Chain lggr logger.Logger ks CSAETHKeystore mercuryPool wsrpc.Pool - pgCfg pg.QConfig chainReader commontypes.ChainReader codec commontypes.Codec @@ -95,24 +91,16 @@ type CSAETHKeystore interface { } type RelayerOpts struct { - *sqlx.DB // legacy: prefer to use ds instead - DS sqlutil.DataSource - pg.QConfig + DS sqlutil.DataSource CSAETHKeystore MercuryPool wsrpc.Pool } func (c RelayerOpts) Validate() error { var err error - if c.DB == nil { - err = errors.Join(err, errors.New("nil DB")) - } if c.DS == nil { err = errors.Join(err, errors.New("nil DataSource")) } - if c.QConfig == nil { - err = errors.Join(err, errors.New("nil QConfig")) - } if c.CSAETHKeystore == nil { err = errors.Join(err, errors.New("nil Keystore")) } @@ -134,13 +122,11 @@ func NewRelayer(lggr logger.Logger, chain legacyevm.Chain, opts RelayerOpts) (*R lloORM := llo.NewORM(opts.DS, chain.ID()) cdcFactory := llo.NewChannelDefinitionCacheFactory(lggr, lloORM, chain.LogPoller()) return &Relayer{ - db: opts.DB, ds: opts.DS, chain: chain, lggr: lggr, ks: opts.CSAETHKeystore, mercuryPool: opts.MercuryPool, - pgCfg: opts.QConfig, cdcFactory: cdcFactory, lloORM: lloORM, mercuryORM: mercuryORM, @@ -637,7 +623,7 @@ func (r *Relayer) NewMedianProvider(rargs commontypes.RelayArgs, pargs commontyp func (r *Relayer) NewAutomationProvider(rargs commontypes.RelayArgs, pargs commontypes.PluginArgs) (commontypes.AutomationProvider, error) { lggr := r.lggr.Named("AutomationProvider").Named(rargs.ExternalJobID.String()) - ocr2keeperRelayer := NewOCR2KeeperRelayer(r.db, r.chain, lggr.Named("OCR2KeeperRelayer"), r.ks.Eth(), r.pgCfg) + ocr2keeperRelayer := NewOCR2KeeperRelayer(r.ds, r.chain, lggr.Named("OCR2KeeperRelayer"), r.ks.Eth()) return ocr2keeperRelayer.NewOCR2KeeperProvider(rargs, pargs) } diff --git a/core/services/relay/evm/evm_test.go b/core/services/relay/evm/evm_test.go index d53fe910bc3..ab60ff2a128 100644 --- a/core/services/relay/evm/evm_test.go +++ b/core/services/relay/evm/evm_test.go @@ -5,20 +5,13 @@ import ( "github.com/stretchr/testify/assert" - "github.com/jmoiron/sqlx" - "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" ) func TestRelayerOpts_Validate(t *testing.T) { - cfg := configtest.NewTestGeneralConfig(t) type fields struct { - DB *sqlx.DB DS sqlutil.DataSource - QConfig pg.QConfig CSAETHKeystore evm.CSAETHKeystore } tests := []struct { @@ -29,33 +22,25 @@ func TestRelayerOpts_Validate(t *testing.T) { { name: "all invalid", fields: fields{ - DB: nil, DS: nil, - QConfig: nil, CSAETHKeystore: nil, }, - wantErrContains: `nil DB -nil DataSource -nil QConfig + wantErrContains: `nil DataSource nil Keystore`, }, { - name: "missing db, ds, keystore", + name: "missing ds, keystore", fields: fields{ - DB: nil, - QConfig: cfg.Database(), + DS: nil, }, - wantErrContains: `nil DB -nil DataSource + wantErrContains: `nil DataSource nil Keystore`, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { c := evm.RelayerOpts{ - DB: tt.fields.DB, DS: tt.fields.DS, - QConfig: tt.fields.QConfig, CSAETHKeystore: tt.fields.CSAETHKeystore, } err := c.Validate() diff --git a/core/services/relay/evm/mercury/wsrpc/pb/mercury_wsrpc.pb.go b/core/services/relay/evm/mercury/wsrpc/pb/mercury_wsrpc.pb.go index 0c31a1d7ac9..4d05db4380f 100644 --- a/core/services/relay/evm/mercury/wsrpc/pb/mercury_wsrpc.pb.go +++ b/core/services/relay/evm/mercury/wsrpc/pb/mercury_wsrpc.pb.go @@ -11,7 +11,6 @@ import ( ) // MercuryClient is the client API for Mercury service. -// type MercuryClient interface { Transmit(ctx context.Context, in *TransmitRequest) (*TransmitResponse, error) LatestReport(ctx context.Context, in *LatestReportRequest) (*LatestReportResponse, error) diff --git a/core/services/relay/evm/ocr2keeper.go b/core/services/relay/evm/ocr2keeper.go index 0dd971123c6..78f4b43b43f 100644 --- a/core/services/relay/evm/ocr2keeper.go +++ b/core/services/relay/evm/ocr2keeper.go @@ -27,7 +27,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/transmit" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/upkeepstate" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) @@ -69,17 +68,15 @@ type ocr2keeperRelayer struct { chain legacyevm.Chain lggr logger.Logger ethKeystore keystore.Eth - dbCfg pg.QConfig } // NewOCR2KeeperRelayer is the constructor of ocr2keeperRelayer -func NewOCR2KeeperRelayer(ds sqlutil.DataSource, chain legacyevm.Chain, lggr logger.Logger, ethKeystore keystore.Eth, dbCfg pg.QConfig) OCR2KeeperRelayer { +func NewOCR2KeeperRelayer(ds sqlutil.DataSource, chain legacyevm.Chain, lggr logger.Logger, ethKeystore keystore.Eth) OCR2KeeperRelayer { return &ocr2keeperRelayer{ ds: ds, chain: chain, lggr: lggr, ethKeystore: ethKeystore, - dbCfg: dbCfg, } } diff --git a/core/services/relay/evm/ocr2vrf.go b/core/services/relay/evm/ocr2vrf.go index 07edd1c5ac6..a108151be47 100644 --- a/core/services/relay/evm/ocr2vrf.go +++ b/core/services/relay/evm/ocr2vrf.go @@ -6,8 +6,6 @@ import ( "fmt" "github.com/ethereum/go-ethereum/common" - "github.com/jmoiron/sqlx" - "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" @@ -44,15 +42,13 @@ var ( // Relayer with added DKG and OCR2VRF provider functions. type ocr2vrfRelayer struct { - db *sqlx.DB chain legacyevm.Chain lggr logger.Logger ethKeystore keystore.Eth } -func NewOCR2VRFRelayer(db *sqlx.DB, chain legacyevm.Chain, lggr logger.Logger, ethKeystore keystore.Eth) OCR2VRFRelayer { +func NewOCR2VRFRelayer(chain legacyevm.Chain, lggr logger.Logger, ethKeystore keystore.Eth) OCR2VRFRelayer { return &ocr2vrfRelayer{ - db: db, chain: chain, lggr: lggr, ethKeystore: ethKeystore, diff --git a/core/services/versioning/orm.go b/core/services/versioning/orm.go index 5a2472eee8e..5f6e3e60222 100644 --- a/core/services/versioning/orm.go +++ b/core/services/versioning/orm.go @@ -23,16 +23,14 @@ type ORM interface { } type orm struct { - ds sqlutil.DataSource - lggr logger.Logger - timeout time.Duration + ds sqlutil.DataSource + lggr logger.Logger } -func NewORM(ds sqlutil.DataSource, lggr logger.Logger, timeout time.Duration) *orm { +func NewORM(ds sqlutil.DataSource, lggr logger.Logger) *orm { return &orm{ - ds: ds, - lggr: lggr.Named("VersioningORM"), - timeout: timeout, + ds: ds, + lggr: lggr.Named("VersioningORM"), } } @@ -47,8 +45,6 @@ func (o *orm) UpsertNodeVersion(ctx context.Context, version NodeVersion) error return errors.Wrapf(err, "%q is not valid semver", version.Version) } - ctx, cancel := context.WithTimeout(ctx, o.timeout) - defer cancel() return sqlutil.TransactDataSource(ctx, o.ds, nil, func(tx sqlutil.DataSource) error { if _, _, err := CheckVersion(ctx, tx, logger.NullLogger, version.Version); err != nil { return err diff --git a/core/services/versioning/orm_test.go b/core/services/versioning/orm_test.go index f655c9c47fe..3504c2bc772 100644 --- a/core/services/versioning/orm_test.go +++ b/core/services/versioning/orm_test.go @@ -10,14 +10,13 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/static" ) func TestORM_NodeVersion_UpsertNodeVersion(t *testing.T) { ctx := testutils.Context(t) db := pgtest.NewSqlxDB(t) - orm := NewORM(db, logger.TestLogger(t), pg.DefaultQueryTimeout) + orm := NewORM(db, logger.TestLogger(t)) err := orm.UpsertNodeVersion(ctx, NewNodeVersion("9.9.8")) require.NoError(t, err) @@ -66,7 +65,7 @@ func Test_Version_CheckVersion(t *testing.T) { lggr := logger.TestLogger(t) - orm := NewORM(db, lggr, pg.DefaultQueryTimeout) + orm := NewORM(db, lggr) err := orm.UpsertNodeVersion(ctx, NewNodeVersion("9.9.8")) require.NoError(t, err) @@ -101,7 +100,7 @@ func Test_Version_CheckVersion(t *testing.T) { func TestORM_NodeVersion_FindLatestNodeVersion(t *testing.T) { ctx := testutils.Context(t) db := pgtest.NewSqlxDB(t) - orm := NewORM(db, logger.TestLogger(t), pg.DefaultQueryTimeout) + orm := NewORM(db, logger.TestLogger(t)) // Not Found _, err := orm.FindLatestNodeVersion(ctx) diff --git a/core/services/vrf/delegate_test.go b/core/services/vrf/delegate_test.go index a3962977257..889b19d0e04 100644 --- a/core/services/vrf/delegate_test.go +++ b/core/services/vrf/delegate_test.go @@ -83,10 +83,10 @@ func buildVrfUni(t *testing.T, db *sqlx.DB, cfg chainlink.GeneralConfig) vrfUniv btORM := bridges.NewORM(db) ks := keystore.NewInMemory(db, utils.FastScryptParams, lggr) _, dbConfig, evmConfig := txmgr.MakeTestConfigs(t) - txm, err := txmgr.NewTxm(db, db, evmConfig, evmConfig.GasEstimator(), evmConfig.Transactions(), nil, dbConfig, dbConfig.Listener(), ec, logger.TestLogger(t), nil, ks.Eth(), nil) + txm, err := txmgr.NewTxm(db, evmConfig, evmConfig.GasEstimator(), evmConfig.Transactions(), nil, dbConfig, dbConfig.Listener(), ec, logger.TestLogger(t), nil, ks.Eth(), nil) orm := headtracker.NewORM(*testutils.FixtureChainID, db) require.NoError(t, orm.IdempotentInsertHead(testutils.Context(t), cltest.Head(51))) - jrm := job.NewORM(db, prm, btORM, ks, lggr, cfg.Database()) + jrm := job.NewORM(db, prm, btORM, ks, lggr) t.Cleanup(func() { assert.NoError(t, jrm.Close()) }) relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{LogBroadcaster: lb, KeyStore: ks.Eth(), Client: ec, DB: db, GeneralConfig: cfg, TxManager: txm}) legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) @@ -165,7 +165,8 @@ func setup(t *testing.T) (vrfUniverse, *v1.Listener, job.Job) { vs := testspecs.GenerateVRFSpec(testspecs.VRFSpecParams{PublicKey: vuni.vrfkey.PublicKey.String(), EVMChainID: testutils.FixtureChainID.String()}) jb, err := vrfcommon.ValidatedVRFSpec(vs.Toml()) require.NoError(t, err) - err = vuni.jrm.CreateJob(&jb) + ctx := testutils.Context(t) + err = vuni.jrm.CreateJob(ctx, &jb) require.NoError(t, err) vl, err := vd.ServicesForSpec(testutils.Context(t), jb) require.NoError(t, err) @@ -701,7 +702,8 @@ func Test_VRFV2PlusServiceFailsWhenVRFOwnerProvided(t *testing.T) { toml := "vrfOwnerAddress=\"0xF62fEFb54a0af9D32CDF0Db21C52710844c7eddb\"\n" + vs.Toml() jb, err := vrfcommon.ValidatedVRFSpec(toml) require.NoError(t, err) - err = vuni.jrm.CreateJob(&jb) + ctx := testutils.Context(t) + err = vuni.jrm.CreateJob(ctx, &jb) require.NoError(t, err) _, err = vd.ServicesForSpec(testutils.Context(t), jb) require.Error(t, err) diff --git a/core/services/vrf/v1/integration_test.go b/core/services/vrf/v1/integration_test.go index c28ad9ce3d0..74006639c6e 100644 --- a/core/services/vrf/v1/integration_test.go +++ b/core/services/vrf/v1/integration_test.go @@ -55,10 +55,10 @@ func TestIntegration_VRF_JPV2(t *testing.T) { cu := vrftesthelpers.NewVRFCoordinatorUniverse(t, key1, key2) incomingConfs := 2 app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, cu.Backend, key1, key2) - require.NoError(t, app.Start(testutils.Context(t))) + require.NoError(t, app.Start(ctx)) jb, vrfKey := createVRFJobRegisterKey(t, cu, app, incomingConfs) - require.NoError(t, app.JobSpawner().CreateJob(&jb)) + require.NoError(t, app.JobSpawner().CreateJob(ctx, nil, &jb)) _, err := cu.ConsumerContract.TestRequestRandomness(cu.Carol, vrfKey.PublicKey.MustHash(), big.NewInt(100)) @@ -93,12 +93,12 @@ func TestIntegration_VRF_JPV2(t *testing.T) { // stop jobs as to not cause a race condition in geth simulated backend // between job creating new tx and fulfillment logs polling below - require.NoError(t, app.JobSpawner().DeleteJob(jb.ID)) + require.NoError(t, app.JobSpawner().DeleteJob(ctx, nil, jb.ID)) // Ensure the eth transaction gets confirmed on chain. gomega.NewWithT(t).Eventually(func() bool { - orm := txmgr.NewTxStore(app.GetSqlxDB(), app.GetLogger()) - uc, err2 := orm.CountUnconfirmedTransactions(testutils.Context(t), key1.Address, testutils.SimulatedChainID) + orm := txmgr.NewTxStore(app.GetDB(), app.GetLogger()) + uc, err2 := orm.CountUnconfirmedTransactions(ctx, key1.Address, testutils.SimulatedChainID) require.NoError(t, err2) return uc == 0 }, testutils.WaitTimeout(t), 100*time.Millisecond).Should(gomega.BeTrue()) @@ -116,11 +116,11 @@ func TestIntegration_VRF_JPV2(t *testing.T) { }, testutils.WaitTimeout(t), 500*time.Millisecond).Should(gomega.BeTrue()) // Check that each sending address sent one transaction - n1, err := cu.Backend.PendingNonceAt(testutils.Context(t), key1.Address) + n1, err := cu.Backend.PendingNonceAt(ctx, key1.Address) require.NoError(t, err) require.EqualValues(t, 1, n1) - n2, err := cu.Backend.PendingNonceAt(testutils.Context(t), key2.Address) + n2, err := cu.Backend.PendingNonceAt(ctx, key2.Address) require.NoError(t, err) require.EqualValues(t, 1, n2) }) @@ -142,7 +142,7 @@ func TestIntegration_VRF_WithBHS(t *testing.T) { cu := vrftesthelpers.NewVRFCoordinatorUniverse(t, key) incomingConfs := 2 app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, cu.Backend, key) - require.NoError(t, app.Start(testutils.Context(t))) + require.NoError(t, app.Start(ctx)) // Create VRF Job but do not start it yet jb, vrfKey := createVRFJobRegisterKey(t, cu, app, incomingConfs) @@ -155,7 +155,7 @@ func TestIntegration_VRF_WithBHS(t *testing.T) { // Ensure log poller is ready and has all logs. require.NoError(t, app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Ready()) - require.NoError(t, app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Replay(testutils.Context(t), 1)) + require.NoError(t, app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Replay(ctx, 1)) // Create a VRF request _, err := cu.ConsumerContract.TestRequestRandomness(cu.Carol, @@ -194,7 +194,7 @@ func TestIntegration_VRF_WithBHS(t *testing.T) { } // Start the VRF Job and wait until it's processed - require.NoError(t, app.JobSpawner().CreateJob(&jb)) + require.NoError(t, app.JobSpawner().CreateJob(ctx, nil, &jb)) var runs []pipeline.Run gomega.NewWithT(t).Eventually(func() bool { @@ -209,13 +209,13 @@ func TestIntegration_VRF_WithBHS(t *testing.T) { // stop jobs as to not cause a race condition in geth simulated backend // between job creating new tx and fulfillment logs polling below - require.NoError(t, app.JobSpawner().DeleteJob(jb.ID)) - require.NoError(t, app.JobSpawner().DeleteJob(bhsJob.ID)) + require.NoError(t, app.JobSpawner().DeleteJob(ctx, nil, jb.ID)) + require.NoError(t, app.JobSpawner().DeleteJob(ctx, nil, bhsJob.ID)) // Ensure the eth transaction gets confirmed on chain. gomega.NewWithT(t).Eventually(func() bool { - orm := txmgr.NewTxStore(app.GetSqlxDB(), app.GetLogger()) - uc, err2 := orm.CountUnconfirmedTransactions(testutils.Context(t), key.Address, testutils.SimulatedChainID) + orm := txmgr.NewTxStore(app.GetDB(), app.GetLogger()) + uc, err2 := orm.CountUnconfirmedTransactions(ctx, key.Address, testutils.SimulatedChainID) require.NoError(t, err2) return uc == 0 }, 5*time.Second, 100*time.Millisecond).Should(gomega.BeTrue()) diff --git a/core/services/vrf/v1/listener_v1.go b/core/services/vrf/v1/listener_v1.go index ddf5779deb0..c8029403084 100644 --- a/core/services/vrf/v1/listener_v1.go +++ b/core/services/vrf/v1/listener_v1.go @@ -28,7 +28,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/recovery" "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrfcommon" "github.com/smartcontractkit/chainlink/v2/core/utils" @@ -57,7 +56,6 @@ type Listener struct { Coordinator *solidity_vrf_coordinator_interface.VRFCoordinator PipelineRunner pipeline.Runner Job job.Job - Q pg.Q GethKs vrfcommon.GethKeyStore MailMon *mailbox.Monitor ReqLogs *mailbox.Mailbox[log.Broadcast] @@ -285,6 +283,8 @@ func (lsn *Listener) RunHeadListener(unsubscribe func()) { } func (lsn *Listener) RunLogListener(unsubscribes []func(), minConfs uint32) { + ctx, cancel := lsn.ChStop.NewCtx() + defer cancel() lsn.L.Infow("Listening for run requests", "gasLimit", lsn.FeeCfg.LimitDefault(), "minConfs", minConfs) @@ -304,8 +304,6 @@ func (lsn *Listener) RunLogListener(unsubscribes []func(), minConfs uint32) { break } recovery.WrapRecover(lsn.L, func() { - ctx, cancel := lsn.ChStop.NewCtx() - defer cancel() lsn.handleLog(ctx, lb, minConfs) }) } @@ -488,8 +486,7 @@ func (lsn *Listener) ProcessRequest(ctx context.Context, req request) bool { // The VRF pipeline has no async tasks, so we don't need to check for `incomplete` if _, err = lsn.PipelineRunner.Run(ctx, run, lggr, true, func(tx sqlutil.DataSource) error { // Always mark consumed regardless of whether the proof failed or not. - //TODO restore tx https://smartcontract-it.atlassian.net/browse/BCF-2978 - if err = lsn.Chain.LogBroadcaster().MarkConsumed(ctx, nil, req.lb); err != nil { + if err = lsn.Chain.LogBroadcaster().MarkConsumed(ctx, tx, req.lb); err != nil { lggr.Errorw("Failed mark consumed", "err", err) } return nil diff --git a/core/services/vrf/v2/integration_helpers_test.go b/core/services/vrf/v2/integration_helpers_test.go index 2e0554fca96..d61779c5714 100644 --- a/core/services/vrf/v2/integration_helpers_test.go +++ b/core/services/vrf/v2/integration_helpers_test.go @@ -1207,7 +1207,6 @@ func testSingleConsumerBigGasCallbackSandwich( ownerKey ethkey.KeyV2, uni coordinatorV2UniverseCommon, batchCoordinatorAddress common.Address, - batchEnabled bool, vrfVersion vrfcommon.Version, nativePayment bool, ) { @@ -1324,7 +1323,6 @@ func testSingleConsumerMultipleGasLanes( ownerKey ethkey.KeyV2, uni coordinatorV2UniverseCommon, batchCoordinatorAddress common.Address, - batchEnabled bool, vrfVersion vrfcommon.Version, nativePayment bool, ) { @@ -1694,7 +1692,7 @@ func testMaliciousConsumer( }).Toml() jb, err := vrfcommon.ValidatedVRFSpec(s) require.NoError(t, err) - err = app.JobSpawner().CreateJob(&jb) + err = app.JobSpawner().CreateJob(ctx, nil, &jb) require.NoError(t, err) time.Sleep(1 * time.Second) @@ -1861,7 +1859,7 @@ func testReplayOldRequestsOnStartUp( jb, err := vrfcommon.ValidatedVRFSpec(spec) require.NoError(t, err) t.Log(jb.VRFSpec.PublicKey.MustHash(), vrfKey.PublicKey.MustHash()) - err = app.JobSpawner().CreateJob(&jb) + err = app.JobSpawner().CreateJob(ctx, nil, &jb) require.NoError(t, err) // Wait until all jobs are active and listening for logs diff --git a/core/services/vrf/v2/integration_v2_plus_test.go b/core/services/vrf/v2/integration_v2_plus_test.go index b885473e488..53baaa0eda3 100644 --- a/core/services/vrf/v2/integration_v2_plus_test.go +++ b/core/services/vrf/v2/integration_v2_plus_test.go @@ -646,29 +646,13 @@ func TestVRFV2PlusIntegration_SingleConsumer_NeedsTopUp(t *testing.T) { func TestVRFV2PlusIntegration_SingleConsumer_BigGasCallback_Sandwich(t *testing.T) { ownerKey := cltest.MustGenerateRandomKey(t) uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1, false) - testSingleConsumerBigGasCallbackSandwich( - t, - ownerKey, - uni.coordinatorV2UniverseCommon, - uni.batchCoordinatorContractAddress, - false, - vrfcommon.V2Plus, - false, - ) + testSingleConsumerBigGasCallbackSandwich(t, ownerKey, uni.coordinatorV2UniverseCommon, uni.batchCoordinatorContractAddress, vrfcommon.V2Plus, false) } func TestVRFV2PlusIntegration_SingleConsumer_MultipleGasLanes(t *testing.T) { ownerKey := cltest.MustGenerateRandomKey(t) uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1, false) - testSingleConsumerMultipleGasLanes( - t, - ownerKey, - uni.coordinatorV2UniverseCommon, - uni.batchCoordinatorContractAddress, - false, - vrfcommon.V2Plus, - false, - ) + testSingleConsumerMultipleGasLanes(t, ownerKey, uni.coordinatorV2UniverseCommon, uni.batchCoordinatorContractAddress, vrfcommon.V2Plus, false) } func TestVRFV2PlusIntegration_SingleConsumer_AlwaysRevertingCallback_StillFulfilled(t *testing.T) { @@ -1178,7 +1162,7 @@ func TestVRFV2PlusIntegration_Migration(t *testing.T) { // Fund gas lane. sendEth(t, ownerKey, uni.backend, key1.Address, 10) - require.NoError(t, app.Start(testutils.Context(t))) + require.NoError(t, app.Start(ctx)) // Create VRF job using key1 and key2 on the same gas lane. jbs := createVRFJobs( @@ -1234,7 +1218,7 @@ func TestVRFV2PlusIntegration_Migration(t *testing.T) { require.NoError(t, err) linkContractBalance, err := uni.linkContract.BalanceOf(nil, uni.migrationTestCoordinatorAddress) require.NoError(t, err) - balance, err := uni.backend.BalanceAt(testutils.Context(t), uni.migrationTestCoordinatorAddress, nil) + balance, err := uni.backend.BalanceAt(ctx, uni.migrationTestCoordinatorAddress, nil) require.NoError(t, err) require.Equal(t, subV1.Balance(), totalLinkBalance) diff --git a/core/services/vrf/v2/integration_v2_reverted_txns_test.go b/core/services/vrf/v2/integration_v2_reverted_txns_test.go index dfee450b6a2..25e3afcf751 100644 --- a/core/services/vrf/v2/integration_v2_reverted_txns_test.go +++ b/core/services/vrf/v2/integration_v2_reverted_txns_test.go @@ -448,7 +448,7 @@ func createVRFJobsNew( jb, err := vrfcommon.ValidatedVRFSpec(s) t.Log(jb.VRFSpec.PublicKey.MustHash(), vrfkey.PublicKey.MustHash()) require.NoError(t, err) - err = app.JobSpawner().CreateJob(&jb) + err = app.JobSpawner().CreateJob(ctx, nil, &jb) require.NoError(t, err) registerProvingKeyHelper(t, uni.coordinatorV2UniverseCommon, coordinator, vrfkey, ptr(gasLanePrices[i].ToInt().Uint64())) jobs = append(jobs, jb) diff --git a/core/services/vrf/v2/integration_v2_test.go b/core/services/vrf/v2/integration_v2_test.go index 543ec943527..e8d4fd255f7 100644 --- a/core/services/vrf/v2/integration_v2_test.go +++ b/core/services/vrf/v2/integration_v2_test.go @@ -574,7 +574,7 @@ func createVRFJobs( jb, err := vrfcommon.ValidatedVRFSpec(spec) require.NoError(t, err) t.Log(jb.VRFSpec.PublicKey.MustHash(), vrfkey.PublicKey.MustHash()) - err = app.JobSpawner().CreateJob(&jb) + err = app.JobSpawner().CreateJob(ctx, nil, &jb) require.NoError(t, err) registerProvingKeyHelper(t, uni, coordinator, vrfkey, ptr(gasLanePrices[i].ToInt().Uint64())) jobs = append(jobs, jb) @@ -1427,29 +1427,13 @@ func TestVRFV2Integration_SingleConsumer_NeedsTopUp(t *testing.T) { func TestVRFV2Integration_SingleConsumer_BigGasCallback_Sandwich(t *testing.T) { ownerKey := cltest.MustGenerateRandomKey(t) uni := newVRFCoordinatorV2Universe(t, ownerKey, 1) - testSingleConsumerBigGasCallbackSandwich( - t, - ownerKey, - uni.coordinatorV2UniverseCommon, - uni.batchCoordinatorContractAddress, - false, - vrfcommon.V2, - false, - ) + testSingleConsumerBigGasCallbackSandwich(t, ownerKey, uni.coordinatorV2UniverseCommon, uni.batchCoordinatorContractAddress, vrfcommon.V2, false) } func TestVRFV2Integration_SingleConsumer_MultipleGasLanes(t *testing.T) { ownerKey := cltest.MustGenerateRandomKey(t) uni := newVRFCoordinatorV2Universe(t, ownerKey, 1) - testSingleConsumerMultipleGasLanes( - t, - ownerKey, - uni.coordinatorV2UniverseCommon, - uni.batchCoordinatorContractAddress, - false, - vrfcommon.V2, - false, - ) + testSingleConsumerMultipleGasLanes(t, ownerKey, uni.coordinatorV2UniverseCommon, uni.batchCoordinatorContractAddress, vrfcommon.V2, false) } func TestVRFV2Integration_SingleConsumer_AlwaysRevertingCallback_StillFulfilled(t *testing.T) { diff --git a/core/services/vrf/vrftesthelpers/helpers.go b/core/services/vrf/vrftesthelpers/helpers.go index 77d3f33a653..33ad8470731 100644 --- a/core/services/vrf/vrftesthelpers/helpers.go +++ b/core/services/vrf/vrftesthelpers/helpers.go @@ -74,7 +74,8 @@ func CreateAndStartBHSJob( jb, err := blockhashstore.ValidatedSpec(s.Toml()) require.NoError(t, err) - require.NoError(t, app.JobSpawner().CreateJob(&jb)) + ctx := testutils.Context(t) + require.NoError(t, app.JobSpawner().CreateJob(ctx, nil, &jb)) gomega.NewWithT(t).Eventually(func() bool { jbs := app.JobSpawner().ActiveJobs() for _, jb := range jbs { @@ -115,7 +116,8 @@ func CreateAndStartBlockHeaderFeederJob( jb, err := blockheaderfeeder.ValidatedSpec(s.Toml()) require.NoError(t, err) - require.NoError(t, app.JobSpawner().CreateJob(&jb)) + ctx := testutils.Context(t) + require.NoError(t, app.JobSpawner().CreateJob(ctx, nil, &jb)) gomega.NewWithT(t).Eventually(func() bool { jbs := app.JobSpawner().ActiveJobs() for _, jb := range jbs { diff --git a/core/services/webhook/authorizer.go b/core/services/webhook/authorizer.go index c745c5d0b09..f5409cfbacc 100644 --- a/core/services/webhook/authorizer.go +++ b/core/services/webhook/authorizer.go @@ -24,29 +24,29 @@ var ( _ Authorizer = &neverAuthorizer{} ) -func NewAuthorizer(db sqlutil.DataSource, user *sessions.User, ei *bridges.ExternalInitiator) Authorizer { +func NewAuthorizer(ds sqlutil.DataSource, user *sessions.User, ei *bridges.ExternalInitiator) Authorizer { if user != nil { return &alwaysAuthorizer{} } else if ei != nil { - return NewEIAuthorizer(db, *ei) + return NewEIAuthorizer(ds, *ei) } return &neverAuthorizer{} } type eiAuthorizer struct { - db sqlutil.DataSource + ds sqlutil.DataSource ei bridges.ExternalInitiator } -func NewEIAuthorizer(db sqlutil.DataSource, ei bridges.ExternalInitiator) *eiAuthorizer { - return &eiAuthorizer{db, ei} +func NewEIAuthorizer(ds sqlutil.DataSource, ei bridges.ExternalInitiator) *eiAuthorizer { + return &eiAuthorizer{ds, ei} } func (ea *eiAuthorizer) CanRun(ctx context.Context, config AuthorizerConfig, jobUUID uuid.UUID) (can bool, err error) { if !config.ExternalInitiatorsEnabled() { return false, nil } - row := ea.db.QueryRowxContext(ctx, ` + row := ea.ds.QueryRowxContext(ctx, ` SELECT EXISTS ( SELECT 1 FROM external_initiator_webhook_specs JOIN jobs ON external_initiator_webhook_specs.webhook_spec_id = jobs.webhook_spec_id diff --git a/core/services/webhook/authorizer_test.go b/core/services/webhook/authorizer_test.go index 82af7c6fcce..202791c26c2 100644 --- a/core/services/webhook/authorizer_test.go +++ b/core/services/webhook/authorizer_test.go @@ -8,9 +8,8 @@ import ( "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/bridges" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/services/webhook" "github.com/smartcontractkit/chainlink/v2/core/sessions" diff --git a/core/services/webhook/external_initiator_manager.go b/core/services/webhook/external_initiator_manager.go index 0c035abde7a..2f9a176906d 100644 --- a/core/services/webhook/external_initiator_manager.go +++ b/core/services/webhook/external_initiator_manager.go @@ -11,12 +11,9 @@ import ( "github.com/lib/pq" "github.com/pkg/errors" - "github.com/jmoiron/sqlx" - + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink/v2/core/bridges" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/static" "github.com/smartcontractkit/chainlink/v2/core/store/models" ) @@ -27,7 +24,7 @@ import ( type ExternalInitiatorManager interface { Notify(ctx context.Context, webhookSpecID int32) error DeleteJob(ctx context.Context, webhookSpecID int32) error - FindExternalInitiatorByName(name string) (bridges.ExternalInitiator, error) + FindExternalInitiatorByName(ctx context.Context, name string) (bridges.ExternalInitiator, error) } //go:generate mockery --quiet --name HTTPClient --output ./mocks/ --case=underscore @@ -36,25 +33,24 @@ type HTTPClient interface { } type externalInitiatorManager struct { - q pg.Q + ds sqlutil.DataSource httpclient HTTPClient } var _ ExternalInitiatorManager = (*externalInitiatorManager)(nil) // NewExternalInitiatorManager returns the concrete externalInitiatorManager -func NewExternalInitiatorManager(db *sqlx.DB, httpclient HTTPClient, lggr logger.Logger, cfg pg.QConfig) *externalInitiatorManager { - namedLogger := lggr.Named("ExternalInitiatorManager") +func NewExternalInitiatorManager(ds sqlutil.DataSource, httpclient HTTPClient) *externalInitiatorManager { return &externalInitiatorManager{ - q: pg.NewQ(db, namedLogger, cfg), + ds: ds, httpclient: httpclient, } } // Notify sends a POST notification to the External Initiator // responsible for initiating the Job Spec. -func (m externalInitiatorManager) Notify(ctx context.Context, webhookSpecID int32) error { - eiWebhookSpecs, jobID, err := m.Load(webhookSpecID) +func (m *externalInitiatorManager) Notify(ctx context.Context, webhookSpecID int32) error { + eiWebhookSpecs, jobID, err := m.Load(ctx, webhookSpecID) if err != nil { return err } @@ -90,19 +86,21 @@ func (m externalInitiatorManager) Notify(ctx context.Context, webhookSpecID int3 return nil } -func (m externalInitiatorManager) Load(webhookSpecID int32) (eiWebhookSpecs []job.ExternalInitiatorWebhookSpec, jobID uuid.UUID, err error) { - err = m.q.Transaction(func(tx pg.Queryer) error { - if err = tx.Get(&jobID, "SELECT external_job_id FROM jobs WHERE webhook_spec_id = $1", webhookSpecID); err != nil { +func (m *externalInitiatorManager) Load(ctx context.Context, webhookSpecID int32) (eiWebhookSpecs []job.ExternalInitiatorWebhookSpec, jobID uuid.UUID, err error) { + err = sqlutil.Transact(ctx, func(ds sqlutil.DataSource) *externalInitiatorManager { + return NewExternalInitiatorManager(ds, m.httpclient) + }, m.ds, nil, func(tx *externalInitiatorManager) error { + if err = tx.ds.GetContext(ctx, &jobID, "SELECT external_job_id FROM jobs WHERE webhook_spec_id = $1", webhookSpecID); err != nil { if err = errors.Wrapf(err, "failed to load job ID from job for webhook spec with ID %d", webhookSpecID); err != nil { return err } } - if err = tx.Select(&eiWebhookSpecs, "SELECT * FROM external_initiator_webhook_specs WHERE external_initiator_webhook_specs.webhook_spec_id = $1", webhookSpecID); err != nil { + if err = tx.ds.SelectContext(ctx, &eiWebhookSpecs, "SELECT * FROM external_initiator_webhook_specs WHERE external_initiator_webhook_specs.webhook_spec_id = $1", webhookSpecID); err != nil { if err = errors.Wrapf(err, "failed to load external_initiator_webhook_specs for webhook_spec_id %d", webhookSpecID); err != nil { return err } } - if err = m.eagerLoadExternalInitiator(tx, eiWebhookSpecs); err != nil { + if err = tx.eagerLoadExternalInitiator(ctx, eiWebhookSpecs); err != nil { if err = errors.Wrapf(err, "failed to preload ExternalInitiator for webhook_spec_id %d", webhookSpecID); err != nil { return err } @@ -113,7 +111,7 @@ func (m externalInitiatorManager) Load(webhookSpecID int32) (eiWebhookSpecs []jo return } -func (m externalInitiatorManager) eagerLoadExternalInitiator(q pg.Queryer, txs []job.ExternalInitiatorWebhookSpec) error { +func (m *externalInitiatorManager) eagerLoadExternalInitiator(ctx context.Context, txs []job.ExternalInitiatorWebhookSpec) error { var ids []int64 for _, tx := range txs { ids = append(ids, tx.ExternalInitiatorID) @@ -122,7 +120,7 @@ func (m externalInitiatorManager) eagerLoadExternalInitiator(q pg.Queryer, txs [ return nil } var externalInitiators []bridges.ExternalInitiator - if err := sqlx.Select(q, &externalInitiators, `SELECT * FROM external_initiators WHERE external_initiators.id = ANY($1);`, pq.Array(ids)); err != nil { + if err := m.ds.SelectContext(ctx, &externalInitiators, `SELECT * FROM external_initiators WHERE external_initiators.id = ANY($1);`, pq.Array(ids)); err != nil { return err } @@ -137,8 +135,8 @@ func (m externalInitiatorManager) eagerLoadExternalInitiator(q pg.Queryer, txs [ return nil } -func (m externalInitiatorManager) DeleteJob(ctx context.Context, webhookSpecID int32) error { - eiWebhookSpecs, jobID, err := m.Load(webhookSpecID) +func (m *externalInitiatorManager) DeleteJob(ctx context.Context, webhookSpecID int32) error { + eiWebhookSpecs, jobID, err := m.Load(ctx, webhookSpecID) if err != nil { return err } @@ -166,9 +164,9 @@ func (m externalInitiatorManager) DeleteJob(ctx context.Context, webhookSpecID i return nil } -func (m externalInitiatorManager) FindExternalInitiatorByName(name string) (bridges.ExternalInitiator, error) { +func (m *externalInitiatorManager) FindExternalInitiatorByName(ctx context.Context, name string) (bridges.ExternalInitiator, error) { var exi bridges.ExternalInitiator - err := m.q.Get(&exi, "SELECT * FROM external_initiators WHERE lower(external_initiators.name) = lower($1)", name) + err := m.ds.GetContext(ctx, &exi, "SELECT * FROM external_initiators WHERE lower(external_initiators.name) = lower($1)", name) return exi, err } @@ -211,6 +209,6 @@ var _ ExternalInitiatorManager = (*NullExternalInitiatorManager)(nil) func (NullExternalInitiatorManager) Notify(context.Context, int32) error { return nil } func (NullExternalInitiatorManager) DeleteJob(context.Context, int32) error { return nil } -func (NullExternalInitiatorManager) FindExternalInitiatorByName(name string) (bridges.ExternalInitiator, error) { +func (NullExternalInitiatorManager) FindExternalInitiatorByName(ctx context.Context, name string) (bridges.ExternalInitiator, error) { return bridges.ExternalInitiator{}, nil } diff --git a/core/services/webhook/external_initiator_manager_test.go b/core/services/webhook/external_initiator_manager_test.go index 22ab50513cf..a2402b4114d 100644 --- a/core/services/webhook/external_initiator_manager_test.go +++ b/core/services/webhook/external_initiator_manager_test.go @@ -17,15 +17,14 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" - "github.com/smartcontractkit/chainlink/v2/core/logger" _ "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/webhook" webhookmocks "github.com/smartcontractkit/chainlink/v2/core/services/webhook/mocks" ) func Test_ExternalInitiatorManager_Load(t *testing.T) { + ctx := testutils.Context(t) db := pgtest.NewSqlxDB(t) - cfg := pgtest.NewQConfig(true) borm := bridges.NewORM(db) eiFoo := cltest.MustInsertExternalInitiator(t, borm) @@ -39,21 +38,21 @@ func Test_ExternalInitiatorManager_Load(t *testing.T) { pgtest.MustExec(t, db, `INSERT INTO external_initiator_webhook_specs (external_initiator_id, webhook_spec_id, spec) VALUES ($1,$2,$3)`, eiBar.ID, webhookSpecTwoEIs.ID, `{"ei": "bar", "name": "webhookSpecTwoEIs"}`) pgtest.MustExec(t, db, `INSERT INTO external_initiator_webhook_specs (external_initiator_id, webhook_spec_id, spec) VALUES ($1,$2,$3)`, eiFoo.ID, webhookSpecOneEI.ID, `{"ei": "foo", "name": "webhookSpecOneEI"}`) - eim := webhook.NewExternalInitiatorManager(db, nil, logger.TestLogger(t), cfg) + eim := webhook.NewExternalInitiatorManager(db, nil) - eiWebhookSpecs, jobID, err := eim.Load(webhookSpecNoEIs.ID) + eiWebhookSpecs, jobID, err := eim.Load(ctx, webhookSpecNoEIs.ID) require.NoError(t, err) assert.Len(t, eiWebhookSpecs, 0) assert.Equal(t, jb3.ExternalJobID, jobID) - eiWebhookSpecs, jobID, err = eim.Load(webhookSpecOneEI.ID) + eiWebhookSpecs, jobID, err = eim.Load(ctx, webhookSpecOneEI.ID) require.NoError(t, err) assert.Len(t, eiWebhookSpecs, 1) assert.Equal(t, `{"ei": "foo", "name": "webhookSpecOneEI"}`, eiWebhookSpecs[0].Spec.Raw) assert.Equal(t, eiFoo.ID, eiWebhookSpecs[0].ExternalInitiator.ID) assert.Equal(t, jb1.ExternalJobID, jobID) - eiWebhookSpecs, jobID, err = eim.Load(webhookSpecTwoEIs.ID) + eiWebhookSpecs, jobID, err = eim.Load(ctx, webhookSpecTwoEIs.ID) require.NoError(t, err) assert.Len(t, eiWebhookSpecs, 2) assert.Equal(t, jb2.ExternalJobID, jobID) @@ -62,7 +61,6 @@ func Test_ExternalInitiatorManager_Load(t *testing.T) { func Test_ExternalInitiatorManager_Notify(t *testing.T) { ctx := tests.Context(t) db := pgtest.NewSqlxDB(t) - cfg := pgtest.NewQConfig(true) borm := bridges.NewORM(db) eiWithURL := cltest.MustInsertExternalInitiatorWithOpts(t, borm, cltest.ExternalInitiatorOpts{ @@ -79,7 +77,7 @@ func Test_ExternalInitiatorManager_Notify(t *testing.T) { pgtest.MustExec(t, db, `INSERT INTO external_initiator_webhook_specs (external_initiator_id, webhook_spec_id, spec) VALUES ($1,$2,$3)`, eiNoURL.ID, webhookSpecTwoEIs.ID, `{"ei": "bar", "name": "webhookSpecTwoEIs"}`) client := webhookmocks.NewHTTPClient(t) - eim := webhook.NewExternalInitiatorManager(db, client, logger.TestLogger(t), cfg) + eim := webhook.NewExternalInitiatorManager(db, client) // Does nothing with no EI require.NoError(t, eim.Notify(ctx, webhookSpecNoEIs.ID)) @@ -102,7 +100,6 @@ func Test_ExternalInitiatorManager_Notify(t *testing.T) { func Test_ExternalInitiatorManager_DeleteJob(t *testing.T) { ctx := testutils.Context(t) db := pgtest.NewSqlxDB(t) - cfg := pgtest.NewQConfig(true) borm := bridges.NewORM(db) eiWithURL := cltest.MustInsertExternalInitiatorWithOpts(t, borm, cltest.ExternalInitiatorOpts{ @@ -119,7 +116,7 @@ func Test_ExternalInitiatorManager_DeleteJob(t *testing.T) { pgtest.MustExec(t, db, `INSERT INTO external_initiator_webhook_specs (external_initiator_id, webhook_spec_id, spec) VALUES ($1,$2,$3)`, eiNoURL.ID, webhookSpecTwoEIs.ID, `{"ei": "bar", "name": "webhookSpecTwoEIs"}`) client := webhookmocks.NewHTTPClient(t) - eim := webhook.NewExternalInitiatorManager(db, client, logger.TestLogger(t), cfg) + eim := webhook.NewExternalInitiatorManager(db, client) // Does nothing with no EI require.NoError(t, eim.DeleteJob(ctx, webhookSpecNoEIs.ID)) diff --git a/core/services/webhook/mocks/external_initiator_manager.go b/core/services/webhook/mocks/external_initiator_manager.go index 9711ae686ea..7a3ee29f62f 100644 --- a/core/services/webhook/mocks/external_initiator_manager.go +++ b/core/services/webhook/mocks/external_initiator_manager.go @@ -33,9 +33,9 @@ func (_m *ExternalInitiatorManager) DeleteJob(ctx context.Context, webhookSpecID return r0 } -// FindExternalInitiatorByName provides a mock function with given fields: name -func (_m *ExternalInitiatorManager) FindExternalInitiatorByName(name string) (bridges.ExternalInitiator, error) { - ret := _m.Called(name) +// FindExternalInitiatorByName provides a mock function with given fields: ctx, name +func (_m *ExternalInitiatorManager) FindExternalInitiatorByName(ctx context.Context, name string) (bridges.ExternalInitiator, error) { + ret := _m.Called(ctx, name) if len(ret) == 0 { panic("no return value specified for FindExternalInitiatorByName") @@ -43,17 +43,17 @@ func (_m *ExternalInitiatorManager) FindExternalInitiatorByName(name string) (br var r0 bridges.ExternalInitiator var r1 error - if rf, ok := ret.Get(0).(func(string) (bridges.ExternalInitiator, error)); ok { - return rf(name) + if rf, ok := ret.Get(0).(func(context.Context, string) (bridges.ExternalInitiator, error)); ok { + return rf(ctx, name) } - if rf, ok := ret.Get(0).(func(string) bridges.ExternalInitiator); ok { - r0 = rf(name) + if rf, ok := ret.Get(0).(func(context.Context, string) bridges.ExternalInitiator); ok { + r0 = rf(ctx, name) } else { r0 = ret.Get(0).(bridges.ExternalInitiator) } - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(name) + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, name) } else { r1 = ret.Error(1) } diff --git a/core/services/webhook/validate.go b/core/services/webhook/validate.go index 6066a863ff7..a6d6aa72e83 100644 --- a/core/services/webhook/validate.go +++ b/core/services/webhook/validate.go @@ -1,6 +1,8 @@ package webhook import ( + "context" + "github.com/pelletier/go-toml" "github.com/pkg/errors" "go.uber.org/multierr" @@ -18,7 +20,7 @@ type TOMLWebhookSpec struct { ExternalInitiators []TOMLWebhookSpecExternalInitiator `toml:"externalInitiators"` } -func ValidatedWebhookSpec(tomlString string, externalInitiatorManager ExternalInitiatorManager) (jb job.Job, err error) { +func ValidatedWebhookSpec(ctx context.Context, tomlString string, externalInitiatorManager ExternalInitiatorManager) (jb job.Job, err error) { var tree *toml.Tree tree, err = toml.Load(tomlString) if err != nil { @@ -40,7 +42,7 @@ func ValidatedWebhookSpec(tomlString string, externalInitiatorManager ExternalIn var externalInitiatorWebhookSpecs []job.ExternalInitiatorWebhookSpec for _, eiSpec := range tomlSpec.ExternalInitiators { - ei, findErr := externalInitiatorManager.FindExternalInitiatorByName(eiSpec.Name) + ei, findErr := externalInitiatorManager.FindExternalInitiatorByName(ctx, eiSpec.Name) if findErr != nil { err = multierr.Combine(err, errors.Wrapf(findErr, "unable to find external initiator named %s", eiSpec.Name)) continue diff --git a/core/services/webhook/validate_test.go b/core/services/webhook/validate_test.go index f6993f6aefe..8d398fc0b68 100644 --- a/core/services/webhook/validate_test.go +++ b/core/services/webhook/validate_test.go @@ -6,9 +6,11 @@ import ( "github.com/manyminds/api2go/jsonapi" "github.com/pkg/errors" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/bridges" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/webhook" webhookmocks "github.com/smartcontractkit/chainlink/v2/core/services/webhook/mocks" @@ -96,8 +98,8 @@ func TestValidatedWebJobSpec(t *testing.T) { """ `, mock: func(t *testing.T, eim *webhookmocks.ExternalInitiatorManager) { - eim.On("FindExternalInitiatorByName", "foo").Return(bridges.ExternalInitiator{ID: 42}, nil).Once() - eim.On("FindExternalInitiatorByName", "bar").Return(bridges.ExternalInitiator{ID: 43}, nil).Once() + eim.On("FindExternalInitiatorByName", mock.Anything, "foo").Return(bridges.ExternalInitiator{ID: 42}, nil).Once() + eim.On("FindExternalInitiatorByName", mock.Anything, "bar").Return(bridges.ExternalInitiator{ID: 43}, nil).Once() }, assertion: func(t *testing.T, s job.Job, err error) { require.NoError(t, err) @@ -134,9 +136,9 @@ func TestValidatedWebJobSpec(t *testing.T) { """ `, mock: func(t *testing.T, eim *webhookmocks.ExternalInitiatorManager) { - eim.On("FindExternalInitiatorByName", "foo").Return(bridges.ExternalInitiator{ID: 42}, nil).Once() - eim.On("FindExternalInitiatorByName", "bar").Return(bridges.ExternalInitiator{}, errors.New("something exploded")).Once() - eim.On("FindExternalInitiatorByName", "baz").Return(bridges.ExternalInitiator{}, errors.New("something exploded")).Once() + eim.On("FindExternalInitiatorByName", mock.Anything, "foo").Return(bridges.ExternalInitiator{ID: 42}, nil).Once() + eim.On("FindExternalInitiatorByName", mock.Anything, "bar").Return(bridges.ExternalInitiator{}, errors.New("something exploded")).Once() + eim.On("FindExternalInitiatorByName", mock.Anything, "baz").Return(bridges.ExternalInitiator{}, errors.New("something exploded")).Once() }, assertion: func(t *testing.T, s job.Job, err error) { require.EqualError(t, err, "unable to find external initiator named bar: something exploded; unable to find external initiator named baz: something exploded") @@ -147,11 +149,12 @@ func TestValidatedWebJobSpec(t *testing.T) { tc := tc t.Run(tc.name, func(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) eim := new(webhookmocks.ExternalInitiatorManager) if tc.mock != nil { tc.mock(t, eim) } - s, err := webhook.ValidatedWebhookSpec(tc.toml, eim) + s, err := webhook.ValidatedWebhookSpec(ctx, tc.toml, eim) tc.assertion(t, s, err) }) } diff --git a/core/sessions/ldapauth/sync.go b/core/sessions/ldapauth/sync.go index 74c606a9684..a6e0366e21d 100644 --- a/core/sessions/ldapauth/sync.go +++ b/core/sessions/ldapauth/sync.go @@ -1,23 +1,23 @@ package ldapauth import ( + "context" "errors" "fmt" "time" "github.com/go-ldap/ldap/v3" - "github.com/jmoiron/sqlx" "github.com/lib/pq" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink/v2/core/config" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/sessions" ) type LDAPServerStateSyncer struct { - q pg.Q + ds sqlutil.DataSource ldapClient LDAPClient config config.LDAP lggr logger.Logger @@ -26,14 +26,13 @@ type LDAPServerStateSyncer struct { // NewLDAPServerStateSync creates a reaper that cleans stale sessions from the store. func NewLDAPServerStateSync( - db *sqlx.DB, - pgCfg pg.QConfig, + ds sqlutil.DataSource, config config.LDAP, lggr logger.Logger, ) *utils.SleeperTask { namedLogger := lggr.Named("LDAPServerStateSync") serverSync := LDAPServerStateSyncer{ - q: pg.NewQ(db, namedLogger, pgCfg), + ds: ds, ldapClient: newLDAPClient(config), config: config, lggr: namedLogger, @@ -65,14 +64,15 @@ func (ldSync *LDAPServerStateSyncer) StartWorkOnTimer() { } func (ldSync *LDAPServerStateSyncer) Work() { + ctx := context.Background() // TODO https://smartcontract-it.atlassian.net/browse/BCF-2887 // Purge expired ldap_sessions and ldap_user_api_tokens recordCreationStaleThreshold := ldSync.config.SessionTimeout().Before(time.Now()) - err := ldSync.deleteStaleSessions(recordCreationStaleThreshold) + err := ldSync.deleteStaleSessions(ctx, recordCreationStaleThreshold) if err != nil { ldSync.lggr.Error("unable to expire local LDAP sessions: ", err) } recordCreationStaleThreshold = ldSync.config.UserAPITokenDuration().Before(time.Now()) - err = ldSync.deleteStaleAPITokens(recordCreationStaleThreshold) + err = ldSync.deleteStaleAPITokens(ctx, recordCreationStaleThreshold) if err != nil { ldSync.lggr.Error("unable to expire user API tokens: ", err) } @@ -160,18 +160,18 @@ func (ldSync *LDAPServerStateSyncer) Work() { // upstreamUserStateMap is now the most up to date source of truth // Now sync database sessions and roles with new data - err = ldSync.q.Transaction(func(tx pg.Queryer) error { + err = sqlutil.TransactDataSource(ctx, ldSync.ds, nil, func(tx sqlutil.DataSource) error { // First, purge users present in the local ldap_sessions table but not in the upstream server type LDAPSession struct { UserEmail string UserRole sessions.UserRole } var existingSessions []LDAPSession - if err = tx.Select(&existingSessions, "SELECT user_email, user_role FROM ldap_sessions WHERE localauth_user = false"); err != nil { + if err = tx.SelectContext(ctx, &existingSessions, "SELECT user_email, user_role FROM ldap_sessions WHERE localauth_user = false"); err != nil { return fmt.Errorf("unable to query ldap_sessions table: %w", err) } var existingAPITokens []LDAPSession - if err = tx.Select(&existingAPITokens, "SELECT user_email, user_role FROM ldap_user_api_tokens WHERE localauth_user = false"); err != nil { + if err = tx.SelectContext(ctx, &existingAPITokens, "SELECT user_email, user_role FROM ldap_user_api_tokens WHERE localauth_user = false"); err != nil { return fmt.Errorf("unable to query ldap_user_api_tokens table: %w", err) } @@ -202,7 +202,7 @@ func (ldSync *LDAPServerStateSyncer) Work() { // Remove any active sessions this user may have if len(emailsToPurge) > 0 { - _, err = ldSync.q.Exec("DELETE FROM ldap_sessions WHERE user_email = ANY($1)", pq.Array(emailsToPurge)) + _, err = tx.ExecContext(ctx, "DELETE FROM ldap_sessions WHERE user_email = ANY($1)", pq.Array(emailsToPurge)) if err != nil { return err } @@ -210,7 +210,7 @@ func (ldSync *LDAPServerStateSyncer) Work() { // Remove any active API tokens this user may have if len(apiTokenEmailsToPurge) > 0 { - _, err = ldSync.q.Exec("DELETE FROM ldap_user_api_tokens WHERE user_email = ANY($1)", pq.Array(apiTokenEmailsToPurge)) + _, err = tx.ExecContext(ctx, "DELETE FROM ldap_user_api_tokens WHERE user_email = ANY($1)", pq.Array(apiTokenEmailsToPurge)) if err != nil { return err } @@ -235,14 +235,14 @@ func (ldSync *LDAPServerStateSyncer) Work() { if len(emailValues) != 0 { // Set new role state for all rows in single Exec query := fmt.Sprintf("UPDATE ldap_sessions SET user_role = CASE %s ELSE user_role END", queryWhenClause) - _, err = ldSync.q.Exec(query, emailValues...) + _, err = tx.ExecContext(ctx, query, emailValues...) if err != nil { return err } // Update role of API tokens as well query = fmt.Sprintf("UPDATE ldap_user_api_tokens SET user_role = CASE %s ELSE user_role END", queryWhenClause) - _, err = ldSync.q.Exec(query, emailValues...) + _, err = tx.ExecContext(ctx, query, emailValues...) if err != nil { return err } @@ -258,14 +258,14 @@ func (ldSync *LDAPServerStateSyncer) Work() { } // deleteStaleSessions deletes all ldap_sessions before the passed time. -func (ldSync *LDAPServerStateSyncer) deleteStaleSessions(before time.Time) error { - _, err := ldSync.q.Exec("DELETE FROM ldap_sessions WHERE created_at < $1", before) +func (ldSync *LDAPServerStateSyncer) deleteStaleSessions(ctx context.Context, before time.Time) error { + _, err := ldSync.ds.ExecContext(ctx, "DELETE FROM ldap_sessions WHERE created_at < $1", before) return err } // deleteStaleAPITokens deletes all ldap_user_api_tokens before the passed time. -func (ldSync *LDAPServerStateSyncer) deleteStaleAPITokens(before time.Time) error { - _, err := ldSync.q.Exec("DELETE FROM ldap_user_api_tokens WHERE created_at < $1", before) +func (ldSync *LDAPServerStateSyncer) deleteStaleAPITokens(ctx context.Context, before time.Time) error { + _, err := ldSync.ds.ExecContext(ctx, "DELETE FROM ldap_user_api_tokens WHERE created_at < $1", before) return err } diff --git a/core/sessions/localauth/reaper.go b/core/sessions/localauth/reaper.go index eef884367aa..7b91e4ce2c0 100644 --- a/core/sessions/localauth/reaper.go +++ b/core/sessions/localauth/reaper.go @@ -1,16 +1,17 @@ package localauth import ( - "database/sql" + "context" "time" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink/v2/core/logger" ) type sessionReaper struct { - db *sql.DB + ds sqlutil.DataSource config SessionReaperConfig lggr logger.Logger } @@ -21,9 +22,9 @@ type SessionReaperConfig interface { } // NewSessionReaper creates a reaper that cleans stale sessions from the store. -func NewSessionReaper(db *sql.DB, config SessionReaperConfig, lggr logger.Logger) *utils.SleeperTask { +func NewSessionReaper(ds sqlutil.DataSource, config SessionReaperConfig, lggr logger.Logger) *utils.SleeperTask { return utils.NewSleeperTask(&sessionReaper{ - db, + ds, config, lggr.Named("SessionReaper"), }) @@ -34,16 +35,17 @@ func (sr *sessionReaper) Name() string { } func (sr *sessionReaper) Work() { + ctx := context.Background() //TODO https://smartcontract-it.atlassian.net/browse/BCF-2887 recordCreationStaleThreshold := sr.config.SessionReaperExpiration().Before( sr.config.SessionTimeout().Before(time.Now())) - err := sr.deleteStaleSessions(recordCreationStaleThreshold) + err := sr.deleteStaleSessions(ctx, recordCreationStaleThreshold) if err != nil { sr.lggr.Error("unable to reap stale sessions: ", err) } } // DeleteStaleSessions deletes all sessions before the passed time. -func (sr *sessionReaper) deleteStaleSessions(before time.Time) error { - _, err := sr.db.Exec("DELETE FROM sessions WHERE last_used < $1", before) +func (sr *sessionReaper) deleteStaleSessions(ctx context.Context, before time.Time) error { + _, err := sr.ds.ExecContext(ctx, "DELETE FROM sessions WHERE last_used < $1", before) return err } diff --git a/core/sessions/localauth/reaper_test.go b/core/sessions/localauth/reaper_test.go index 47413c5fc62..806c9448682 100644 --- a/core/sessions/localauth/reaper_test.go +++ b/core/sessions/localauth/reaper_test.go @@ -37,7 +37,7 @@ func TestSessionReaper_ReapSessions(t *testing.T) { lggr := logger.TestLogger(t) orm := localauth.NewORM(db, config.SessionTimeout().Duration(), lggr, audit.NoopLogger) - r := localauth.NewSessionReaper(db.DB, config, lggr) + r := localauth.NewSessionReaper(db, config, lggr) t.Cleanup(func() { assert.NoError(t, r.Stop()) }) diff --git a/core/store/migrate/migrate.go b/core/store/migrate/migrate.go index aff3229e92a..c8f70e87383 100644 --- a/core/store/migrate/migrate.go +++ b/core/store/migrate/migrate.go @@ -9,13 +9,12 @@ import ( "strconv" "strings" - "github.com/jmoiron/sqlx" pkgerrors "github.com/pkg/errors" "github.com/pressly/goose/v3" "gopkg.in/guregu/null.v4" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink/v2/core/config/env" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/store/migrate/migrations" // Invoke init() functions within migrations pkg. @@ -36,7 +35,7 @@ func init() { } // Ensure we migrated from v1 migrations to goose_migrations -func ensureMigrated(ctx context.Context, db *sql.DB, lggr logger.Logger) error { +func ensureMigrated(ctx context.Context, db *sql.DB) error { sqlxDB := pg.WrapDbWithSqlx(db) var names []string err := sqlxDB.SelectContext(ctx, &names, `SELECT id FROM migrations`) @@ -44,12 +43,10 @@ func ensureMigrated(ctx context.Context, db *sql.DB, lggr logger.Logger) error { // already migrated return nil } - err = pg.SqlTransaction(ctx, db, lggr, func(tx *sqlx.Tx) error { - // ensure that no legacy job specs are present: we _must_ bail out early if - // so because otherwise we run the risk of dropping working jobs if the - // user has not read the release notes - return migrations.CheckNoLegacyJobs(tx.Tx) - }) + // ensure that no legacy job specs are present: we _must_ bail out early if + // so because otherwise we run the risk of dropping working jobs if the + // user has not read the release notes + err = migrations.CheckNoLegacyJobs(ctx, db) if err != nil { return err } @@ -66,14 +63,14 @@ func ensureMigrated(ctx context.Context, db *sql.DB, lggr logger.Logger) error { } // ensure a goose migrations table exists with it's initial v0 - if _, err = goose.GetDBVersion(db); err != nil { + if _, err = goose.GetDBVersionContext(ctx, db); err != nil { return err } // insert records for existing migrations //nolint sql := fmt.Sprintf(`INSERT INTO %s (version_id, is_applied) VALUES ($1, true);`, goose.TableName()) - return pg.SqlTransaction(ctx, db, lggr, func(tx *sqlx.Tx) error { + return sqlutil.TransactDataSource(ctx, sqlxDB, nil, func(tx sqlutil.DataSource) error { for _, name := range names { var id int64 // the first migration doesn't follow the naming convention @@ -92,18 +89,18 @@ func ensureMigrated(ctx context.Context, db *sql.DB, lggr logger.Logger) error { } } - if _, err = db.Exec(sql, id); err != nil { + if _, err = tx.ExecContext(ctx, sql, id); err != nil { return err } } - _, err = db.Exec("DROP TABLE migrations;") + _, err = tx.ExecContext(ctx, "DROP TABLE migrations;") return err }) } -func Migrate(ctx context.Context, db *sql.DB, lggr logger.Logger) error { - if err := ensureMigrated(ctx, db, lggr); err != nil { +func Migrate(ctx context.Context, db *sql.DB) error { + if err := ensureMigrated(ctx, db); err != nil { return err } // WithAllowMissing is necessary when upgrading from 0.10.14 since it @@ -111,8 +108,8 @@ func Migrate(ctx context.Context, db *sql.DB, lggr logger.Logger) error { return goose.Up(db, MIGRATIONS_DIR, goose.WithAllowMissing()) } -func Rollback(ctx context.Context, db *sql.DB, lggr logger.Logger, version null.Int) error { - if err := ensureMigrated(ctx, db, lggr); err != nil { +func Rollback(ctx context.Context, db *sql.DB, version null.Int) error { + if err := ensureMigrated(ctx, db); err != nil { return err } if version.Valid { @@ -121,15 +118,15 @@ func Rollback(ctx context.Context, db *sql.DB, lggr logger.Logger, version null. return goose.Down(db, MIGRATIONS_DIR) } -func Current(ctx context.Context, db *sql.DB, lggr logger.Logger) (int64, error) { - if err := ensureMigrated(ctx, db, lggr); err != nil { +func Current(ctx context.Context, db *sql.DB) (int64, error) { + if err := ensureMigrated(ctx, db); err != nil { return -1, err } return goose.EnsureDBVersion(db) } -func Status(ctx context.Context, db *sql.DB, lggr logger.Logger) error { - if err := ensureMigrated(ctx, db, lggr); err != nil { +func Status(ctx context.Context, db *sql.DB) error { + if err := ensureMigrated(ctx, db); err != nil { return err } return goose.Status(db, MIGRATIONS_DIR) diff --git a/core/store/migrate/migrate_test.go b/core/store/migrate/migrate_test.go index 3c0c2dc2158..8169368eb1f 100644 --- a/core/store/migrate/migrate_test.go +++ b/core/store/migrate/migrate_test.go @@ -21,11 +21,9 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/store/migrate" "github.com/smartcontractkit/chainlink/v2/core/store/models" @@ -79,13 +77,13 @@ func TestMigrate_0100_BootstrapConfigs(t *testing.T) { pipelineORM := pipeline.NewORM(db, lggr, cfg.JobPipeline().MaxSuccessfulRuns()) ctx := testutils.Context(t) - pipelineID, err := pipelineORM.CreateSpec(ctx, nil, pipeline.Pipeline{}, 0) + pipelineID, err := pipelineORM.CreateSpec(ctx, pipeline.Pipeline{}, 0) require.NoError(t, err) - pipelineID2, err := pipelineORM.CreateSpec(ctx, nil, pipeline.Pipeline{}, 0) + pipelineID2, err := pipelineORM.CreateSpec(ctx, pipeline.Pipeline{}, 0) require.NoError(t, err) - nonBootstrapPipelineID, err := pipelineORM.CreateSpec(ctx, nil, pipeline.Pipeline{}, 0) + nonBootstrapPipelineID, err := pipelineORM.CreateSpec(ctx, pipeline.Pipeline{}, 0) require.NoError(t, err) - newFormatBoostrapPipelineID2, err := pipelineORM.CreateSpec(ctx, nil, pipeline.Pipeline{}, 0) + newFormatBoostrapPipelineID2, err := pipelineORM.CreateSpec(ctx, pipeline.Pipeline{}, 0) require.NoError(t, err) // OCR2 struct at migration v0099 @@ -392,25 +390,24 @@ func TestMigrate_101_GenericOCR2(t *testing.T) { func TestMigrate(t *testing.T) { ctx := testutils.Context(t) - lggr := logger.TestLogger(t) _, db := heavyweight.FullTestDBEmptyV2(t, nil) err := goose.UpTo(db.DB, migrationDir, 100) require.NoError(t, err) - err = migrate.Status(ctx, db.DB, lggr) + err = migrate.Status(ctx, db.DB) require.NoError(t, err) - ver, err := migrate.Current(ctx, db.DB, lggr) + ver, err := migrate.Current(ctx, db.DB) require.NoError(t, err) require.Equal(t, int64(100), ver) - err = migrate.Migrate(ctx, db.DB, lggr) + err = migrate.Migrate(ctx, db.DB) require.NoError(t, err) - err = migrate.Rollback(ctx, db.DB, lggr, null.IntFrom(99)) + err = migrate.Rollback(ctx, db.DB, null.IntFrom(99)) require.NoError(t, err) - ver, err = migrate.Current(ctx, db.DB, lggr) + ver, err = migrate.Current(ctx, db.DB) require.NoError(t, err) require.Equal(t, int64(99), ver) } @@ -543,6 +540,7 @@ func TestNoTriggers(t *testing.T) { } func BenchmarkBackfillingRecordsWithMigration202(b *testing.B) { + ctx := testutils.Context(b) previousMigration := int64(201) backfillMigration := int64(202) chainCount := 2 @@ -555,7 +553,6 @@ func BenchmarkBackfillingRecordsWithMigration202(b *testing.B) { err := goose.UpTo(db.DB, migrationDir, previousMigration) require.NoError(b, err) - q := pg.NewQ(db, logger.NullLogger, pgtest.NewQConfig(true)) for j := 0; j < chainCount; j++ { // Insert 100_000 block to database, can't do all at once, so batching by 10k var blocks []logpoller.LogPollerBlock @@ -574,7 +571,7 @@ func BenchmarkBackfillingRecordsWithMigration202(b *testing.B) { end = maxLogsSize } - err = q.ExecQNamed(` + _, err = db.NamedExecContext(ctx, ` INSERT INTO evm.log_poller_blocks (evm_chain_id, block_hash, block_number, finalized_block_number, block_timestamp, created_at) VALUES @@ -600,7 +597,7 @@ func BenchmarkBackfillingRecordsWithMigration202(b *testing.B) { err = goose.DownTo(db.DB, migrationDir, previousMigration) require.NoError(b, err) - err = q.ExecQ(` + _, err = db.ExecContext(ctx, ` UPDATE evm.log_poller_blocks SET finalized_block_number = 0`) require.NoError(b, err) diff --git a/core/store/migrate/migrations/0054_remove_legacy_pipeline.go b/core/store/migrate/migrations/0054_remove_legacy_pipeline.go index 924d32308b8..b5ddcccd89b 100644 --- a/core/store/migrate/migrations/0054_remove_legacy_pipeline.go +++ b/core/store/migrate/migrations/0054_remove_legacy_pipeline.go @@ -32,9 +32,13 @@ func init() { goose.AddMigrationContext(Up54, Down54) } +type queryer interface { + QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row +} + // nolint func Up54(ctx context.Context, tx *sql.Tx) error { - if err := CheckNoLegacyJobs(tx); err != nil { + if err := CheckNoLegacyJobs(ctx, tx); err != nil { return err } if _, err := tx.ExecContext(ctx, up54); err != nil { @@ -49,9 +53,9 @@ func Down54(ctx context.Context, tx *sql.Tx) error { } // CheckNoLegacyJobs ensures that there are no legacy job specs -func CheckNoLegacyJobs(tx *sql.Tx) error { +func CheckNoLegacyJobs(ctx context.Context, ds queryer) error { var count int - if err := tx.QueryRow(`SELECT COUNT(*) FROM job_specs WHERE deleted_at IS NULL`).Scan(&count); err != nil { + if err := ds.QueryRowContext(ctx, `SELECT COUNT(*) FROM job_specs WHERE deleted_at IS NULL`).Scan(&count); err != nil { return err } if count > 0 { diff --git a/core/web/bridge_types_controller.go b/core/web/bridge_types_controller.go index 1c9fd7365f7..c787ca2fb54 100644 --- a/core/web/bridge_types_controller.go +++ b/core/web/bridge_types_controller.go @@ -213,7 +213,7 @@ func (btc *BridgeTypesController) Destroy(c *gin.Context) { jsonAPIError(c, http.StatusInternalServerError, fmt.Errorf("error searching for bridge: %+v", err)) return } - jobsUsingBridge, err := btc.App.JobORM().FindJobIDsWithBridge(name) + jobsUsingBridge, err := btc.App.JobORM().FindJobIDsWithBridge(ctx, name) if err != nil { jsonAPIError(c, http.StatusInternalServerError, fmt.Errorf("error searching for associated v2 jobs: %+v", err)) return diff --git a/core/web/eth_keys_controller_test.go b/core/web/eth_keys_controller_test.go index 09a3eb5fa1e..34cde6f6a64 100644 --- a/core/web/eth_keys_controller_test.go +++ b/core/web/eth_keys_controller_test.go @@ -425,8 +425,7 @@ func TestETHKeysController_ChainSuccess_ResetWithAbandon(t *testing.T) { }) assert.NoError(t, err) - db := app.GetSqlxDB() - txStore := txmgr.NewTxStore(db, logger.TestLogger(t)) + txStore := txmgr.NewTxStore(app.GetDB(), logger.TestLogger(t)) txes, err := txStore.FindTxesByFromAddressAndState(testutils.Context(t), addr, "fatal_error") require.NoError(t, err) diff --git a/core/web/evm_transactions_controller_test.go b/core/web/evm_transactions_controller_test.go index a4dd21c9f03..3eb667bc6f8 100644 --- a/core/web/evm_transactions_controller_test.go +++ b/core/web/evm_transactions_controller_test.go @@ -25,8 +25,8 @@ func TestTransactionsController_Index_Success(t *testing.T) { ctx := testutils.Context(t) require.NoError(t, app.Start(ctx)) - db := app.GetSqlxDB() - txStore := cltest.NewTestTxStore(t, app.GetSqlxDB()) + db := app.GetDB() + txStore := cltest.NewTestTxStore(t, app.GetDB()) ethKeyStore := cltest.NewKeyStore(t, db).Eth() client := app.NewHTTPClient(nil) _, from := cltest.MustInsertRandomKey(t, ethKeyStore) @@ -84,7 +84,7 @@ func TestTransactionsController_Show_Success(t *testing.T) { ctx := testutils.Context(t) require.NoError(t, app.Start(ctx)) - txStore := cltest.NewTestTxStore(t, app.GetSqlxDB()) + txStore := cltest.NewTestTxStore(t, app.GetDB()) client := app.NewHTTPClient(nil) _, from := cltest.MustInsertRandomKey(t, app.KeyStore.Eth()) @@ -118,7 +118,7 @@ func TestTransactionsController_Show_NotFound(t *testing.T) { ctx := testutils.Context(t) require.NoError(t, app.Start(ctx)) - txStore := cltest.NewTestTxStore(t, app.GetSqlxDB()) + txStore := cltest.NewTestTxStore(t, app.GetDB()) client := app.NewHTTPClient(nil) _, from := cltest.MustInsertRandomKey(t, app.KeyStore.Eth()) tx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 1, from) diff --git a/core/web/evm_transfer_controller_test.go b/core/web/evm_transfer_controller_test.go index bfac6752f51..fff30a7df31 100644 --- a/core/web/evm_transfer_controller_test.go +++ b/core/web/evm_transfer_controller_test.go @@ -10,9 +10,8 @@ import ( "testing" "time" - "github.com/jmoiron/sqlx" - commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" @@ -72,7 +71,7 @@ func TestTransfersController_CreateSuccess_From(t *testing.T) { assert.Equal(t, http.StatusOK, resp.StatusCode) assert.Len(t, errors.Errors, 0) - validateTxCount(t, app.GetSqlxDB(), 1) + validateTxCount(t, app.GetDB(), 1) } func TestTransfersController_CreateSuccess_From_WEI(t *testing.T) { @@ -113,7 +112,7 @@ func TestTransfersController_CreateSuccess_From_WEI(t *testing.T) { assert.Equal(t, http.StatusOK, resp.StatusCode) assert.Len(t, errors.Errors, 0) - validateTxCount(t, app.GetSqlxDB(), 1) + validateTxCount(t, app.GetDB(), 1) } func TestTransfersController_CreateSuccess_From_BalanceMonitorDisabled(t *testing.T) { @@ -159,7 +158,7 @@ func TestTransfersController_CreateSuccess_From_BalanceMonitorDisabled(t *testin assert.Equal(t, http.StatusOK, resp.StatusCode) assert.Len(t, errors.Errors, 0) - validateTxCount(t, app.GetSqlxDB(), 1) + validateTxCount(t, app.GetDB(), 1) } func TestTransfersController_TransferZeroAddressError(t *testing.T) { @@ -327,7 +326,7 @@ func TestTransfersController_CreateSuccess_eip1559(t *testing.T) { err = web.ParseJSONAPIResponse(cltest.ParseResponseBody(t, resp), &resource) assert.NoError(t, err) - validateTxCount(t, app.GetSqlxDB(), 1) + validateTxCount(t, app.GetDB(), 1) // check returned data assert.NotEmpty(t, resource.Hash) @@ -398,8 +397,8 @@ func TestTransfersController_FindTxAttempt(t *testing.T) { }) } -func validateTxCount(t *testing.T, db *sqlx.DB, count int) { - txStore := txmgr.NewTxStore(db, logger.TestLogger(t)) +func validateTxCount(t *testing.T, ds sqlutil.DataSource, count int) { + txStore := txmgr.NewTxStore(ds, logger.TestLogger(t)) txes, err := txStore.GetAllTxes(testutils.Context(t)) require.NoError(t, err) diff --git a/core/web/evm_tx_attempts_controller_test.go b/core/web/evm_tx_attempts_controller_test.go index a92c8293a3f..f277f1f37bf 100644 --- a/core/web/evm_tx_attempts_controller_test.go +++ b/core/web/evm_tx_attempts_controller_test.go @@ -20,7 +20,7 @@ func TestTxAttemptsController_Index_Success(t *testing.T) { app := cltest.NewApplicationWithKey(t) require.NoError(t, app.Start(testutils.Context(t))) - txStore := cltest.NewTestTxStore(t, app.GetSqlxDB()) + txStore := cltest.NewTestTxStore(t, app.GetDB()) client := app.NewHTTPClient(nil) _, from := cltest.MustInsertRandomKey(t, app.KeyStore.Eth()) diff --git a/core/web/external_initiators_controller_test.go b/core/web/external_initiators_controller_test.go index 3c1425bcfdd..a79909c5864 100644 --- a/core/web/external_initiators_controller_test.go +++ b/core/web/external_initiators_controller_test.go @@ -75,7 +75,7 @@ func TestExternalInitiatorsController_Index(t *testing.T) { client := app.NewHTTPClient(nil) - db := app.GetSqlxDB() + db := app.GetDB() borm := bridges.NewORM(db) eiFoo := cltest.MustInsertExternalInitiatorWithOpts(t, borm, cltest.ExternalInitiatorOpts{ diff --git a/core/web/jobs_controller.go b/core/web/jobs_controller.go index 0808422cca7..5ca00476007 100644 --- a/core/web/jobs_controller.go +++ b/core/web/jobs_controller.go @@ -26,7 +26,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/streams" "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrfcommon" "github.com/smartcontractkit/chainlink/v2/core/services/webhook" @@ -48,7 +47,7 @@ func (jc *JobsController) Index(c *gin.Context, size, page, offset int) { size = 1000 } - jobs, count, err := jc.App.JobORM().FindJobs(offset, size) + jobs, count, err := jc.App.JobORM().FindJobs(c.Request.Context(), offset, size) if err != nil { jsonAPIError(c, http.StatusInternalServerError, err) return @@ -66,14 +65,15 @@ func (jc *JobsController) Index(c *gin.Context, size, page, offset int) { // Example: // "GET /jobs/:ID" func (jc *JobsController) Show(c *gin.Context) { + ctx := c.Request.Context() var err error jobSpec := job.Job{} if externalJobID, pErr := uuid.Parse(c.Param("ID")); pErr == nil { // Find a job by external job ID - jobSpec, err = jc.App.JobORM().FindJobByExternalJobID(externalJobID, pg.WithParentCtx(c.Request.Context())) + jobSpec, err = jc.App.JobORM().FindJobByExternalJobID(ctx, externalJobID) } else if pErr = jobSpec.SetID(c.Param("ID")); pErr == nil { // Find a job by job ID - jobSpec, err = jc.App.JobORM().FindJobTx(c, jobSpec.ID) + jobSpec, err = jc.App.JobORM().FindJobTx(ctx, jobSpec.ID) } else { jsonAPIError(c, http.StatusUnprocessableEntity, pErr) return @@ -242,7 +242,7 @@ func (jc *JobsController) validateJobSpec(ctx context.Context, tomlString string case job.VRF: jb, err = vrfcommon.ValidatedVRFSpec(tomlString) case job.Webhook: - jb, err = webhook.ValidatedWebhookSpec(tomlString, jc.App.GetExternalInitiatorManager()) + jb, err = webhook.ValidatedWebhookSpec(ctx, tomlString, jc.App.GetExternalInitiatorManager()) case job.BlockhashStore: jb, err = blockhashstore.ValidatedSpec(tomlString) case job.BlockHeaderFeeder: diff --git a/core/web/jobs_controller_test.go b/core/web/jobs_controller_test.go index 9c7b529b6bf..bade8fe293b 100644 --- a/core/web/jobs_controller_test.go +++ b/core/web/jobs_controller_test.go @@ -24,8 +24,7 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - "github.com/jmoiron/sqlx" - + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/utils" evmclimocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" @@ -37,7 +36,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/vrfkey" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/testdata/testspecs" "github.com/smartcontractkit/chainlink/v2/core/utils/tomlutils" "github.com/smartcontractkit/chainlink/v2/core/web" @@ -129,7 +127,7 @@ func TestJobController_Create_DirectRequest_Fast(t *testing.T) { }(i) } wg.Wait() - cltest.AssertCount(t, app.GetSqlxDB(), "direct_request_specs", int64(n)) + cltest.AssertCount(t, app.GetDB(), "direct_request_specs", int64(n)) } func mustInt32FromString(t *testing.T, s string) int32 { @@ -141,7 +139,7 @@ func mustInt32FromString(t *testing.T, s string) int32 { func TestJobController_Create_HappyPath(t *testing.T) { ctx := testutils.Context(t) app, client := setupJobsControllerTests(t) - b1, b2 := setupBridges(t, app.GetSqlxDB(), app.GetConfig().Database()) + b1, b2 := setupBridges(t, app.GetDB()) require.NoError(t, app.KeyStore.OCR().Add(ctx, cltest.DefaultOCRKey)) var pks []vrfkey.KeyV2 var k []p2pkey.KeyV2 @@ -220,7 +218,8 @@ func TestJobController_Create_HappyPath(t *testing.T) { // services failed to start require.Contains(t, errs.Errors[0].Detail, "no contract code at given address") // but the job should still exist - jb, err := jorm.FindJobByExternalJobID(uuid.MustParse(nameAndExternalJobID)) + ctx := testutils.Context(t) + jb, err := jorm.FindJobByExternalJobID(ctx, uuid.MustParse(nameAndExternalJobID)) require.NoError(t, err) require.NotNil(t, jb.KeeperSpec) @@ -333,7 +332,8 @@ func TestJobController_Create_HappyPath(t *testing.T) { // services failed to start require.Contains(t, errs.Errors[0].Detail, "no contract code at given address") // but the job should still exist - jb, err := jorm.FindJobByExternalJobID(uuid.MustParse(nameAndExternalJobID)) + ctx := testutils.Context(t) + jb, err := jorm.FindJobByExternalJobID(ctx, uuid.MustParse(nameAndExternalJobID)) require.NoError(t, err) require.NotNil(t, jb.FluxMonitorSpec) @@ -481,8 +481,8 @@ func TestJobsController_Create_WebhookSpec(t *testing.T) { app := cltest.NewApplicationEVMDisabled(t) require.NoError(t, app.Start(testutils.Context(t))) - _, fetchBridge := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{}) - _, submitBridge := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{}) + _, fetchBridge := cltest.MustCreateBridge(t, app.GetDB(), cltest.BridgeOpts{}) + _, submitBridge := cltest.MustCreateBridge(t, app.GetDB(), cltest.BridgeOpts{}) client := app.NewHTTPClient(nil) @@ -620,10 +620,10 @@ func TestJobsController_Update_HappyPath(t *testing.T) { app := cltest.NewApplicationWithConfigAndKey(t, cfg, cltest.DefaultP2PKey) require.NoError(t, app.KeyStore.OCR().Add(ctx, cltest.DefaultOCRKey)) - require.NoError(t, app.Start(testutils.Context(t))) + require.NoError(t, app.Start(ctx)) - _, bridge := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{}) - _, bridge2 := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{}) + _, bridge := cltest.MustCreateBridge(t, app.GetDB(), cltest.BridgeOpts{}) + _, bridge2 := cltest.MustCreateBridge(t, app.GetDB(), cltest.BridgeOpts{}) client := app.NewHTTPClient(nil) @@ -639,16 +639,16 @@ func TestJobsController_Update_HappyPath(t *testing.T) { // BCF-2095 // disable fkey checks until the end of the test transaction require.NoError(t, utils.JustError( - app.GetSqlxDB().Exec(`SET CONSTRAINTS job_spec_errors_v2_job_id_fkey DEFERRED`))) + app.GetDB().ExecContext(ctx, `SET CONSTRAINTS job_spec_errors_v2_job_id_fkey DEFERRED`))) var ocrSpec job.OCROracleSpec err = toml.Unmarshal([]byte(ocrspec.Toml()), &ocrSpec) require.NoError(t, err) jb.OCROracleSpec = &ocrSpec jb.OCROracleSpec.TransmitterAddress = &app.Keys[0].EIP55Address - err = app.AddJobV2(testutils.Context(t), &jb) + err = app.AddJobV2(ctx, &jb) require.NoError(t, err) - dbJb, err := app.JobORM().FindJob(testutils.Context(t), jb.ID) + dbJb, err := app.JobORM().FindJob(ctx, jb.ID) require.NoError(t, err) require.Equal(t, dbJb.Name.String, ocrspec.Name) @@ -666,7 +666,7 @@ func TestJobsController_Update_HappyPath(t *testing.T) { response, cleanup := client.Put("/v2/jobs/"+fmt.Sprintf("%v", jb.ID), bytes.NewReader(body)) t.Cleanup(cleanup) - dbJb, err = app.JobORM().FindJob(testutils.Context(t), jb.ID) + dbJb, err = app.JobORM().FindJob(ctx, jb.ID) require.NoError(t, err) require.Equal(t, dbJb.Name.String, updatedSpec.Name) @@ -686,8 +686,8 @@ func TestJobsController_Update_NonExistentID(t *testing.T) { require.NoError(t, app.KeyStore.OCR().Add(ctx, cltest.DefaultOCRKey)) require.NoError(t, app.Start(ctx)) - _, bridge := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{}) - _, bridge2 := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{}) + _, bridge := cltest.MustCreateBridge(t, app.GetDB(), cltest.BridgeOpts{}) + _, bridge2 := cltest.MustCreateBridge(t, app.GetDB(), cltest.BridgeOpts{}) client := app.NewHTTPClient(nil) @@ -754,9 +754,9 @@ func runDirectRequestJobSpecAssertions(t *testing.T, ereJobSpecFromFile job.Job, assert.Contains(t, ereJobSpecFromServer.DirectRequestSpec.UpdatedAt.String(), "20") } -func setupBridges(t *testing.T, db *sqlx.DB, cfg pg.QConfig) (b1, b2 string) { - _, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}) - _, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}) +func setupBridges(t *testing.T, ds sqlutil.DataSource) (b1, b2 string) { + _, bridge := cltest.MustCreateBridge(t, ds, cltest.BridgeOpts{}) + _, bridge2 := cltest.MustCreateBridge(t, ds, cltest.BridgeOpts{}) return bridge.Name.String(), bridge2.Name.String() } @@ -800,8 +800,8 @@ func setupJobSpecsControllerTestsWithJobs(t *testing.T) (*cltest.TestApplication require.NoError(t, app.KeyStore.OCR().Add(ctx, cltest.DefaultOCRKey)) require.NoError(t, app.Start(ctx)) - _, bridge := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{}) - _, bridge2 := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{}) + _, bridge := cltest.MustCreateBridge(t, app.GetDB(), cltest.BridgeOpts{}) + _, bridge2 := cltest.MustCreateBridge(t, app.GetDB(), cltest.BridgeOpts{}) client := app.NewHTTPClient(nil) diff --git a/core/web/loader/feeds_manager.go b/core/web/loader/feeds_manager.go index fb894d38b6e..a29d510a09d 100644 --- a/core/web/loader/feeds_manager.go +++ b/core/web/loader/feeds_manager.go @@ -14,7 +14,7 @@ type feedsBatcher struct { app chainlink.Application } -func (b *feedsBatcher) loadByIDs(_ context.Context, keys dataloader.Keys) []*dataloader.Result { +func (b *feedsBatcher) loadByIDs(ctx context.Context, keys dataloader.Keys) []*dataloader.Result { // Create a map for remembering the order of keys passed in keyOrder := make(map[string]int, len(keys)) // Collect the keys to search for @@ -28,7 +28,7 @@ func (b *feedsBatcher) loadByIDs(_ context.Context, keys dataloader.Keys) []*dat } // Fetch the feeds managers - managers, err := b.app.GetFeedsService().ListManagersByIDs(managersIDs) + managers, err := b.app.GetFeedsService().ListManagersByIDs(ctx, managersIDs) if err != nil { return []*dataloader.Result{{Data: nil, Error: err}} } diff --git a/core/web/loader/feeds_manager_chain_config.go b/core/web/loader/feeds_manager_chain_config.go index 89d35919fd1..661edc33219 100644 --- a/core/web/loader/feeds_manager_chain_config.go +++ b/core/web/loader/feeds_manager_chain_config.go @@ -14,10 +14,10 @@ type feedsManagerChainConfigBatcher struct { app chainlink.Application } -func (b *feedsManagerChainConfigBatcher) loadByManagerIDs(_ context.Context, keys dataloader.Keys) []*dataloader.Result { +func (b *feedsManagerChainConfigBatcher) loadByManagerIDs(ctx context.Context, keys dataloader.Keys) []*dataloader.Result { ids, keyOrder := keyOrderInt64(keys) - cfgs, err := b.app.GetFeedsService().ListChainConfigsByManagerIDs(ids) + cfgs, err := b.app.GetFeedsService().ListChainConfigsByManagerIDs(ctx, ids) if err != nil { return []*dataloader.Result{{Data: nil, Error: err}} } diff --git a/core/web/loader/job.go b/core/web/loader/job.go index 11eb2c76814..a37c2809625 100644 --- a/core/web/loader/job.go +++ b/core/web/loader/job.go @@ -16,7 +16,7 @@ type jobBatcher struct { app chainlink.Application } -func (b *jobBatcher) loadByExternalJobIDs(_ context.Context, keys dataloader.Keys) []*dataloader.Result { +func (b *jobBatcher) loadByExternalJobIDs(ctx context.Context, keys dataloader.Keys) []*dataloader.Result { // Create a map for remembering the order of keys passed in keyOrder := make(map[string]int, len(keys)) // Collect the keys to search for @@ -33,7 +33,7 @@ func (b *jobBatcher) loadByExternalJobIDs(_ context.Context, keys dataloader.Key // Fetch the jobs var jobs []job.Job for _, id := range jobIDs { - job, err := b.app.JobORM().FindJobByExternalJobID(id) + job, err := b.app.JobORM().FindJobByExternalJobID(ctx, id) if err != nil { return []*dataloader.Result{{Data: nil, Error: err}} @@ -63,7 +63,7 @@ func (b *jobBatcher) loadByExternalJobIDs(_ context.Context, keys dataloader.Key return results } -func (b *jobBatcher) loadByPipelineSpecIDs(_ context.Context, keys dataloader.Keys) []*dataloader.Result { +func (b *jobBatcher) loadByPipelineSpecIDs(ctx context.Context, keys dataloader.Keys) []*dataloader.Result { // Create a map for remembering the order of keys passed in keyOrder := make(map[string]int, len(keys)) // Collect the keys to search for @@ -77,7 +77,7 @@ func (b *jobBatcher) loadByPipelineSpecIDs(_ context.Context, keys dataloader.Ke } // Fetch the jobs - jobs, err := b.app.JobORM().FindJobsByPipelineSpecIDs(plSpecIDs) + jobs, err := b.app.JobORM().FindJobsByPipelineSpecIDs(ctx, plSpecIDs) if err != nil { return []*dataloader.Result{{Data: nil, Error: err}} } diff --git a/core/web/loader/job_proposal.go b/core/web/loader/job_proposal.go index ac24e620f47..17fb6bc67c2 100644 --- a/core/web/loader/job_proposal.go +++ b/core/web/loader/job_proposal.go @@ -14,7 +14,7 @@ type jobProposalBatcher struct { app chainlink.Application } -func (b *jobProposalBatcher) loadByManagersIDs(_ context.Context, keys dataloader.Keys) []*dataloader.Result { +func (b *jobProposalBatcher) loadByManagersIDs(ctx context.Context, keys dataloader.Keys) []*dataloader.Result { // Create a map for remembering the order of keys passed in keyOrder := make(map[string]int, len(keys)) // Collect the keys to search for @@ -28,7 +28,7 @@ func (b *jobProposalBatcher) loadByManagersIDs(_ context.Context, keys dataloade keyOrder[key.String()] = ix } - jps, err := b.app.GetFeedsService().ListJobProposalsByManagersIDs(mgrsIDs) + jps, err := b.app.GetFeedsService().ListJobProposalsByManagersIDs(ctx, mgrsIDs) if err != nil { return []*dataloader.Result{{Data: nil, Error: err}} } diff --git a/core/web/loader/job_proposal_spec.go b/core/web/loader/job_proposal_spec.go index bb6720903dc..bff112268f8 100644 --- a/core/web/loader/job_proposal_spec.go +++ b/core/web/loader/job_proposal_spec.go @@ -14,10 +14,10 @@ type jobProposalSpecBatcher struct { app chainlink.Application } -func (b *jobProposalSpecBatcher) loadByJobProposalsIDs(_ context.Context, keys dataloader.Keys) []*dataloader.Result { +func (b *jobProposalSpecBatcher) loadByJobProposalsIDs(ctx context.Context, keys dataloader.Keys) []*dataloader.Result { ids, keyOrder := keyOrderInt64(keys) - specs, err := b.app.GetFeedsService().ListSpecsByJobProposalIDs(ids) + specs, err := b.app.GetFeedsService().ListSpecsByJobProposalIDs(ctx, ids) if err != nil { return []*dataloader.Result{{Data: nil, Error: err}} } diff --git a/core/web/loader/job_run.go b/core/web/loader/job_run.go index 691b27a3511..4367eec2c78 100644 --- a/core/web/loader/job_run.go +++ b/core/web/loader/job_run.go @@ -14,7 +14,7 @@ type jobRunBatcher struct { app chainlink.Application } -func (b *jobRunBatcher) loadByIDs(_ context.Context, keys dataloader.Keys) []*dataloader.Result { +func (b *jobRunBatcher) loadByIDs(ctx context.Context, keys dataloader.Keys) []*dataloader.Result { // Create a map for remembering the order of keys passed in keyOrder := make(map[string]int, len(keys)) // Collect the keys to search for @@ -29,7 +29,7 @@ func (b *jobRunBatcher) loadByIDs(_ context.Context, keys dataloader.Keys) []*da } // Fetch the runs - runs, err := b.app.JobORM().FindPipelineRunsByIDs(runIDs) + runs, err := b.app.JobORM().FindPipelineRunsByIDs(ctx, runIDs) if err != nil { return []*dataloader.Result{{Data: nil, Error: err}} } diff --git a/core/web/loader/job_spec_errors.go b/core/web/loader/job_spec_errors.go index 5ef23154d2e..5d558c52ec5 100644 --- a/core/web/loader/job_spec_errors.go +++ b/core/web/loader/job_spec_errors.go @@ -7,7 +7,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/utils/stringutils" ) @@ -29,7 +28,7 @@ func (b *jobSpecErrorsBatcher) loadByJobIDs(ctx context.Context, keys dataloader keyOrder[key.String()] = ix } - specErrors, err := b.app.JobORM().FindSpecErrorsByJobIDs(jobIDs, pg.WithParentCtx(ctx)) + specErrors, err := b.app.JobORM().FindSpecErrorsByJobIDs(ctx, jobIDs) if err != nil { return []*dataloader.Result{{Data: nil, Error: err}} } diff --git a/core/web/loader/loader_test.go b/core/web/loader/loader_test.go index d12a10a9e52..5e22c9afef6 100644 --- a/core/web/loader/loader_test.go +++ b/core/web/loader/loader_test.go @@ -125,7 +125,7 @@ func TestLoader_FeedsManagers(t *testing.T) { Name: "manager 3", } - fsvc.On("ListManagersByIDs", []int64{3, 1, 2, 5}).Return([]feeds.FeedsManager{ + fsvc.On("ListManagersByIDs", mock.Anything, []int64{3, 1, 2, 5}).Return([]feeds.FeedsManager{ mgr1, mgr2, mgr3, }, nil) app.On("GetFeedsService").Return(fsvc) @@ -167,7 +167,7 @@ func TestLoader_JobProposals(t *testing.T) { Status: feeds.JobProposalStatusRejected, } - fsvc.On("ListJobProposalsByManagersIDs", []int64{3, 1, 2}).Return([]feeds.JobProposal{ + fsvc.On("ListJobProposalsByManagersIDs", mock.Anything, []int64{3, 1, 2}).Return([]feeds.JobProposal{ jp1, jp3, jp2, }, nil) app.On("GetFeedsService").Return(fsvc) @@ -194,7 +194,7 @@ func TestLoader_JobRuns(t *testing.T) { run2 := pipeline.Run{ID: int64(2)} run3 := pipeline.Run{ID: int64(3)} - jobsORM.On("FindPipelineRunsByIDs", []int64{3, 1, 2}).Return([]pipeline.Run{ + jobsORM.On("FindPipelineRunsByIDs", mock.Anything, []int64{3, 1, 2}).Return([]pipeline.Run{ run3, run1, run2, }, nil) app.On("JobORM").Return(jobsORM) @@ -224,7 +224,7 @@ func TestLoader_JobsByPipelineSpecIDs(t *testing.T) { job2 := job.Job{ID: int32(3), PipelineSpecID: int32(2)} job3 := job.Job{ID: int32(4), PipelineSpecID: int32(3)} - jobsORM.On("FindJobsByPipelineSpecIDs", []int32{3, 1, 2}).Return([]job.Job{ + jobsORM.On("FindJobsByPipelineSpecIDs", mock.Anything, []int32{3, 1, 2}).Return([]job.Job{ job1, job2, job3, }, nil) app.On("JobORM").Return(jobsORM) @@ -247,7 +247,7 @@ func TestLoader_JobsByPipelineSpecIDs(t *testing.T) { app := coremocks.NewApplication(t) ctx := InjectDataloader(testutils.Context(t), app) - jobsORM.On("FindJobsByPipelineSpecIDs", []int32{3, 1, 2}).Return([]job.Job{}, sql.ErrNoRows) + jobsORM.On("FindJobsByPipelineSpecIDs", mock.Anything, []int32{3, 1, 2}).Return([]job.Job{}, sql.ErrNoRows) app.On("JobORM").Return(jobsORM) batcher := jobBatcher{app} @@ -274,7 +274,7 @@ func TestLoader_JobsByExternalJobIDs(t *testing.T) { ejID := uuid.New() job := job.Job{ID: int32(2), ExternalJobID: ejID} - jobsORM.On("FindJobByExternalJobID", ejID).Return(job, nil) + jobsORM.On("FindJobByExternalJobID", mock.Anything, ejID).Return(job, nil) app.On("JobORM").Return(jobsORM) batcher := jobBatcher{app} @@ -335,7 +335,7 @@ func TestLoader_SpecErrorsByJobID(t *testing.T) { specErr2 := job.SpecError{ID: int64(3), JobID: int32(2)} specErr3 := job.SpecError{ID: int64(4), JobID: int32(3)} - jobsORM.On("FindSpecErrorsByJobIDs", []int32{3, 1, 2}, mock.Anything).Return([]job.SpecError{ + jobsORM.On("FindSpecErrorsByJobIDs", mock.Anything, []int32{3, 1, 2}, mock.Anything).Return([]job.SpecError{ specErr1, specErr2, specErr3, }, nil) app.On("JobORM").Return(jobsORM) @@ -358,7 +358,7 @@ func TestLoader_SpecErrorsByJobID(t *testing.T) { app := coremocks.NewApplication(t) ctx := InjectDataloader(testutils.Context(t), app) - jobsORM.On("FindSpecErrorsByJobIDs", []int32{3, 1, 2}, mock.Anything).Return([]job.SpecError{}, sql.ErrNoRows) + jobsORM.On("FindSpecErrorsByJobIDs", mock.Anything, []int32{3, 1, 2}, mock.Anything).Return([]job.SpecError{}, sql.ErrNoRows) app.On("JobORM").Return(jobsORM) batcher := jobSpecErrorsBatcher{app} diff --git a/core/web/pipeline_job_spec_errors_controller_test.go b/core/web/pipeline_job_spec_errors_controller_test.go index 8ec77a84f05..9729bfac51d 100644 --- a/core/web/pipeline_job_spec_errors_controller_test.go +++ b/core/web/pipeline_job_spec_errors_controller_test.go @@ -17,7 +17,8 @@ func TestPipelineJobSpecErrorsController_Delete_2(t *testing.T) { description := "job spec error description" - require.NoError(t, app.JobORM().RecordError(jID, description)) + ctx := testutils.Context(t) + require.NoError(t, app.JobORM().RecordError(ctx, jID, description)) // FindJob -> find error j, err := app.JobORM().FindJob(testutils.Context(t), jID) diff --git a/core/web/pipeline_runs_controller.go b/core/web/pipeline_runs_controller.go index 1bd52b021c3..099f824e0c3 100644 --- a/core/web/pipeline_runs_controller.go +++ b/core/web/pipeline_runs_controller.go @@ -40,8 +40,9 @@ func (prc *PipelineRunsController) Index(c *gin.Context, size, page, offset int) var count int var err error + ctx := c.Request.Context() if id == "" { - pipelineRuns, count, err = prc.App.JobORM().PipelineRuns(nil, offset, size) + pipelineRuns, count, err = prc.App.JobORM().PipelineRuns(ctx, nil, offset, size) } else { jobSpec := job.Job{} err = jobSpec.SetID(c.Param("ID")) @@ -50,7 +51,7 @@ func (prc *PipelineRunsController) Index(c *gin.Context, size, page, offset int) return } - pipelineRuns, count, err = prc.App.JobORM().PipelineRuns(&jobSpec.ID, offset, size) + pipelineRuns, count, err = prc.App.JobORM().PipelineRuns(ctx, &jobSpec.ID, offset, size) } if err != nil { @@ -113,13 +114,13 @@ func (prc *PipelineRunsController) Create(c *gin.Context) { // Is it a UUID? Then process it as a webhook job jobUUID, err := uuid.Parse(idStr) if err == nil { - canRun, err2 := authorizer.CanRun(c.Request.Context(), prc.App.GetConfig().JobPipeline(), jobUUID) + canRun, err2 := authorizer.CanRun(ctx, prc.App.GetConfig().JobPipeline(), jobUUID) if err2 != nil { jsonAPIError(c, http.StatusInternalServerError, err2) return } if canRun { - jobRunID, err3 := prc.App.RunWebhookJobV2(c.Request.Context(), jobUUID, string(bodyBytes), jsonserializable.JSONSerializable{}) + jobRunID, err3 := prc.App.RunWebhookJobV2(ctx, jobUUID, string(bodyBytes), jsonserializable.JSONSerializable{}) if errors.Is(err3, webhook.ErrJobNotExists) { jsonAPIError(c, http.StatusNotFound, err3) return @@ -141,7 +142,7 @@ func (prc *PipelineRunsController) Create(c *gin.Context) { jobID64, err := strconv.ParseInt(idStr, 10, 32) if err == nil { jobID = int32(jobID64) - jobRunID, err := prc.App.RunJobV2(c.Request.Context(), jobID, nil) + jobRunID, err := prc.App.RunJobV2(ctx, jobID, nil) if err != nil { jsonAPIError(c, http.StatusInternalServerError, err) return diff --git a/core/web/pipeline_runs_controller_test.go b/core/web/pipeline_runs_controller_test.go index f6b4291a34f..e123df2bdb3 100644 --- a/core/web/pipeline_runs_controller_test.go +++ b/core/web/pipeline_runs_controller_test.go @@ -33,6 +33,7 @@ import ( func TestPipelineRunsController_CreateWithBody_HappyPath(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) ethClient := cltest.NewEthMocksWithStartupAssertions(t) cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { c.JobPipeline.HTTPRequest.DefaultTimeout = commonconfig.MustNewDuration(2 * time.Second) @@ -50,13 +51,13 @@ func TestPipelineRunsController_CreateWithBody_HappyPath(t *testing.T) { require.Equal(t, `{"result":"12345"}`, string(bs)) }) - _, bridge := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{URL: mockServer.URL}) + _, bridge := cltest.MustCreateBridge(t, app.GetDB(), cltest.BridgeOpts{URL: mockServer.URL}) // Add the job uuid := uuid.New() { tomlStr := fmt.Sprintf(testspecs.WebhookSpecWithBodyTemplate, uuid, bridge.Name.String()) - jb, err := webhook.ValidatedWebhookSpec(tomlStr, app.GetExternalInitiatorManager()) + jb, err := webhook.ValidatedWebhookSpec(ctx, tomlStr, app.GetExternalInitiatorManager()) require.NoError(t, err) err = app.AddJobV2(testutils.Context(t), &jb) @@ -88,6 +89,7 @@ func TestPipelineRunsController_CreateWithBody_HappyPath(t *testing.T) { func TestPipelineRunsController_CreateNoBody_HappyPath(t *testing.T) { t.Parallel() + ctx := testutils.Context(t) ethClient := cltest.NewEthMocksWithStartupAssertions(t) cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { c.JobPipeline.HTTPRequest.DefaultTimeout = commonconfig.MustNewDuration(2 * time.Second) @@ -100,7 +102,7 @@ func TestPipelineRunsController_CreateNoBody_HappyPath(t *testing.T) { // Setup the bridges mockServer := cltest.NewHTTPMockServer(t, 200, "POST", `{"data":{"result":"123.45"}}`) - _, bridge := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{URL: mockServer.URL}) + _, bridge := cltest.MustCreateBridge(t, app.GetDB(), cltest.BridgeOpts{URL: mockServer.URL}) mockServer = cltest.NewHTTPMockServerWithRequest(t, 200, `{}`, func(r *http.Request) { defer r.Body.Close() @@ -109,13 +111,13 @@ func TestPipelineRunsController_CreateNoBody_HappyPath(t *testing.T) { require.Equal(t, `{"result":"12345"}`, string(bs)) }) - _, submitBridge := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{URL: mockServer.URL}) + _, submitBridge := cltest.MustCreateBridge(t, app.GetDB(), cltest.BridgeOpts{URL: mockServer.URL}) // Add the job uuid := uuid.New() { tomlStr := testspecs.GetWebhookSpecNoBody(uuid, bridge.Name.String(), submitBridge.Name.String()) - jb, err := webhook.ValidatedWebhookSpec(tomlStr, app.GetExternalInitiatorManager()) + jb, err := webhook.ValidatedWebhookSpec(ctx, tomlStr, app.GetExternalInitiatorManager()) require.NoError(t, err) err = app.AddJobV2(testutils.Context(t), &jb) diff --git a/core/web/resolver/bridge_test.go b/core/web/resolver/bridge_test.go index 706d3fb6d5a..2244ddf3dac 100644 --- a/core/web/resolver/bridge_test.go +++ b/core/web/resolver/bridge_test.go @@ -418,7 +418,7 @@ func Test_DeleteBridgeMutation(t *testing.T) { f.Mocks.bridgeORM.On("FindBridge", mock.Anything, name).Return(bridge, nil) f.Mocks.bridgeORM.On("DeleteBridgeType", mock.Anything, &bridge).Return(nil) - f.Mocks.jobORM.On("FindJobIDsWithBridge", name.String()).Return([]int32{}, nil) + f.Mocks.jobORM.On("FindJobIDsWithBridge", mock.Anything, name.String()).Return([]int32{}, nil) f.App.On("JobORM").Return(f.Mocks.jobORM) f.App.On("BridgeORM").Return(f.Mocks.bridgeORM) }, @@ -481,7 +481,7 @@ func Test_DeleteBridgeMutation(t *testing.T) { }, before: func(f *gqlTestFramework) { f.Mocks.bridgeORM.On("FindBridge", mock.Anything, name).Return(bridges.BridgeType{}, nil) - f.Mocks.jobORM.On("FindJobIDsWithBridge", name.String()).Return([]int32{1}, nil) + f.Mocks.jobORM.On("FindJobIDsWithBridge", mock.Anything, name.String()).Return([]int32{1}, nil) f.App.On("BridgeORM").Return(f.Mocks.bridgeORM) f.App.On("JobORM").Return(f.Mocks.jobORM) }, diff --git a/core/web/resolver/feeds_manager_chain_config_test.go b/core/web/resolver/feeds_manager_chain_config_test.go index ae869b50874..31208aa0581 100644 --- a/core/web/resolver/feeds_manager_chain_config_test.go +++ b/core/web/resolver/feeds_manager_chain_config_test.go @@ -101,7 +101,7 @@ func Test_CreateFeedsManagerChainConfig(t *testing.T) { }, }, }).Return(cfgID, nil) - f.Mocks.feedsSvc.On("GetChainConfig", cfgID).Return(&feeds.ChainConfig{ + f.Mocks.feedsSvc.On("GetChainConfig", mock.Anything, cfgID).Return(&feeds.ChainConfig{ ID: cfgID, ChainType: feeds.ChainTypeEVM, ChainID: chainID, @@ -164,7 +164,7 @@ func Test_CreateFeedsManagerChainConfig(t *testing.T) { before: func(f *gqlTestFramework) { f.App.On("GetFeedsService").Return(f.Mocks.feedsSvc) f.Mocks.feedsSvc.On("CreateChainConfig", mock.Anything, mock.IsType(feeds.ChainConfig{})).Return(cfgID, nil) - f.Mocks.feedsSvc.On("GetChainConfig", cfgID).Return(nil, sql.ErrNoRows) + f.Mocks.feedsSvc.On("GetChainConfig", mock.Anything, cfgID).Return(nil, sql.ErrNoRows) }, query: mutation, variables: variables, @@ -211,7 +211,7 @@ func Test_DeleteFeedsManagerChainConfig(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("GetFeedsService").Return(f.Mocks.feedsSvc) - f.Mocks.feedsSvc.On("GetChainConfig", cfgID).Return(&feeds.ChainConfig{ + f.Mocks.feedsSvc.On("GetChainConfig", mock.Anything, cfgID).Return(&feeds.ChainConfig{ ID: cfgID, }, nil) f.Mocks.feedsSvc.On("DeleteChainConfig", mock.Anything, cfgID).Return(cfgID, nil) @@ -232,7 +232,7 @@ func Test_DeleteFeedsManagerChainConfig(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("GetFeedsService").Return(f.Mocks.feedsSvc) - f.Mocks.feedsSvc.On("GetChainConfig", cfgID).Return(nil, sql.ErrNoRows) + f.Mocks.feedsSvc.On("GetChainConfig", mock.Anything, cfgID).Return(nil, sql.ErrNoRows) }, query: mutation, variables: variables, @@ -249,7 +249,7 @@ func Test_DeleteFeedsManagerChainConfig(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("GetFeedsService").Return(f.Mocks.feedsSvc) - f.Mocks.feedsSvc.On("GetChainConfig", cfgID).Return(&feeds.ChainConfig{ + f.Mocks.feedsSvc.On("GetChainConfig", mock.Anything, cfgID).Return(&feeds.ChainConfig{ ID: cfgID, }, nil) f.Mocks.feedsSvc.On("DeleteChainConfig", mock.Anything, cfgID).Return(int64(0), sql.ErrNoRows) @@ -352,7 +352,7 @@ func Test_UpdateFeedsManagerChainConfig(t *testing.T) { }, }, }).Return(cfgID, nil) - f.Mocks.feedsSvc.On("GetChainConfig", cfgID).Return(&feeds.ChainConfig{ + f.Mocks.feedsSvc.On("GetChainConfig", mock.Anything, cfgID).Return(&feeds.ChainConfig{ ID: cfgID, AccountAddress: accountAddr, AdminAddress: adminAddr, @@ -413,7 +413,7 @@ func Test_UpdateFeedsManagerChainConfig(t *testing.T) { before: func(f *gqlTestFramework) { f.App.On("GetFeedsService").Return(f.Mocks.feedsSvc) f.Mocks.feedsSvc.On("UpdateChainConfig", mock.Anything, mock.IsType(feeds.ChainConfig{})).Return(cfgID, nil) - f.Mocks.feedsSvc.On("GetChainConfig", cfgID).Return(nil, sql.ErrNoRows) + f.Mocks.feedsSvc.On("GetChainConfig", mock.Anything, cfgID).Return(nil, sql.ErrNoRows) }, query: mutation, variables: variables, diff --git a/core/web/resolver/feeds_manager_test.go b/core/web/resolver/feeds_manager_test.go index 84558090da5..a3ea80a6443 100644 --- a/core/web/resolver/feeds_manager_test.go +++ b/core/web/resolver/feeds_manager_test.go @@ -42,14 +42,14 @@ func Test_FeedsManagers(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("GetFeedsService").Return(f.Mocks.feedsSvc) - f.Mocks.feedsSvc.On("ListJobProposalsByManagersIDs", []int64{1}).Return([]feeds.JobProposal{ + f.Mocks.feedsSvc.On("ListJobProposalsByManagersIDs", mock.Anything, []int64{1}).Return([]feeds.JobProposal{ { ID: int64(100), FeedsManagerID: int64(1), Status: feeds.JobProposalStatusApproved, }, }, nil) - f.Mocks.feedsSvc.On("ListManagers").Return([]feeds.FeedsManager{ + f.Mocks.feedsSvc.On("ListManagers", mock.Anything).Return([]feeds.FeedsManager{ { ID: 1, Name: "manager1", @@ -115,7 +115,7 @@ func Test_FeedsManager(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("GetFeedsService").Return(f.Mocks.feedsSvc) - f.Mocks.feedsSvc.On("GetManager", mgrID).Return(&feeds.FeedsManager{ + f.Mocks.feedsSvc.On("GetManager", mock.Anything, mgrID).Return(&feeds.FeedsManager{ ID: mgrID, Name: "manager1", URI: "localhost:2000", @@ -142,7 +142,7 @@ func Test_FeedsManager(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("GetFeedsService").Return(f.Mocks.feedsSvc) - f.Mocks.feedsSvc.On("GetManager", mgrID).Return(nil, sql.ErrNoRows) + f.Mocks.feedsSvc.On("GetManager", mock.Anything, mgrID).Return(nil, sql.ErrNoRows) }, query: query, result: ` @@ -219,7 +219,7 @@ func Test_CreateFeedsManager(t *testing.T) { URI: uri, PublicKey: *pubKey, }).Return(mgrID, nil) - f.Mocks.feedsSvc.On("GetManager", mgrID).Return(&feeds.FeedsManager{ + f.Mocks.feedsSvc.On("GetManager", mock.Anything, mgrID).Return(&feeds.FeedsManager{ ID: mgrID, Name: name, URI: uri, @@ -269,7 +269,7 @@ func Test_CreateFeedsManager(t *testing.T) { before: func(f *gqlTestFramework) { f.App.On("GetFeedsService").Return(f.Mocks.feedsSvc) f.Mocks.feedsSvc.On("RegisterManager", mock.Anything, mock.IsType(feeds.RegisterManagerParams{})).Return(mgrID, nil) - f.Mocks.feedsSvc.On("GetManager", mgrID).Return(nil, sql.ErrNoRows) + f.Mocks.feedsSvc.On("GetManager", mock.Anything, mgrID).Return(nil, sql.ErrNoRows) }, query: mutation, variables: variables, @@ -366,7 +366,7 @@ func Test_UpdateFeedsManager(t *testing.T) { URI: uri, PublicKey: *pubKey, }).Return(nil) - f.Mocks.feedsSvc.On("GetManager", mgrID).Return(&feeds.FeedsManager{ + f.Mocks.feedsSvc.On("GetManager", mock.Anything, mgrID).Return(&feeds.FeedsManager{ ID: mgrID, Name: name, URI: uri, @@ -397,7 +397,7 @@ func Test_UpdateFeedsManager(t *testing.T) { before: func(f *gqlTestFramework) { f.App.On("GetFeedsService").Return(f.Mocks.feedsSvc) f.Mocks.feedsSvc.On("UpdateManager", mock.Anything, mock.IsType(feeds.FeedsManager{})).Return(nil) - f.Mocks.feedsSvc.On("GetManager", mgrID).Return(nil, sql.ErrNoRows) + f.Mocks.feedsSvc.On("GetManager", mock.Anything, mgrID).Return(nil, sql.ErrNoRows) }, query: mutation, variables: variables, diff --git a/core/web/resolver/job.go b/core/web/resolver/job.go index cb79b0c6e63..e9855fdb8fe 100644 --- a/core/web/resolver/job.go +++ b/core/web/resolver/job.go @@ -113,7 +113,7 @@ func (r *JobResolver) Runs(ctx context.Context, args struct { limit = 100 } - ids, err := r.app.JobORM().FindPipelineRunIDsByJobID(r.j.ID, offset, limit) + ids, err := r.app.JobORM().FindPipelineRunIDsByJobID(ctx, r.j.ID, offset, limit) if err != nil { return nil, err } @@ -123,7 +123,7 @@ func (r *JobResolver) Runs(ctx context.Context, args struct { return nil, err } - count, err := r.app.JobORM().CountPipelineRunsByJobID(r.j.ID) + count, err := r.app.JobORM().CountPipelineRunsByJobID(ctx, r.j.ID) if err != nil { return nil, err } diff --git a/core/web/resolver/job_error_test.go b/core/web/resolver/job_error_test.go index 30d06289ed6..69899a3ec47 100644 --- a/core/web/resolver/job_error_test.go +++ b/core/web/resolver/job_error_test.go @@ -29,10 +29,10 @@ func TestResolver_JobErrors(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("JobORM").Return(f.Mocks.jobORM) - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{ + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{ ID: int32(1), }, nil) - f.Mocks.jobORM.On("FindSpecErrorsByJobIDs", []int32{1}, mock.Anything).Return([]job.SpecError{ + f.Mocks.jobORM.On("FindSpecErrorsByJobIDs", mock.Anything, []int32{1}, mock.Anything).Return([]job.SpecError{ { ID: errorID, Description: "no contract code at given address", @@ -124,7 +124,7 @@ func TestResolver_DismissJobError(t *testing.T) { name: "success", authenticated: true, before: func(f *gqlTestFramework) { - f.Mocks.jobORM.On("FindSpecError", id).Return(job.SpecError{ + f.Mocks.jobORM.On("FindSpecError", mock.Anything, id).Return(job.SpecError{ ID: id, Occurrences: 5, Description: "test-description", @@ -141,7 +141,7 @@ func TestResolver_DismissJobError(t *testing.T) { name: "not found on FindSpecError()", authenticated: true, before: func(f *gqlTestFramework) { - f.Mocks.jobORM.On("FindSpecError", id).Return(job.SpecError{}, sql.ErrNoRows) + f.Mocks.jobORM.On("FindSpecError", mock.Anything, id).Return(job.SpecError{}, sql.ErrNoRows) f.App.On("JobORM").Return(f.Mocks.jobORM) }, query: mutation, @@ -159,7 +159,7 @@ func TestResolver_DismissJobError(t *testing.T) { name: "not found on DismissError()", authenticated: true, before: func(f *gqlTestFramework) { - f.Mocks.jobORM.On("FindSpecError", id).Return(job.SpecError{}, nil) + f.Mocks.jobORM.On("FindSpecError", mock.Anything, id).Return(job.SpecError{}, nil) f.Mocks.jobORM.On("DismissError", mock.Anything, id).Return(sql.ErrNoRows) f.App.On("JobORM").Return(f.Mocks.jobORM) }, @@ -178,7 +178,7 @@ func TestResolver_DismissJobError(t *testing.T) { name: "generic error on FindSpecError()", authenticated: true, before: func(f *gqlTestFramework) { - f.Mocks.jobORM.On("FindSpecError", id).Return(job.SpecError{}, gError) + f.Mocks.jobORM.On("FindSpecError", mock.Anything, id).Return(job.SpecError{}, gError) f.App.On("JobORM").Return(f.Mocks.jobORM) }, query: mutation, @@ -197,7 +197,7 @@ func TestResolver_DismissJobError(t *testing.T) { name: "generic error on DismissError()", authenticated: true, before: func(f *gqlTestFramework) { - f.Mocks.jobORM.On("FindSpecError", id).Return(job.SpecError{}, nil) + f.Mocks.jobORM.On("FindSpecError", mock.Anything, id).Return(job.SpecError{}, nil) f.Mocks.jobORM.On("DismissError", mock.Anything, id).Return(gError) f.App.On("JobORM").Return(f.Mocks.jobORM) }, diff --git a/core/web/resolver/job_proposal_spec_test.go b/core/web/resolver/job_proposal_spec_test.go index 2681129b2ae..c65702c5622 100644 --- a/core/web/resolver/job_proposal_spec_test.go +++ b/core/web/resolver/job_proposal_spec_test.go @@ -53,7 +53,7 @@ func TestResolver_ApproveJobProposalSpec(t *testing.T) { before: func(f *gqlTestFramework) { f.App.On("GetFeedsService").Return(f.Mocks.feedsSvc) f.Mocks.feedsSvc.On("ApproveSpec", mock.Anything, specID, false).Return(nil) - f.Mocks.feedsSvc.On("GetSpec", specID).Return(&feeds.JobProposalSpec{ + f.Mocks.feedsSvc.On("GetSpec", mock.Anything, specID).Return(&feeds.JobProposalSpec{ ID: specID, }, nil) }, @@ -84,7 +84,7 @@ func TestResolver_ApproveJobProposalSpec(t *testing.T) { before: func(f *gqlTestFramework) { f.App.On("GetFeedsService").Return(f.Mocks.feedsSvc) f.Mocks.feedsSvc.On("ApproveSpec", mock.Anything, specID, false).Return(nil) - f.Mocks.feedsSvc.On("GetSpec", specID).Return(nil, sql.ErrNoRows) + f.Mocks.feedsSvc.On("GetSpec", mock.Anything, specID).Return(nil, sql.ErrNoRows) }, query: mutation, variables: variables, @@ -157,7 +157,7 @@ func TestResolver_CancelJobProposalSpec(t *testing.T) { before: func(f *gqlTestFramework) { f.App.On("GetFeedsService").Return(f.Mocks.feedsSvc) f.Mocks.feedsSvc.On("CancelSpec", mock.Anything, specID).Return(nil) - f.Mocks.feedsSvc.On("GetSpec", specID).Return(&feeds.JobProposalSpec{ + f.Mocks.feedsSvc.On("GetSpec", mock.Anything, specID).Return(&feeds.JobProposalSpec{ ID: specID, }, nil) @@ -189,7 +189,7 @@ func TestResolver_CancelJobProposalSpec(t *testing.T) { before: func(f *gqlTestFramework) { f.App.On("GetFeedsService").Return(f.Mocks.feedsSvc) f.Mocks.feedsSvc.On("CancelSpec", mock.Anything, specID).Return(nil) - f.Mocks.feedsSvc.On("GetSpec", specID).Return(nil, sql.ErrNoRows) + f.Mocks.feedsSvc.On("GetSpec", mock.Anything, specID).Return(nil, sql.ErrNoRows) }, query: mutation, variables: variables, @@ -245,7 +245,7 @@ func TestResolver_RejectJobProposalSpec(t *testing.T) { before: func(f *gqlTestFramework) { f.App.On("GetFeedsService").Return(f.Mocks.feedsSvc) f.Mocks.feedsSvc.On("RejectSpec", mock.Anything, specID).Return(nil) - f.Mocks.feedsSvc.On("GetSpec", specID).Return(&feeds.JobProposalSpec{ + f.Mocks.feedsSvc.On("GetSpec", mock.Anything, specID).Return(&feeds.JobProposalSpec{ ID: specID, }, nil) }, @@ -276,7 +276,7 @@ func TestResolver_RejectJobProposalSpec(t *testing.T) { before: func(f *gqlTestFramework) { f.App.On("GetFeedsService").Return(f.Mocks.feedsSvc) f.Mocks.feedsSvc.On("RejectSpec", mock.Anything, specID).Return(nil) - f.Mocks.feedsSvc.On("GetSpec", specID).Return(nil, sql.ErrNoRows) + f.Mocks.feedsSvc.On("GetSpec", mock.Anything, specID).Return(nil, sql.ErrNoRows) }, query: mutation, variables: variables, @@ -335,7 +335,7 @@ func TestResolver_UpdateJobProposalSpecDefinition(t *testing.T) { before: func(f *gqlTestFramework) { f.App.On("GetFeedsService").Return(f.Mocks.feedsSvc) f.Mocks.feedsSvc.On("UpdateSpecDefinition", mock.Anything, specID, "").Return(nil) - f.Mocks.feedsSvc.On("GetSpec", specID).Return(&feeds.JobProposalSpec{ + f.Mocks.feedsSvc.On("GetSpec", mock.Anything, specID).Return(&feeds.JobProposalSpec{ ID: specID, }, nil) }, @@ -367,7 +367,7 @@ func TestResolver_UpdateJobProposalSpecDefinition(t *testing.T) { before: func(f *gqlTestFramework) { f.App.On("GetFeedsService").Return(f.Mocks.feedsSvc) f.Mocks.feedsSvc.On("UpdateSpecDefinition", mock.Anything, specID, "").Return(nil) - f.Mocks.feedsSvc.On("GetSpec", specID).Return(nil, sql.ErrNoRows) + f.Mocks.feedsSvc.On("GetSpec", mock.Anything, specID).Return(nil, sql.ErrNoRows) }, query: mutation, variables: variables, @@ -446,7 +446,7 @@ func TestResolver_GetJobProposal_Spec(t *testing.T) { name: "success", authenticated: true, before: func(f *gqlTestFramework) { - f.Mocks.feedsSvc.On("GetJobProposal", jpID).Return(&feeds.JobProposal{ + f.Mocks.feedsSvc.On("GetJobProposal", mock.Anything, jpID).Return(&feeds.JobProposal{ ID: jpID, Status: feeds.JobProposalStatusApproved, FeedsManagerID: 1, @@ -454,7 +454,7 @@ func TestResolver_GetJobProposal_Spec(t *testing.T) { PendingUpdate: false, }, nil) f.Mocks.feedsSvc. - On("ListSpecsByJobProposalIDs", []int64{jpID}). + On("ListSpecsByJobProposalIDs", mock.Anything, []int64{jpID}). Return(specs, nil) f.App.On("GetFeedsService").Return(f.Mocks.feedsSvc) }, diff --git a/core/web/resolver/job_proposal_test.go b/core/web/resolver/job_proposal_test.go index 466ddd5d8ab..5544b39c936 100644 --- a/core/web/resolver/job_proposal_test.go +++ b/core/web/resolver/job_proposal_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/google/uuid" + "github.com/stretchr/testify/mock" "gopkg.in/guregu/null.v4" "github.com/smartcontractkit/chainlink/v2/core/services/feeds" @@ -64,13 +65,13 @@ func TestResolver_GetJobProposal(t *testing.T) { name: "success", authenticated: true, before: func(f *gqlTestFramework) { - f.Mocks.feedsSvc.On("ListManagersByIDs", []int64{1}).Return([]feeds.FeedsManager{ + f.Mocks.feedsSvc.On("ListManagersByIDs", mock.Anything, []int64{1}).Return([]feeds.FeedsManager{ { ID: 1, Name: "manager", }, }, nil) - f.Mocks.feedsSvc.On("GetJobProposal", jpID).Return(&feeds.JobProposal{ + f.Mocks.feedsSvc.On("GetJobProposal", mock.Anything, jpID).Return(&feeds.JobProposal{ ID: jpID, Name: null.StringFrom(name), Status: feeds.JobProposalStatusApproved, @@ -89,7 +90,7 @@ func TestResolver_GetJobProposal(t *testing.T) { name: "not found error", authenticated: true, before: func(f *gqlTestFramework) { - f.Mocks.feedsSvc.On("GetJobProposal", jpID).Return(nil, sql.ErrNoRows) + f.Mocks.feedsSvc.On("GetJobProposal", mock.Anything, jpID).Return(nil, sql.ErrNoRows) f.App.On("GetFeedsService").Return(f.Mocks.feedsSvc) }, query: query, diff --git a/core/web/resolver/job_run_test.go b/core/web/resolver/job_run_test.go index a35a2f66ac5..51631864e8c 100644 --- a/core/web/resolver/job_run_test.go +++ b/core/web/resolver/job_run_test.go @@ -40,7 +40,7 @@ func TestQuery_PaginatedJobRuns(t *testing.T) { name: "success", authenticated: true, before: func(f *gqlTestFramework) { - f.Mocks.jobORM.On("PipelineRuns", (*int32)(nil), PageDefaultOffset, PageDefaultLimit).Return([]pipeline.Run{ + f.Mocks.jobORM.On("PipelineRuns", mock.Anything, (*int32)(nil), PageDefaultOffset, PageDefaultLimit).Return([]pipeline.Run{ { ID: int64(200), }, @@ -64,7 +64,7 @@ func TestQuery_PaginatedJobRuns(t *testing.T) { name: "generic error on PipelineRuns()", authenticated: true, before: func(f *gqlTestFramework) { - f.Mocks.jobORM.On("PipelineRuns", (*int32)(nil), PageDefaultOffset, PageDefaultLimit).Return(nil, 0, gError) + f.Mocks.jobORM.On("PipelineRuns", mock.Anything, (*int32)(nil), PageDefaultOffset, PageDefaultLimit).Return(nil, 0, gError) f.App.On("JobORM").Return(f.Mocks.jobORM) }, query: query, @@ -131,7 +131,7 @@ func TestResolver_JobRun(t *testing.T) { name: "success", authenticated: true, before: func(f *gqlTestFramework) { - f.Mocks.jobORM.On("FindPipelineRunByID", int64(2)).Return(pipeline.Run{ + f.Mocks.jobORM.On("FindPipelineRunByID", mock.Anything, int64(2)).Return(pipeline.Run{ ID: 2, PipelineSpecID: 5, CreatedAt: f.Timestamp(), @@ -142,7 +142,7 @@ func TestResolver_JobRun(t *testing.T) { Outputs: outputs, State: pipeline.RunStatusErrored, }, nil) - f.Mocks.jobORM.On("FindJobsByPipelineSpecIDs", []int32{5}).Return([]job.Job{ + f.Mocks.jobORM.On("FindJobsByPipelineSpecIDs", mock.Anything, []int32{5}).Return([]job.Job{ { ID: 1, PipelineSpecID: 2, @@ -180,7 +180,7 @@ func TestResolver_JobRun(t *testing.T) { name: "not found error", authenticated: true, before: func(f *gqlTestFramework) { - f.Mocks.jobORM.On("FindPipelineRunByID", int64(2)).Return(pipeline.Run{}, sql.ErrNoRows) + f.Mocks.jobORM.On("FindPipelineRunByID", mock.Anything, int64(2)).Return(pipeline.Run{}, sql.ErrNoRows) f.App.On("JobORM").Return(f.Mocks.jobORM) }, query: query, @@ -197,7 +197,7 @@ func TestResolver_JobRun(t *testing.T) { name: "generic error on FindPipelineRunByID()", authenticated: true, before: func(f *gqlTestFramework) { - f.Mocks.jobORM.On("FindPipelineRunByID", int64(2)).Return(pipeline.Run{}, gError) + f.Mocks.jobORM.On("FindPipelineRunByID", mock.Anything, int64(2)).Return(pipeline.Run{}, gError) f.App.On("JobORM").Return(f.Mocks.jobORM) }, query: query, diff --git a/core/web/resolver/job_test.go b/core/web/resolver/job_test.go index e91e37b6903..0615e47a621 100644 --- a/core/web/resolver/job_test.go +++ b/core/web/resolver/job_test.go @@ -72,7 +72,7 @@ func TestResolver_Jobs(t *testing.T) { plnSpecID := int32(12) f.App.On("JobORM").Return(f.Mocks.jobORM) - f.Mocks.jobORM.On("FindJobs", 0, 50).Return([]job.Job{ + f.Mocks.jobORM.On("FindJobs", mock.Anything, 0, 50).Return([]job.Job{ { ID: 1, Name: null.StringFrom("job1"), @@ -89,13 +89,13 @@ func TestResolver_Jobs(t *testing.T) { }, }, 1, nil) f.Mocks.jobORM. - On("FindPipelineRunIDsByJobID", int32(1), 0, 50). + On("FindPipelineRunIDsByJobID", mock.Anything, int32(1), 0, 50). Return([]int64{200}, nil) f.Mocks.jobORM. - On("FindPipelineRunsByIDs", []int64{200}). + On("FindPipelineRunsByIDs", mock.Anything, []int64{200}). Return([]pipeline.Run{{ID: 200}}, nil) f.Mocks.jobORM. - On("CountPipelineRunsByJobID", int32(1)). + On("CountPipelineRunsByJobID", mock.Anything, int32(1)). Return(int32(1), nil) }, query: query, @@ -208,7 +208,7 @@ func TestResolver_Job(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("JobORM").Return(f.Mocks.jobORM) - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{ + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{ ID: 1, Name: null.StringFrom("job1"), SchemaVersion: 1, @@ -223,13 +223,13 @@ func TestResolver_Job(t *testing.T) { }, }, nil) f.Mocks.jobORM. - On("FindPipelineRunIDsByJobID", int32(1), 0, 50). + On("FindPipelineRunIDsByJobID", mock.Anything, int32(1), 0, 50). Return([]int64{200}, nil) f.Mocks.jobORM. - On("FindPipelineRunsByIDs", []int64{200}). + On("FindPipelineRunsByIDs", mock.Anything, []int64{200}). Return([]pipeline.Run{{ID: 200}}, nil) f.Mocks.jobORM. - On("CountPipelineRunsByJobID", int32(1)). + On("CountPipelineRunsByJobID", mock.Anything, int32(1)). Return(int32(1), nil) }, query: query, @@ -240,7 +240,7 @@ func TestResolver_Job(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("JobORM").Return(f.Mocks.jobORM) - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{}, sql.ErrNoRows) + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{}, sql.ErrNoRows) }, query: query, result: ` @@ -257,7 +257,7 @@ func TestResolver_Job(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("JobORM").Return(f.Mocks.jobORM) - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{ + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{ ID: 1, Name: null.StringFrom("job1"), SchemaVersion: 1, @@ -272,13 +272,13 @@ func TestResolver_Job(t *testing.T) { }, }, chains.ErrNoSuchChainID) f.Mocks.jobORM. - On("FindPipelineRunIDsByJobID", int32(1), 0, 50). + On("FindPipelineRunIDsByJobID", mock.Anything, int32(1), 0, 50). Return([]int64{200}, nil) f.Mocks.jobORM. - On("FindPipelineRunsByIDs", []int64{200}). + On("FindPipelineRunsByIDs", mock.Anything, []int64{200}). Return([]pipeline.Run{{ID: 200}}, nil) f.Mocks.jobORM. - On("CountPipelineRunsByJobID", int32(1)). + On("CountPipelineRunsByJobID", mock.Anything, int32(1)). Return(int32(1), nil) }, query: query, @@ -453,7 +453,7 @@ func TestResolver_DeleteJob(t *testing.T) { name: "success", authenticated: true, before: func(f *gqlTestFramework) { - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{ + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{ ID: id, Name: null.StringFrom("test-job"), ExternalJobID: extJID, @@ -471,7 +471,7 @@ func TestResolver_DeleteJob(t *testing.T) { name: "not found on FindJob()", authenticated: true, before: func(f *gqlTestFramework) { - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{}, sql.ErrNoRows) + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{}, sql.ErrNoRows) f.App.On("JobORM").Return(f.Mocks.jobORM) }, query: mutation, @@ -489,7 +489,7 @@ func TestResolver_DeleteJob(t *testing.T) { name: "not found on DeleteJob()", authenticated: true, before: func(f *gqlTestFramework) { - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{}, nil) + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{}, nil) f.App.On("JobORM").Return(f.Mocks.jobORM) f.App.On("DeleteJob", mock.Anything, id).Return(sql.ErrNoRows) }, @@ -508,7 +508,7 @@ func TestResolver_DeleteJob(t *testing.T) { name: "generic error on FindJob()", authenticated: true, before: func(f *gqlTestFramework) { - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{}, gError) + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{}, gError) f.App.On("JobORM").Return(f.Mocks.jobORM) }, query: mutation, @@ -527,7 +527,7 @@ func TestResolver_DeleteJob(t *testing.T) { name: "generic error on DeleteJob()", authenticated: true, before: func(f *gqlTestFramework) { - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{}, nil) + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{}, nil) f.App.On("JobORM").Return(f.Mocks.jobORM) f.App.On("DeleteJob", mock.Anything, id).Return(gError) }, diff --git a/core/web/resolver/mutation.go b/core/web/resolver/mutation.go index 9663f9dfe82..641eabdfd8b 100644 --- a/core/web/resolver/mutation.go +++ b/core/web/resolver/mutation.go @@ -238,7 +238,7 @@ func (r *Resolver) CreateFeedsManagerChainConfig(ctx context.Context, args struc return nil, err } - ccfg, err := fsvc.GetChainConfig(id) + ccfg, err := fsvc.GetChainConfig(ctx, id) if err != nil { if errors.Is(err, sql.ErrNoRows) { return NewCreateFeedsManagerChainConfigPayload(nil, err, nil), nil @@ -267,7 +267,7 @@ func (r *Resolver) DeleteFeedsManagerChainConfig(ctx context.Context, args struc fsvc := r.App.GetFeedsService() - ccfg, err := fsvc.GetChainConfig(id) + ccfg, err := fsvc.GetChainConfig(ctx, id) if err != nil { if errors.Is(err, sql.ErrNoRows) { return NewDeleteFeedsManagerChainConfigPayload(nil, err), nil @@ -367,7 +367,7 @@ func (r *Resolver) UpdateFeedsManagerChainConfig(ctx context.Context, args struc return nil, err } - ccfg, err := fsvc.GetChainConfig(id) + ccfg, err := fsvc.GetChainConfig(ctx, id) if err != nil { if errors.Is(err, sql.ErrNoRows) { return NewUpdateFeedsManagerChainConfigPayload(nil, err, nil), nil @@ -418,7 +418,7 @@ func (r *Resolver) CreateFeedsManager(ctx context.Context, args struct { return nil, err } - mgr, err := feedsService.GetManager(id) + mgr, err := feedsService.GetManager(ctx, id) if err != nil { if errors.Is(err, sql.ErrNoRows) { return NewCreateFeedsManagerPayload(nil, err, nil), nil @@ -541,7 +541,7 @@ func (r *Resolver) UpdateFeedsManager(ctx context.Context, args struct { return nil, err } - mgr, err = feedsService.GetManager(id) + mgr, err = feedsService.GetManager(ctx, id) if err != nil { if errors.Is(err, sql.ErrNoRows) { return NewUpdateFeedsManagerPayload(nil, err, nil), nil @@ -615,7 +615,7 @@ func (r *Resolver) DeleteBridge(ctx context.Context, args struct { return nil, err } - jobsUsingBridge, err := r.App.JobORM().FindJobIDsWithBridge(string(args.ID)) + jobsUsingBridge, err := r.App.JobORM().FindJobIDsWithBridge(ctx, string(args.ID)) if err != nil { return nil, err } @@ -751,7 +751,7 @@ func (r *Resolver) ApproveJobProposalSpec(ctx context.Context, args struct { return nil, err } - spec, err := feedsSvc.GetSpec(id) + spec, err := feedsSvc.GetSpec(ctx, id) if err != nil { if !errors.Is(err, sql.ErrNoRows) { return nil, err @@ -786,7 +786,7 @@ func (r *Resolver) CancelJobProposalSpec(ctx context.Context, args struct { return nil, err } - spec, err := feedsSvc.GetSpec(id) + spec, err := feedsSvc.GetSpec(ctx, id) if err != nil { if !errors.Is(err, sql.ErrNoRows) { return nil, err @@ -821,7 +821,7 @@ func (r *Resolver) RejectJobProposalSpec(ctx context.Context, args struct { return nil, err } - spec, err := feedsSvc.GetSpec(id) + spec, err := feedsSvc.GetSpec(ctx, id) if err != nil { if !errors.Is(err, sql.ErrNoRows) { return nil, err @@ -859,7 +859,7 @@ func (r *Resolver) UpdateJobProposalSpecDefinition(ctx context.Context, args str return nil, err } - spec, err := feedsSvc.GetSpec(id) + spec, err := feedsSvc.GetSpec(ctx, id) if err != nil { if !errors.Is(err, sql.ErrNoRows) { return nil, err @@ -1039,7 +1039,7 @@ func (r *Resolver) CreateJob(ctx context.Context, args struct { case job.VRF: jb, err = vrfcommon.ValidatedVRFSpec(args.Input.TOML) case job.Webhook: - jb, err = webhook.ValidatedWebhookSpec(args.Input.TOML, r.App.GetExternalInitiatorManager()) + jb, err = webhook.ValidatedWebhookSpec(ctx, args.Input.TOML, r.App.GetExternalInitiatorManager()) case job.BlockhashStore: jb, err = blockhashstore.ValidatedSpec(args.Input.TOML) case job.BlockHeaderFeeder: @@ -1085,7 +1085,7 @@ func (r *Resolver) DeleteJob(ctx context.Context, args struct { return nil, err } - j, err := r.App.JobORM().FindJobWithoutSpecErrors(id) + j, err := r.App.JobORM().FindJobWithoutSpecErrors(ctx, id) if err != nil { if errors.Is(err, sql.ErrNoRows) { return NewDeleteJobPayload(r.App, nil, err), nil @@ -1119,7 +1119,7 @@ func (r *Resolver) DismissJobError(ctx context.Context, args struct { return nil, err } - specErr, err := r.App.JobORM().FindSpecError(id) + specErr, err := r.App.JobORM().FindSpecError(ctx, id) if err != nil { if errors.Is(err, sql.ErrNoRows) { return NewDismissJobErrorPayload(nil, err), nil diff --git a/core/web/resolver/query.go b/core/web/resolver/query.go index e24974e765d..9de678adc51 100644 --- a/core/web/resolver/query.go +++ b/core/web/resolver/query.go @@ -132,7 +132,7 @@ func (r *Resolver) FeedsManager(ctx context.Context, args struct{ ID graphql.ID return nil, err } - mgr, err := r.App.GetFeedsService().GetManager(id) + mgr, err := r.App.GetFeedsService().GetManager(ctx, id) if err != nil { if errors.Is(err, sql.ErrNoRows) { return NewFeedsManagerPayload(nil, err), nil @@ -149,7 +149,7 @@ func (r *Resolver) FeedsManagers(ctx context.Context) (*FeedsManagersPayloadReso return nil, err } - mgrs, err := r.App.GetFeedsService().ListManagers() + mgrs, err := r.App.GetFeedsService().ListManagers(ctx) if err != nil { return nil, err } @@ -168,7 +168,7 @@ func (r *Resolver) Job(ctx context.Context, args struct{ ID graphql.ID }) (*JobP return nil, err } - j, err := r.App.JobORM().FindJobWithoutSpecErrors(id) + j, err := r.App.JobORM().FindJobWithoutSpecErrors(ctx, id) if err != nil { if errors.Is(err, sql.ErrNoRows) { return NewJobPayload(r.App, nil, err), nil @@ -197,7 +197,7 @@ func (r *Resolver) Jobs(ctx context.Context, args struct { offset := pageOffset(args.Offset) limit := pageLimit(args.Limit) - jobs, count, err := r.App.JobORM().FindJobs(offset, limit) + jobs, count, err := r.App.JobORM().FindJobs(ctx, offset, limit) if err != nil { return nil, err } @@ -328,7 +328,7 @@ func (r *Resolver) JobProposal(ctx context.Context, args struct { return nil, err } - jp, err := r.App.GetFeedsService().GetJobProposal(id) + jp, err := r.App.GetFeedsService().GetJobProposal(ctx, id) if err != nil { if errors.Is(err, sql.ErrNoRows) { return NewJobProposalPayload(nil, err), nil @@ -377,7 +377,7 @@ func (r *Resolver) JobRuns(ctx context.Context, args struct { limit := pageLimit(args.Limit) offset := pageOffset(args.Offset) - runs, count, err := r.App.JobORM().PipelineRuns(nil, offset, limit) + runs, count, err := r.App.JobORM().PipelineRuns(ctx, nil, offset, limit) if err != nil { return nil, err } @@ -397,7 +397,7 @@ func (r *Resolver) JobRun(ctx context.Context, args struct { return nil, err } - jr, err := r.App.JobORM().FindPipelineRunByID(id) + jr, err := r.App.JobORM().FindPipelineRunByID(ctx, id) if err != nil { if errors.Is(err, sql.ErrNoRows) { return NewJobRunPayload(nil, r.App, err), nil diff --git a/core/web/resolver/spec_test.go b/core/web/resolver/spec_test.go index 7021576fdcf..43682c14ead 100644 --- a/core/web/resolver/spec_test.go +++ b/core/web/resolver/spec_test.go @@ -6,6 +6,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/lib/pq" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "gopkg.in/guregu/null.v4" @@ -35,7 +36,7 @@ func TestResolver_CronSpec(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("JobORM").Return(f.Mocks.jobORM) - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{ + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{ Type: job.Cron, CronSpec: &job.CronSpec{ CronSchedule: "CRON_TZ=UTC 0 0 1 1 *", @@ -89,7 +90,7 @@ func TestResolver_DirectRequestSpec(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("JobORM").Return(f.Mocks.jobORM) - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{ + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{ Type: job.DirectRequest, DirectRequestSpec: &job.DirectRequestSpec{ ContractAddress: contractAddress, @@ -154,7 +155,7 @@ func TestResolver_FluxMonitorSpec(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("JobORM").Return(f.Mocks.jobORM) - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{ + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{ Type: job.FluxMonitor, FluxMonitorSpec: &job.FluxMonitorSpec{ ContractAddress: contractAddress, @@ -221,7 +222,7 @@ func TestResolver_FluxMonitorSpec(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("JobORM").Return(f.Mocks.jobORM) - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{ + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{ Type: job.FluxMonitor, FluxMonitorSpec: &job.FluxMonitorSpec{ ContractAddress: contractAddress, @@ -304,7 +305,7 @@ func TestResolver_KeeperSpec(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("JobORM").Return(f.Mocks.jobORM) - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{ + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{ Type: job.Keeper, KeeperSpec: &job.KeeperSpec{ ContractAddress: contractAddress, @@ -368,7 +369,7 @@ func TestResolver_OCRSpec(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("JobORM").Return(f.Mocks.jobORM) - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{ + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{ Type: job.OffchainReporting, OCROracleSpec: &job.OCROracleSpec{ BlockchainTimeout: models.Interval(1 * time.Minute), @@ -473,7 +474,7 @@ func TestResolver_OCR2Spec(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("JobORM").Return(f.Mocks.jobORM) - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{ + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{ Type: job.OffchainReporting2, OCR2OracleSpec: &job.OCR2OracleSpec{ BlockchainTimeout: models.Interval(1 * time.Minute), @@ -575,7 +576,7 @@ func TestResolver_VRFSpec(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("JobORM").Return(f.Mocks.jobORM) - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{ + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{ Type: job.VRF, VRFSpec: &job.VRFSpec{ BatchCoordinatorAddress: &batchCoordinatorAddress, @@ -671,7 +672,7 @@ func TestResolver_WebhookSpec(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("JobORM").Return(f.Mocks.jobORM) - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{ + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{ Type: job.Webhook, WebhookSpec: &job.WebhookSpec{ CreatedAt: f.Timestamp(), @@ -740,7 +741,7 @@ func TestResolver_BlockhashStoreSpec(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("JobORM").Return(f.Mocks.jobORM) - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{ + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{ Type: job.BlockhashStore, BlockhashStoreSpec: &job.BlockhashStoreSpec{ CoordinatorV1Address: &coordinatorV1Address, @@ -844,7 +845,7 @@ func TestResolver_BlockHeaderFeederSpec(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("JobORM").Return(f.Mocks.jobORM) - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{ + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{ Type: job.BlockHeaderFeeder, BlockHeaderFeederSpec: &job.BlockHeaderFeederSpec{ CoordinatorV1Address: &coordinatorV1Address, @@ -931,7 +932,7 @@ func TestResolver_BootstrapSpec(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("JobORM").Return(f.Mocks.jobORM) - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{ + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{ Type: job.Bootstrap, BootstrapSpec: &job.BootstrapSpec{ ID: id, @@ -1003,7 +1004,7 @@ func TestResolver_WorkflowSpec(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("JobORM").Return(f.Mocks.jobORM) - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{ + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{ Type: job.Workflow, WorkflowSpec: &job.WorkflowSpec{ ID: id, @@ -1061,7 +1062,7 @@ func TestResolver_GatewaySpec(t *testing.T) { authenticated: true, before: func(f *gqlTestFramework) { f.App.On("JobORM").Return(f.Mocks.jobORM) - f.Mocks.jobORM.On("FindJobWithoutSpecErrors", id).Return(job.Job{ + f.Mocks.jobORM.On("FindJobWithoutSpecErrors", mock.Anything, id).Return(job.Job{ Type: job.Gateway, GatewaySpec: &job.GatewaySpec{ ID: id, diff --git a/core/web/sessions_controller_test.go b/core/web/sessions_controller_test.go index cd63628390e..049be4e2b69 100644 --- a/core/web/sessions_controller_test.go +++ b/core/web/sessions_controller_test.go @@ -8,10 +8,10 @@ import ( "testing" "time" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" clhttptest "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/httptest" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/sessions" "github.com/smartcontractkit/chainlink/v2/core/web" @@ -25,7 +25,7 @@ func TestSessionsController_Create(t *testing.T) { ctx := testutils.Context(t) app := cltest.NewApplicationEVMDisabled(t) - require.NoError(t, app.Start(testutils.Context(t))) + require.NoError(t, app.Start(ctx)) user := cltest.MustRandomUser(t) require.NoError(t, app.AuthenticationProvider().CreateUser(ctx, &user)) @@ -44,6 +44,7 @@ func TestSessionsController_Create(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { + ctx := testutils.Context(t) body := fmt.Sprintf(`{"email":"%s","password":"%s"}`, test.email, test.password) request, err := http.NewRequestWithContext(ctx, "POST", app.Server.URL+"/sessions", bytes.NewBufferString(body)) assert.NoError(t, err) @@ -78,9 +79,10 @@ func TestSessionsController_Create(t *testing.T) { } } -func mustInsertSession(t *testing.T, q pg.Q, session *sessions.Session) { +func mustInsertSession(t *testing.T, ds sqlutil.DataSource, session *sessions.Session) { + ctx := testutils.Context(t) sql := "INSERT INTO sessions (id, email, last_used, created_at) VALUES ($1, $2, $3, $4) RETURNING *" - _, err := q.Exec(sql, session.ID, session.Email, session.LastUsed, session.CreatedAt) + _, err := ds.ExecContext(ctx, sql, session.ID, session.Email, session.LastUsed, session.CreatedAt) require.NoError(t, err) } @@ -97,8 +99,7 @@ func TestSessionsController_Create_ReapSessions(t *testing.T) { staleSession := cltest.NewSession() staleSession.LastUsed = time.Now().Add(-cltest.MustParseDuration(t, "241h")) staleSession.Email = user.Email - q := pg.NewQ(app.GetSqlxDB(), app.GetLogger(), app.GetConfig().Database()) - mustInsertSession(t, q, &staleSession) + mustInsertSession(t, app.GetDB(), &staleSession) body := fmt.Sprintf(`{"email":"%s","password":"%s"}`, user.Email, cltest.Password) req, err := http.NewRequestWithContext(ctx, "POST", app.Server.URL+"/sessions", bytes.NewBufferString(body)) @@ -127,15 +128,14 @@ func TestSessionsController_Destroy(t *testing.T) { ctx := testutils.Context(t) app := cltest.NewApplicationEVMDisabled(t) - require.NoError(t, app.Start(testutils.Context(t))) + require.NoError(t, app.Start(ctx)) user := cltest.MustRandomUser(t) require.NoError(t, app.AuthenticationProvider().CreateUser(ctx, &user)) correctSession := sessions.NewSession() correctSession.Email = user.Email - q := pg.NewQ(app.GetSqlxDB(), app.GetLogger(), app.GetConfig().Database()) - mustInsertSession(t, q, &correctSession) + mustInsertSession(t, app.GetDB(), &correctSession) client := clhttptest.NewTestLocalOnlyHTTPClient() tests := []struct { @@ -148,6 +148,7 @@ func TestSessionsController_Destroy(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { + ctx := testutils.Context(t) cookie := cltest.MustGenerateSessionCookie(t, test.sessionID) request, err := http.NewRequestWithContext(ctx, "DELETE", app.Server.URL+"/sessions", nil) assert.NoError(t, err) @@ -173,8 +174,7 @@ func TestSessionsController_Destroy_ReapSessions(t *testing.T) { client := clhttptest.NewTestLocalOnlyHTTPClient() app := cltest.NewApplicationEVMDisabled(t) - q := pg.NewQ(app.GetSqlxDB(), app.GetLogger(), app.GetConfig().Database()) - require.NoError(t, app.Start(testutils.Context(t))) + require.NoError(t, app.Start(ctx)) user := cltest.MustRandomUser(t) require.NoError(t, app.AuthenticationProvider().CreateUser(ctx, &user)) @@ -182,13 +182,13 @@ func TestSessionsController_Destroy_ReapSessions(t *testing.T) { correctSession := sessions.NewSession() correctSession.Email = user.Email - mustInsertSession(t, q, &correctSession) + mustInsertSession(t, app.GetDB(), &correctSession) cookie := cltest.MustGenerateSessionCookie(t, correctSession.ID) staleSession := cltest.NewSession() staleSession.Email = user.Email staleSession.LastUsed = time.Now().Add(-cltest.MustParseDuration(t, "241h")) - mustInsertSession(t, q, &staleSession) + mustInsertSession(t, app.GetDB(), &staleSession) request, err := http.NewRequestWithContext(ctx, "DELETE", app.Server.URL+"/sessions", nil) assert.NoError(t, err) diff --git a/go.mod b/go.mod index b357e57eac5..0a09e3d9693 100644 --- a/go.mod +++ b/go.mod @@ -73,7 +73,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.10 github.com/smartcontractkit/chainlink-automation v1.0.3 github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 - github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58 diff --git a/go.sum b/go.sum index 664ddd5efe0..68cd0abbd7f 100644 --- a/go.sum +++ b/go.sum @@ -1182,8 +1182,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfs github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 h1:54hM3/SrOM166it2K35hGb5K7gQ49/Op0aHp9WkqpqU= github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 h1:MvaNzuaQh1vX4CAYLM8qFd99cf0ZF1JNwtDZtLU7WvU= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee h1:eFuBKyEbL2b+eyfgV/Eu9+8HuCEev+IcBi+K9l1dG7g= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540/go.mod h1:sjAmX8K2kbQhvDarZE1ZZgDgmHJ50s0BBc/66vKY2ek= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab h1:Ct1oUlyn03HDUVdFHJqtRGRUujMqdoMzvf/Cjhe30Ag= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index d07e68c9f7a..24a5d1ee7a6 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -377,7 +377,7 @@ require ( github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.10 // indirect - github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 // indirect + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index efef8224d85..8c66ce7ca8c 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1519,8 +1519,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfs github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 h1:54hM3/SrOM166it2K35hGb5K7gQ49/Op0aHp9WkqpqU= github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 h1:MvaNzuaQh1vX4CAYLM8qFd99cf0ZF1JNwtDZtLU7WvU= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee h1:eFuBKyEbL2b+eyfgV/Eu9+8HuCEev+IcBi+K9l1dG7g= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540/go.mod h1:sjAmX8K2kbQhvDarZE1ZZgDgmHJ50s0BBc/66vKY2ek= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab h1:Ct1oUlyn03HDUVdFHJqtRGRUujMqdoMzvf/Cjhe30Ag= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index a7a37ab1e0e..13a8e2f4f34 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -366,7 +366,7 @@ require ( github.com/shopspring/decimal v1.3.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.10 // indirect - github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 // indirect + github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 // indirect github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index d50656bfed5..5720d19de02 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1502,8 +1502,8 @@ github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfs github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 h1:54hM3/SrOM166it2K35hGb5K7gQ49/Op0aHp9WkqpqU= github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92 h1:MvaNzuaQh1vX4CAYLM8qFd99cf0ZF1JNwtDZtLU7WvU= -github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419131812-73d148593d92/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee h1:eFuBKyEbL2b+eyfgV/Eu9+8HuCEev+IcBi+K9l1dG7g= +github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540/go.mod h1:sjAmX8K2kbQhvDarZE1ZZgDgmHJ50s0BBc/66vKY2ek= github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab h1:Ct1oUlyn03HDUVdFHJqtRGRUujMqdoMzvf/Cjhe30Ag= From 74c6d028659e80d9b5092c2406a598a1d2249d21 Mon Sep 17 00:00:00 2001 From: Chris Cushman <104409744+vreff@users.noreply.github.com> Date: Wed, 24 Apr 2024 18:32:21 -0400 Subject: [PATCH 25/77] Revert ocr2vrf gethwrappers change (#12957) * Revert "[VRF-886] Move vestigial ocr2vrf gethwrappers to chainlink-vrf archive (#12134)" This reverts commit e9ea7c85facefb9bcbc0f9baf9e9f4848fda938e. * fix conflicts --- contracts/GNUmakefile | 12 + .../scripts/native_solc_compile_all_ocr2vrf | 42 + .../gethwrappers/ocr2vrf/generated/dkg/dkg.go | 1274 ++++++ .../load_test_beacon_consumer.go | 1422 ++++++ .../generated/vrf_beacon/vrf_beacon.go | 2846 ++++++++++++ .../vrf_beacon_consumer.go | 1034 +++++ .../vrf_coordinator/vrf_coordinator.go | 3870 +++++++++++++++++ ...rapper-dependency-versions-do-not-edit.txt | 7 + core/gethwrappers/ocr2vrf/go_generate.go | 10 + core/internal/mocks/go_generate.go | 4 +- core/scripts/ocr2vrf/util.go | 10 +- core/scripts/ocr2vrf/verify.go | 6 +- .../ocr2vrf/coordinator/coordinator.go | 8 +- .../ocr2vrf/coordinator/coordinator_test.go | 6 +- .../ocr2vrf/coordinator/mocks/vrf_beacon.go | 2 +- .../coordinator/mocks/vrf_coordinator.go | 2 +- .../plugins/ocr2vrf/coordinator/router.go | 4 +- .../ocr2vrf/coordinator/router_test.go | 4 +- .../plugins/ocr2vrf/coordinator/topics.go | 4 +- .../internal/ocr2vrf_integration_test.go | 10 +- go.mod | 2 +- go.sum | 4 +- .../contracts/contract_vrf_models.go | 4 +- .../contracts/ethereum_ocr2vrf_contracts.go | 8 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 28 files changed, 10562 insertions(+), 45 deletions(-) create mode 100755 contracts/scripts/native_solc_compile_all_ocr2vrf create mode 100644 core/gethwrappers/ocr2vrf/generated/dkg/dkg.go create mode 100644 core/gethwrappers/ocr2vrf/generated/load_test_beacon_consumer/load_test_beacon_consumer.go create mode 100644 core/gethwrappers/ocr2vrf/generated/vrf_beacon/vrf_beacon.go create mode 100644 core/gethwrappers/ocr2vrf/generated/vrf_beacon_consumer/vrf_beacon_consumer.go create mode 100644 core/gethwrappers/ocr2vrf/generated/vrf_coordinator/vrf_coordinator.go create mode 100644 core/gethwrappers/ocr2vrf/generation/generated-wrapper-dependency-versions-do-not-edit.txt create mode 100644 core/gethwrappers/ocr2vrf/go_generate.go diff --git a/contracts/GNUmakefile b/contracts/GNUmakefile index 38547ce3a57..4ec8057b975 100644 --- a/contracts/GNUmakefile +++ b/contracts/GNUmakefile @@ -73,6 +73,18 @@ wrappers-all: pnpmdep mockery abigen ## Recompiles solidity contracts and their # go_generate contains a call to compile all contracts before generating wrappers go generate ../core/gethwrappers/go_generate.go +# Custom wrapper generation for OCR2VRF as their contracts do not exist in this repo +.PHONY: go-solidity-wrappers-ocr2vrf +go-solidity-wrappers-ocr2vrf: pnpmdep abigen ## Recompiles OCR2VRF solidity contracts and their go wrappers. + ./scripts/native_solc_compile_all_ocr2vrf + # replace the go:generate_disabled directive with the regular go:generate directive + sed -i '' 's/go:generate_disabled/go:generate/g' ../core/gethwrappers/ocr2vrf/go_generate.go + go generate ../core/gethwrappers/ocr2vrf + go generate ../core/internal/mocks + # put the go:generate_disabled directive back + sed -i '' 's/go:generate/go:generate_disabled/g' ../core/gethwrappers/ocr2vrf/go_generate.go + + help: @echo "" @echo " .__ .__ .__ .__ __" diff --git a/contracts/scripts/native_solc_compile_all_ocr2vrf b/contracts/scripts/native_solc_compile_all_ocr2vrf new file mode 100755 index 00000000000..755edd34f56 --- /dev/null +++ b/contracts/scripts/native_solc_compile_all_ocr2vrf @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +set -e + +echo " ┌──────────────────────────────────────────────┐" +echo " │ Compiling OCR2 VRF contracts... │" +echo " └──────────────────────────────────────────────┘" + +SOLC_VERSION="0.8.19" +OPTIMIZE_RUNS=1000000 +# The VRF contracts are not contained in the `chainlink` repository. +# Change me. +FOLDER="ocr2vrf-origin" + +echo "Compiling OCR2VRF contracts..." + +SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +ROOT="$( cd "$(dirname "$0")" >/dev/null 2>&1; cd ../../ && pwd -P )" +python3 -m pip install --require-hashes -r "$SCRIPTPATH"/requirements.txt + +solc-select install $SOLC_VERSION +solc-select use $SOLC_VERSION +export SOLC_VERSION=$SOLC_VERSION + + +compileContract () { + local contract + contract=$(basename "$1" ".sol") + + solc --overwrite --optimize --optimize-runs "$2" --metadata-hash none \ + -o "$ROOT"/contracts/solc/v0.8.19/"$contract" \ + --abi --bin \ + --allow-paths "$ROOT"/../$FOLDER/contracts \ + "$ROOT"/"$1" +} + +# OCR2VRF +compileContract ../$FOLDER/contracts/DKG.sol $OPTIMIZE_RUNS +compileContract ../$FOLDER/contracts/VRFBeacon.sol $OPTIMIZE_RUNS +compileContract ../$FOLDER/contracts/VRFCoordinator.sol 1 +compileContract ../$FOLDER/contracts/test/TestBeaconVRFConsumer.sol $OPTIMIZE_RUNS +compileContract ../$FOLDER/contracts/test/LoadTestBeaconVRFConsumer.sol $OPTIMIZE_RUNS diff --git a/core/gethwrappers/ocr2vrf/generated/dkg/dkg.go b/core/gethwrappers/ocr2vrf/generated/dkg/dkg.go new file mode 100644 index 00000000000..7a18b7f55bd --- /dev/null +++ b/core/gethwrappers/ocr2vrf/generated/dkg/dkg.go @@ -0,0 +1,1274 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package dkg + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type KeyDataStructKeyData struct { + PublicKey []byte + Hashes [][32]byte +} + +var DKGMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expectedLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualLength\",\"type\":\"uint256\"}],\"name\":\"CalldataLengthMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expectedNumSignatures\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ssLength\",\"type\":\"uint256\"}],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expectedLength\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"actualLength\",\"type\":\"uint256\"}],\"name\":\"InvalidOnchainConfigLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"KeyIDCopyFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"numFaultyOracles\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"}],\"name\":\"NumberOfFaultyOraclesTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"repeatedSignerAddress\",\"type\":\"address\"}],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"repeatedTransmitterAddress\",\"type\":\"address\"}],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"numTransmitters\",\"type\":\"uint256\"}],\"name\":\"SignersTransmittersMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"maxOracles\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"providedOracles\",\"type\":\"uint256\"}],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractDKGClient\",\"name\":\"client\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"errorData\",\"type\":\"bytes\"}],\"name\":\"DKGClientError\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"keyID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"publicKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashes\",\"type\":\"bytes32[]\"}],\"indexed\":false,\"internalType\":\"structKeyDataStruct.KeyData\",\"name\":\"key\",\"type\":\"tuple\"}],\"name\":\"KeyGenerated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyID\",\"type\":\"bytes32\"},{\"internalType\":\"contractDKGClient\",\"name\":\"clientAddress\",\"type\":\"address\"}],\"name\":\"addClient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_keyID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_configDigest\",\"type\":\"bytes32\"}],\"name\":\"getKey\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"publicKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashes\",\"type\":\"bytes32[]\"}],\"internalType\":\"structKeyDataStruct.KeyData\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyID\",\"type\":\"bytes32\"},{\"internalType\":\"contractDKGClient\",\"name\":\"clientAddress\",\"type\":\"address\"}],\"name\":\"removeClient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"_f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"_offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"_offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b503380600081620000695760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156200009c576200009c81620000a5565b50505062000150565b336001600160a01b03821603620000ff5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000060565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b612b8080620001606000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80638da5cb5b11610081578063c3105a6b1161005b578063c3105a6b146101db578063e3d0e712146101fb578063f2fde38b1461020e57600080fd5b80638da5cb5b14610176578063afcb95d71461019e578063b1dc65a4146101c857600080fd5b806379ba5097116100b257806379ba50971461012b5780637bf1ffc51461013357806381ff70481461014657600080fd5b8063181f5a77146100ce5780635429a79e14610116575b600080fd5b604080518082018252600981527f444b4720302e302e3100000000000000000000000000000000000000000000006020820152905161010d9190611fc8565b60405180910390f35b610129610124366004612004565b610221565b005b6101296104b0565b610129610141366004612004565b6105b2565b6007546005546040805163ffffffff8085168252640100000000909404909316602084015282015260600161010d565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161010d565b6005546004546040805160008152602081019390935263ffffffff9091169082015260600161010d565b6101296101d6366004612080565b61061e565b6101ee6101e9366004612165565b610761565b60405161010d9190612187565b6101296102093660046123dd565b61088a565b61012961021c3660046124aa565b6111ec565b610229611200565b60008281526002602090815260408083208054825181850281018501909352808352919290919083018282801561029657602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161026b575b505050505090506000815167ffffffffffffffff8111156102b9576102b961220d565b6040519080825280602002602001820160405280156102e2578160200160208202803683370190505b5090506000805b83518110156103b9578473ffffffffffffffffffffffffffffffffffffffff1684828151811061031b5761031b6124c7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161461039957848361034a8484612525565b8151811061035a5761035a6124c7565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506103a7565b816103a381612538565b9250505b806103b181612538565b9150506102e9565b5060008184516103c99190612525565b67ffffffffffffffff8111156103e1576103e161220d565b60405190808252806020026020018201604052801561040a578160200160208202803683370190505b50905060005b82855161041d9190612525565b81101561048757838181518110610436576104366124c7565b6020026020010151828281518110610450576104506124c7565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101528061047f81612538565b915050610410565b50600086815260026020908152604090912082516104a792840190611e61565b50505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610536576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6105ba611200565b600091825260026020908152604083208054600181018255908452922090910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055565b60005a604080516020601f8b018190048102820181019092528981529192508a3591818c01359161066e9184918491908e908e908190840183828082843760009201919091525061128392505050565b6040805183815263ffffffff600884901c1660208201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a16040805160608101825260055480825260065460ff808216602085015261010090910416928201929092529083146107215780516040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101919091526024810184905260440161052d565b61072f8b8b8b8b8b8b611512565b6107408c8c8c8c8c8c8c8c89611599565b50505063ffffffff811061075657610756612570565b505050505050505050565b604080518082019091526060808252602082015260008381526003602090815260408083208584529091529081902081518083019092528054829082906107a79061259f565b80601f01602080910402602001604051908101604052809291908181526020018280546107d39061259f565b80156108205780601f106107f557610100808354040283529160200191610820565b820191906000526020600020905b81548152906001019060200180831161080357829003601f168201915b505050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561087857602002820191906000526020600020905b815481526020019060010190808311610864575b50505050508152505090505b92915050565b8551855185601f8311156108d4576040517f809fc428000000000000000000000000000000000000000000000000000000008152601f60048201526024810184905260440161052d565b818314610917576040517f988a0804000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260440161052d565b6109228160036125f2565b60ff168311610969576040517ffda9db7800000000000000000000000000000000000000000000000000000000815260ff821660048201526024810184905260440161052d565b8060ff166000036109a6576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109ae611200565b6040805160c0810182528a8152602081018a905260ff8916918101919091526060810187905267ffffffffffffffff8616608082015260a081018590525b60095415610ba157600954600090610a0690600190612525565b9050600060098281548110610a1d57610a1d6124c7565b6000918252602082200154600a805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110610a5757610a576124c7565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff85811684526008909252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090811690915592909116808452922080549091169055600980549192509080610ad757610ad7612615565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055600a805480610b4057610b40612615565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055506109ec915050565b60005b81515181101561101c5760006008600084600001518481518110610bca57610bca6124c7565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115610c1457610c14612644565b14610c84578151805182908110610c2d57610c2d6124c7565b60200260200101516040517f7451f83e00000000000000000000000000000000000000000000000000000000815260040161052d919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6040805180820190915260ff82168152600160208201528251805160089160009185908110610cb557610cb56124c7565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610d5657610d56612644565b021790555060009150610d669050565b6008600084602001518481518110610d8057610d806124c7565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115610dca57610dca612644565b14610e3c5781602001518181518110610de557610de56124c7565b60200260200101516040517fe8d2989900000000000000000000000000000000000000000000000000000000815260040161052d919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6040805180820190915260ff821681526020810160028152506008600084602001518481518110610e6f57610e6f6124c7565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610f1057610f10612644565b021790555050825180516009925083908110610f2e57610f2e6124c7565b602090810291909101810151825460018101845560009384529282902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909316929092179091558201518051600a919083908110610faa57610faa6124c7565b60209081029190910181015182546001810184556000938452919092200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790558061101481612538565b915050610ba4565b506040810151600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600754640100000000900463ffffffff1661106c611a2f565b6007805463ffffffff928316640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff8216811783556001936000926110bd928692908116911617612673565b92506101000a81548163ffffffff021916908363ffffffff160217905550600061111e4630600760009054906101000a900463ffffffff1663ffffffff1686600001518760200151886040015189606001518a608001518b60a00151611ac6565b6005819055835180516006805460ff909216610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff9092169190911790556007546020860151604080880151606089015160808a015160a08b015193519798507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05976111c3978b978b9763ffffffff9091169691959094909390929091906126e1565b60405180910390a16111de8360400151846060015183611b71565b505050505050505050505050565b6111f4611200565b6111fd81611d6c565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611281576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161052d565b565b60006060808380602001905181019061129c9190612777565b60408051808201825283815260208082018490526000868152600282528381208054855181850281018501909652808652979a509598509396509094929391929083018282801561132357602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116112f8575b5050505050905060005b815181101561144d57818181518110611348576113486124c7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1663bf2732c7846040518263ffffffff1660e01b81526004016113889190612187565b600060405180830381600087803b1580156113a257600080fd5b505af19250505080156113b3575060015b61143b573d8080156113e1576040519150601f19603f3d011682016040523d82523d6000602084013e6113e6565b606091505b507f116391732f5df106193bda7cedf1728f3b07b62f6cdcdd611c9eeec44efcae5483838151811061141a5761141a6124c7565b602002602001015182604051611431929190612875565b60405180910390a1505b8061144581612538565b91505061132d565b5060008581526003602090815260408083208b845290915290208251839190819061147890826128fb565b5060208281015180516114919260018501920190611eeb565b5090505084887fc8db841f5b2231ccf7190311f440aa197b161e369f3b40b023508160cc555656846040516114c69190612187565b60405180910390a350506004805460089690961c63ffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000909616959095179094555050505050565b600061151f826020612a15565b61152a856020612a15565b61153688610144612a2c565b6115409190612a2c565b61154a9190612a2c565b611555906000612a2c565b90503681146104a7576040517ff7b94f0a0000000000000000000000000000000000000000000000000000000081526004810182905236602482015260440161052d565b60006002826020015183604001516115b19190612a3f565b6115bb9190612a58565b6115c6906001612a3f565b60408051600180825281830190925260ff929092169250600091906020820181803683370190505090508160f81b81600081518110611607576116076124c7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535086821415806116455750868514155b1561168d576040517fe307bd5700000000000000000000000000000000000000000000000000000000815260048101839052602481018890526044810186905260640161052d565b3360009081526008602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156116d0576116d0612644565b60028111156116e1576116e1612644565b90525090506002816020015160028111156116fe576116fe612644565b1415806117465750600a816000015160ff1681548110611720576117206124c7565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff163314155b1561177f576040517f2d0f0c0f00000000000000000000000000000000000000000000000000000000815233600482015260240161052d565b50505060008888604051611794929190612aa1565b6040519081900381206117ab918c90602001612ab1565b6040516020818303038152906040528051906020012090506117cb611f26565b604080518082019091526000808252602082015260005b88811015611a20576000600185888460208110611801576118016124c7565b61180e91901a601b612a3f565b8d8d86818110611820576118206124c7565b905060200201358c8c87818110611839576118396124c7565b9050602002013560405160008152602001604052604051611876949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611898573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526008602090815290849020838501909452835460ff8082168552929650929450840191610100900416600281111561191857611918612644565b600281111561192957611929612644565b905250925060018360200151600281111561194657611946612644565b14611995576040517fbf18af4300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161052d565b8251849060ff16601f81106119ac576119ac6124c7565b6020020151156119e8576040517f21cf3b4400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600184846000015160ff16601f8110611a0357611a036124c7565b911515602090920201525080611a1881612538565b9150506117e2565b50505050505050505050505050565b60004661a4b1811480611a44575062066eed81145b15611abf57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ab99190612ac5565b91505090565b4391505090565b6000808a8a8a8a8a8a8a8a8a604051602001611aea99989796959493929190612ade565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b6000808351602014611bbc5783516040517f1625adfe00000000000000000000000000000000000000000000000000000000815260206004820152602481019190915260440161052d565b60208401519150808203611bfc576040517faf5e77d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201909152606080825260208201526000838152600360209081526040808320878452909152902081518291908190611c3a90826128fb565b506020828101518051611c539260018501920190611eeb565b505050600083815260026020908152604080832080548251818502810185019093528083529192909190830182828015611cc357602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611c98575b5050505050905060005b8151811015611d6257818181518110611ce857611ce86124c7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166355e487496040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611d3757600080fd5b505af1158015611d4b573d6000803e3d6000fd5b505050508080611d5a90612538565b915050611ccd565b5050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603611deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161052d565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215611edb579160200282015b82811115611edb57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190611e81565b50611ee7929150611f45565b5090565b828054828255906000526020600020908101928215611edb579160200282015b82811115611edb578251825591602001919060010190611f0b565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115611ee75760008155600101611f46565b60005b83811015611f75578181015183820152602001611f5d565b50506000910152565b60008151808452611f96816020860160208601611f5a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611fdb6020830184611f7e565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff811681146111fd57600080fd5b6000806040838503121561201757600080fd5b82359150602083013561202981611fe2565b809150509250929050565b60008083601f84011261204657600080fd5b50813567ffffffffffffffff81111561205e57600080fd5b6020830191508360208260051b850101111561207957600080fd5b9250929050565b60008060008060008060008060e0898b03121561209c57600080fd5b606089018a8111156120ad57600080fd5b8998503567ffffffffffffffff808211156120c757600080fd5b818b0191508b601f8301126120db57600080fd5b8135818111156120ea57600080fd5b8c60208285010111156120fc57600080fd5b6020830199508098505060808b013591508082111561211a57600080fd5b6121268c838d01612034565b909750955060a08b013591508082111561213f57600080fd5b5061214c8b828c01612034565b999c989b50969995989497949560c00135949350505050565b6000806040838503121561217857600080fd5b50508035926020909101359150565b6000602080835283516040828501526121a36060850182611f7e565b858301518582037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040870152805180835290840192506000918401905b8083101561220257835182529284019260019290920191908401906121e2565b509695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156122835761228361220d565b604052919050565b600067ffffffffffffffff8211156122a5576122a561220d565b5060051b60200190565b600082601f8301126122c057600080fd5b813560206122d56122d08361228b565b61223c565b82815260059290921b840181019181810190868411156122f457600080fd5b8286015b8481101561220257803561230b81611fe2565b83529183019183016122f8565b803560ff8116811461232957600080fd5b919050565b600067ffffffffffffffff8211156123485761234861220d565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261238557600080fd5b81356123936122d08261232e565b8181528460208386010111156123a857600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff8116811461232957600080fd5b60008060008060008060c087890312156123f657600080fd5b863567ffffffffffffffff8082111561240e57600080fd5b61241a8a838b016122af565b9750602089013591508082111561243057600080fd5b61243c8a838b016122af565b965061244a60408a01612318565b9550606089013591508082111561246057600080fd5b61246c8a838b01612374565b945061247a60808a016123c5565b935060a089013591508082111561249057600080fd5b5061249d89828a01612374565b9150509295509295509295565b6000602082840312156124bc57600080fd5b8135611fdb81611fe2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610884576108846124f6565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612569576125696124f6565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600181811c908216806125b357607f821691505b6020821081036125ec577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60ff818116838216029081169081811461260e5761260e6124f6565b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b63ffffffff81811683821601908082111561260e5761260e6124f6565b600081518084526020808501945080840160005b838110156126d657815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016126a4565b509495945050505050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526127118184018a612690565b905082810360808401526127258189612690565b905060ff871660a084015282810360c08401526127428187611f7e565b905067ffffffffffffffff851660e08401528281036101008401526127678185611f7e565b9c9b505050505050505050505050565b60008060006060848603121561278c57600080fd5b8351925060208085015167ffffffffffffffff808211156127ac57600080fd5b818701915087601f8301126127c057600080fd5b81516127ce6122d08261232e565b81815289858386010111156127e257600080fd5b6127f182868301878701611f5a565b60408901519096509250508082111561280957600080fd5b508501601f8101871361281b57600080fd5b80516128296122d08261228b565b81815260059190911b8201830190838101908983111561284857600080fd5b928401925b828410156128665783518252928401929084019061284d565b80955050505050509250925092565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006128a46040830184611f7e565b949350505050565b601f8211156128f657600081815260208120601f850160051c810160208610156128d35750805b601f850160051c820191505b818110156128f2578281556001016128df565b5050505b505050565b815167ffffffffffffffff8111156129155761291561220d565b61292981612923845461259f565b846128ac565b602080601f83116001811461297c57600084156129465750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556128f2565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156129c9578886015182559484019460019091019084016129aa565b5085821015612a0557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b8082028115828204841417610884576108846124f6565b80820180821115610884576108846124f6565b60ff8181168382160190811115610884576108846124f6565b600060ff831680612a92577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b8183823760009101908152919050565b828152606082602083013760800192915050565b600060208284031215612ad757600080fd5b5051919050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152612b258285018b612690565b91508382036080850152612b39828a612690565b915060ff881660a085015283820360c0850152612b568288611f7e565b90861660e085015283810361010085015290506127678185611f7e56fea164736f6c6343000813000a", +} + +var DKGABI = DKGMetaData.ABI + +var DKGBin = DKGMetaData.Bin + +func DeployDKG(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *DKG, error) { + parsed, err := DKGMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(DKGBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &DKG{DKGCaller: DKGCaller{contract: contract}, DKGTransactor: DKGTransactor{contract: contract}, DKGFilterer: DKGFilterer{contract: contract}}, nil +} + +type DKG struct { + address common.Address + abi abi.ABI + DKGCaller + DKGTransactor + DKGFilterer +} + +type DKGCaller struct { + contract *bind.BoundContract +} + +type DKGTransactor struct { + contract *bind.BoundContract +} + +type DKGFilterer struct { + contract *bind.BoundContract +} + +type DKGSession struct { + Contract *DKG + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type DKGCallerSession struct { + Contract *DKGCaller + CallOpts bind.CallOpts +} + +type DKGTransactorSession struct { + Contract *DKGTransactor + TransactOpts bind.TransactOpts +} + +type DKGRaw struct { + Contract *DKG +} + +type DKGCallerRaw struct { + Contract *DKGCaller +} + +type DKGTransactorRaw struct { + Contract *DKGTransactor +} + +func NewDKG(address common.Address, backend bind.ContractBackend) (*DKG, error) { + abi, err := abi.JSON(strings.NewReader(DKGABI)) + if err != nil { + return nil, err + } + contract, err := bindDKG(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &DKG{address: address, abi: abi, DKGCaller: DKGCaller{contract: contract}, DKGTransactor: DKGTransactor{contract: contract}, DKGFilterer: DKGFilterer{contract: contract}}, nil +} + +func NewDKGCaller(address common.Address, caller bind.ContractCaller) (*DKGCaller, error) { + contract, err := bindDKG(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &DKGCaller{contract: contract}, nil +} + +func NewDKGTransactor(address common.Address, transactor bind.ContractTransactor) (*DKGTransactor, error) { + contract, err := bindDKG(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &DKGTransactor{contract: contract}, nil +} + +func NewDKGFilterer(address common.Address, filterer bind.ContractFilterer) (*DKGFilterer, error) { + contract, err := bindDKG(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &DKGFilterer{contract: contract}, nil +} + +func bindDKG(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := DKGMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_DKG *DKGRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DKG.Contract.DKGCaller.contract.Call(opts, result, method, params...) +} + +func (_DKG *DKGRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DKG.Contract.DKGTransactor.contract.Transfer(opts) +} + +func (_DKG *DKGRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DKG.Contract.DKGTransactor.contract.Transact(opts, method, params...) +} + +func (_DKG *DKGCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DKG.Contract.contract.Call(opts, result, method, params...) +} + +func (_DKG *DKGTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DKG.Contract.contract.Transfer(opts) +} + +func (_DKG *DKGTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DKG.Contract.contract.Transact(opts, method, params...) +} + +func (_DKG *DKGCaller) GetKey(opts *bind.CallOpts, _keyID [32]byte, _configDigest [32]byte) (KeyDataStructKeyData, error) { + var out []interface{} + err := _DKG.contract.Call(opts, &out, "getKey", _keyID, _configDigest) + + if err != nil { + return *new(KeyDataStructKeyData), err + } + + out0 := *abi.ConvertType(out[0], new(KeyDataStructKeyData)).(*KeyDataStructKeyData) + + return out0, err + +} + +func (_DKG *DKGSession) GetKey(_keyID [32]byte, _configDigest [32]byte) (KeyDataStructKeyData, error) { + return _DKG.Contract.GetKey(&_DKG.CallOpts, _keyID, _configDigest) +} + +func (_DKG *DKGCallerSession) GetKey(_keyID [32]byte, _configDigest [32]byte) (KeyDataStructKeyData, error) { + return _DKG.Contract.GetKey(&_DKG.CallOpts, _keyID, _configDigest) +} + +func (_DKG *DKGCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) { + var out []interface{} + err := _DKG.contract.Call(opts, &out, "latestConfigDetails") + + outstruct := new(LatestConfigDetails) + if err != nil { + return *outstruct, err + } + + outstruct.ConfigCount = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.BlockNumber = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.ConfigDigest = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + + return *outstruct, err + +} + +func (_DKG *DKGSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _DKG.Contract.LatestConfigDetails(&_DKG.CallOpts) +} + +func (_DKG *DKGCallerSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _DKG.Contract.LatestConfigDetails(&_DKG.CallOpts) +} + +func (_DKG *DKGCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) { + var out []interface{} + err := _DKG.contract.Call(opts, &out, "latestConfigDigestAndEpoch") + + outstruct := new(LatestConfigDigestAndEpoch) + if err != nil { + return *outstruct, err + } + + outstruct.ScanLogs = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.ConfigDigest = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + outstruct.Epoch = *abi.ConvertType(out[2], new(uint32)).(*uint32) + + return *outstruct, err + +} + +func (_DKG *DKGSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _DKG.Contract.LatestConfigDigestAndEpoch(&_DKG.CallOpts) +} + +func (_DKG *DKGCallerSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _DKG.Contract.LatestConfigDigestAndEpoch(&_DKG.CallOpts) +} + +func (_DKG *DKGCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _DKG.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_DKG *DKGSession) Owner() (common.Address, error) { + return _DKG.Contract.Owner(&_DKG.CallOpts) +} + +func (_DKG *DKGCallerSession) Owner() (common.Address, error) { + return _DKG.Contract.Owner(&_DKG.CallOpts) +} + +func (_DKG *DKGCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _DKG.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_DKG *DKGSession) TypeAndVersion() (string, error) { + return _DKG.Contract.TypeAndVersion(&_DKG.CallOpts) +} + +func (_DKG *DKGCallerSession) TypeAndVersion() (string, error) { + return _DKG.Contract.TypeAndVersion(&_DKG.CallOpts) +} + +func (_DKG *DKGTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DKG.contract.Transact(opts, "acceptOwnership") +} + +func (_DKG *DKGSession) AcceptOwnership() (*types.Transaction, error) { + return _DKG.Contract.AcceptOwnership(&_DKG.TransactOpts) +} + +func (_DKG *DKGTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _DKG.Contract.AcceptOwnership(&_DKG.TransactOpts) +} + +func (_DKG *DKGTransactor) AddClient(opts *bind.TransactOpts, keyID [32]byte, clientAddress common.Address) (*types.Transaction, error) { + return _DKG.contract.Transact(opts, "addClient", keyID, clientAddress) +} + +func (_DKG *DKGSession) AddClient(keyID [32]byte, clientAddress common.Address) (*types.Transaction, error) { + return _DKG.Contract.AddClient(&_DKG.TransactOpts, keyID, clientAddress) +} + +func (_DKG *DKGTransactorSession) AddClient(keyID [32]byte, clientAddress common.Address) (*types.Transaction, error) { + return _DKG.Contract.AddClient(&_DKG.TransactOpts, keyID, clientAddress) +} + +func (_DKG *DKGTransactor) RemoveClient(opts *bind.TransactOpts, keyID [32]byte, clientAddress common.Address) (*types.Transaction, error) { + return _DKG.contract.Transact(opts, "removeClient", keyID, clientAddress) +} + +func (_DKG *DKGSession) RemoveClient(keyID [32]byte, clientAddress common.Address) (*types.Transaction, error) { + return _DKG.Contract.RemoveClient(&_DKG.TransactOpts, keyID, clientAddress) +} + +func (_DKG *DKGTransactorSession) RemoveClient(keyID [32]byte, clientAddress common.Address) (*types.Transaction, error) { + return _DKG.Contract.RemoveClient(&_DKG.TransactOpts, keyID, clientAddress) +} + +func (_DKG *DKGTransactor) SetConfig(opts *bind.TransactOpts, _signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) { + return _DKG.contract.Transact(opts, "setConfig", _signers, _transmitters, _f, _onchainConfig, _offchainConfigVersion, _offchainConfig) +} + +func (_DKG *DKGSession) SetConfig(_signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) { + return _DKG.Contract.SetConfig(&_DKG.TransactOpts, _signers, _transmitters, _f, _onchainConfig, _offchainConfigVersion, _offchainConfig) +} + +func (_DKG *DKGTransactorSession) SetConfig(_signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) { + return _DKG.Contract.SetConfig(&_DKG.TransactOpts, _signers, _transmitters, _f, _onchainConfig, _offchainConfigVersion, _offchainConfig) +} + +func (_DKG *DKGTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _DKG.contract.Transact(opts, "transferOwnership", to) +} + +func (_DKG *DKGSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _DKG.Contract.TransferOwnership(&_DKG.TransactOpts, to) +} + +func (_DKG *DKGTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _DKG.Contract.TransferOwnership(&_DKG.TransactOpts, to) +} + +func (_DKG *DKGTransactor) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _DKG.contract.Transact(opts, "transmit", reportContext, report, rs, ss, rawVs) +} + +func (_DKG *DKGSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _DKG.Contract.Transmit(&_DKG.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_DKG *DKGTransactorSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _DKG.Contract.Transmit(&_DKG.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +type DKGConfigSetIterator struct { + Event *DKGConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DKGConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DKGConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DKGConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DKGConfigSetIterator) Error() error { + return it.fail +} + +func (it *DKGConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DKGConfigSet struct { + PreviousConfigBlockNumber uint32 + ConfigDigest [32]byte + ConfigCount uint64 + Signers []common.Address + Transmitters []common.Address + F uint8 + OnchainConfig []byte + OffchainConfigVersion uint64 + OffchainConfig []byte + Raw types.Log +} + +func (_DKG *DKGFilterer) FilterConfigSet(opts *bind.FilterOpts) (*DKGConfigSetIterator, error) { + + logs, sub, err := _DKG.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &DKGConfigSetIterator{contract: _DKG.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_DKG *DKGFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *DKGConfigSet) (event.Subscription, error) { + + logs, sub, err := _DKG.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DKGConfigSet) + if err := _DKG.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DKG *DKGFilterer) ParseConfigSet(log types.Log) (*DKGConfigSet, error) { + event := new(DKGConfigSet) + if err := _DKG.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DKGDKGClientErrorIterator struct { + Event *DKGDKGClientError + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DKGDKGClientErrorIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DKGDKGClientError) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DKGDKGClientError) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DKGDKGClientErrorIterator) Error() error { + return it.fail +} + +func (it *DKGDKGClientErrorIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DKGDKGClientError struct { + Client common.Address + ErrorData []byte + Raw types.Log +} + +func (_DKG *DKGFilterer) FilterDKGClientError(opts *bind.FilterOpts) (*DKGDKGClientErrorIterator, error) { + + logs, sub, err := _DKG.contract.FilterLogs(opts, "DKGClientError") + if err != nil { + return nil, err + } + return &DKGDKGClientErrorIterator{contract: _DKG.contract, event: "DKGClientError", logs: logs, sub: sub}, nil +} + +func (_DKG *DKGFilterer) WatchDKGClientError(opts *bind.WatchOpts, sink chan<- *DKGDKGClientError) (event.Subscription, error) { + + logs, sub, err := _DKG.contract.WatchLogs(opts, "DKGClientError") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DKGDKGClientError) + if err := _DKG.contract.UnpackLog(event, "DKGClientError", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DKG *DKGFilterer) ParseDKGClientError(log types.Log) (*DKGDKGClientError, error) { + event := new(DKGDKGClientError) + if err := _DKG.contract.UnpackLog(event, "DKGClientError", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DKGKeyGeneratedIterator struct { + Event *DKGKeyGenerated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DKGKeyGeneratedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DKGKeyGenerated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DKGKeyGenerated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DKGKeyGeneratedIterator) Error() error { + return it.fail +} + +func (it *DKGKeyGeneratedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DKGKeyGenerated struct { + ConfigDigest [32]byte + KeyID [32]byte + Key KeyDataStructKeyData + Raw types.Log +} + +func (_DKG *DKGFilterer) FilterKeyGenerated(opts *bind.FilterOpts, configDigest [][32]byte, keyID [][32]byte) (*DKGKeyGeneratedIterator, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + var keyIDRule []interface{} + for _, keyIDItem := range keyID { + keyIDRule = append(keyIDRule, keyIDItem) + } + + logs, sub, err := _DKG.contract.FilterLogs(opts, "KeyGenerated", configDigestRule, keyIDRule) + if err != nil { + return nil, err + } + return &DKGKeyGeneratedIterator{contract: _DKG.contract, event: "KeyGenerated", logs: logs, sub: sub}, nil +} + +func (_DKG *DKGFilterer) WatchKeyGenerated(opts *bind.WatchOpts, sink chan<- *DKGKeyGenerated, configDigest [][32]byte, keyID [][32]byte) (event.Subscription, error) { + + var configDigestRule []interface{} + for _, configDigestItem := range configDigest { + configDigestRule = append(configDigestRule, configDigestItem) + } + var keyIDRule []interface{} + for _, keyIDItem := range keyID { + keyIDRule = append(keyIDRule, keyIDItem) + } + + logs, sub, err := _DKG.contract.WatchLogs(opts, "KeyGenerated", configDigestRule, keyIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DKGKeyGenerated) + if err := _DKG.contract.UnpackLog(event, "KeyGenerated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DKG *DKGFilterer) ParseKeyGenerated(log types.Log) (*DKGKeyGenerated, error) { + event := new(DKGKeyGenerated) + if err := _DKG.contract.UnpackLog(event, "KeyGenerated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DKGOwnershipTransferRequestedIterator struct { + Event *DKGOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DKGOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DKGOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DKGOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DKGOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *DKGOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DKGOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_DKG *DKGFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DKGOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _DKG.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &DKGOwnershipTransferRequestedIterator{contract: _DKG.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_DKG *DKGFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *DKGOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _DKG.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DKGOwnershipTransferRequested) + if err := _DKG.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DKG *DKGFilterer) ParseOwnershipTransferRequested(log types.Log) (*DKGOwnershipTransferRequested, error) { + event := new(DKGOwnershipTransferRequested) + if err := _DKG.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DKGOwnershipTransferredIterator struct { + Event *DKGOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DKGOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DKGOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DKGOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DKGOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *DKGOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DKGOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_DKG *DKGFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DKGOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _DKG.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &DKGOwnershipTransferredIterator{contract: _DKG.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_DKG *DKGFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *DKGOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _DKG.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DKGOwnershipTransferred) + if err := _DKG.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DKG *DKGFilterer) ParseOwnershipTransferred(log types.Log) (*DKGOwnershipTransferred, error) { + event := new(DKGOwnershipTransferred) + if err := _DKG.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type DKGTransmittedIterator struct { + Event *DKGTransmitted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *DKGTransmittedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(DKGTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(DKGTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *DKGTransmittedIterator) Error() error { + return it.fail +} + +func (it *DKGTransmittedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type DKGTransmitted struct { + ConfigDigest [32]byte + Epoch uint32 + Raw types.Log +} + +func (_DKG *DKGFilterer) FilterTransmitted(opts *bind.FilterOpts) (*DKGTransmittedIterator, error) { + + logs, sub, err := _DKG.contract.FilterLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return &DKGTransmittedIterator{contract: _DKG.contract, event: "Transmitted", logs: logs, sub: sub}, nil +} + +func (_DKG *DKGFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *DKGTransmitted) (event.Subscription, error) { + + logs, sub, err := _DKG.contract.WatchLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(DKGTransmitted) + if err := _DKG.contract.UnpackLog(event, "Transmitted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_DKG *DKGFilterer) ParseTransmitted(log types.Log) (*DKGTransmitted, error) { + event := new(DKGTransmitted) + if err := _DKG.contract.UnpackLog(event, "Transmitted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LatestConfigDetails struct { + ConfigCount uint32 + BlockNumber uint32 + ConfigDigest [32]byte +} +type LatestConfigDigestAndEpoch struct { + ScanLogs bool + ConfigDigest [32]byte + Epoch uint32 +} + +func (_DKG *DKG) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _DKG.abi.Events["ConfigSet"].ID: + return _DKG.ParseConfigSet(log) + case _DKG.abi.Events["DKGClientError"].ID: + return _DKG.ParseDKGClientError(log) + case _DKG.abi.Events["KeyGenerated"].ID: + return _DKG.ParseKeyGenerated(log) + case _DKG.abi.Events["OwnershipTransferRequested"].ID: + return _DKG.ParseOwnershipTransferRequested(log) + case _DKG.abi.Events["OwnershipTransferred"].ID: + return _DKG.ParseOwnershipTransferred(log) + case _DKG.abi.Events["Transmitted"].ID: + return _DKG.ParseTransmitted(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (DKGConfigSet) Topic() common.Hash { + return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") +} + +func (DKGDKGClientError) Topic() common.Hash { + return common.HexToHash("0x116391732f5df106193bda7cedf1728f3b07b62f6cdcdd611c9eeec44efcae54") +} + +func (DKGKeyGenerated) Topic() common.Hash { + return common.HexToHash("0xc8db841f5b2231ccf7190311f440aa197b161e369f3b40b023508160cc555656") +} + +func (DKGOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (DKGOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (DKGTransmitted) Topic() common.Hash { + return common.HexToHash("0xb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62") +} + +func (_DKG *DKG) Address() common.Address { + return _DKG.address +} + +type DKGInterface interface { + GetKey(opts *bind.CallOpts, _keyID [32]byte, _configDigest [32]byte) (KeyDataStructKeyData, error) + + LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) + + LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + AddClient(opts *bind.TransactOpts, keyID [32]byte, clientAddress common.Address) (*types.Transaction, error) + + RemoveClient(opts *bind.TransactOpts, keyID [32]byte, clientAddress common.Address) (*types.Transaction, error) + + SetConfig(opts *bind.TransactOpts, _signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) + + FilterConfigSet(opts *bind.FilterOpts) (*DKGConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *DKGConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*DKGConfigSet, error) + + FilterDKGClientError(opts *bind.FilterOpts) (*DKGDKGClientErrorIterator, error) + + WatchDKGClientError(opts *bind.WatchOpts, sink chan<- *DKGDKGClientError) (event.Subscription, error) + + ParseDKGClientError(log types.Log) (*DKGDKGClientError, error) + + FilterKeyGenerated(opts *bind.FilterOpts, configDigest [][32]byte, keyID [][32]byte) (*DKGKeyGeneratedIterator, error) + + WatchKeyGenerated(opts *bind.WatchOpts, sink chan<- *DKGKeyGenerated, configDigest [][32]byte, keyID [][32]byte) (event.Subscription, error) + + ParseKeyGenerated(log types.Log) (*DKGKeyGenerated, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DKGOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *DKGOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*DKGOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*DKGOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *DKGOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*DKGOwnershipTransferred, error) + + FilterTransmitted(opts *bind.FilterOpts) (*DKGTransmittedIterator, error) + + WatchTransmitted(opts *bind.WatchOpts, sink chan<- *DKGTransmitted) (event.Subscription, error) + + ParseTransmitted(log types.Log) (*DKGTransmitted, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ocr2vrf/generated/load_test_beacon_consumer/load_test_beacon_consumer.go b/core/gethwrappers/ocr2vrf/generated/load_test_beacon_consumer/load_test_beacon_consumer.go new file mode 100644 index 00000000000..32bf1e66219 --- /dev/null +++ b/core/gethwrappers/ocr2vrf/generated/load_test_beacon_consumer/load_test_beacon_consumer.go @@ -0,0 +1,1422 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package load_test_beacon_consumer + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var LoadTestBeaconVRFConsumerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"shouldFail\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"beaconPeriodBlocks\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"MustBeCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeOwnerOrCoordinator\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"CoordinatorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fail\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"reqID\",\"type\":\"uint256\"}],\"name\":\"getFulfillmentDurationByRequestID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"reqID\",\"type\":\"uint256\"}],\"name\":\"getRawFulfillmentDurationByRequestID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_beaconPeriodBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingRequests\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"arguments\",\"type\":\"bytes\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"requestHeights\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reset\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_ReceivedRandomnessByRequestID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_arguments\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_averageFulfillmentInMillions\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fastestFulfillment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_fulfillmentDurationInBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_gasAvailable\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_mostRecentRequestID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_myBeaconRequests\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"slotNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"confirmationDelay\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_randomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_rawFulfillmentDurationInBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requestIDs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requestOutputHeights\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"\",\"type\":\"uint24\"}],\"name\":\"s_requestsIDs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_resetCounter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_slowestFulfillment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_slowestRequestID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_subId\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalFulfilled\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalRequests\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"shouldFail\",\"type\":\"bool\"}],\"name\":\"setFail\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"reqId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"height\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"delay\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"}],\"name\":\"storeBeaconRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"}],\"name\":\"testRedeemRandomness\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"confirmationDelayArg\",\"type\":\"uint24\"}],\"name\":\"testRequestRandomness\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"uint24\",\"name\":\"confDelay\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"arguments\",\"type\":\"bytes\"}],\"name\":\"testRequestRandomnessFulfillment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"uint24\",\"name\":\"confirmationDelayArg\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"arguments\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"batchSize\",\"type\":\"uint256\"}],\"name\":\"testRequestRandomnessFulfillmentBatch\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040526000600d556000600e556103e7600f556000601055600060115560006012553480156200003057600080fd5b5060405162001f6138038062001f618339810160408190526200005391620001d0565b828282823380600081620000ae5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000e157620000e18162000125565b5050600280546001600160a01b0319166001600160a01b03939093169290921790915550600b805460ff191692151592909217909155600c55506200022792505050565b336001600160a01b038216036200017f5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000a5565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080600060608486031215620001e657600080fd5b83516001600160a01b0381168114620001fe57600080fd5b602085015190935080151581146200021557600080fd5b80925050604084015190509250925092565b611d2a80620002376000396000f3fe608060405234801561001057600080fd5b50600436106102775760003560e01c806379ba509711610160578063d0705f04116100d8578063f2fde38b1161008c578063f6eaffc811610071578063f6eaffc8146105bc578063fc7fea37146105cf578063ffe97ca4146105d857600080fd5b8063f2fde38b1461057e578063f371829b1461059157600080fd5b8063d826f88f116100bd578063d826f88f1461055a578063ea7502ab14610562578063f08c5daa1461057557600080fd5b8063d0705f0414610534578063d21ea8fd1461054757600080fd5b80638ea981171161012f578063a9cc471811610114578063a9cc4718146104fb578063c6d6130114610518578063cd0593df1461052b57600080fd5b80638ea98117146104a95780639d769402146104bc57600080fd5b806379ba5097146104675780638866c6bd1461046f5780638d0e3165146104785780638da5cb5b1461048157600080fd5b80635a947873116101f35780636df57cc3116101c2578063737144bc116101a7578063737144bc1461044057806374dba124146104495780637716cdaa1461045257600080fd5b80636df57cc314610400578063706da1ca1461041357600080fd5b80635a947873146103b05780635f15cccc146103c3578063601201d3146103ee578063689b77ab146103f757600080fd5b80632b1a21301161024a578063341867a21161022f578063341867a21461035b578063353e0f60146103705780634a0aee291461039b57600080fd5b80632b1a21301461031d5780632fe8fa311461033057600080fd5b80631591950a1461027c5780631757f11c146102ba578063195e0d75146102c35780631e87f20e146102f0575b600080fd5b6102a761028a366004611503565b601560209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6102a7600e5481565b6102a76102d1366004611525565b6012546000908152601860209081526040808320938352929052205490565b6102a76102fe366004611525565b6012546000908152601760209081526040808320938352929052205490565b6102a761032b366004611503565b61068b565b6102a761033e366004611503565b601760209081526000928352604080842090915290825290205481565b61036e610369366004611503565b6106bc565b005b6102a761037e366004611503565b601660209081526000928352604080842090915290825290205481565b6103a36107b1565b6040516102b1919061153e565b6103a36103be3660046116cc565b6108c1565b6102a76103d136600461174d565b600460209081526000928352604080842090915290825290205481565b6102a760115481565b6102a760085481565b61036e61040e366004611779565b610a1f565b6009546104279067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016102b1565b6102a7600d5481565b6102a7600f5481565b61045a610b5a565b6040516102b19190611823565b61036e610be8565b6102a760105481565b6102a760135481565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102b1565b61036e6104b736600461183d565b610cea565b61036e6104ca366004611873565b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b600b546105089060ff1681565b60405190151581526020016102b1565b6102a7610526366004611895565b610dd0565b6102a7600c5481565b6102a7610542366004611503565b610eda565b61036e6105553660046118f5565b610ef6565b61036e610f57565b6102a76105703660046119be565b610f8d565b6102a7600a5481565b61036e61058c36600461183d565b61109d565b6102a761059f366004611503565b601860209081526000928352604080842090915290825290205481565b6102a76105ca366004611525565b6110b1565b6102a760125481565b6106416105e6366004611525565b60056020526000908152604090205463ffffffff811690640100000000810462ffffff1690670100000000000000810461ffff16906901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1684565b6040805163ffffffff909516855262ffffff909316602085015261ffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff1660608201526080016102b1565b601460205281600052604060002081815481106106a757600080fd5b90600052602060002001600091509150505481565b60025460408051602081018252600080825291517facfc6cdd000000000000000000000000000000000000000000000000000000008152919273ffffffffffffffffffffffffffffffffffffffff169163acfc6cdd916107229187918791600401611a37565b6000604051808303816000875af1158015610741573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526107879190810190611a5f565b600083815260066020908152604090912082519293506107ab9290918401906114a3565b50505050565b6012546000908152601460205260408120546060919067ffffffffffffffff8111156107df576107df6115c0565b604051908082528060200260200182016040528015610808578160200160208202803683370190505b5090506000805b6012546000908152601460205260409020548110156108b957601254600090815260146020526040812080548390811061084b5761084b611af0565b600091825260208083209091015460125483526017825260408084208285529092529082205490925090036108a6578084848151811061088d5761088d611af0565b6020908102919091010152826108a281611b4e565b9350505b50806108b181611b4e565b91505061080f565b508152919050565b606060008267ffffffffffffffff8111156108de576108de6115c0565b604051908082528060200260200182016040528015610907578160200160208202803683370190505b5090506000600c546109176110d2565b6109219190611bb5565b9050600081600c546109316110d2565b61093b9190611bc9565b6109459190611be2565b905060005b85811015610a105760006109618c8c8c8c8c610f8d565b60108054919250600061097383611b4e565b90915550506012546000908152601560209081526040808320848452909152902083905561099f6110d2565b60128054600090815260166020908152604080832086845282528083209490945591548152601482529182208054600181018255908352912001819055845181908690849081106109f2576109f2611af0565b60209081029190910101525080610a0881611b4e565b91505061094a565b50919998505050505050505050565b600083815260046020908152604080832062ffffff861684529091528120859055600c54610a4d9085611bf5565b6040805160808101825263ffffffff928316815262ffffff958616602080830191825261ffff968716838501908152306060850190815260009b8c526005909252939099209151825491519351995173ffffffffffffffffffffffffffffffffffffffff166901000000000000000000027fffffff0000000000000000000000000000000000000000ffffffffffffffffff9a90971667010000000000000002999099167fffffff00000000000000000000000000000000000000000000ffffffffffffff93909716640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffff000000000000009091169890931697909717919091171692909217179092555050565b60078054610b6790611c09565b80601f0160208091040260200160405190810160405280929190818152602001828054610b9390611c09565b8015610be05780601f10610bb557610100808354040283529160200191610be0565b820191906000526020600020905b815481529060010190602001808311610bc357829003601f168201915b505050505081565b60015473ffffffffffffffffffffffffffffffffffffffff163314610c6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610d2a575060025473ffffffffffffffffffffffffffffffffffffffff163314155b15610d61576040517fd4e06fd700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517fc258faa9a17ddfdf4130b4acff63a289202e7d5f9e42f366add65368575486bc90600090a250565b600080600c54610dde6110d2565b610de89190611bb5565b9050600081600c54610df86110d2565b610e029190611bc9565b610e0c9190611be2565b60025460408051602081018252600080825291517f4ffac83a000000000000000000000000000000000000000000000000000000008152939450909273ffffffffffffffffffffffffffffffffffffffff90921691634ffac83a91610e7a918a918c918b9190600401611c5c565b6020604051808303816000875af1158015610e99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ebd9190611c94565b9050610ecb8183878a610a1f565b60088190559695505050505050565b600660205281600052604060002081815481106106a757600080fd5b60025473ffffffffffffffffffffffffffffffffffffffff163314610f47576040517f66bf9c7200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f52838383611169565b505050565b6000600d819055600e8190556103e7600f556010819055601181905560138190556012805491610f8683611b4e565b9190505550565b600080600c54610f9b6110d2565b610fa59190611bb5565b9050600081600c54610fb56110d2565b610fbf9190611bc9565b610fc99190611be2565b60025460408051602081018252600080825291517fdb972c8b000000000000000000000000000000000000000000000000000000008152939450909273ffffffffffffffffffffffffffffffffffffffff9092169163db972c8b9161103b918d918d918d918d918d9190600401611cad565b6020604051808303816000875af115801561105a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107e9190611c94565b905061108c8183898b610a1f565b600881905598975050505050505050565b6110a561132b565b6110ae816113ae565b50565b600381815481106110c157600080fd5b600091825260209091200154905081565b60004661a4b18114806110e7575062066eed81145b1561116257606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611138573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115c9190611c94565b91505090565b4391505090565b600b5460ff16156111d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f206661696c656420696e2066756c66696c6c52616e646f6d576f7264730000006044820152606401610c65565b600083815260066020908152604090912083516111f5928501906114a3565b50601254600090815260156020908152604080832086845290915281205461121b6110d2565b6112259190611be2565b60125460009081526016602090815260408083208884529091528120549192509061124e6110d2565b6112589190611be2565b9050600061126983620f4240611d06565b9050600e5483111561128057600e83905560138690555b600f54831061129157600f54611293565b825b600f556011546112a357806112d6565b6011546112b1906001611bc9565b81601154600d546112c29190611d06565b6112cc9190611bc9565b6112d69190611bf5565b600d55601180549060006112e983611b4e565b90915550506012805460009081526017602090815260408083208a84528252808320969096559154815260188252848120978152969052509320929092555050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146113ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610c65565b565b3373ffffffffffffffffffffffffffffffffffffffff82160361142d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610c65565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b8280548282559060005260206000209081019282156114de579160200282015b828111156114de5782518255916020019190600101906114c3565b506114ea9291506114ee565b5090565b5b808211156114ea57600081556001016114ef565b6000806040838503121561151657600080fd5b50508035926020909101359150565b60006020828403121561153757600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b818110156115765783518352928401929184019160010161155a565b50909695505050505050565b803561ffff8116811461159457600080fd5b919050565b803562ffffff8116811461159457600080fd5b803563ffffffff8116811461159457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611636576116366115c0565b604052919050565b600082601f83011261164f57600080fd5b813567ffffffffffffffff811115611669576116696115c0565b61169a60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016115ef565b8181528460208386010111156116af57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c087890312156116e557600080fd5b863595506116f560208801611582565b945061170360408801611599565b9350611711606088016115ac565b9250608087013567ffffffffffffffff81111561172d57600080fd5b61173989828a0161163e565b92505060a087013590509295509295509295565b6000806040838503121561176057600080fd5b8235915061177060208401611599565b90509250929050565b6000806000806080858703121561178f57600080fd5b84359350602085013592506117a660408601611599565b91506117b460608601611582565b905092959194509250565b6000815180845260005b818110156117e5576020818501810151868301820152016117c9565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061183660208301846117bf565b9392505050565b60006020828403121561184f57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461183657600080fd5b60006020828403121561188557600080fd5b8135801515811461183657600080fd5b6000806000606084860312156118aa57600080fd5b6118b384611582565b9250602084013591506118c860408501611599565b90509250925092565b600067ffffffffffffffff8211156118eb576118eb6115c0565b5060051b60200190565b60008060006060848603121561190a57600080fd5b8335925060208085013567ffffffffffffffff8082111561192a57600080fd5b818701915087601f83011261193e57600080fd5b813561195161194c826118d1565b6115ef565b81815260059190911b8301840190848101908a83111561197057600080fd5b938501935b8285101561198e57843582529385019390850190611975565b9650505060408701359250808311156119a657600080fd5b50506119b48682870161163e565b9150509250925092565b600080600080600060a086880312156119d657600080fd5b853594506119e660208701611582565b93506119f460408701611599565b9250611a02606087016115ac565b9150608086013567ffffffffffffffff811115611a1e57600080fd5b611a2a8882890161163e565b9150509295509295909350565b838152826020820152606060408201526000611a5660608301846117bf565b95945050505050565b60006020808385031215611a7257600080fd5b825167ffffffffffffffff811115611a8957600080fd5b8301601f81018513611a9a57600080fd5b8051611aa861194c826118d1565b81815260059190911b82018301908381019087831115611ac757600080fd5b928401925b82841015611ae557835182529284019290840190611acc565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611b7f57611b7f611b1f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611bc457611bc4611b86565b500690565b80820180821115611bdc57611bdc611b1f565b92915050565b81810381811115611bdc57611bdc611b1f565b600082611c0457611c04611b86565b500490565b600181811c90821680611c1d57607f821691505b602082108103611c56577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b84815261ffff8416602082015262ffffff83166040820152608060608201526000611c8a60808301846117bf565b9695505050505050565b600060208284031215611ca657600080fd5b5051919050565b86815261ffff8616602082015262ffffff8516604082015263ffffffff8416606082015260c060808201526000611ce760c08301856117bf565b82810360a0840152611cf981856117bf565b9998505050505050505050565b8082028115828204841417611bdc57611bdc611b1f56fea164736f6c6343000813000a", +} + +var LoadTestBeaconVRFConsumerABI = LoadTestBeaconVRFConsumerMetaData.ABI + +var LoadTestBeaconVRFConsumerBin = LoadTestBeaconVRFConsumerMetaData.Bin + +func DeployLoadTestBeaconVRFConsumer(auth *bind.TransactOpts, backend bind.ContractBackend, coordinator common.Address, shouldFail bool, beaconPeriodBlocks *big.Int) (common.Address, *types.Transaction, *LoadTestBeaconVRFConsumer, error) { + parsed, err := LoadTestBeaconVRFConsumerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(LoadTestBeaconVRFConsumerBin), backend, coordinator, shouldFail, beaconPeriodBlocks) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &LoadTestBeaconVRFConsumer{LoadTestBeaconVRFConsumerCaller: LoadTestBeaconVRFConsumerCaller{contract: contract}, LoadTestBeaconVRFConsumerTransactor: LoadTestBeaconVRFConsumerTransactor{contract: contract}, LoadTestBeaconVRFConsumerFilterer: LoadTestBeaconVRFConsumerFilterer{contract: contract}}, nil +} + +type LoadTestBeaconVRFConsumer struct { + address common.Address + abi abi.ABI + LoadTestBeaconVRFConsumerCaller + LoadTestBeaconVRFConsumerTransactor + LoadTestBeaconVRFConsumerFilterer +} + +type LoadTestBeaconVRFConsumerCaller struct { + contract *bind.BoundContract +} + +type LoadTestBeaconVRFConsumerTransactor struct { + contract *bind.BoundContract +} + +type LoadTestBeaconVRFConsumerFilterer struct { + contract *bind.BoundContract +} + +type LoadTestBeaconVRFConsumerSession struct { + Contract *LoadTestBeaconVRFConsumer + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type LoadTestBeaconVRFConsumerCallerSession struct { + Contract *LoadTestBeaconVRFConsumerCaller + CallOpts bind.CallOpts +} + +type LoadTestBeaconVRFConsumerTransactorSession struct { + Contract *LoadTestBeaconVRFConsumerTransactor + TransactOpts bind.TransactOpts +} + +type LoadTestBeaconVRFConsumerRaw struct { + Contract *LoadTestBeaconVRFConsumer +} + +type LoadTestBeaconVRFConsumerCallerRaw struct { + Contract *LoadTestBeaconVRFConsumerCaller +} + +type LoadTestBeaconVRFConsumerTransactorRaw struct { + Contract *LoadTestBeaconVRFConsumerTransactor +} + +func NewLoadTestBeaconVRFConsumer(address common.Address, backend bind.ContractBackend) (*LoadTestBeaconVRFConsumer, error) { + abi, err := abi.JSON(strings.NewReader(LoadTestBeaconVRFConsumerABI)) + if err != nil { + return nil, err + } + contract, err := bindLoadTestBeaconVRFConsumer(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &LoadTestBeaconVRFConsumer{address: address, abi: abi, LoadTestBeaconVRFConsumerCaller: LoadTestBeaconVRFConsumerCaller{contract: contract}, LoadTestBeaconVRFConsumerTransactor: LoadTestBeaconVRFConsumerTransactor{contract: contract}, LoadTestBeaconVRFConsumerFilterer: LoadTestBeaconVRFConsumerFilterer{contract: contract}}, nil +} + +func NewLoadTestBeaconVRFConsumerCaller(address common.Address, caller bind.ContractCaller) (*LoadTestBeaconVRFConsumerCaller, error) { + contract, err := bindLoadTestBeaconVRFConsumer(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &LoadTestBeaconVRFConsumerCaller{contract: contract}, nil +} + +func NewLoadTestBeaconVRFConsumerTransactor(address common.Address, transactor bind.ContractTransactor) (*LoadTestBeaconVRFConsumerTransactor, error) { + contract, err := bindLoadTestBeaconVRFConsumer(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &LoadTestBeaconVRFConsumerTransactor{contract: contract}, nil +} + +func NewLoadTestBeaconVRFConsumerFilterer(address common.Address, filterer bind.ContractFilterer) (*LoadTestBeaconVRFConsumerFilterer, error) { + contract, err := bindLoadTestBeaconVRFConsumer(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &LoadTestBeaconVRFConsumerFilterer{contract: contract}, nil +} + +func bindLoadTestBeaconVRFConsumer(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := LoadTestBeaconVRFConsumerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LoadTestBeaconVRFConsumer.Contract.LoadTestBeaconVRFConsumerCaller.contract.Call(opts, result, method, params...) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.LoadTestBeaconVRFConsumerTransactor.contract.Transfer(opts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.LoadTestBeaconVRFConsumerTransactor.contract.Transact(opts, method, params...) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _LoadTestBeaconVRFConsumer.Contract.contract.Call(opts, result, method, params...) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.contract.Transfer(opts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.contract.Transact(opts, method, params...) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) Fail(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "fail") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) Fail() (bool, error) { + return _LoadTestBeaconVRFConsumer.Contract.Fail(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) Fail() (bool, error) { + return _LoadTestBeaconVRFConsumer.Contract.Fail(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) GetFulfillmentDurationByRequestID(opts *bind.CallOpts, reqID *big.Int) (*big.Int, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "getFulfillmentDurationByRequestID", reqID) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) GetFulfillmentDurationByRequestID(reqID *big.Int) (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.GetFulfillmentDurationByRequestID(&_LoadTestBeaconVRFConsumer.CallOpts, reqID) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) GetFulfillmentDurationByRequestID(reqID *big.Int) (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.GetFulfillmentDurationByRequestID(&_LoadTestBeaconVRFConsumer.CallOpts, reqID) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) GetRawFulfillmentDurationByRequestID(opts *bind.CallOpts, reqID *big.Int) (*big.Int, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "getRawFulfillmentDurationByRequestID", reqID) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) GetRawFulfillmentDurationByRequestID(reqID *big.Int) (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.GetRawFulfillmentDurationByRequestID(&_LoadTestBeaconVRFConsumer.CallOpts, reqID) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) GetRawFulfillmentDurationByRequestID(reqID *big.Int) (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.GetRawFulfillmentDurationByRequestID(&_LoadTestBeaconVRFConsumer.CallOpts, reqID) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) IBeaconPeriodBlocks(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "i_beaconPeriodBlocks") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) IBeaconPeriodBlocks() (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.IBeaconPeriodBlocks(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) IBeaconPeriodBlocks() (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.IBeaconPeriodBlocks(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) Owner() (common.Address, error) { + return _LoadTestBeaconVRFConsumer.Contract.Owner(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) Owner() (common.Address, error) { + return _LoadTestBeaconVRFConsumer.Contract.Owner(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) PendingRequests(opts *bind.CallOpts) ([]*big.Int, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "pendingRequests") + + if err != nil { + return *new([]*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) PendingRequests() ([]*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.PendingRequests(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) PendingRequests() ([]*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.PendingRequests(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) RequestHeights(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "requestHeights", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) RequestHeights(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.RequestHeights(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) RequestHeights(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.RequestHeights(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SReceivedRandomnessByRequestID(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_ReceivedRandomnessByRequestID", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SReceivedRandomnessByRequestID(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SReceivedRandomnessByRequestID(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SReceivedRandomnessByRequestID(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SReceivedRandomnessByRequestID(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SArguments(opts *bind.CallOpts) ([]byte, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_arguments") + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SArguments() ([]byte, error) { + return _LoadTestBeaconVRFConsumer.Contract.SArguments(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SArguments() ([]byte, error) { + return _LoadTestBeaconVRFConsumer.Contract.SArguments(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SAverageFulfillmentInMillions(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_averageFulfillmentInMillions") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SAverageFulfillmentInMillions() (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SAverageFulfillmentInMillions(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SAverageFulfillmentInMillions() (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SAverageFulfillmentInMillions(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SFastestFulfillment(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_fastestFulfillment") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SFastestFulfillment() (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SFastestFulfillment(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SFastestFulfillment() (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SFastestFulfillment(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SFulfillmentDurationInBlocks(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_fulfillmentDurationInBlocks", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SFulfillmentDurationInBlocks(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SFulfillmentDurationInBlocks(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SFulfillmentDurationInBlocks(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SFulfillmentDurationInBlocks(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SGasAvailable(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_gasAvailable") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SGasAvailable() (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SGasAvailable(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SGasAvailable() (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SGasAvailable(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SMostRecentRequestID(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_mostRecentRequestID") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SMostRecentRequestID() (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SMostRecentRequestID(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SMostRecentRequestID() (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SMostRecentRequestID(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SMyBeaconRequests(opts *bind.CallOpts, arg0 *big.Int) (SMyBeaconRequests, + + error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_myBeaconRequests", arg0) + + outstruct := new(SMyBeaconRequests) + if err != nil { + return *outstruct, err + } + + outstruct.SlotNumber = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.ConfirmationDelay = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.NumWords = *abi.ConvertType(out[2], new(uint16)).(*uint16) + outstruct.Requester = *abi.ConvertType(out[3], new(common.Address)).(*common.Address) + + return *outstruct, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SMyBeaconRequests(arg0 *big.Int) (SMyBeaconRequests, + + error) { + return _LoadTestBeaconVRFConsumer.Contract.SMyBeaconRequests(&_LoadTestBeaconVRFConsumer.CallOpts, arg0) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SMyBeaconRequests(arg0 *big.Int) (SMyBeaconRequests, + + error) { + return _LoadTestBeaconVRFConsumer.Contract.SMyBeaconRequests(&_LoadTestBeaconVRFConsumer.CallOpts, arg0) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SRandomWords(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_randomWords", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SRandomWords(arg0 *big.Int) (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SRandomWords(&_LoadTestBeaconVRFConsumer.CallOpts, arg0) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SRandomWords(arg0 *big.Int) (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SRandomWords(&_LoadTestBeaconVRFConsumer.CallOpts, arg0) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SRawFulfillmentDurationInBlocks(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_rawFulfillmentDurationInBlocks", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SRawFulfillmentDurationInBlocks(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SRawFulfillmentDurationInBlocks(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SRawFulfillmentDurationInBlocks(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SRawFulfillmentDurationInBlocks(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SRequestIDs(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_requestIDs", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SRequestIDs(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SRequestIDs(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SRequestIDs(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SRequestIDs(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SRequestOutputHeights(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_requestOutputHeights", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SRequestOutputHeights(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SRequestOutputHeights(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SRequestOutputHeights(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SRequestOutputHeights(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SRequestsIDs(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_requestsIDs", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SRequestsIDs(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SRequestsIDs(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SRequestsIDs(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SRequestsIDs(&_LoadTestBeaconVRFConsumer.CallOpts, arg0, arg1) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SResetCounter(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_resetCounter") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SResetCounter() (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SResetCounter(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SResetCounter() (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SResetCounter(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SSlowestFulfillment(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_slowestFulfillment") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SSlowestFulfillment() (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SSlowestFulfillment(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SSlowestFulfillment() (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SSlowestFulfillment(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SSlowestRequestID(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_slowestRequestID") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SSlowestRequestID() (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SSlowestRequestID(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SSlowestRequestID() (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.SSlowestRequestID(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) SSubId(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_subId") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SSubId() (uint64, error) { + return _LoadTestBeaconVRFConsumer.Contract.SSubId(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) SSubId() (uint64, error) { + return _LoadTestBeaconVRFConsumer.Contract.SSubId(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) STotalFulfilled(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_totalFulfilled") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) STotalFulfilled() (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.STotalFulfilled(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) STotalFulfilled() (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.STotalFulfilled(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCaller) STotalRequests(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _LoadTestBeaconVRFConsumer.contract.Call(opts, &out, "s_totalRequests") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) STotalRequests() (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.STotalRequests(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerCallerSession) STotalRequests() (*big.Int, error) { + return _LoadTestBeaconVRFConsumer.Contract.STotalRequests(&_LoadTestBeaconVRFConsumer.CallOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.contract.Transact(opts, "acceptOwnership") +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) AcceptOwnership() (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.AcceptOwnership(&_LoadTestBeaconVRFConsumer.TransactOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.AcceptOwnership(&_LoadTestBeaconVRFConsumer.TransactOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactor) RawFulfillRandomWords(opts *bind.TransactOpts, requestID *big.Int, randomWords []*big.Int, arguments []byte) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.contract.Transact(opts, "rawFulfillRandomWords", requestID, randomWords, arguments) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) RawFulfillRandomWords(requestID *big.Int, randomWords []*big.Int, arguments []byte) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.RawFulfillRandomWords(&_LoadTestBeaconVRFConsumer.TransactOpts, requestID, randomWords, arguments) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorSession) RawFulfillRandomWords(requestID *big.Int, randomWords []*big.Int, arguments []byte) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.RawFulfillRandomWords(&_LoadTestBeaconVRFConsumer.TransactOpts, requestID, randomWords, arguments) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactor) Reset(opts *bind.TransactOpts) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.contract.Transact(opts, "reset") +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) Reset() (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.Reset(&_LoadTestBeaconVRFConsumer.TransactOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorSession) Reset() (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.Reset(&_LoadTestBeaconVRFConsumer.TransactOpts) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactor) SetCoordinator(opts *bind.TransactOpts, coordinator common.Address) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.contract.Transact(opts, "setCoordinator", coordinator) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SetCoordinator(coordinator common.Address) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.SetCoordinator(&_LoadTestBeaconVRFConsumer.TransactOpts, coordinator) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorSession) SetCoordinator(coordinator common.Address) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.SetCoordinator(&_LoadTestBeaconVRFConsumer.TransactOpts, coordinator) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactor) SetFail(opts *bind.TransactOpts, shouldFail bool) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.contract.Transact(opts, "setFail", shouldFail) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) SetFail(shouldFail bool) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.SetFail(&_LoadTestBeaconVRFConsumer.TransactOpts, shouldFail) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorSession) SetFail(shouldFail bool) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.SetFail(&_LoadTestBeaconVRFConsumer.TransactOpts, shouldFail) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactor) StoreBeaconRequest(opts *bind.TransactOpts, reqId *big.Int, height *big.Int, delay *big.Int, numWords uint16) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.contract.Transact(opts, "storeBeaconRequest", reqId, height, delay, numWords) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) StoreBeaconRequest(reqId *big.Int, height *big.Int, delay *big.Int, numWords uint16) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.StoreBeaconRequest(&_LoadTestBeaconVRFConsumer.TransactOpts, reqId, height, delay, numWords) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorSession) StoreBeaconRequest(reqId *big.Int, height *big.Int, delay *big.Int, numWords uint16) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.StoreBeaconRequest(&_LoadTestBeaconVRFConsumer.TransactOpts, reqId, height, delay, numWords) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactor) TestRedeemRandomness(opts *bind.TransactOpts, subID *big.Int, requestID *big.Int) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.contract.Transact(opts, "testRedeemRandomness", subID, requestID) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) TestRedeemRandomness(subID *big.Int, requestID *big.Int) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.TestRedeemRandomness(&_LoadTestBeaconVRFConsumer.TransactOpts, subID, requestID) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorSession) TestRedeemRandomness(subID *big.Int, requestID *big.Int) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.TestRedeemRandomness(&_LoadTestBeaconVRFConsumer.TransactOpts, subID, requestID) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactor) TestRequestRandomness(opts *bind.TransactOpts, numWords uint16, subID *big.Int, confirmationDelayArg *big.Int) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.contract.Transact(opts, "testRequestRandomness", numWords, subID, confirmationDelayArg) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) TestRequestRandomness(numWords uint16, subID *big.Int, confirmationDelayArg *big.Int) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.TestRequestRandomness(&_LoadTestBeaconVRFConsumer.TransactOpts, numWords, subID, confirmationDelayArg) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorSession) TestRequestRandomness(numWords uint16, subID *big.Int, confirmationDelayArg *big.Int) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.TestRequestRandomness(&_LoadTestBeaconVRFConsumer.TransactOpts, numWords, subID, confirmationDelayArg) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactor) TestRequestRandomnessFulfillment(opts *bind.TransactOpts, subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.contract.Transact(opts, "testRequestRandomnessFulfillment", subID, numWords, confDelay, callbackGasLimit, arguments) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) TestRequestRandomnessFulfillment(subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.TestRequestRandomnessFulfillment(&_LoadTestBeaconVRFConsumer.TransactOpts, subID, numWords, confDelay, callbackGasLimit, arguments) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorSession) TestRequestRandomnessFulfillment(subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.TestRequestRandomnessFulfillment(&_LoadTestBeaconVRFConsumer.TransactOpts, subID, numWords, confDelay, callbackGasLimit, arguments) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactor) TestRequestRandomnessFulfillmentBatch(opts *bind.TransactOpts, subID *big.Int, numWords uint16, confirmationDelayArg *big.Int, callbackGasLimit uint32, arguments []byte, batchSize *big.Int) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.contract.Transact(opts, "testRequestRandomnessFulfillmentBatch", subID, numWords, confirmationDelayArg, callbackGasLimit, arguments, batchSize) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) TestRequestRandomnessFulfillmentBatch(subID *big.Int, numWords uint16, confirmationDelayArg *big.Int, callbackGasLimit uint32, arguments []byte, batchSize *big.Int) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.TestRequestRandomnessFulfillmentBatch(&_LoadTestBeaconVRFConsumer.TransactOpts, subID, numWords, confirmationDelayArg, callbackGasLimit, arguments, batchSize) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorSession) TestRequestRandomnessFulfillmentBatch(subID *big.Int, numWords uint16, confirmationDelayArg *big.Int, callbackGasLimit uint32, arguments []byte, batchSize *big.Int) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.TestRequestRandomnessFulfillmentBatch(&_LoadTestBeaconVRFConsumer.TransactOpts, subID, numWords, confirmationDelayArg, callbackGasLimit, arguments, batchSize) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.contract.Transact(opts, "transferOwnership", to) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.TransferOwnership(&_LoadTestBeaconVRFConsumer.TransactOpts, to) +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _LoadTestBeaconVRFConsumer.Contract.TransferOwnership(&_LoadTestBeaconVRFConsumer.TransactOpts, to) +} + +type LoadTestBeaconVRFConsumerCoordinatorUpdatedIterator struct { + Event *LoadTestBeaconVRFConsumerCoordinatorUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LoadTestBeaconVRFConsumerCoordinatorUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LoadTestBeaconVRFConsumerCoordinatorUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LoadTestBeaconVRFConsumerCoordinatorUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LoadTestBeaconVRFConsumerCoordinatorUpdatedIterator) Error() error { + return it.fail +} + +func (it *LoadTestBeaconVRFConsumerCoordinatorUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LoadTestBeaconVRFConsumerCoordinatorUpdated struct { + Coordinator common.Address + Raw types.Log +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerFilterer) FilterCoordinatorUpdated(opts *bind.FilterOpts, coordinator []common.Address) (*LoadTestBeaconVRFConsumerCoordinatorUpdatedIterator, error) { + + var coordinatorRule []interface{} + for _, coordinatorItem := range coordinator { + coordinatorRule = append(coordinatorRule, coordinatorItem) + } + + logs, sub, err := _LoadTestBeaconVRFConsumer.contract.FilterLogs(opts, "CoordinatorUpdated", coordinatorRule) + if err != nil { + return nil, err + } + return &LoadTestBeaconVRFConsumerCoordinatorUpdatedIterator{contract: _LoadTestBeaconVRFConsumer.contract, event: "CoordinatorUpdated", logs: logs, sub: sub}, nil +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerFilterer) WatchCoordinatorUpdated(opts *bind.WatchOpts, sink chan<- *LoadTestBeaconVRFConsumerCoordinatorUpdated, coordinator []common.Address) (event.Subscription, error) { + + var coordinatorRule []interface{} + for _, coordinatorItem := range coordinator { + coordinatorRule = append(coordinatorRule, coordinatorItem) + } + + logs, sub, err := _LoadTestBeaconVRFConsumer.contract.WatchLogs(opts, "CoordinatorUpdated", coordinatorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LoadTestBeaconVRFConsumerCoordinatorUpdated) + if err := _LoadTestBeaconVRFConsumer.contract.UnpackLog(event, "CoordinatorUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerFilterer) ParseCoordinatorUpdated(log types.Log) (*LoadTestBeaconVRFConsumerCoordinatorUpdated, error) { + event := new(LoadTestBeaconVRFConsumerCoordinatorUpdated) + if err := _LoadTestBeaconVRFConsumer.contract.UnpackLog(event, "CoordinatorUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LoadTestBeaconVRFConsumerOwnershipTransferRequestedIterator struct { + Event *LoadTestBeaconVRFConsumerOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LoadTestBeaconVRFConsumerOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LoadTestBeaconVRFConsumerOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LoadTestBeaconVRFConsumerOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LoadTestBeaconVRFConsumerOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *LoadTestBeaconVRFConsumerOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LoadTestBeaconVRFConsumerOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LoadTestBeaconVRFConsumerOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LoadTestBeaconVRFConsumer.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &LoadTestBeaconVRFConsumerOwnershipTransferRequestedIterator{contract: _LoadTestBeaconVRFConsumer.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *LoadTestBeaconVRFConsumerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LoadTestBeaconVRFConsumer.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LoadTestBeaconVRFConsumerOwnershipTransferRequested) + if err := _LoadTestBeaconVRFConsumer.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerFilterer) ParseOwnershipTransferRequested(log types.Log) (*LoadTestBeaconVRFConsumerOwnershipTransferRequested, error) { + event := new(LoadTestBeaconVRFConsumerOwnershipTransferRequested) + if err := _LoadTestBeaconVRFConsumer.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LoadTestBeaconVRFConsumerOwnershipTransferredIterator struct { + Event *LoadTestBeaconVRFConsumerOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LoadTestBeaconVRFConsumerOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LoadTestBeaconVRFConsumerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(LoadTestBeaconVRFConsumerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *LoadTestBeaconVRFConsumerOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *LoadTestBeaconVRFConsumerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LoadTestBeaconVRFConsumerOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LoadTestBeaconVRFConsumerOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LoadTestBeaconVRFConsumer.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &LoadTestBeaconVRFConsumerOwnershipTransferredIterator{contract: _LoadTestBeaconVRFConsumer.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *LoadTestBeaconVRFConsumerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _LoadTestBeaconVRFConsumer.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LoadTestBeaconVRFConsumerOwnershipTransferred) + if err := _LoadTestBeaconVRFConsumer.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumerFilterer) ParseOwnershipTransferred(log types.Log) (*LoadTestBeaconVRFConsumerOwnershipTransferred, error) { + event := new(LoadTestBeaconVRFConsumerOwnershipTransferred) + if err := _LoadTestBeaconVRFConsumer.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type SMyBeaconRequests struct { + SlotNumber uint32 + ConfirmationDelay *big.Int + NumWords uint16 + Requester common.Address +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumer) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _LoadTestBeaconVRFConsumer.abi.Events["CoordinatorUpdated"].ID: + return _LoadTestBeaconVRFConsumer.ParseCoordinatorUpdated(log) + case _LoadTestBeaconVRFConsumer.abi.Events["OwnershipTransferRequested"].ID: + return _LoadTestBeaconVRFConsumer.ParseOwnershipTransferRequested(log) + case _LoadTestBeaconVRFConsumer.abi.Events["OwnershipTransferred"].ID: + return _LoadTestBeaconVRFConsumer.ParseOwnershipTransferred(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (LoadTestBeaconVRFConsumerCoordinatorUpdated) Topic() common.Hash { + return common.HexToHash("0xc258faa9a17ddfdf4130b4acff63a289202e7d5f9e42f366add65368575486bc") +} + +func (LoadTestBeaconVRFConsumerOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (LoadTestBeaconVRFConsumerOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (_LoadTestBeaconVRFConsumer *LoadTestBeaconVRFConsumer) Address() common.Address { + return _LoadTestBeaconVRFConsumer.address +} + +type LoadTestBeaconVRFConsumerInterface interface { + Fail(opts *bind.CallOpts) (bool, error) + + GetFulfillmentDurationByRequestID(opts *bind.CallOpts, reqID *big.Int) (*big.Int, error) + + GetRawFulfillmentDurationByRequestID(opts *bind.CallOpts, reqID *big.Int) (*big.Int, error) + + IBeaconPeriodBlocks(opts *bind.CallOpts) (*big.Int, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + PendingRequests(opts *bind.CallOpts) ([]*big.Int, error) + + RequestHeights(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) + + SReceivedRandomnessByRequestID(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) + + SArguments(opts *bind.CallOpts) ([]byte, error) + + SAverageFulfillmentInMillions(opts *bind.CallOpts) (*big.Int, error) + + SFastestFulfillment(opts *bind.CallOpts) (*big.Int, error) + + SFulfillmentDurationInBlocks(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) + + SGasAvailable(opts *bind.CallOpts) (*big.Int, error) + + SMostRecentRequestID(opts *bind.CallOpts) (*big.Int, error) + + SMyBeaconRequests(opts *bind.CallOpts, arg0 *big.Int) (SMyBeaconRequests, + + error) + + SRandomWords(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) + + SRawFulfillmentDurationInBlocks(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) + + SRequestIDs(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) + + SRequestOutputHeights(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) + + SRequestsIDs(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) + + SResetCounter(opts *bind.CallOpts) (*big.Int, error) + + SSlowestFulfillment(opts *bind.CallOpts) (*big.Int, error) + + SSlowestRequestID(opts *bind.CallOpts) (*big.Int, error) + + SSubId(opts *bind.CallOpts) (uint64, error) + + STotalFulfilled(opts *bind.CallOpts) (*big.Int, error) + + STotalRequests(opts *bind.CallOpts) (*big.Int, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + RawFulfillRandomWords(opts *bind.TransactOpts, requestID *big.Int, randomWords []*big.Int, arguments []byte) (*types.Transaction, error) + + Reset(opts *bind.TransactOpts) (*types.Transaction, error) + + SetCoordinator(opts *bind.TransactOpts, coordinator common.Address) (*types.Transaction, error) + + SetFail(opts *bind.TransactOpts, shouldFail bool) (*types.Transaction, error) + + StoreBeaconRequest(opts *bind.TransactOpts, reqId *big.Int, height *big.Int, delay *big.Int, numWords uint16) (*types.Transaction, error) + + TestRedeemRandomness(opts *bind.TransactOpts, subID *big.Int, requestID *big.Int) (*types.Transaction, error) + + TestRequestRandomness(opts *bind.TransactOpts, numWords uint16, subID *big.Int, confirmationDelayArg *big.Int) (*types.Transaction, error) + + TestRequestRandomnessFulfillment(opts *bind.TransactOpts, subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte) (*types.Transaction, error) + + TestRequestRandomnessFulfillmentBatch(opts *bind.TransactOpts, subID *big.Int, numWords uint16, confirmationDelayArg *big.Int, callbackGasLimit uint32, arguments []byte, batchSize *big.Int) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterCoordinatorUpdated(opts *bind.FilterOpts, coordinator []common.Address) (*LoadTestBeaconVRFConsumerCoordinatorUpdatedIterator, error) + + WatchCoordinatorUpdated(opts *bind.WatchOpts, sink chan<- *LoadTestBeaconVRFConsumerCoordinatorUpdated, coordinator []common.Address) (event.Subscription, error) + + ParseCoordinatorUpdated(log types.Log) (*LoadTestBeaconVRFConsumerCoordinatorUpdated, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LoadTestBeaconVRFConsumerOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *LoadTestBeaconVRFConsumerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*LoadTestBeaconVRFConsumerOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*LoadTestBeaconVRFConsumerOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *LoadTestBeaconVRFConsumerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*LoadTestBeaconVRFConsumerOwnershipTransferred, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ocr2vrf/generated/vrf_beacon/vrf_beacon.go b/core/gethwrappers/ocr2vrf/generated/vrf_beacon/vrf_beacon.go new file mode 100644 index 00000000000..b44019de548 --- /dev/null +++ b/core/gethwrappers/ocr2vrf/generated/vrf_beacon/vrf_beacon.go @@ -0,0 +1,2846 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package vrf_beacon + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type ECCArithmeticG1Point struct { + P [2]*big.Int +} + +type KeyDataStructKeyData struct { + PublicKey []byte + Hashes [][32]byte +} + +type VRFBeaconReportReport struct { + Outputs []VRFBeaconTypesVRFOutput + JuelsPerFeeCoin *big.Int + ReasonableGasPrice uint64 + RecentBlockHeight uint64 + RecentBlockHash [32]byte +} + +type VRFBeaconTypesCallback struct { + RequestID *big.Int + NumWords uint16 + Requester common.Address + Arguments []byte + GasAllowance *big.Int + SubID *big.Int + GasPrice *big.Int + WeiPerUnitLink *big.Int +} + +type VRFBeaconTypesCostedCallback struct { + Callback VRFBeaconTypesCallback + Price *big.Int +} + +type VRFBeaconTypesOutputServed struct { + Height uint64 + ConfirmationDelay *big.Int + ProofG1X *big.Int + ProofG1Y *big.Int +} + +type VRFBeaconTypesVRFOutput struct { + BlockHeight uint64 + ConfirmationDelay *big.Int + VrfOutput ECCArithmeticG1Point + Callbacks []VRFBeaconTypesCostedCallback + ShouldStore bool +} + +var VRFBeaconMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"contractIVRFCoordinatorProducerAPI\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"contractDKG\",\"name\":\"keyProvider\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"keyID\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expectedLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualLength\",\"type\":\"uint256\"}],\"name\":\"CalldataLengthMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotAcceptPayeeship\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"providedHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"onchainHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"blockHeight\",\"type\":\"uint64\"}],\"name\":\"HistoryDomainSeparatorWrong\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numTransmitters\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"numPayees\",\"type\":\"uint256\"}],\"name\":\"IncorrectNumberOfPayees\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"expectedNumSignatures\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"rsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ssLength\",\"type\":\"uint256\"}],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"actualBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredBalance\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyProvider\",\"type\":\"address\"}],\"name\":\"KeyInfoMustComeFromProvider\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeftGasExceedsInitialGas\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeOwnerOrBillingAdmin\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"numFaultyOracles\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"}],\"name\":\"NumberOfFaultyOraclesTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"expectedLength\",\"type\":\"uint256\"}],\"name\":\"OnchainConfigHasWrongLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCurrentPayee\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"existingPayee\",\"type\":\"address\"}],\"name\":\"PayeeAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"repeatedSignerAddress\",\"type\":\"address\"}],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"repeatedTransmitterAddress\",\"type\":\"address\"}],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReportDoesNotContainNewOutputs\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"numTransmitters\",\"type\":\"uint256\"}],\"name\":\"SignersTransmittersMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"maxOracles\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"providedOracles\",\"type\":\"uint256\"}],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"ocrVersion\",\"type\":\"uint64\"}],\"name\":\"UnknownConfigVersion\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contractAccessControllerInterface\",\"name\":\"old\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contractAccessControllerInterface\",\"name\":\"current\",\"type\":\"address\"}],\"name\":\"BillingAccessControllerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"maximumGasPrice\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"reasonableGasPrice\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"observationPayment\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"transmissionPayment\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint24\",\"name\":\"accountingGas\",\"type\":\"uint24\"}],\"name\":\"BillingSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint40\",\"name\":\"epochAndRound\",\"type\":\"uint40\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint192\",\"name\":\"juelsPerFeeCoin\",\"type\":\"uint192\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"reasonableGasPrice\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"NewTransmission\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"contractLinkTokenInterface\",\"name\":\"linkToken\",\"type\":\"address\"}],\"name\":\"OraclePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"recentBlockHeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint192\",\"name\":\"juelsPerFeeCoin\",\"type\":\"uint192\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"reasonableGasPrice\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"height\",\"type\":\"uint64\"},{\"internalType\":\"uint24\",\"name\":\"confirmationDelay\",\"type\":\"uint24\"},{\"internalType\":\"uint256\",\"name\":\"proofG1X\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofG1Y\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structVRFBeaconTypes.OutputServed[]\",\"name\":\"outputsServed\",\"type\":\"tuple[]\"}],\"name\":\"OutputsServed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"current\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previous\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"current\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"requestIDs\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"successfulFulfillment\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes[]\",\"name\":\"truncatedErrorData\",\"type\":\"bytes[]\"},{\"indexed\":false,\"internalType\":\"uint96[]\",\"name\":\"subBalances\",\"type\":\"uint96[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"subIDs\",\"type\":\"uint256[]\"}],\"name\":\"RandomWordsFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nextBeaconOutputHeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint24\",\"name\":\"confDelay\",\"type\":\"uint24\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasAllowance\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"weiPerUnitLink\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"arguments\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"costJuels\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSubBalance\",\"type\":\"uint256\"}],\"name\":\"RandomnessFulfillmentRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"}],\"name\":\"RandomnessRedeemed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nextBeaconOutputHeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint24\",\"name\":\"confDelay\",\"type\":\"uint24\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"costJuels\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSubBalance\",\"type\":\"uint256\"}],\"name\":\"RandomnessRequested\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"NUM_CONF_DELAYS\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"acceptPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"blockHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint24\",\"name\":\"confirmationDelay\",\"type\":\"uint24\"},{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"p\",\"type\":\"uint256[2]\"}],\"internalType\":\"structECCArithmetic.G1Point\",\"name\":\"vrfOutput\",\"type\":\"tuple\"},{\"components\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"arguments\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"gasAllowance\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"weiPerUnitLink\",\"type\":\"uint256\"}],\"internalType\":\"structVRFBeaconTypes.Callback\",\"name\":\"callback\",\"type\":\"tuple\"},{\"internalType\":\"uint96\",\"name\":\"price\",\"type\":\"uint96\"}],\"internalType\":\"structVRFBeaconTypes.CostedCallback[]\",\"name\":\"callbacks\",\"type\":\"tuple[]\"},{\"internalType\":\"bool\",\"name\":\"shouldStore\",\"type\":\"bool\"}],\"internalType\":\"structVRFBeaconTypes.VRFOutput[]\",\"name\":\"outputs\",\"type\":\"tuple[]\"},{\"internalType\":\"uint192\",\"name\":\"juelsPerFeeCoin\",\"type\":\"uint192\"},{\"internalType\":\"uint64\",\"name\":\"reasonableGasPrice\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"recentBlockHeight\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"recentBlockHash\",\"type\":\"bytes32\"}],\"internalType\":\"structVRFBeaconReport.Report\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"exposeType\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBilling\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"maximumGasPrice\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"reasonableGasPrice\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"observationPayment\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"transmissionPayment\",\"type\":\"uint64\"},{\"internalType\":\"uint24\",\"name\":\"accountingGas\",\"type\":\"uint24\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBillingAccessController\",\"outputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_coordinator\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorProducerAPI\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_link\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"publicKey\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"hashes\",\"type\":\"bytes32[]\"}],\"internalType\":\"structKeyDataStruct.KeyData\",\"name\":\"kd\",\"type\":\"tuple\"}],\"name\":\"keyGenerated\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"availableBalance\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"newKeyRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitterAddress\",\"type\":\"address\"}],\"name\":\"owedPayment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_keyID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_keyProvider\",\"outputs\":[{\"internalType\":\"contractDKG\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_provingKeyHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"maximumGasPrice\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"reasonableGasPrice\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"observationPayment\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"transmissionPayment\",\"type\":\"uint64\"},{\"internalType\":\"uint24\",\"name\":\"accountingGas\",\"type\":\"uint24\"}],\"name\":\"setBilling\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"_billingAccessController\",\"type\":\"address\"}],\"name\":\"setBillingAccessController\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"setPayees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"withdrawPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b5060405162004dfe38038062004dfe8339810160408190526200003491620001c7565b8181858581813380600081620000915760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c457620000c48162000103565b5050506001600160a01b03918216608052811660a052600e80546001600160a01b03191695909116949094179093555060c05250620002219350505050565b336001600160a01b038216036200015d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000088565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b0381168114620001c457600080fd5b50565b60008060008060808587031215620001de57600080fd5b8451620001eb81620001ae565b6020860151909450620001fe81620001ae565b60408601519093506200021181620001ae565b6060959095015193969295505050565b60805160a05160c051614b28620002d660003960006104810152600081816103820152818161114e015281816112260152818161131c0152818161141d015281816114bb01528181612216015281816122ee015281816124650152818161275a01528181612b8301528181612c5b0152818161316501526136cd01526000818161032b015281816112540152818161144a0152818161231c015281816124c301528181612c8901526130500152614b286000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c8063afcb95d7116100f9578063d09dc33911610097578063e53bbc9a11610071578063e53bbc9a146104c7578063eb5dcd6c146104da578063f2fde38b146104ed578063fbffd2c11461050057600080fd5b8063d09dc339146104a3578063d57fc45a146104ab578063e3d0e712146104b457600080fd5b8063bf2732c7116100d3578063bf2732c714610438578063c10753291461044b578063c4c92b371461045e578063cc31f7dd1461047c57600080fd5b8063afcb95d7146103e8578063b121e14714610412578063b1dc65a41461042557600080fd5b806379ba5097116101665780638a1b1772116101405780638a1b17721461037d5780638ac28d5a146103a45780638da5cb5b146103b75780639c849b30146103d557600080fd5b806379ba50971461031e5780637d253aff1461032657806381ff70481461034d57600080fd5b806329937268116101a257806329937268146102415780632f7527cc146102b757806355e48749146102d15780635f27026f146102d957600080fd5b806305aeed58146101c95780630eafb25b146101dc578063181f5a7714610202575b600080fd5b6101da6101d73660046137f7565b50565b005b6101ef6101ea366004613854565b610513565b6040519081526020015b60405180910390f35b604080518082018252600f81527f565246426561636f6e20312e302e300000000000000000000000000000000000602082015290516101f991906138df565b60025460035460408051610100840467ffffffffffffffff9081168252690100000000000000000085048116602083015271010000000000000000000000000000000000909404841691810191909152918116606083015268010000000000000000900462ffffff16608082015260a0016101f9565b6102bf600881565b60405160ff90911681526020016101f9565b6101da61059f565b600e546102f99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f9565b6101da61061c565b6102f97f000000000000000000000000000000000000000000000000000000000000000081565b6004546005546040805163ffffffff808516825264010000000090940490931660208401528201526060016101f9565b6102f97f000000000000000000000000000000000000000000000000000000000000000081565b6101da6103b2366004613854565b610719565b60005473ffffffffffffffffffffffffffffffffffffffff166102f9565b6101da6103e336600461393e565b610782565b6005546006546040805160008152602081019390935263ffffffff909116908201526060016101f9565b6101da610420366004613854565b6109d4565b6101da6104333660046139ec565b610acc565b6101da610446366004613c89565b610f87565b6101da610459366004613d56565b611046565b600d5473ffffffffffffffffffffffffffffffffffffffff166102f9565b6101ef7f000000000000000000000000000000000000000000000000000000000000000081565b6101ef6113e0565b6101ef600f5481565b6101da6104c2366004613db9565b611573565b6101da6104d5366004613eb8565b611dc9565b6101da6104e8366004613f29565b61201b565b6101da6104fb366004613854565b612174565b6101da61050e366004613854565b612185565b73ffffffffffffffffffffffffffffffffffffffff811660009081526007602090815260408083208151606081018352905460ff80821615158084526101008304909116948301949094526201000090046bffffffffffffffffffffffff1691810191909152906105875750600092915050565b604001516bffffffffffffffffffffffff1692915050565b600e5473ffffffffffffffffffffffffffffffffffffffff16338114610614576040517f292f4fb500000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff821660248201526044015b60405180910390fd5b506000600f55565b60015473ffffffffffffffffffffffffffffffffffffffff16331461069d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161060b565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152600b6020526040902054163314610779576040517fdce38c2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101d781612196565b61078a612569565b8281146107cd576040517f36d20459000000000000000000000000000000000000000000000000000000008152600481018490526024810182905260440161060b565b60005b838110156109cd5760008585838181106107ec576107ec613f62565b90506020020160208101906108019190613854565b9050600084848481811061081757610817613f62565b905060200201602081019061082c9190613854565b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600b602052604090205491925016801580158161089257508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b156108e9576040517febdf175600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80861660048301528316602482015260440161060b565b73ffffffffffffffffffffffffffffffffffffffff8481166000908152600b6020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016858316908117909155908316146109b6578273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b360405160405180910390a45b5050505080806109c590613fc0565b9150506107d0565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152600c6020526040902054163314610a34576040517f9d12ec4f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8181166000818152600b602090815260408083208054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217909355600c909452828520805490921690915590519416939092849290917f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b39190a45050565b60005a6040805160c08101825260025460ff808216835267ffffffffffffffff61010083048116602080860191909152690100000000000000000084048216858701527101000000000000000000000000000000000090930481166060850152600354908116608085015262ffffff680100000000000000009091041660a08401523360009081526007835293909320549394509092908c01359116610ba0576040517fb1c1f68e00000000000000000000000000000000000000000000000000000000815233600482015260240161060b565b6005548b3514610bea576005546040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101919091528b35602482015260440161060b565b610bf88a8a8a8a8a8a6125ec565b8151610c05906001613ff8565b60ff1687141580610c165750868514155b15610c6e578151610c28906001613ff8565b6040517ffc33647500000000000000000000000000000000000000000000000000000000815260ff9091166004820152602481018890526044810186905260640161060b565b60008a8a604051610c80929190614011565b604051908190038120610c97918e90602001614021565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012083830190925260008084529083018190529092509060005b8a811015610e885760006001858a8460208110610d0457610d04613f62565b610d1191901a601b613ff8565b8f8f86818110610d2357610d23613f62565b905060200201358e8e87818110610d3c57610d3c613f62565b9050602002013560405160008152602001604052604051610d79949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015610d9b573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526008602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290955092509050610e61576040517f20fb74ee00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161060b565b826020015160080260ff166001901b84019350508080610e8090613fc0565b915050610ce5565b5081827e010101010101010101010101010101010101010101010101010101010101011614610ee3576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060009150819050610f328d826020020135848e8e8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061267c92505050565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff600888901c161790559092509050610f7884838388336128c6565b50505050505050505050505050565b600e5473ffffffffffffffffffffffffffffffffffffffff16338114610ff7576040517f292f4fb500000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8216602482015260440161060b565b81516040516110099190602001614035565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120600f555050565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906111075750600d546040517f6b14daf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690636b14daf8906110c4903390600090369060040161409a565b602060405180830381865afa1580156110e1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061110591906140da565b155b1561113e576040517fc04ecc2800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611148612a24565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663597d2f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111db91906140f5565b905060006111e9828461410e565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301529192506000917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa15801561129b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bf91906140f5565b905081811015611305576040517fcf479181000000000000000000000000000000000000000000000000000000008152600481018290526024810183905260440161060b565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663f99b1d688761135561134f8686614121565b89612b1f565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526024820152604401600060405180830381600087803b1580156113c057600080fd5b505af11580156113d4573d6000803e3d6000fd5b50505050505050505050565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015260009182917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015611491573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114b591906140f5565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663597d2f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611524573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154891906140f5565b90506000611554612a24565b9050816115618285614134565b61156b9190614134565b935050505090565b888787601f8311156115bb576040517f809fc428000000000000000000000000000000000000000000000000000000008152601f60048201526024810184905260440161060b565b8183146115fe576040517f988a0804000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260440161060b565b61160981600361415b565b60ff168311611650576040517ffda9db7800000000000000000000000000000000000000000000000000000000815260ff821660048201526024810184905260440161060b565b61165c8160ff16612b39565b611664612569565b60006040518060c001604052808f8f80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505081526020018d8d8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050509082525060ff8c1660208083019190915260408051601f8d0183900483028101830182528c8152920191908c908c908190840183828082843760009201919091525050509082525067ffffffffffffffff891660208083019190915260408051601f8a01839004830281018301825289815292019190899089908190840183828082843760009201919091525050509152509050611786612b73565b60095460005b8181101561187f576000600982815481106117a9576117a9613f62565b6000918252602082200154600a805473ffffffffffffffffffffffffffffffffffffffff909216935090849081106117e3576117e3613f62565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff948516835260088252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016905594168252600790529190912080547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169055508061187781613fc0565b91505061178c565b5061188c6009600061373a565b611898600a600061373a565b60005b825151811015611c215760086000846000015183815181106118bf576118bf613f62565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff161561196357825180518290811061190c5761190c613f62565b60200260200101516040517f7451f83e00000000000000000000000000000000000000000000000000000000815260040161060b919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b604080518082019091526001815260ff82166020820152835180516008916000918590811061199457611994613f62565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281810192909252604001600090812083518154948401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009095169015157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff161761010060ff90951694909402939093179092558401518051600792919084908110611a4657611a46613f62565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff1615611aec5782602001518181518110611a9557611a95613f62565b60200260200101516040517fe8d2989900000000000000000000000000000000000000000000000000000000815260040161060b919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405180606001604052806001151581526020018260ff16815260200160006bffffffffffffffffffffffff168152506007600085602001518481518110611b3657611b36613f62565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600020835181549385015194909201516bffffffffffffffffffffffff1662010000027fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff931515939093167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090941693909317919091179290921617905580611c1981613fc0565b91505061189b565b5081518051611c3891600991602090910190613758565b506020808301518051611c4f92600a920190613758565b506040820151600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600454640100000000900463ffffffff16611c9f6131d5565b6004805463ffffffff928316640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff82168117909255600092611ced9281169116176001614177565b905080600460006101000a81548163ffffffff021916908363ffffffff1602179055506000611d4146308463ffffffff16886000015189602001518a604001518b606001518c608001518d60a0015161326c565b9050806005819055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e058360055484886000015189602001518a604001518b606001518c608001518d60a00151604051611da3999897969594939291906141e5565b60405180910390a1611db58d8d613317565b505050505050505050505050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590611e8a5750600d546040517f6b14daf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690636b14daf890611e47903390600090369060040161409a565b602060405180830381865afa158015611e64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e8891906140da565b155b15611ec1576040517fc04ecc2800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ec9612b73565b6002805467ffffffffffffffff8581167101000000000000000000000000000000000081027fffffffffffffff0000000000000000ffffffffffffffffffffffffffffffffff898416690100000000000000000081027fffffffffffffffffffffffffffffff0000000000000000ffffffffffffffffff8d87166101008102919091167fffffffffffffffffffffffffffffff00000000000000000000000000000000ff909816979097171791909116919091179094556003805462ffffff87166801000000000000000081027fffffffffffffffffffffffffffffffffffffffffff00000000000000000000009092169489169485179190911790915560408051948552602085019590955293830152606082015260808101919091527f49275ddcdfc9c0519b3d094308c8bf675f06070a754ce90c152163cb6e66e8a09060a00160405180910390a15050505050565b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600b602052604090205416331461207b576040517fdce38c2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811633036120ca576040517fb387a23800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600c6020526040902080548383167fffffffffffffffffffffffff00000000000000000000000000000000000000008216811790925590911690811461216f5760405173ffffffffffffffffffffffffffffffffffffffff8084169133918616907f84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e3836790600090a45b505050565b61217c612569565b6101d781613325565b61218d612569565b6101d78161341a565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600760209081526040918290208251606081018452905460ff80821615158084526101008304909116938301939093526201000090046bffffffffffffffffffffffff1692810192909252612205575050565b600061221083610513565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663597d2f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561227f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122a391906140f5565b905060006122b1828461410e565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301529192506000917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015612363573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061238791906140f5565b9050818110156123cd576040517fcf479181000000000000000000000000000000000000000000000000000000008152600481018290526024810183905260440161060b565b83156125615773ffffffffffffffffffffffffffffffffffffffff8681166000908152600b602090815260408083205460079092529182902080547fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff16905590517ff99b1d680000000000000000000000000000000000000000000000000000000081529082166004820181905260248201879052917f0000000000000000000000000000000000000000000000000000000000000000169063f99b1d6890604401600060405180830381600087803b1580156124a957600080fd5b505af11580156124bd573d6000803e3d6000fd5b505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167fd0b1dac935d85bd54cf0a33b0d41d39f8cf53a968465fc7ea2377526b8ac712c8860405161255791815260200190565b60405180910390a4505b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146125ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161060b565b565b60006125f982602061427b565b61260485602061427b565b6126108861014461410e565b61261a919061410e565b612624919061410e565b61262f90600061410e565b9050368114612673576040517ff7b94f0a0000000000000000000000000000000000000000000000000000000081526004810182905236602482015260440161060b565b50505050505050565b60008060008380602001905181019061269591906144bf565b905060006126a682606001516134c2565b90508082608001511461270957608082015160608301516040517faed0afe500000000000000000000000000000000000000000000000000000000815260048101929092526024820183905267ffffffffffffffff16604482015260640161060b565b81516020830151604080850151606086015191517f76f2e3f400000000000000000000000000000000000000000000000000000000815260009473ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016946376f2e3f4946127929492939192916004016147fa565b6020604051808303816000875af11580156127b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127d591906140da565b90508061280e576040517f69c920fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8664ffffffffff167ffc3c7a7927e878a0fca37c904953c3c75cee3ca1d1640184a0ab1c65eec6274333856020015186604001518c6040516128a5949392919073ffffffffffffffffffffffffffffffffffffffff94909416845277ffffffffffffffffffffffffffffffffffffffffffffffff92909216602084015267ffffffffffffffff166040830152606082015260800190565b60405180910390a28260200151836040015194509450505050935093915050565b60006128f23a67ffffffffffffffff8616156128e257856128e8565b87604001515b88602001516135a5565b90506010360260005a9050600061291b8663ffffffff1685858c60a0015162ffffff16866135f6565b90506000670de0b6b3a764000077ffffffffffffffffffffffffffffffffffffffffffffffff8a16830273ffffffffffffffffffffffffffffffffffffffff881660009081526007602052604090205460808d01519290910492506201000090046bffffffffffffffffffffffff9081169167ffffffffffffffff16828401019081168211156129b157505050505050506109cd565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260076020526040902080546bffffffffffffffffffffffff90921662010000027fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff9092169190911790555050505050505050505050565b600080600a805480602002602001604051908101604052809291908181526020018280548015612a8a57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612a5f575b505083519394506000925050505b81811015612b195760076000848381518110612ab657612ab6613f62565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054612b05906201000090046bffffffffffffffffffffffff168561410e565b935080612b1181613fc0565b915050612a98565b50505090565b600081831015612b30575081612b33565b50805b92915050565b806000036101d7576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612b7d612a24565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663597d2f3c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c1091906140f5565b90506000612c1e828461410e565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301529192506000917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015612cd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cf491906140f5565b905081811015612d3a576040517fcf479181000000000000000000000000000000000000000000000000000000008152600481018290526024810183905260440161060b565b6000600a805480602002602001604051908101604052809291908181526020018280548015612d9f57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612d74575b5050505050905060008151905060008167ffffffffffffffff811115612dc757612dc7613aa3565b604051908082528060200260200182016040528015612df0578160200160208202803683370190505b50905060008267ffffffffffffffff811115612e0e57612e0e613aa3565b604051908082528060200260200182016040528015612e37578160200160208202803683370190505b5090506000805b8481101561311157600060076000888481518110612e5e57612e5e613f62565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160029054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff169050600060076000898581518110612ee457612ee4613f62565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002080546bffffffffffffffffffffffff9290921662010000027fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff909216919091179055808015613107576000600b60008a8681518110612f7557612f75613f62565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905080878681518110612fed57612fed613f62565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508186868151811061303a5761303a613f62565b60200260200101818152505084806001019550507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff168a86815181106130ae576130ae613f62565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fd0b1dac935d85bd54cf0a33b0d41d39f8cf53a968465fc7ea2377526b8ac712c856040516130fd91815260200190565b60405180910390a4505b5050600101612e3e565b5081518114613121578082528083525b8151156131ca576040517f73433a2f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906373433a2f9061319c908690869060040161496a565b600060405180830381600087803b1580156131b657600080fd5b505af1158015610f78573d6000803e3d6000fd5b505050505050505050565b60004661a4b18114806131ea575062066eed81145b1561326557606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561323b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061325f91906140f5565b91505090565b4391505090565b6000808a8a8a8a8a8a8a8a8a604051602001613290999897969594939291906149c1565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b613321828261363e565b5050565b3373ffffffffffffffffffffffffffffffffffffffff8216036133a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161060b565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600d5473ffffffffffffffffffffffffffffffffffffffff908116908216811461332157600d80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84811691821790925560408051928416835260208301919091527f793cb73064f3c8cde7e187ae515511e6e56d1ee89bf08b82fa60fb70f8d48912910160405180910390a15050565b60004661a4b18114806134d7575062066eed81145b15613595576101008367ffffffffffffffff166134f26131d5565b6134fc9190614121565b111561350b5750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152606490632b407a8290602401602060405180830381865afa15801561356a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061358e91906140f5565b9392505050565b505067ffffffffffffffff164090565b60008367ffffffffffffffff84168110156135d9576002858567ffffffffffffffff1603816135d6576135d661493b565b04015b6135ed818467ffffffffffffffff16612b1f565b95945050505050565b600081861015613632576040517f3fef97df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50909303019091010290565b610100818114613680578282826040517f418a179b00000000000000000000000000000000000000000000000000000000815260040161060b93929190614a56565b600061368e83850185614a7a565b90506040517f8eef585f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690638eef585f90613702908490600401614ae4565b600060405180830381600087803b15801561371c57600080fd5b505af1158015613730573d6000803e3d6000fd5b5050505050505050565b50805460008255906000526020600020908101906101d791906137e2565b8280548282559060005260206000209081019282156137d2579160200282015b828111156137d257825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190613778565b506137de9291506137e2565b5090565b5b808211156137de57600081556001016137e3565b60006020828403121561380957600080fd5b813567ffffffffffffffff81111561382057600080fd5b820160a0818503121561358e57600080fd5b73ffffffffffffffffffffffffffffffffffffffff811681146101d757600080fd5b60006020828403121561386657600080fd5b813561358e81613832565b60005b8381101561388c578181015183820152602001613874565b50506000910152565b600081518084526138ad816020860160208601613871565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061358e6020830184613895565b60008083601f84011261390457600080fd5b50813567ffffffffffffffff81111561391c57600080fd5b6020830191508360208260051b850101111561393757600080fd5b9250929050565b6000806000806040858703121561395457600080fd5b843567ffffffffffffffff8082111561396c57600080fd5b613978888389016138f2565b9096509450602087013591508082111561399157600080fd5b5061399e878288016138f2565b95989497509550505050565b60008083601f8401126139bc57600080fd5b50813567ffffffffffffffff8111156139d457600080fd5b60208301915083602082850101111561393757600080fd5b60008060008060008060008060e0898b031215613a0857600080fd5b606089018a811115613a1957600080fd5b8998503567ffffffffffffffff80821115613a3357600080fd5b613a3f8c838d016139aa565b909950975060808b0135915080821115613a5857600080fd5b613a648c838d016138f2565b909750955060a08b0135915080821115613a7d57600080fd5b50613a8a8b828c016138f2565b999c989b50969995989497949560c00135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715613af557613af5613aa3565b60405290565b604051610100810167ffffffffffffffff81118282101715613af557613af5613aa3565b60405160a0810167ffffffffffffffff81118282101715613af557613af5613aa3565b6040516020810167ffffffffffffffff81118282101715613af557613af5613aa3565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613bac57613bac613aa3565b604052919050565b600067ffffffffffffffff821115613bce57613bce613aa3565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600067ffffffffffffffff821115613c1457613c14613aa3565b5060051b60200190565b600082601f830112613c2f57600080fd5b81356020613c44613c3f83613bfa565b613b65565b82815260059290921b84018101918181019086841115613c6357600080fd5b8286015b84811015613c7e5780358352918301918301613c67565b509695505050505050565b60006020808385031215613c9c57600080fd5b823567ffffffffffffffff80821115613cb457600080fd5b9084019060408287031215613cc857600080fd5b613cd0613ad2565b823582811115613cdf57600080fd5b8301601f81018813613cf057600080fd5b8035613cfe613c3f82613bb4565b8181528987838501011115613d1257600080fd5b818784018883013760008783830101528084525050508383013582811115613d3957600080fd5b613d4588828601613c1e565b948201949094529695505050505050565b60008060408385031215613d6957600080fd5b8235613d7481613832565b946020939093013593505050565b803560ff81168114613d9357600080fd5b919050565b67ffffffffffffffff811681146101d757600080fd5b8035613d9381613d98565b60008060008060008060008060008060c08b8d031215613dd857600080fd5b8a3567ffffffffffffffff80821115613df057600080fd5b613dfc8e838f016138f2565b909c509a5060208d0135915080821115613e1557600080fd5b613e218e838f016138f2565b909a509850889150613e3560408e01613d82565b975060608d0135915080821115613e4b57600080fd5b613e578e838f016139aa565b9097509550859150613e6b60808e01613dae565b945060a08d0135915080821115613e8157600080fd5b50613e8e8d828e016139aa565b915080935050809150509295989b9194979a5092959850565b62ffffff811681146101d757600080fd5b600080600080600060a08688031215613ed057600080fd5b8535613edb81613d98565b94506020860135613eeb81613d98565b93506040860135613efb81613d98565b92506060860135613f0b81613d98565b91506080860135613f1b81613ea7565b809150509295509295909350565b60008060408385031215613f3c57600080fd5b8235613f4781613832565b91506020830135613f5781613832565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613ff157613ff1613f91565b5060010190565b60ff8181168382160190811115612b3357612b33613f91565b8183823760009101908152919050565b828152606082602083013760800192915050565b60008251614047818460208701613871565b9190910192915050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff841681526040602082015260006135ed604083018486614051565b80518015158114613d9357600080fd5b6000602082840312156140ec57600080fd5b61358e826140ca565b60006020828403121561410757600080fd5b5051919050565b80820180821115612b3357612b33613f91565b81810381811115612b3357612b33613f91565b818103600083128015838313168383128216171561415457614154613f91565b5092915050565b60ff818116838216029081169081811461415457614154613f91565b63ffffffff81811683821601908082111561415457614154613f91565b600081518084526020808501945080840160005b838110156141da57815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016141a8565b509495945050505050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526142158184018a614194565b905082810360808401526142298189614194565b905060ff871660a084015282810360c08401526142468187613895565b905067ffffffffffffffff851660e084015282810361010084015261426b8185613895565b9c9b505050505050505050505050565b8082028115828204841417612b3357612b33613f91565b8051613d9381613d98565b805161ffff81168114613d9357600080fd5b8051613d9381613832565b600082601f8301126142cb57600080fd5b81516142d9613c3f82613bb4565b8181528460208386010111156142ee57600080fd5b6142ff826020830160208701613871565b949350505050565b80516bffffffffffffffffffffffff81168114613d9357600080fd5b600082601f83011261433457600080fd5b81516020614344613c3f83613bfa565b82815260059290921b8401810191818101908684111561436357600080fd5b8286015b84811015613c7e57805167ffffffffffffffff8082111561438757600080fd5b908801907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06040838c03820112156143be57600080fd5b6143c6613ad2565b87840151838111156143d757600080fd5b8401610100818e03840112156143ec57600080fd5b6143f4613afb565b92508881015183526144086040820161429d565b89840152614418606082016142af565b604084015260808101518481111561442f57600080fd5b61443d8e8b838501016142ba565b60608501525061444f60a08201614307565b608084015260c081015160a084015260e081015160c084015261010081015160e08401525081815261448360408501614307565b818901528652505050918301918301614367565b805177ffffffffffffffffffffffffffffffffffffffffffffffff81168114613d9357600080fd5b6000602082840312156144d157600080fd5b815167ffffffffffffffff808211156144e957600080fd5b9083019060a082860312156144fd57600080fd5b614505613b1f565b82518281111561451457600080fd5b8301601f8101871361452557600080fd5b8051614533613c3f82613bfa565b8082825260208201915060208360051b85010192508983111561455557600080fd5b602084015b838110156146a25780518781111561457157600080fd5b850160c0818d037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00112156145a557600080fd5b6145ad613b1f565b60208201516145bb81613d98565b815260408201516145cb81613ea7565b60208201526040828e037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa001121561460257600080fd5b61460a613b42565b8d607f84011261461957600080fd5b614621613ad2565b808f60a08601111561463257600080fd5b606085015b60a08601811015614652578051835260209283019201614637565b50825250604082015260a08201518981111561466d57600080fd5b61467c8e602083860101614323565b60608301525061468e60c083016140ca565b60808201528452506020928301920161455a565b508452506146b591505060208401614497565b60208201526146c660408401614292565b60408201526146d760608401614292565b60608201526080830151608082015280935050505092915050565b600081518084526020808501808196508360051b8101915082860160005b858110156147ed57828403895281516040815181875280518288015287810151606061ffff8216818a01528383015193506080915073ffffffffffffffffffffffffffffffffffffffff8416828a01528083015193505061010060a081818b015261477f6101408b0186613895565b9284015192945060c06147a18b8201856bffffffffffffffffffffffff169052565b9084015160e08b81019190915290840151918a01919091529091015161012088015250908601516bffffffffffffffffffffffff16948601949094529784019790840190600101614710565b5091979650505050505050565b6000608080830181845280885180835260a092508286019150828160051b8701016020808c016000805b858110156148df578a85037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600187528251805167ffffffffffffffff1686528481015162ffffff16858701526040808201515160c091859089015b600282101561489e57825181529188019160019190910190880161487f565b5050506060820151818c8901526148b7828901826146f2565b928c0151801515898d01529291506148cc9050565b9785019795505091830191600101614824565b50505081965061490a8189018c77ffffffffffffffffffffffffffffffffffffffffffffffff169052565b505050505050614926604083018567ffffffffffffffff169052565b67ffffffffffffffff831660608301526135ed565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60408152600061497d6040830185614194565b82810360208481019190915284518083528582019282019060005b818110156149b457845183529383019391830191600101614998565b5090979650505050505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152614a088285018b614194565b91508382036080850152614a1c828a614194565b915060ff881660a085015283820360c0850152614a398288613895565b90861660e0850152838103610100850152905061426b8185613895565b604081526000614a6a604083018587614051565b9050826020830152949350505050565b6000610100808385031215614a8e57600080fd5b83601f840112614a9d57600080fd5b614aa5613afb565b908301908085831115614ab757600080fd5b845b83811015614ada578035614acc81613ea7565b835260209283019201614ab9565b5095945050505050565b6101008101818360005b6008811015614b1257815162ffffff16835260209283019290910190600101614aee565b5050509291505056fea164736f6c6343000813000a", +} + +var VRFBeaconABI = VRFBeaconMetaData.ABI + +var VRFBeaconBin = VRFBeaconMetaData.Bin + +func DeployVRFBeacon(auth *bind.TransactOpts, backend bind.ContractBackend, link common.Address, coordinator common.Address, keyProvider common.Address, keyID [32]byte) (common.Address, *types.Transaction, *VRFBeacon, error) { + parsed, err := VRFBeaconMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(VRFBeaconBin), backend, link, coordinator, keyProvider, keyID) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &VRFBeacon{VRFBeaconCaller: VRFBeaconCaller{contract: contract}, VRFBeaconTransactor: VRFBeaconTransactor{contract: contract}, VRFBeaconFilterer: VRFBeaconFilterer{contract: contract}}, nil +} + +type VRFBeacon struct { + address common.Address + abi abi.ABI + VRFBeaconCaller + VRFBeaconTransactor + VRFBeaconFilterer +} + +type VRFBeaconCaller struct { + contract *bind.BoundContract +} + +type VRFBeaconTransactor struct { + contract *bind.BoundContract +} + +type VRFBeaconFilterer struct { + contract *bind.BoundContract +} + +type VRFBeaconSession struct { + Contract *VRFBeacon + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type VRFBeaconCallerSession struct { + Contract *VRFBeaconCaller + CallOpts bind.CallOpts +} + +type VRFBeaconTransactorSession struct { + Contract *VRFBeaconTransactor + TransactOpts bind.TransactOpts +} + +type VRFBeaconRaw struct { + Contract *VRFBeacon +} + +type VRFBeaconCallerRaw struct { + Contract *VRFBeaconCaller +} + +type VRFBeaconTransactorRaw struct { + Contract *VRFBeaconTransactor +} + +func NewVRFBeacon(address common.Address, backend bind.ContractBackend) (*VRFBeacon, error) { + abi, err := abi.JSON(strings.NewReader(VRFBeaconABI)) + if err != nil { + return nil, err + } + contract, err := bindVRFBeacon(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &VRFBeacon{address: address, abi: abi, VRFBeaconCaller: VRFBeaconCaller{contract: contract}, VRFBeaconTransactor: VRFBeaconTransactor{contract: contract}, VRFBeaconFilterer: VRFBeaconFilterer{contract: contract}}, nil +} + +func NewVRFBeaconCaller(address common.Address, caller bind.ContractCaller) (*VRFBeaconCaller, error) { + contract, err := bindVRFBeacon(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &VRFBeaconCaller{contract: contract}, nil +} + +func NewVRFBeaconTransactor(address common.Address, transactor bind.ContractTransactor) (*VRFBeaconTransactor, error) { + contract, err := bindVRFBeacon(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &VRFBeaconTransactor{contract: contract}, nil +} + +func NewVRFBeaconFilterer(address common.Address, filterer bind.ContractFilterer) (*VRFBeaconFilterer, error) { + contract, err := bindVRFBeacon(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &VRFBeaconFilterer{contract: contract}, nil +} + +func bindVRFBeacon(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := VRFBeaconMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_VRFBeacon *VRFBeaconRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _VRFBeacon.Contract.VRFBeaconCaller.contract.Call(opts, result, method, params...) +} + +func (_VRFBeacon *VRFBeaconRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFBeacon.Contract.VRFBeaconTransactor.contract.Transfer(opts) +} + +func (_VRFBeacon *VRFBeaconRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VRFBeacon.Contract.VRFBeaconTransactor.contract.Transact(opts, method, params...) +} + +func (_VRFBeacon *VRFBeaconCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _VRFBeacon.Contract.contract.Call(opts, result, method, params...) +} + +func (_VRFBeacon *VRFBeaconTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFBeacon.Contract.contract.Transfer(opts) +} + +func (_VRFBeacon *VRFBeaconTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VRFBeacon.Contract.contract.Transact(opts, method, params...) +} + +func (_VRFBeacon *VRFBeaconCaller) NUMCONFDELAYS(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _VRFBeacon.contract.Call(opts, &out, "NUM_CONF_DELAYS") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_VRFBeacon *VRFBeaconSession) NUMCONFDELAYS() (uint8, error) { + return _VRFBeacon.Contract.NUMCONFDELAYS(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCallerSession) NUMCONFDELAYS() (uint8, error) { + return _VRFBeacon.Contract.NUMCONFDELAYS(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCaller) GetBilling(opts *bind.CallOpts) (GetBilling, + + error) { + var out []interface{} + err := _VRFBeacon.contract.Call(opts, &out, "getBilling") + + outstruct := new(GetBilling) + if err != nil { + return *outstruct, err + } + + outstruct.MaximumGasPrice = *abi.ConvertType(out[0], new(uint64)).(*uint64) + outstruct.ReasonableGasPrice = *abi.ConvertType(out[1], new(uint64)).(*uint64) + outstruct.ObservationPayment = *abi.ConvertType(out[2], new(uint64)).(*uint64) + outstruct.TransmissionPayment = *abi.ConvertType(out[3], new(uint64)).(*uint64) + outstruct.AccountingGas = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_VRFBeacon *VRFBeaconSession) GetBilling() (GetBilling, + + error) { + return _VRFBeacon.Contract.GetBilling(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCallerSession) GetBilling() (GetBilling, + + error) { + return _VRFBeacon.Contract.GetBilling(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCaller) GetBillingAccessController(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFBeacon.contract.Call(opts, &out, "getBillingAccessController") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFBeacon *VRFBeaconSession) GetBillingAccessController() (common.Address, error) { + return _VRFBeacon.Contract.GetBillingAccessController(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCallerSession) GetBillingAccessController() (common.Address, error) { + return _VRFBeacon.Contract.GetBillingAccessController(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCaller) ICoordinator(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFBeacon.contract.Call(opts, &out, "i_coordinator") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFBeacon *VRFBeaconSession) ICoordinator() (common.Address, error) { + return _VRFBeacon.Contract.ICoordinator(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCallerSession) ICoordinator() (common.Address, error) { + return _VRFBeacon.Contract.ICoordinator(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCaller) ILink(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFBeacon.contract.Call(opts, &out, "i_link") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFBeacon *VRFBeaconSession) ILink() (common.Address, error) { + return _VRFBeacon.Contract.ILink(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCallerSession) ILink() (common.Address, error) { + return _VRFBeacon.Contract.ILink(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) { + var out []interface{} + err := _VRFBeacon.contract.Call(opts, &out, "latestConfigDetails") + + outstruct := new(LatestConfigDetails) + if err != nil { + return *outstruct, err + } + + outstruct.ConfigCount = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.BlockNumber = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.ConfigDigest = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + + return *outstruct, err + +} + +func (_VRFBeacon *VRFBeaconSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _VRFBeacon.Contract.LatestConfigDetails(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCallerSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _VRFBeacon.Contract.LatestConfigDetails(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) { + var out []interface{} + err := _VRFBeacon.contract.Call(opts, &out, "latestConfigDigestAndEpoch") + + outstruct := new(LatestConfigDigestAndEpoch) + if err != nil { + return *outstruct, err + } + + outstruct.ScanLogs = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.ConfigDigest = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + outstruct.Epoch = *abi.ConvertType(out[2], new(uint32)).(*uint32) + + return *outstruct, err + +} + +func (_VRFBeacon *VRFBeaconSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _VRFBeacon.Contract.LatestConfigDigestAndEpoch(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCallerSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _VRFBeacon.Contract.LatestConfigDigestAndEpoch(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCaller) LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFBeacon.contract.Call(opts, &out, "linkAvailableForPayment") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFBeacon *VRFBeaconSession) LinkAvailableForPayment() (*big.Int, error) { + return _VRFBeacon.Contract.LinkAvailableForPayment(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCallerSession) LinkAvailableForPayment() (*big.Int, error) { + return _VRFBeacon.Contract.LinkAvailableForPayment(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCaller) OwedPayment(opts *bind.CallOpts, transmitterAddress common.Address) (*big.Int, error) { + var out []interface{} + err := _VRFBeacon.contract.Call(opts, &out, "owedPayment", transmitterAddress) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFBeacon *VRFBeaconSession) OwedPayment(transmitterAddress common.Address) (*big.Int, error) { + return _VRFBeacon.Contract.OwedPayment(&_VRFBeacon.CallOpts, transmitterAddress) +} + +func (_VRFBeacon *VRFBeaconCallerSession) OwedPayment(transmitterAddress common.Address) (*big.Int, error) { + return _VRFBeacon.Contract.OwedPayment(&_VRFBeacon.CallOpts, transmitterAddress) +} + +func (_VRFBeacon *VRFBeaconCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFBeacon.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFBeacon *VRFBeaconSession) Owner() (common.Address, error) { + return _VRFBeacon.Contract.Owner(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCallerSession) Owner() (common.Address, error) { + return _VRFBeacon.Contract.Owner(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCaller) SKeyID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _VRFBeacon.contract.Call(opts, &out, "s_keyID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_VRFBeacon *VRFBeaconSession) SKeyID() ([32]byte, error) { + return _VRFBeacon.Contract.SKeyID(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCallerSession) SKeyID() ([32]byte, error) { + return _VRFBeacon.Contract.SKeyID(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCaller) SKeyProvider(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFBeacon.contract.Call(opts, &out, "s_keyProvider") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFBeacon *VRFBeaconSession) SKeyProvider() (common.Address, error) { + return _VRFBeacon.Contract.SKeyProvider(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCallerSession) SKeyProvider() (common.Address, error) { + return _VRFBeacon.Contract.SKeyProvider(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCaller) SProvingKeyHash(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _VRFBeacon.contract.Call(opts, &out, "s_provingKeyHash") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_VRFBeacon *VRFBeaconSession) SProvingKeyHash() ([32]byte, error) { + return _VRFBeacon.Contract.SProvingKeyHash(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCallerSession) SProvingKeyHash() ([32]byte, error) { + return _VRFBeacon.Contract.SProvingKeyHash(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _VRFBeacon.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_VRFBeacon *VRFBeaconSession) TypeAndVersion() (string, error) { + return _VRFBeacon.Contract.TypeAndVersion(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconCallerSession) TypeAndVersion() (string, error) { + return _VRFBeacon.Contract.TypeAndVersion(&_VRFBeacon.CallOpts) +} + +func (_VRFBeacon *VRFBeaconTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFBeacon.contract.Transact(opts, "acceptOwnership") +} + +func (_VRFBeacon *VRFBeaconSession) AcceptOwnership() (*types.Transaction, error) { + return _VRFBeacon.Contract.AcceptOwnership(&_VRFBeacon.TransactOpts) +} + +func (_VRFBeacon *VRFBeaconTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _VRFBeacon.Contract.AcceptOwnership(&_VRFBeacon.TransactOpts) +} + +func (_VRFBeacon *VRFBeaconTransactor) AcceptPayeeship(opts *bind.TransactOpts, transmitter common.Address) (*types.Transaction, error) { + return _VRFBeacon.contract.Transact(opts, "acceptPayeeship", transmitter) +} + +func (_VRFBeacon *VRFBeaconSession) AcceptPayeeship(transmitter common.Address) (*types.Transaction, error) { + return _VRFBeacon.Contract.AcceptPayeeship(&_VRFBeacon.TransactOpts, transmitter) +} + +func (_VRFBeacon *VRFBeaconTransactorSession) AcceptPayeeship(transmitter common.Address) (*types.Transaction, error) { + return _VRFBeacon.Contract.AcceptPayeeship(&_VRFBeacon.TransactOpts, transmitter) +} + +func (_VRFBeacon *VRFBeaconTransactor) ExposeType(opts *bind.TransactOpts, arg0 VRFBeaconReportReport) (*types.Transaction, error) { + return _VRFBeacon.contract.Transact(opts, "exposeType", arg0) +} + +func (_VRFBeacon *VRFBeaconSession) ExposeType(arg0 VRFBeaconReportReport) (*types.Transaction, error) { + return _VRFBeacon.Contract.ExposeType(&_VRFBeacon.TransactOpts, arg0) +} + +func (_VRFBeacon *VRFBeaconTransactorSession) ExposeType(arg0 VRFBeaconReportReport) (*types.Transaction, error) { + return _VRFBeacon.Contract.ExposeType(&_VRFBeacon.TransactOpts, arg0) +} + +func (_VRFBeacon *VRFBeaconTransactor) KeyGenerated(opts *bind.TransactOpts, kd KeyDataStructKeyData) (*types.Transaction, error) { + return _VRFBeacon.contract.Transact(opts, "keyGenerated", kd) +} + +func (_VRFBeacon *VRFBeaconSession) KeyGenerated(kd KeyDataStructKeyData) (*types.Transaction, error) { + return _VRFBeacon.Contract.KeyGenerated(&_VRFBeacon.TransactOpts, kd) +} + +func (_VRFBeacon *VRFBeaconTransactorSession) KeyGenerated(kd KeyDataStructKeyData) (*types.Transaction, error) { + return _VRFBeacon.Contract.KeyGenerated(&_VRFBeacon.TransactOpts, kd) +} + +func (_VRFBeacon *VRFBeaconTransactor) NewKeyRequested(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFBeacon.contract.Transact(opts, "newKeyRequested") +} + +func (_VRFBeacon *VRFBeaconSession) NewKeyRequested() (*types.Transaction, error) { + return _VRFBeacon.Contract.NewKeyRequested(&_VRFBeacon.TransactOpts) +} + +func (_VRFBeacon *VRFBeaconTransactorSession) NewKeyRequested() (*types.Transaction, error) { + return _VRFBeacon.Contract.NewKeyRequested(&_VRFBeacon.TransactOpts) +} + +func (_VRFBeacon *VRFBeaconTransactor) SetBilling(opts *bind.TransactOpts, maximumGasPrice uint64, reasonableGasPrice uint64, observationPayment uint64, transmissionPayment uint64, accountingGas *big.Int) (*types.Transaction, error) { + return _VRFBeacon.contract.Transact(opts, "setBilling", maximumGasPrice, reasonableGasPrice, observationPayment, transmissionPayment, accountingGas) +} + +func (_VRFBeacon *VRFBeaconSession) SetBilling(maximumGasPrice uint64, reasonableGasPrice uint64, observationPayment uint64, transmissionPayment uint64, accountingGas *big.Int) (*types.Transaction, error) { + return _VRFBeacon.Contract.SetBilling(&_VRFBeacon.TransactOpts, maximumGasPrice, reasonableGasPrice, observationPayment, transmissionPayment, accountingGas) +} + +func (_VRFBeacon *VRFBeaconTransactorSession) SetBilling(maximumGasPrice uint64, reasonableGasPrice uint64, observationPayment uint64, transmissionPayment uint64, accountingGas *big.Int) (*types.Transaction, error) { + return _VRFBeacon.Contract.SetBilling(&_VRFBeacon.TransactOpts, maximumGasPrice, reasonableGasPrice, observationPayment, transmissionPayment, accountingGas) +} + +func (_VRFBeacon *VRFBeaconTransactor) SetBillingAccessController(opts *bind.TransactOpts, _billingAccessController common.Address) (*types.Transaction, error) { + return _VRFBeacon.contract.Transact(opts, "setBillingAccessController", _billingAccessController) +} + +func (_VRFBeacon *VRFBeaconSession) SetBillingAccessController(_billingAccessController common.Address) (*types.Transaction, error) { + return _VRFBeacon.Contract.SetBillingAccessController(&_VRFBeacon.TransactOpts, _billingAccessController) +} + +func (_VRFBeacon *VRFBeaconTransactorSession) SetBillingAccessController(_billingAccessController common.Address) (*types.Transaction, error) { + return _VRFBeacon.Contract.SetBillingAccessController(&_VRFBeacon.TransactOpts, _billingAccessController) +} + +func (_VRFBeacon *VRFBeaconTransactor) SetConfig(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _VRFBeacon.contract.Transact(opts, "setConfig", signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_VRFBeacon *VRFBeaconSession) SetConfig(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _VRFBeacon.Contract.SetConfig(&_VRFBeacon.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_VRFBeacon *VRFBeaconTransactorSession) SetConfig(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _VRFBeacon.Contract.SetConfig(&_VRFBeacon.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_VRFBeacon *VRFBeaconTransactor) SetPayees(opts *bind.TransactOpts, transmitters []common.Address, payees []common.Address) (*types.Transaction, error) { + return _VRFBeacon.contract.Transact(opts, "setPayees", transmitters, payees) +} + +func (_VRFBeacon *VRFBeaconSession) SetPayees(transmitters []common.Address, payees []common.Address) (*types.Transaction, error) { + return _VRFBeacon.Contract.SetPayees(&_VRFBeacon.TransactOpts, transmitters, payees) +} + +func (_VRFBeacon *VRFBeaconTransactorSession) SetPayees(transmitters []common.Address, payees []common.Address) (*types.Transaction, error) { + return _VRFBeacon.Contract.SetPayees(&_VRFBeacon.TransactOpts, transmitters, payees) +} + +func (_VRFBeacon *VRFBeaconTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _VRFBeacon.contract.Transact(opts, "transferOwnership", to) +} + +func (_VRFBeacon *VRFBeaconSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _VRFBeacon.Contract.TransferOwnership(&_VRFBeacon.TransactOpts, to) +} + +func (_VRFBeacon *VRFBeaconTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _VRFBeacon.Contract.TransferOwnership(&_VRFBeacon.TransactOpts, to) +} + +func (_VRFBeacon *VRFBeaconTransactor) TransferPayeeship(opts *bind.TransactOpts, transmitter common.Address, proposed common.Address) (*types.Transaction, error) { + return _VRFBeacon.contract.Transact(opts, "transferPayeeship", transmitter, proposed) +} + +func (_VRFBeacon *VRFBeaconSession) TransferPayeeship(transmitter common.Address, proposed common.Address) (*types.Transaction, error) { + return _VRFBeacon.Contract.TransferPayeeship(&_VRFBeacon.TransactOpts, transmitter, proposed) +} + +func (_VRFBeacon *VRFBeaconTransactorSession) TransferPayeeship(transmitter common.Address, proposed common.Address) (*types.Transaction, error) { + return _VRFBeacon.Contract.TransferPayeeship(&_VRFBeacon.TransactOpts, transmitter, proposed) +} + +func (_VRFBeacon *VRFBeaconTransactor) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _VRFBeacon.contract.Transact(opts, "transmit", reportContext, report, rs, ss, rawVs) +} + +func (_VRFBeacon *VRFBeaconSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _VRFBeacon.Contract.Transmit(&_VRFBeacon.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_VRFBeacon *VRFBeaconTransactorSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _VRFBeacon.Contract.Transmit(&_VRFBeacon.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_VRFBeacon *VRFBeaconTransactor) WithdrawFunds(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _VRFBeacon.contract.Transact(opts, "withdrawFunds", recipient, amount) +} + +func (_VRFBeacon *VRFBeaconSession) WithdrawFunds(recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _VRFBeacon.Contract.WithdrawFunds(&_VRFBeacon.TransactOpts, recipient, amount) +} + +func (_VRFBeacon *VRFBeaconTransactorSession) WithdrawFunds(recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _VRFBeacon.Contract.WithdrawFunds(&_VRFBeacon.TransactOpts, recipient, amount) +} + +func (_VRFBeacon *VRFBeaconTransactor) WithdrawPayment(opts *bind.TransactOpts, transmitter common.Address) (*types.Transaction, error) { + return _VRFBeacon.contract.Transact(opts, "withdrawPayment", transmitter) +} + +func (_VRFBeacon *VRFBeaconSession) WithdrawPayment(transmitter common.Address) (*types.Transaction, error) { + return _VRFBeacon.Contract.WithdrawPayment(&_VRFBeacon.TransactOpts, transmitter) +} + +func (_VRFBeacon *VRFBeaconTransactorSession) WithdrawPayment(transmitter common.Address) (*types.Transaction, error) { + return _VRFBeacon.Contract.WithdrawPayment(&_VRFBeacon.TransactOpts, transmitter) +} + +type VRFBeaconBillingAccessControllerSetIterator struct { + Event *VRFBeaconBillingAccessControllerSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFBeaconBillingAccessControllerSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFBeaconBillingAccessControllerSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFBeaconBillingAccessControllerSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFBeaconBillingAccessControllerSetIterator) Error() error { + return it.fail +} + +func (it *VRFBeaconBillingAccessControllerSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFBeaconBillingAccessControllerSet struct { + Old common.Address + Current common.Address + Raw types.Log +} + +func (_VRFBeacon *VRFBeaconFilterer) FilterBillingAccessControllerSet(opts *bind.FilterOpts) (*VRFBeaconBillingAccessControllerSetIterator, error) { + + logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "BillingAccessControllerSet") + if err != nil { + return nil, err + } + return &VRFBeaconBillingAccessControllerSetIterator{contract: _VRFBeacon.contract, event: "BillingAccessControllerSet", logs: logs, sub: sub}, nil +} + +func (_VRFBeacon *VRFBeaconFilterer) WatchBillingAccessControllerSet(opts *bind.WatchOpts, sink chan<- *VRFBeaconBillingAccessControllerSet) (event.Subscription, error) { + + logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "BillingAccessControllerSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFBeaconBillingAccessControllerSet) + if err := _VRFBeacon.contract.UnpackLog(event, "BillingAccessControllerSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFBeacon *VRFBeaconFilterer) ParseBillingAccessControllerSet(log types.Log) (*VRFBeaconBillingAccessControllerSet, error) { + event := new(VRFBeaconBillingAccessControllerSet) + if err := _VRFBeacon.contract.UnpackLog(event, "BillingAccessControllerSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFBeaconBillingSetIterator struct { + Event *VRFBeaconBillingSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFBeaconBillingSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFBeaconBillingSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFBeaconBillingSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFBeaconBillingSetIterator) Error() error { + return it.fail +} + +func (it *VRFBeaconBillingSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFBeaconBillingSet struct { + MaximumGasPrice uint64 + ReasonableGasPrice uint64 + ObservationPayment uint64 + TransmissionPayment uint64 + AccountingGas *big.Int + Raw types.Log +} + +func (_VRFBeacon *VRFBeaconFilterer) FilterBillingSet(opts *bind.FilterOpts) (*VRFBeaconBillingSetIterator, error) { + + logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "BillingSet") + if err != nil { + return nil, err + } + return &VRFBeaconBillingSetIterator{contract: _VRFBeacon.contract, event: "BillingSet", logs: logs, sub: sub}, nil +} + +func (_VRFBeacon *VRFBeaconFilterer) WatchBillingSet(opts *bind.WatchOpts, sink chan<- *VRFBeaconBillingSet) (event.Subscription, error) { + + logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "BillingSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFBeaconBillingSet) + if err := _VRFBeacon.contract.UnpackLog(event, "BillingSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFBeacon *VRFBeaconFilterer) ParseBillingSet(log types.Log) (*VRFBeaconBillingSet, error) { + event := new(VRFBeaconBillingSet) + if err := _VRFBeacon.contract.UnpackLog(event, "BillingSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFBeaconConfigSetIterator struct { + Event *VRFBeaconConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFBeaconConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFBeaconConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFBeaconConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFBeaconConfigSetIterator) Error() error { + return it.fail +} + +func (it *VRFBeaconConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFBeaconConfigSet struct { + PreviousConfigBlockNumber uint32 + ConfigDigest [32]byte + ConfigCount uint64 + Signers []common.Address + Transmitters []common.Address + F uint8 + OnchainConfig []byte + OffchainConfigVersion uint64 + OffchainConfig []byte + Raw types.Log +} + +func (_VRFBeacon *VRFBeaconFilterer) FilterConfigSet(opts *bind.FilterOpts) (*VRFBeaconConfigSetIterator, error) { + + logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &VRFBeaconConfigSetIterator{contract: _VRFBeacon.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_VRFBeacon *VRFBeaconFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *VRFBeaconConfigSet) (event.Subscription, error) { + + logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFBeaconConfigSet) + if err := _VRFBeacon.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFBeacon *VRFBeaconFilterer) ParseConfigSet(log types.Log) (*VRFBeaconConfigSet, error) { + event := new(VRFBeaconConfigSet) + if err := _VRFBeacon.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFBeaconNewTransmissionIterator struct { + Event *VRFBeaconNewTransmission + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFBeaconNewTransmissionIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFBeaconNewTransmission) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFBeaconNewTransmission) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFBeaconNewTransmissionIterator) Error() error { + return it.fail +} + +func (it *VRFBeaconNewTransmissionIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFBeaconNewTransmission struct { + EpochAndRound *big.Int + Transmitter common.Address + JuelsPerFeeCoin *big.Int + ReasonableGasPrice uint64 + ConfigDigest [32]byte + Raw types.Log +} + +func (_VRFBeacon *VRFBeaconFilterer) FilterNewTransmission(opts *bind.FilterOpts, epochAndRound []*big.Int) (*VRFBeaconNewTransmissionIterator, error) { + + var epochAndRoundRule []interface{} + for _, epochAndRoundItem := range epochAndRound { + epochAndRoundRule = append(epochAndRoundRule, epochAndRoundItem) + } + + logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "NewTransmission", epochAndRoundRule) + if err != nil { + return nil, err + } + return &VRFBeaconNewTransmissionIterator{contract: _VRFBeacon.contract, event: "NewTransmission", logs: logs, sub: sub}, nil +} + +func (_VRFBeacon *VRFBeaconFilterer) WatchNewTransmission(opts *bind.WatchOpts, sink chan<- *VRFBeaconNewTransmission, epochAndRound []*big.Int) (event.Subscription, error) { + + var epochAndRoundRule []interface{} + for _, epochAndRoundItem := range epochAndRound { + epochAndRoundRule = append(epochAndRoundRule, epochAndRoundItem) + } + + logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "NewTransmission", epochAndRoundRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFBeaconNewTransmission) + if err := _VRFBeacon.contract.UnpackLog(event, "NewTransmission", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFBeacon *VRFBeaconFilterer) ParseNewTransmission(log types.Log) (*VRFBeaconNewTransmission, error) { + event := new(VRFBeaconNewTransmission) + if err := _VRFBeacon.contract.UnpackLog(event, "NewTransmission", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFBeaconOraclePaidIterator struct { + Event *VRFBeaconOraclePaid + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFBeaconOraclePaidIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFBeaconOraclePaid) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFBeaconOraclePaid) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFBeaconOraclePaidIterator) Error() error { + return it.fail +} + +func (it *VRFBeaconOraclePaidIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFBeaconOraclePaid struct { + Transmitter common.Address + Payee common.Address + Amount *big.Int + LinkToken common.Address + Raw types.Log +} + +func (_VRFBeacon *VRFBeaconFilterer) FilterOraclePaid(opts *bind.FilterOpts, transmitter []common.Address, payee []common.Address, linkToken []common.Address) (*VRFBeaconOraclePaidIterator, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var payeeRule []interface{} + for _, payeeItem := range payee { + payeeRule = append(payeeRule, payeeItem) + } + + var linkTokenRule []interface{} + for _, linkTokenItem := range linkToken { + linkTokenRule = append(linkTokenRule, linkTokenItem) + } + + logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "OraclePaid", transmitterRule, payeeRule, linkTokenRule) + if err != nil { + return nil, err + } + return &VRFBeaconOraclePaidIterator{contract: _VRFBeacon.contract, event: "OraclePaid", logs: logs, sub: sub}, nil +} + +func (_VRFBeacon *VRFBeaconFilterer) WatchOraclePaid(opts *bind.WatchOpts, sink chan<- *VRFBeaconOraclePaid, transmitter []common.Address, payee []common.Address, linkToken []common.Address) (event.Subscription, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var payeeRule []interface{} + for _, payeeItem := range payee { + payeeRule = append(payeeRule, payeeItem) + } + + var linkTokenRule []interface{} + for _, linkTokenItem := range linkToken { + linkTokenRule = append(linkTokenRule, linkTokenItem) + } + + logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "OraclePaid", transmitterRule, payeeRule, linkTokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFBeaconOraclePaid) + if err := _VRFBeacon.contract.UnpackLog(event, "OraclePaid", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFBeacon *VRFBeaconFilterer) ParseOraclePaid(log types.Log) (*VRFBeaconOraclePaid, error) { + event := new(VRFBeaconOraclePaid) + if err := _VRFBeacon.contract.UnpackLog(event, "OraclePaid", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFBeaconOutputsServedIterator struct { + Event *VRFBeaconOutputsServed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFBeaconOutputsServedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFBeaconOutputsServed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFBeaconOutputsServed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFBeaconOutputsServedIterator) Error() error { + return it.fail +} + +func (it *VRFBeaconOutputsServedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFBeaconOutputsServed struct { + RecentBlockHeight uint64 + JuelsPerFeeCoin *big.Int + ReasonableGasPrice uint64 + OutputsServed []VRFBeaconTypesOutputServed + Raw types.Log +} + +func (_VRFBeacon *VRFBeaconFilterer) FilterOutputsServed(opts *bind.FilterOpts) (*VRFBeaconOutputsServedIterator, error) { + + logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "OutputsServed") + if err != nil { + return nil, err + } + return &VRFBeaconOutputsServedIterator{contract: _VRFBeacon.contract, event: "OutputsServed", logs: logs, sub: sub}, nil +} + +func (_VRFBeacon *VRFBeaconFilterer) WatchOutputsServed(opts *bind.WatchOpts, sink chan<- *VRFBeaconOutputsServed) (event.Subscription, error) { + + logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "OutputsServed") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFBeaconOutputsServed) + if err := _VRFBeacon.contract.UnpackLog(event, "OutputsServed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFBeacon *VRFBeaconFilterer) ParseOutputsServed(log types.Log) (*VRFBeaconOutputsServed, error) { + event := new(VRFBeaconOutputsServed) + if err := _VRFBeacon.contract.UnpackLog(event, "OutputsServed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFBeaconOwnershipTransferRequestedIterator struct { + Event *VRFBeaconOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFBeaconOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFBeaconOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFBeaconOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFBeaconOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *VRFBeaconOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFBeaconOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_VRFBeacon *VRFBeaconFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFBeaconOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &VRFBeaconOwnershipTransferRequestedIterator{contract: _VRFBeacon.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_VRFBeacon *VRFBeaconFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFBeaconOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFBeaconOwnershipTransferRequested) + if err := _VRFBeacon.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFBeacon *VRFBeaconFilterer) ParseOwnershipTransferRequested(log types.Log) (*VRFBeaconOwnershipTransferRequested, error) { + event := new(VRFBeaconOwnershipTransferRequested) + if err := _VRFBeacon.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFBeaconOwnershipTransferredIterator struct { + Event *VRFBeaconOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFBeaconOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFBeaconOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFBeaconOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFBeaconOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *VRFBeaconOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFBeaconOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_VRFBeacon *VRFBeaconFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFBeaconOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &VRFBeaconOwnershipTransferredIterator{contract: _VRFBeacon.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_VRFBeacon *VRFBeaconFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFBeaconOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFBeaconOwnershipTransferred) + if err := _VRFBeacon.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFBeacon *VRFBeaconFilterer) ParseOwnershipTransferred(log types.Log) (*VRFBeaconOwnershipTransferred, error) { + event := new(VRFBeaconOwnershipTransferred) + if err := _VRFBeacon.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFBeaconPayeeshipTransferRequestedIterator struct { + Event *VRFBeaconPayeeshipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFBeaconPayeeshipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFBeaconPayeeshipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFBeaconPayeeshipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFBeaconPayeeshipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *VRFBeaconPayeeshipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFBeaconPayeeshipTransferRequested struct { + Transmitter common.Address + Current common.Address + Proposed common.Address + Raw types.Log +} + +func (_VRFBeacon *VRFBeaconFilterer) FilterPayeeshipTransferRequested(opts *bind.FilterOpts, transmitter []common.Address, current []common.Address, proposed []common.Address) (*VRFBeaconPayeeshipTransferRequestedIterator, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var currentRule []interface{} + for _, currentItem := range current { + currentRule = append(currentRule, currentItem) + } + var proposedRule []interface{} + for _, proposedItem := range proposed { + proposedRule = append(proposedRule, proposedItem) + } + + logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "PayeeshipTransferRequested", transmitterRule, currentRule, proposedRule) + if err != nil { + return nil, err + } + return &VRFBeaconPayeeshipTransferRequestedIterator{contract: _VRFBeacon.contract, event: "PayeeshipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_VRFBeacon *VRFBeaconFilterer) WatchPayeeshipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFBeaconPayeeshipTransferRequested, transmitter []common.Address, current []common.Address, proposed []common.Address) (event.Subscription, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var currentRule []interface{} + for _, currentItem := range current { + currentRule = append(currentRule, currentItem) + } + var proposedRule []interface{} + for _, proposedItem := range proposed { + proposedRule = append(proposedRule, proposedItem) + } + + logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "PayeeshipTransferRequested", transmitterRule, currentRule, proposedRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFBeaconPayeeshipTransferRequested) + if err := _VRFBeacon.contract.UnpackLog(event, "PayeeshipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFBeacon *VRFBeaconFilterer) ParsePayeeshipTransferRequested(log types.Log) (*VRFBeaconPayeeshipTransferRequested, error) { + event := new(VRFBeaconPayeeshipTransferRequested) + if err := _VRFBeacon.contract.UnpackLog(event, "PayeeshipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFBeaconPayeeshipTransferredIterator struct { + Event *VRFBeaconPayeeshipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFBeaconPayeeshipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFBeaconPayeeshipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFBeaconPayeeshipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFBeaconPayeeshipTransferredIterator) Error() error { + return it.fail +} + +func (it *VRFBeaconPayeeshipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFBeaconPayeeshipTransferred struct { + Transmitter common.Address + Previous common.Address + Current common.Address + Raw types.Log +} + +func (_VRFBeacon *VRFBeaconFilterer) FilterPayeeshipTransferred(opts *bind.FilterOpts, transmitter []common.Address, previous []common.Address, current []common.Address) (*VRFBeaconPayeeshipTransferredIterator, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var previousRule []interface{} + for _, previousItem := range previous { + previousRule = append(previousRule, previousItem) + } + var currentRule []interface{} + for _, currentItem := range current { + currentRule = append(currentRule, currentItem) + } + + logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "PayeeshipTransferred", transmitterRule, previousRule, currentRule) + if err != nil { + return nil, err + } + return &VRFBeaconPayeeshipTransferredIterator{contract: _VRFBeacon.contract, event: "PayeeshipTransferred", logs: logs, sub: sub}, nil +} + +func (_VRFBeacon *VRFBeaconFilterer) WatchPayeeshipTransferred(opts *bind.WatchOpts, sink chan<- *VRFBeaconPayeeshipTransferred, transmitter []common.Address, previous []common.Address, current []common.Address) (event.Subscription, error) { + + var transmitterRule []interface{} + for _, transmitterItem := range transmitter { + transmitterRule = append(transmitterRule, transmitterItem) + } + var previousRule []interface{} + for _, previousItem := range previous { + previousRule = append(previousRule, previousItem) + } + var currentRule []interface{} + for _, currentItem := range current { + currentRule = append(currentRule, currentItem) + } + + logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "PayeeshipTransferred", transmitterRule, previousRule, currentRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFBeaconPayeeshipTransferred) + if err := _VRFBeacon.contract.UnpackLog(event, "PayeeshipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFBeacon *VRFBeaconFilterer) ParsePayeeshipTransferred(log types.Log) (*VRFBeaconPayeeshipTransferred, error) { + event := new(VRFBeaconPayeeshipTransferred) + if err := _VRFBeacon.contract.UnpackLog(event, "PayeeshipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFBeaconRandomWordsFulfilledIterator struct { + Event *VRFBeaconRandomWordsFulfilled + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFBeaconRandomWordsFulfilledIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFBeaconRandomWordsFulfilled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFBeaconRandomWordsFulfilled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFBeaconRandomWordsFulfilledIterator) Error() error { + return it.fail +} + +func (it *VRFBeaconRandomWordsFulfilledIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFBeaconRandomWordsFulfilled struct { + RequestIDs []*big.Int + SuccessfulFulfillment []byte + TruncatedErrorData [][]byte + SubBalances []*big.Int + SubIDs []*big.Int + Raw types.Log +} + +func (_VRFBeacon *VRFBeaconFilterer) FilterRandomWordsFulfilled(opts *bind.FilterOpts) (*VRFBeaconRandomWordsFulfilledIterator, error) { + + logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "RandomWordsFulfilled") + if err != nil { + return nil, err + } + return &VRFBeaconRandomWordsFulfilledIterator{contract: _VRFBeacon.contract, event: "RandomWordsFulfilled", logs: logs, sub: sub}, nil +} + +func (_VRFBeacon *VRFBeaconFilterer) WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFBeaconRandomWordsFulfilled) (event.Subscription, error) { + + logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "RandomWordsFulfilled") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFBeaconRandomWordsFulfilled) + if err := _VRFBeacon.contract.UnpackLog(event, "RandomWordsFulfilled", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFBeacon *VRFBeaconFilterer) ParseRandomWordsFulfilled(log types.Log) (*VRFBeaconRandomWordsFulfilled, error) { + event := new(VRFBeaconRandomWordsFulfilled) + if err := _VRFBeacon.contract.UnpackLog(event, "RandomWordsFulfilled", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFBeaconRandomnessFulfillmentRequestedIterator struct { + Event *VRFBeaconRandomnessFulfillmentRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFBeaconRandomnessFulfillmentRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFBeaconRandomnessFulfillmentRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFBeaconRandomnessFulfillmentRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFBeaconRandomnessFulfillmentRequestedIterator) Error() error { + return it.fail +} + +func (it *VRFBeaconRandomnessFulfillmentRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFBeaconRandomnessFulfillmentRequested struct { + RequestID *big.Int + Requester common.Address + NextBeaconOutputHeight uint64 + ConfDelay *big.Int + SubID *big.Int + NumWords uint16 + GasAllowance uint32 + GasPrice *big.Int + WeiPerUnitLink *big.Int + Arguments []byte + CostJuels *big.Int + NewSubBalance *big.Int + Raw types.Log +} + +func (_VRFBeacon *VRFBeaconFilterer) FilterRandomnessFulfillmentRequested(opts *bind.FilterOpts, requestID []*big.Int) (*VRFBeaconRandomnessFulfillmentRequestedIterator, error) { + + var requestIDRule []interface{} + for _, requestIDItem := range requestID { + requestIDRule = append(requestIDRule, requestIDItem) + } + + logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "RandomnessFulfillmentRequested", requestIDRule) + if err != nil { + return nil, err + } + return &VRFBeaconRandomnessFulfillmentRequestedIterator{contract: _VRFBeacon.contract, event: "RandomnessFulfillmentRequested", logs: logs, sub: sub}, nil +} + +func (_VRFBeacon *VRFBeaconFilterer) WatchRandomnessFulfillmentRequested(opts *bind.WatchOpts, sink chan<- *VRFBeaconRandomnessFulfillmentRequested, requestID []*big.Int) (event.Subscription, error) { + + var requestIDRule []interface{} + for _, requestIDItem := range requestID { + requestIDRule = append(requestIDRule, requestIDItem) + } + + logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "RandomnessFulfillmentRequested", requestIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFBeaconRandomnessFulfillmentRequested) + if err := _VRFBeacon.contract.UnpackLog(event, "RandomnessFulfillmentRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFBeacon *VRFBeaconFilterer) ParseRandomnessFulfillmentRequested(log types.Log) (*VRFBeaconRandomnessFulfillmentRequested, error) { + event := new(VRFBeaconRandomnessFulfillmentRequested) + if err := _VRFBeacon.contract.UnpackLog(event, "RandomnessFulfillmentRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFBeaconRandomnessRedeemedIterator struct { + Event *VRFBeaconRandomnessRedeemed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFBeaconRandomnessRedeemedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFBeaconRandomnessRedeemed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFBeaconRandomnessRedeemed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFBeaconRandomnessRedeemedIterator) Error() error { + return it.fail +} + +func (it *VRFBeaconRandomnessRedeemedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFBeaconRandomnessRedeemed struct { + RequestID *big.Int + Requester common.Address + SubID *big.Int + Raw types.Log +} + +func (_VRFBeacon *VRFBeaconFilterer) FilterRandomnessRedeemed(opts *bind.FilterOpts, requestID []*big.Int, requester []common.Address) (*VRFBeaconRandomnessRedeemedIterator, error) { + + var requestIDRule []interface{} + for _, requestIDItem := range requestID { + requestIDRule = append(requestIDRule, requestIDItem) + } + var requesterRule []interface{} + for _, requesterItem := range requester { + requesterRule = append(requesterRule, requesterItem) + } + + logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "RandomnessRedeemed", requestIDRule, requesterRule) + if err != nil { + return nil, err + } + return &VRFBeaconRandomnessRedeemedIterator{contract: _VRFBeacon.contract, event: "RandomnessRedeemed", logs: logs, sub: sub}, nil +} + +func (_VRFBeacon *VRFBeaconFilterer) WatchRandomnessRedeemed(opts *bind.WatchOpts, sink chan<- *VRFBeaconRandomnessRedeemed, requestID []*big.Int, requester []common.Address) (event.Subscription, error) { + + var requestIDRule []interface{} + for _, requestIDItem := range requestID { + requestIDRule = append(requestIDRule, requestIDItem) + } + var requesterRule []interface{} + for _, requesterItem := range requester { + requesterRule = append(requesterRule, requesterItem) + } + + logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "RandomnessRedeemed", requestIDRule, requesterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFBeaconRandomnessRedeemed) + if err := _VRFBeacon.contract.UnpackLog(event, "RandomnessRedeemed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFBeacon *VRFBeaconFilterer) ParseRandomnessRedeemed(log types.Log) (*VRFBeaconRandomnessRedeemed, error) { + event := new(VRFBeaconRandomnessRedeemed) + if err := _VRFBeacon.contract.UnpackLog(event, "RandomnessRedeemed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFBeaconRandomnessRequestedIterator struct { + Event *VRFBeaconRandomnessRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFBeaconRandomnessRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFBeaconRandomnessRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFBeaconRandomnessRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFBeaconRandomnessRequestedIterator) Error() error { + return it.fail +} + +func (it *VRFBeaconRandomnessRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFBeaconRandomnessRequested struct { + RequestID *big.Int + Requester common.Address + NextBeaconOutputHeight uint64 + ConfDelay *big.Int + SubID *big.Int + NumWords uint16 + CostJuels *big.Int + NewSubBalance *big.Int + Raw types.Log +} + +func (_VRFBeacon *VRFBeaconFilterer) FilterRandomnessRequested(opts *bind.FilterOpts, requestID []*big.Int) (*VRFBeaconRandomnessRequestedIterator, error) { + + var requestIDRule []interface{} + for _, requestIDItem := range requestID { + requestIDRule = append(requestIDRule, requestIDItem) + } + + logs, sub, err := _VRFBeacon.contract.FilterLogs(opts, "RandomnessRequested", requestIDRule) + if err != nil { + return nil, err + } + return &VRFBeaconRandomnessRequestedIterator{contract: _VRFBeacon.contract, event: "RandomnessRequested", logs: logs, sub: sub}, nil +} + +func (_VRFBeacon *VRFBeaconFilterer) WatchRandomnessRequested(opts *bind.WatchOpts, sink chan<- *VRFBeaconRandomnessRequested, requestID []*big.Int) (event.Subscription, error) { + + var requestIDRule []interface{} + for _, requestIDItem := range requestID { + requestIDRule = append(requestIDRule, requestIDItem) + } + + logs, sub, err := _VRFBeacon.contract.WatchLogs(opts, "RandomnessRequested", requestIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFBeaconRandomnessRequested) + if err := _VRFBeacon.contract.UnpackLog(event, "RandomnessRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFBeacon *VRFBeaconFilterer) ParseRandomnessRequested(log types.Log) (*VRFBeaconRandomnessRequested, error) { + event := new(VRFBeaconRandomnessRequested) + if err := _VRFBeacon.contract.UnpackLog(event, "RandomnessRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetBilling struct { + MaximumGasPrice uint64 + ReasonableGasPrice uint64 + ObservationPayment uint64 + TransmissionPayment uint64 + AccountingGas *big.Int +} +type LatestConfigDetails struct { + ConfigCount uint32 + BlockNumber uint32 + ConfigDigest [32]byte +} +type LatestConfigDigestAndEpoch struct { + ScanLogs bool + ConfigDigest [32]byte + Epoch uint32 +} + +func (_VRFBeacon *VRFBeacon) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _VRFBeacon.abi.Events["BillingAccessControllerSet"].ID: + return _VRFBeacon.ParseBillingAccessControllerSet(log) + case _VRFBeacon.abi.Events["BillingSet"].ID: + return _VRFBeacon.ParseBillingSet(log) + case _VRFBeacon.abi.Events["ConfigSet"].ID: + return _VRFBeacon.ParseConfigSet(log) + case _VRFBeacon.abi.Events["NewTransmission"].ID: + return _VRFBeacon.ParseNewTransmission(log) + case _VRFBeacon.abi.Events["OraclePaid"].ID: + return _VRFBeacon.ParseOraclePaid(log) + case _VRFBeacon.abi.Events["OutputsServed"].ID: + return _VRFBeacon.ParseOutputsServed(log) + case _VRFBeacon.abi.Events["OwnershipTransferRequested"].ID: + return _VRFBeacon.ParseOwnershipTransferRequested(log) + case _VRFBeacon.abi.Events["OwnershipTransferred"].ID: + return _VRFBeacon.ParseOwnershipTransferred(log) + case _VRFBeacon.abi.Events["PayeeshipTransferRequested"].ID: + return _VRFBeacon.ParsePayeeshipTransferRequested(log) + case _VRFBeacon.abi.Events["PayeeshipTransferred"].ID: + return _VRFBeacon.ParsePayeeshipTransferred(log) + case _VRFBeacon.abi.Events["RandomWordsFulfilled"].ID: + return _VRFBeacon.ParseRandomWordsFulfilled(log) + case _VRFBeacon.abi.Events["RandomnessFulfillmentRequested"].ID: + return _VRFBeacon.ParseRandomnessFulfillmentRequested(log) + case _VRFBeacon.abi.Events["RandomnessRedeemed"].ID: + return _VRFBeacon.ParseRandomnessRedeemed(log) + case _VRFBeacon.abi.Events["RandomnessRequested"].ID: + return _VRFBeacon.ParseRandomnessRequested(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (VRFBeaconBillingAccessControllerSet) Topic() common.Hash { + return common.HexToHash("0x793cb73064f3c8cde7e187ae515511e6e56d1ee89bf08b82fa60fb70f8d48912") +} + +func (VRFBeaconBillingSet) Topic() common.Hash { + return common.HexToHash("0x49275ddcdfc9c0519b3d094308c8bf675f06070a754ce90c152163cb6e66e8a0") +} + +func (VRFBeaconConfigSet) Topic() common.Hash { + return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") +} + +func (VRFBeaconNewTransmission) Topic() common.Hash { + return common.HexToHash("0xfc3c7a7927e878a0fca37c904953c3c75cee3ca1d1640184a0ab1c65eec62743") +} + +func (VRFBeaconOraclePaid) Topic() common.Hash { + return common.HexToHash("0xd0b1dac935d85bd54cf0a33b0d41d39f8cf53a968465fc7ea2377526b8ac712c") +} + +func (VRFBeaconOutputsServed) Topic() common.Hash { + return common.HexToHash("0xf10ea936d00579b4c52035ee33bf46929646b3aa87554c565d8fb2c7aa549c44") +} + +func (VRFBeaconOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (VRFBeaconOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (VRFBeaconPayeeshipTransferRequested) Topic() common.Hash { + return common.HexToHash("0x84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e38367") +} + +func (VRFBeaconPayeeshipTransferred) Topic() common.Hash { + return common.HexToHash("0x78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b3") +} + +func (VRFBeaconRandomWordsFulfilled) Topic() common.Hash { + return common.HexToHash("0x8f79f730779e875ce76c428039cc2052b5b5918c2a55c598fab251c1198aec54") +} + +func (VRFBeaconRandomnessFulfillmentRequested) Topic() common.Hash { + return common.HexToHash("0x01872fb9c7d6d68af06a17347935e04412da302a377224c205e672c26e18c37f") +} + +func (VRFBeaconRandomnessRedeemed) Topic() common.Hash { + return common.HexToHash("0x16f3f633197fafab10a5df69e6f3f2f7f20092f08d8d47de0a91c0f4b96a1a25") +} + +func (VRFBeaconRandomnessRequested) Topic() common.Hash { + return common.HexToHash("0xb7933fba96b6b452eb44f99fdc08052a45dff82363d59abaff0456931c3d2459") +} + +func (_VRFBeacon *VRFBeacon) Address() common.Address { + return _VRFBeacon.address +} + +type VRFBeaconInterface interface { + NUMCONFDELAYS(opts *bind.CallOpts) (uint8, error) + + GetBilling(opts *bind.CallOpts) (GetBilling, + + error) + + GetBillingAccessController(opts *bind.CallOpts) (common.Address, error) + + ICoordinator(opts *bind.CallOpts) (common.Address, error) + + ILink(opts *bind.CallOpts) (common.Address, error) + + LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) + + LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) + + LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) + + OwedPayment(opts *bind.CallOpts, transmitterAddress common.Address) (*big.Int, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SKeyID(opts *bind.CallOpts) ([32]byte, error) + + SKeyProvider(opts *bind.CallOpts) (common.Address, error) + + SProvingKeyHash(opts *bind.CallOpts) ([32]byte, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + AcceptPayeeship(opts *bind.TransactOpts, transmitter common.Address) (*types.Transaction, error) + + ExposeType(opts *bind.TransactOpts, arg0 VRFBeaconReportReport) (*types.Transaction, error) + + KeyGenerated(opts *bind.TransactOpts, kd KeyDataStructKeyData) (*types.Transaction, error) + + NewKeyRequested(opts *bind.TransactOpts) (*types.Transaction, error) + + SetBilling(opts *bind.TransactOpts, maximumGasPrice uint64, reasonableGasPrice uint64, observationPayment uint64, transmissionPayment uint64, accountingGas *big.Int) (*types.Transaction, error) + + SetBillingAccessController(opts *bind.TransactOpts, _billingAccessController common.Address) (*types.Transaction, error) + + SetConfig(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) + + SetPayees(opts *bind.TransactOpts, transmitters []common.Address, payees []common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + TransferPayeeship(opts *bind.TransactOpts, transmitter common.Address, proposed common.Address) (*types.Transaction, error) + + Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) + + WithdrawFunds(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) + + WithdrawPayment(opts *bind.TransactOpts, transmitter common.Address) (*types.Transaction, error) + + FilterBillingAccessControllerSet(opts *bind.FilterOpts) (*VRFBeaconBillingAccessControllerSetIterator, error) + + WatchBillingAccessControllerSet(opts *bind.WatchOpts, sink chan<- *VRFBeaconBillingAccessControllerSet) (event.Subscription, error) + + ParseBillingAccessControllerSet(log types.Log) (*VRFBeaconBillingAccessControllerSet, error) + + FilterBillingSet(opts *bind.FilterOpts) (*VRFBeaconBillingSetIterator, error) + + WatchBillingSet(opts *bind.WatchOpts, sink chan<- *VRFBeaconBillingSet) (event.Subscription, error) + + ParseBillingSet(log types.Log) (*VRFBeaconBillingSet, error) + + FilterConfigSet(opts *bind.FilterOpts) (*VRFBeaconConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *VRFBeaconConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*VRFBeaconConfigSet, error) + + FilterNewTransmission(opts *bind.FilterOpts, epochAndRound []*big.Int) (*VRFBeaconNewTransmissionIterator, error) + + WatchNewTransmission(opts *bind.WatchOpts, sink chan<- *VRFBeaconNewTransmission, epochAndRound []*big.Int) (event.Subscription, error) + + ParseNewTransmission(log types.Log) (*VRFBeaconNewTransmission, error) + + FilterOraclePaid(opts *bind.FilterOpts, transmitter []common.Address, payee []common.Address, linkToken []common.Address) (*VRFBeaconOraclePaidIterator, error) + + WatchOraclePaid(opts *bind.WatchOpts, sink chan<- *VRFBeaconOraclePaid, transmitter []common.Address, payee []common.Address, linkToken []common.Address) (event.Subscription, error) + + ParseOraclePaid(log types.Log) (*VRFBeaconOraclePaid, error) + + FilterOutputsServed(opts *bind.FilterOpts) (*VRFBeaconOutputsServedIterator, error) + + WatchOutputsServed(opts *bind.WatchOpts, sink chan<- *VRFBeaconOutputsServed) (event.Subscription, error) + + ParseOutputsServed(log types.Log) (*VRFBeaconOutputsServed, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFBeaconOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFBeaconOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*VRFBeaconOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFBeaconOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFBeaconOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*VRFBeaconOwnershipTransferred, error) + + FilterPayeeshipTransferRequested(opts *bind.FilterOpts, transmitter []common.Address, current []common.Address, proposed []common.Address) (*VRFBeaconPayeeshipTransferRequestedIterator, error) + + WatchPayeeshipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFBeaconPayeeshipTransferRequested, transmitter []common.Address, current []common.Address, proposed []common.Address) (event.Subscription, error) + + ParsePayeeshipTransferRequested(log types.Log) (*VRFBeaconPayeeshipTransferRequested, error) + + FilterPayeeshipTransferred(opts *bind.FilterOpts, transmitter []common.Address, previous []common.Address, current []common.Address) (*VRFBeaconPayeeshipTransferredIterator, error) + + WatchPayeeshipTransferred(opts *bind.WatchOpts, sink chan<- *VRFBeaconPayeeshipTransferred, transmitter []common.Address, previous []common.Address, current []common.Address) (event.Subscription, error) + + ParsePayeeshipTransferred(log types.Log) (*VRFBeaconPayeeshipTransferred, error) + + FilterRandomWordsFulfilled(opts *bind.FilterOpts) (*VRFBeaconRandomWordsFulfilledIterator, error) + + WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFBeaconRandomWordsFulfilled) (event.Subscription, error) + + ParseRandomWordsFulfilled(log types.Log) (*VRFBeaconRandomWordsFulfilled, error) + + FilterRandomnessFulfillmentRequested(opts *bind.FilterOpts, requestID []*big.Int) (*VRFBeaconRandomnessFulfillmentRequestedIterator, error) + + WatchRandomnessFulfillmentRequested(opts *bind.WatchOpts, sink chan<- *VRFBeaconRandomnessFulfillmentRequested, requestID []*big.Int) (event.Subscription, error) + + ParseRandomnessFulfillmentRequested(log types.Log) (*VRFBeaconRandomnessFulfillmentRequested, error) + + FilterRandomnessRedeemed(opts *bind.FilterOpts, requestID []*big.Int, requester []common.Address) (*VRFBeaconRandomnessRedeemedIterator, error) + + WatchRandomnessRedeemed(opts *bind.WatchOpts, sink chan<- *VRFBeaconRandomnessRedeemed, requestID []*big.Int, requester []common.Address) (event.Subscription, error) + + ParseRandomnessRedeemed(log types.Log) (*VRFBeaconRandomnessRedeemed, error) + + FilterRandomnessRequested(opts *bind.FilterOpts, requestID []*big.Int) (*VRFBeaconRandomnessRequestedIterator, error) + + WatchRandomnessRequested(opts *bind.WatchOpts, sink chan<- *VRFBeaconRandomnessRequested, requestID []*big.Int) (event.Subscription, error) + + ParseRandomnessRequested(log types.Log) (*VRFBeaconRandomnessRequested, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ocr2vrf/generated/vrf_beacon_consumer/vrf_beacon_consumer.go b/core/gethwrappers/ocr2vrf/generated/vrf_beacon_consumer/vrf_beacon_consumer.go new file mode 100644 index 00000000000..edc4ec6556d --- /dev/null +++ b/core/gethwrappers/ocr2vrf/generated/vrf_beacon_consumer/vrf_beacon_consumer.go @@ -0,0 +1,1034 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package vrf_beacon_consumer + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var BeaconVRFConsumerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"shouldFail\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"beaconPeriodBlocks\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"MustBeCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeOwnerOrCoordinator\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"CoordinatorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fail\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_beaconPeriodBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"arguments\",\"type\":\"bytes\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_ReceivedRandomnessByRequestID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_arguments\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_gasAvailable\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_mostRecentRequestID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_myBeaconRequests\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"slotNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"confirmationDelay\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_randomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"\",\"type\":\"uint24\"}],\"name\":\"s_requestsIDs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_subId\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"shouldFail\",\"type\":\"bool\"}],\"name\":\"setFail\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"reqId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"height\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"delay\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"}],\"name\":\"storeBeaconRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"}],\"name\":\"testRedeemRandomness\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint24\",\"name\":\"confirmationDelayArg\",\"type\":\"uint24\"}],\"name\":\"testRequestRandomness\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"uint24\",\"name\":\"confDelay\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"arguments\",\"type\":\"bytes\"}],\"name\":\"testRequestRandomnessFulfillment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b50604051620018db380380620018db8339810160408190526200003491620001aa565b8233806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620000ff565b5050600280546001600160a01b0319166001600160a01b03939093169290921790915550600b805460ff191692151592909217909155600c555062000201565b336001600160a01b03821603620001595760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080600060608486031215620001c057600080fd5b83516001600160a01b0381168114620001d857600080fd5b60208501519093508015158114620001ef57600080fd5b80925050604084015190509250925092565b6116ca80620002116000396000f3fe608060405234801561001057600080fd5b506004361061016c5760003560e01c8063a9cc4718116100cd578063ea7502ab11610081578063f2fde38b11610066578063f2fde38b1461031f578063f6eaffc814610332578063ffe97ca41461034557600080fd5b8063ea7502ab14610303578063f08c5daa1461031657600080fd5b8063cd0593df116100b2578063cd0593df146102d4578063d0705f04146102dd578063d21ea8fd146102f057600080fd5b8063a9cc4718146102a4578063c6d61301146102c157600080fd5b80637716cdaa116101245780638da5cb5b116101095780638da5cb5b1461022a5780638ea98117146102525780639d7694021461026557600080fd5b80637716cdaa1461020d57806379ba50971461022257600080fd5b8063689b77ab11610155578063689b77ab146101c45780636df57cc3146101cd578063706da1ca146101e057600080fd5b8063341867a2146101715780635f15cccc14610186575b600080fd5b61018461017f366004610e87565b6103f8565b005b6101b1610194366004610ec1565b600460209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6101b160085481565b6101846101db366004610eff565b6104ed565b6009546101f49067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016101bb565b610215610628565b6040516101bb9190610fa9565b6101846106b6565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101bb565b610184610260366004610fc3565b6107b8565b610184610273366004610ff9565b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b600b546102b19060ff1681565b60405190151581526020016101bb565b6101b16102cf36600461101b565b61089e565b6101b1600c5481565b6101b16102eb366004610e87565b6109a8565b6101846102fe366004611187565b6109d9565b6101b1610311366004611250565b610a3a565b6101b1600a5481565b61018461032d366004610fc3565b610b4a565b6101b16103403660046112d4565b610b5e565b6103ae6103533660046112d4565b60056020526000908152604090205463ffffffff811690640100000000810462ffffff1690670100000000000000810461ffff16906901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1684565b6040805163ffffffff909516855262ffffff909316602085015261ffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff1660608201526080016101bb565b60025460408051602081018252600080825291517facfc6cdd000000000000000000000000000000000000000000000000000000008152919273ffffffffffffffffffffffffffffffffffffffff169163acfc6cdd9161045e91879187916004016112ed565b6000604051808303816000875af115801561047d573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526104c39190810190611315565b600083815260066020908152604090912082519293506104e7929091840190610e27565b50505050565b600083815260046020908152604080832062ffffff861684529091528120859055600c5461051b9085611404565b6040805160808101825263ffffffff928316815262ffffff958616602080830191825261ffff968716838501908152306060850190815260009b8c526005909252939099209151825491519351995173ffffffffffffffffffffffffffffffffffffffff166901000000000000000000027fffffff0000000000000000000000000000000000000000ffffffffffffffffff9a90971667010000000000000002999099167fffffff00000000000000000000000000000000000000000000ffffffffffffff93909716640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffff000000000000009091169890931697909717919091171692909217179092555050565b6007805461063590611418565b80601f016020809104026020016040519081016040528092919081815260200182805461066190611418565b80156106ae5780601f10610683576101008083540402835291602001916106ae565b820191906000526020600020905b81548152906001019060200180831161069157829003601f168201915b505050505081565b60015473ffffffffffffffffffffffffffffffffffffffff16331461073c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906107f8575060025473ffffffffffffffffffffffffffffffffffffffff163314155b1561082f576040517fd4e06fd700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517fc258faa9a17ddfdf4130b4acff63a289202e7d5f9e42f366add65368575486bc90600090a250565b600080600c546108ac610b7f565b6108b6919061146b565b9050600081600c546108c6610b7f565b6108d0919061147f565b6108da9190611498565b60025460408051602081018252600080825291517f4ffac83a000000000000000000000000000000000000000000000000000000008152939450909273ffffffffffffffffffffffffffffffffffffffff90921691634ffac83a91610948918a918c918b91906004016114ab565b6020604051808303816000875af1158015610967573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098b91906114e3565b90506109998183878a6104ed565b60088190559695505050505050565b600660205281600052604060002081815481106109c457600080fd5b90600052602060002001600091509150505481565b60025473ffffffffffffffffffffffffffffffffffffffff163314610a2a576040517f66bf9c7200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a35838383610c16565b505050565b600080600c54610a48610b7f565b610a52919061146b565b9050600081600c54610a62610b7f565b610a6c919061147f565b610a769190611498565b60025460408051602081018252600080825291517fdb972c8b000000000000000000000000000000000000000000000000000000008152939450909273ffffffffffffffffffffffffffffffffffffffff9092169163db972c8b91610ae8918d918d918d918d918d91906004016114fc565b6020604051808303816000875af1158015610b07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2b91906114e3565b9050610b398183898b6104ed565b600881905598975050505050505050565b610b52610caf565b610b5b81610d32565b50565b60038181548110610b6e57600080fd5b600091825260209091200154905081565b60004661a4b1811480610b94575062066eed81145b15610c0f57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610be5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0991906114e3565b91505090565b4391505090565b600b5460ff1615610c83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f206661696c656420696e2066756c66696c6c52616e646f6d576f7264730000006044820152606401610733565b60008381526006602090815260409091208351610ca292850190610e27565b5060076104e782826115a3565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610733565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610db1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610733565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610e62579160200282015b82811115610e62578251825591602001919060010190610e47565b50610e6e929150610e72565b5090565b5b80821115610e6e5760008155600101610e73565b60008060408385031215610e9a57600080fd5b50508035926020909101359150565b803562ffffff81168114610ebc57600080fd5b919050565b60008060408385031215610ed457600080fd5b82359150610ee460208401610ea9565b90509250929050565b803561ffff81168114610ebc57600080fd5b60008060008060808587031215610f1557600080fd5b8435935060208501359250610f2c60408601610ea9565b9150610f3a60608601610eed565b905092959194509250565b6000815180845260005b81811015610f6b57602081850181015186830182015201610f4f565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610fbc6020830184610f45565b9392505050565b600060208284031215610fd557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610fbc57600080fd5b60006020828403121561100b57600080fd5b81358015158114610fbc57600080fd5b60008060006060848603121561103057600080fd5b61103984610eed565b92506020840135915061104e60408501610ea9565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156110cd576110cd611057565b604052919050565b600067ffffffffffffffff8211156110ef576110ef611057565b5060051b60200190565b600082601f83011261110a57600080fd5b813567ffffffffffffffff81111561112457611124611057565b61115560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611086565b81815284602083860101111561116a57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121561119c57600080fd5b8335925060208085013567ffffffffffffffff808211156111bc57600080fd5b818701915087601f8301126111d057600080fd5b81356111e36111de826110d5565b611086565b81815260059190911b8301840190848101908a83111561120257600080fd5b938501935b8285101561122057843582529385019390850190611207565b96505050604087013592508083111561123857600080fd5b5050611246868287016110f9565b9150509250925092565b600080600080600060a0868803121561126857600080fd5b8535945061127860208701610eed565b935061128660408701610ea9565b9250606086013563ffffffff8116811461129f57600080fd5b9150608086013567ffffffffffffffff8111156112bb57600080fd5b6112c7888289016110f9565b9150509295509295909350565b6000602082840312156112e657600080fd5b5035919050565b83815282602082015260606040820152600061130c6060830184610f45565b95945050505050565b6000602080838503121561132857600080fd5b825167ffffffffffffffff81111561133f57600080fd5b8301601f8101851361135057600080fd5b805161135e6111de826110d5565b81815260059190911b8201830190838101908783111561137d57600080fd5b928401925b8284101561139b57835182529284019290840190611382565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082611413576114136113a6565b500490565b600181811c9082168061142c57607f821691505b602082108103611465577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60008261147a5761147a6113a6565b500690565b80820180821115611492576114926113d5565b92915050565b81810381811115611492576114926113d5565b84815261ffff8416602082015262ffffff831660408201526080606082015260006114d96080830184610f45565b9695505050505050565b6000602082840312156114f557600080fd5b5051919050565b86815261ffff8616602082015262ffffff8516604082015263ffffffff8416606082015260c06080820152600061153660c0830185610f45565b82810360a08401526115488185610f45565b9998505050505050505050565b601f821115610a3557600081815260208120601f850160051c8101602086101561157c5750805b601f850160051c820191505b8181101561159b57828155600101611588565b505050505050565b815167ffffffffffffffff8111156115bd576115bd611057565b6115d1816115cb8454611418565b84611555565b602080601f83116001811461162457600084156115ee5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561159b565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561167157888601518255948401946001909101908401611652565b50858210156116ad57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000813000a", +} + +var BeaconVRFConsumerABI = BeaconVRFConsumerMetaData.ABI + +var BeaconVRFConsumerBin = BeaconVRFConsumerMetaData.Bin + +func DeployBeaconVRFConsumer(auth *bind.TransactOpts, backend bind.ContractBackend, coordinator common.Address, shouldFail bool, beaconPeriodBlocks *big.Int) (common.Address, *types.Transaction, *BeaconVRFConsumer, error) { + parsed, err := BeaconVRFConsumerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(BeaconVRFConsumerBin), backend, coordinator, shouldFail, beaconPeriodBlocks) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &BeaconVRFConsumer{BeaconVRFConsumerCaller: BeaconVRFConsumerCaller{contract: contract}, BeaconVRFConsumerTransactor: BeaconVRFConsumerTransactor{contract: contract}, BeaconVRFConsumerFilterer: BeaconVRFConsumerFilterer{contract: contract}}, nil +} + +type BeaconVRFConsumer struct { + address common.Address + abi abi.ABI + BeaconVRFConsumerCaller + BeaconVRFConsumerTransactor + BeaconVRFConsumerFilterer +} + +type BeaconVRFConsumerCaller struct { + contract *bind.BoundContract +} + +type BeaconVRFConsumerTransactor struct { + contract *bind.BoundContract +} + +type BeaconVRFConsumerFilterer struct { + contract *bind.BoundContract +} + +type BeaconVRFConsumerSession struct { + Contract *BeaconVRFConsumer + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type BeaconVRFConsumerCallerSession struct { + Contract *BeaconVRFConsumerCaller + CallOpts bind.CallOpts +} + +type BeaconVRFConsumerTransactorSession struct { + Contract *BeaconVRFConsumerTransactor + TransactOpts bind.TransactOpts +} + +type BeaconVRFConsumerRaw struct { + Contract *BeaconVRFConsumer +} + +type BeaconVRFConsumerCallerRaw struct { + Contract *BeaconVRFConsumerCaller +} + +type BeaconVRFConsumerTransactorRaw struct { + Contract *BeaconVRFConsumerTransactor +} + +func NewBeaconVRFConsumer(address common.Address, backend bind.ContractBackend) (*BeaconVRFConsumer, error) { + abi, err := abi.JSON(strings.NewReader(BeaconVRFConsumerABI)) + if err != nil { + return nil, err + } + contract, err := bindBeaconVRFConsumer(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &BeaconVRFConsumer{address: address, abi: abi, BeaconVRFConsumerCaller: BeaconVRFConsumerCaller{contract: contract}, BeaconVRFConsumerTransactor: BeaconVRFConsumerTransactor{contract: contract}, BeaconVRFConsumerFilterer: BeaconVRFConsumerFilterer{contract: contract}}, nil +} + +func NewBeaconVRFConsumerCaller(address common.Address, caller bind.ContractCaller) (*BeaconVRFConsumerCaller, error) { + contract, err := bindBeaconVRFConsumer(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &BeaconVRFConsumerCaller{contract: contract}, nil +} + +func NewBeaconVRFConsumerTransactor(address common.Address, transactor bind.ContractTransactor) (*BeaconVRFConsumerTransactor, error) { + contract, err := bindBeaconVRFConsumer(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &BeaconVRFConsumerTransactor{contract: contract}, nil +} + +func NewBeaconVRFConsumerFilterer(address common.Address, filterer bind.ContractFilterer) (*BeaconVRFConsumerFilterer, error) { + contract, err := bindBeaconVRFConsumer(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &BeaconVRFConsumerFilterer{contract: contract}, nil +} + +func bindBeaconVRFConsumer(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := BeaconVRFConsumerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _BeaconVRFConsumer.Contract.BeaconVRFConsumerCaller.contract.Call(opts, result, method, params...) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BeaconVRFConsumer.Contract.BeaconVRFConsumerTransactor.contract.Transfer(opts) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _BeaconVRFConsumer.Contract.BeaconVRFConsumerTransactor.contract.Transact(opts, method, params...) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _BeaconVRFConsumer.Contract.contract.Call(opts, result, method, params...) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BeaconVRFConsumer.Contract.contract.Transfer(opts) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _BeaconVRFConsumer.Contract.contract.Transact(opts, method, params...) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCaller) Fail(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _BeaconVRFConsumer.contract.Call(opts, &out, "fail") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerSession) Fail() (bool, error) { + return _BeaconVRFConsumer.Contract.Fail(&_BeaconVRFConsumer.CallOpts) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCallerSession) Fail() (bool, error) { + return _BeaconVRFConsumer.Contract.Fail(&_BeaconVRFConsumer.CallOpts) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCaller) IBeaconPeriodBlocks(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _BeaconVRFConsumer.contract.Call(opts, &out, "i_beaconPeriodBlocks") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerSession) IBeaconPeriodBlocks() (*big.Int, error) { + return _BeaconVRFConsumer.Contract.IBeaconPeriodBlocks(&_BeaconVRFConsumer.CallOpts) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCallerSession) IBeaconPeriodBlocks() (*big.Int, error) { + return _BeaconVRFConsumer.Contract.IBeaconPeriodBlocks(&_BeaconVRFConsumer.CallOpts) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BeaconVRFConsumer.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerSession) Owner() (common.Address, error) { + return _BeaconVRFConsumer.Contract.Owner(&_BeaconVRFConsumer.CallOpts) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCallerSession) Owner() (common.Address, error) { + return _BeaconVRFConsumer.Contract.Owner(&_BeaconVRFConsumer.CallOpts) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCaller) SReceivedRandomnessByRequestID(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + var out []interface{} + err := _BeaconVRFConsumer.contract.Call(opts, &out, "s_ReceivedRandomnessByRequestID", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerSession) SReceivedRandomnessByRequestID(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + return _BeaconVRFConsumer.Contract.SReceivedRandomnessByRequestID(&_BeaconVRFConsumer.CallOpts, arg0, arg1) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCallerSession) SReceivedRandomnessByRequestID(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + return _BeaconVRFConsumer.Contract.SReceivedRandomnessByRequestID(&_BeaconVRFConsumer.CallOpts, arg0, arg1) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCaller) SArguments(opts *bind.CallOpts) ([]byte, error) { + var out []interface{} + err := _BeaconVRFConsumer.contract.Call(opts, &out, "s_arguments") + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerSession) SArguments() ([]byte, error) { + return _BeaconVRFConsumer.Contract.SArguments(&_BeaconVRFConsumer.CallOpts) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCallerSession) SArguments() ([]byte, error) { + return _BeaconVRFConsumer.Contract.SArguments(&_BeaconVRFConsumer.CallOpts) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCaller) SGasAvailable(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _BeaconVRFConsumer.contract.Call(opts, &out, "s_gasAvailable") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerSession) SGasAvailable() (*big.Int, error) { + return _BeaconVRFConsumer.Contract.SGasAvailable(&_BeaconVRFConsumer.CallOpts) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCallerSession) SGasAvailable() (*big.Int, error) { + return _BeaconVRFConsumer.Contract.SGasAvailable(&_BeaconVRFConsumer.CallOpts) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCaller) SMostRecentRequestID(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _BeaconVRFConsumer.contract.Call(opts, &out, "s_mostRecentRequestID") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerSession) SMostRecentRequestID() (*big.Int, error) { + return _BeaconVRFConsumer.Contract.SMostRecentRequestID(&_BeaconVRFConsumer.CallOpts) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCallerSession) SMostRecentRequestID() (*big.Int, error) { + return _BeaconVRFConsumer.Contract.SMostRecentRequestID(&_BeaconVRFConsumer.CallOpts) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCaller) SMyBeaconRequests(opts *bind.CallOpts, arg0 *big.Int) (SMyBeaconRequests, + + error) { + var out []interface{} + err := _BeaconVRFConsumer.contract.Call(opts, &out, "s_myBeaconRequests", arg0) + + outstruct := new(SMyBeaconRequests) + if err != nil { + return *outstruct, err + } + + outstruct.SlotNumber = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.ConfirmationDelay = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.NumWords = *abi.ConvertType(out[2], new(uint16)).(*uint16) + outstruct.Requester = *abi.ConvertType(out[3], new(common.Address)).(*common.Address) + + return *outstruct, err + +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerSession) SMyBeaconRequests(arg0 *big.Int) (SMyBeaconRequests, + + error) { + return _BeaconVRFConsumer.Contract.SMyBeaconRequests(&_BeaconVRFConsumer.CallOpts, arg0) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCallerSession) SMyBeaconRequests(arg0 *big.Int) (SMyBeaconRequests, + + error) { + return _BeaconVRFConsumer.Contract.SMyBeaconRequests(&_BeaconVRFConsumer.CallOpts, arg0) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCaller) SRandomWords(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { + var out []interface{} + err := _BeaconVRFConsumer.contract.Call(opts, &out, "s_randomWords", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerSession) SRandomWords(arg0 *big.Int) (*big.Int, error) { + return _BeaconVRFConsumer.Contract.SRandomWords(&_BeaconVRFConsumer.CallOpts, arg0) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCallerSession) SRandomWords(arg0 *big.Int) (*big.Int, error) { + return _BeaconVRFConsumer.Contract.SRandomWords(&_BeaconVRFConsumer.CallOpts, arg0) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCaller) SRequestsIDs(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + var out []interface{} + err := _BeaconVRFConsumer.contract.Call(opts, &out, "s_requestsIDs", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerSession) SRequestsIDs(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + return _BeaconVRFConsumer.Contract.SRequestsIDs(&_BeaconVRFConsumer.CallOpts, arg0, arg1) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCallerSession) SRequestsIDs(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) { + return _BeaconVRFConsumer.Contract.SRequestsIDs(&_BeaconVRFConsumer.CallOpts, arg0, arg1) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCaller) SSubId(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _BeaconVRFConsumer.contract.Call(opts, &out, "s_subId") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerSession) SSubId() (uint64, error) { + return _BeaconVRFConsumer.Contract.SSubId(&_BeaconVRFConsumer.CallOpts) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerCallerSession) SSubId() (uint64, error) { + return _BeaconVRFConsumer.Contract.SSubId(&_BeaconVRFConsumer.CallOpts) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BeaconVRFConsumer.contract.Transact(opts, "acceptOwnership") +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerSession) AcceptOwnership() (*types.Transaction, error) { + return _BeaconVRFConsumer.Contract.AcceptOwnership(&_BeaconVRFConsumer.TransactOpts) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _BeaconVRFConsumer.Contract.AcceptOwnership(&_BeaconVRFConsumer.TransactOpts) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerTransactor) RawFulfillRandomWords(opts *bind.TransactOpts, requestID *big.Int, randomWords []*big.Int, arguments []byte) (*types.Transaction, error) { + return _BeaconVRFConsumer.contract.Transact(opts, "rawFulfillRandomWords", requestID, randomWords, arguments) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerSession) RawFulfillRandomWords(requestID *big.Int, randomWords []*big.Int, arguments []byte) (*types.Transaction, error) { + return _BeaconVRFConsumer.Contract.RawFulfillRandomWords(&_BeaconVRFConsumer.TransactOpts, requestID, randomWords, arguments) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerTransactorSession) RawFulfillRandomWords(requestID *big.Int, randomWords []*big.Int, arguments []byte) (*types.Transaction, error) { + return _BeaconVRFConsumer.Contract.RawFulfillRandomWords(&_BeaconVRFConsumer.TransactOpts, requestID, randomWords, arguments) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerTransactor) SetCoordinator(opts *bind.TransactOpts, coordinator common.Address) (*types.Transaction, error) { + return _BeaconVRFConsumer.contract.Transact(opts, "setCoordinator", coordinator) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerSession) SetCoordinator(coordinator common.Address) (*types.Transaction, error) { + return _BeaconVRFConsumer.Contract.SetCoordinator(&_BeaconVRFConsumer.TransactOpts, coordinator) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerTransactorSession) SetCoordinator(coordinator common.Address) (*types.Transaction, error) { + return _BeaconVRFConsumer.Contract.SetCoordinator(&_BeaconVRFConsumer.TransactOpts, coordinator) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerTransactor) SetFail(opts *bind.TransactOpts, shouldFail bool) (*types.Transaction, error) { + return _BeaconVRFConsumer.contract.Transact(opts, "setFail", shouldFail) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerSession) SetFail(shouldFail bool) (*types.Transaction, error) { + return _BeaconVRFConsumer.Contract.SetFail(&_BeaconVRFConsumer.TransactOpts, shouldFail) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerTransactorSession) SetFail(shouldFail bool) (*types.Transaction, error) { + return _BeaconVRFConsumer.Contract.SetFail(&_BeaconVRFConsumer.TransactOpts, shouldFail) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerTransactor) StoreBeaconRequest(opts *bind.TransactOpts, reqId *big.Int, height *big.Int, delay *big.Int, numWords uint16) (*types.Transaction, error) { + return _BeaconVRFConsumer.contract.Transact(opts, "storeBeaconRequest", reqId, height, delay, numWords) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerSession) StoreBeaconRequest(reqId *big.Int, height *big.Int, delay *big.Int, numWords uint16) (*types.Transaction, error) { + return _BeaconVRFConsumer.Contract.StoreBeaconRequest(&_BeaconVRFConsumer.TransactOpts, reqId, height, delay, numWords) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerTransactorSession) StoreBeaconRequest(reqId *big.Int, height *big.Int, delay *big.Int, numWords uint16) (*types.Transaction, error) { + return _BeaconVRFConsumer.Contract.StoreBeaconRequest(&_BeaconVRFConsumer.TransactOpts, reqId, height, delay, numWords) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerTransactor) TestRedeemRandomness(opts *bind.TransactOpts, subID *big.Int, requestID *big.Int) (*types.Transaction, error) { + return _BeaconVRFConsumer.contract.Transact(opts, "testRedeemRandomness", subID, requestID) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerSession) TestRedeemRandomness(subID *big.Int, requestID *big.Int) (*types.Transaction, error) { + return _BeaconVRFConsumer.Contract.TestRedeemRandomness(&_BeaconVRFConsumer.TransactOpts, subID, requestID) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerTransactorSession) TestRedeemRandomness(subID *big.Int, requestID *big.Int) (*types.Transaction, error) { + return _BeaconVRFConsumer.Contract.TestRedeemRandomness(&_BeaconVRFConsumer.TransactOpts, subID, requestID) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerTransactor) TestRequestRandomness(opts *bind.TransactOpts, numWords uint16, subID *big.Int, confirmationDelayArg *big.Int) (*types.Transaction, error) { + return _BeaconVRFConsumer.contract.Transact(opts, "testRequestRandomness", numWords, subID, confirmationDelayArg) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerSession) TestRequestRandomness(numWords uint16, subID *big.Int, confirmationDelayArg *big.Int) (*types.Transaction, error) { + return _BeaconVRFConsumer.Contract.TestRequestRandomness(&_BeaconVRFConsumer.TransactOpts, numWords, subID, confirmationDelayArg) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerTransactorSession) TestRequestRandomness(numWords uint16, subID *big.Int, confirmationDelayArg *big.Int) (*types.Transaction, error) { + return _BeaconVRFConsumer.Contract.TestRequestRandomness(&_BeaconVRFConsumer.TransactOpts, numWords, subID, confirmationDelayArg) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerTransactor) TestRequestRandomnessFulfillment(opts *bind.TransactOpts, subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte) (*types.Transaction, error) { + return _BeaconVRFConsumer.contract.Transact(opts, "testRequestRandomnessFulfillment", subID, numWords, confDelay, callbackGasLimit, arguments) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerSession) TestRequestRandomnessFulfillment(subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte) (*types.Transaction, error) { + return _BeaconVRFConsumer.Contract.TestRequestRandomnessFulfillment(&_BeaconVRFConsumer.TransactOpts, subID, numWords, confDelay, callbackGasLimit, arguments) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerTransactorSession) TestRequestRandomnessFulfillment(subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte) (*types.Transaction, error) { + return _BeaconVRFConsumer.Contract.TestRequestRandomnessFulfillment(&_BeaconVRFConsumer.TransactOpts, subID, numWords, confDelay, callbackGasLimit, arguments) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _BeaconVRFConsumer.contract.Transact(opts, "transferOwnership", to) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _BeaconVRFConsumer.Contract.TransferOwnership(&_BeaconVRFConsumer.TransactOpts, to) +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _BeaconVRFConsumer.Contract.TransferOwnership(&_BeaconVRFConsumer.TransactOpts, to) +} + +type BeaconVRFConsumerCoordinatorUpdatedIterator struct { + Event *BeaconVRFConsumerCoordinatorUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BeaconVRFConsumerCoordinatorUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BeaconVRFConsumerCoordinatorUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BeaconVRFConsumerCoordinatorUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BeaconVRFConsumerCoordinatorUpdatedIterator) Error() error { + return it.fail +} + +func (it *BeaconVRFConsumerCoordinatorUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BeaconVRFConsumerCoordinatorUpdated struct { + Coordinator common.Address + Raw types.Log +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerFilterer) FilterCoordinatorUpdated(opts *bind.FilterOpts, coordinator []common.Address) (*BeaconVRFConsumerCoordinatorUpdatedIterator, error) { + + var coordinatorRule []interface{} + for _, coordinatorItem := range coordinator { + coordinatorRule = append(coordinatorRule, coordinatorItem) + } + + logs, sub, err := _BeaconVRFConsumer.contract.FilterLogs(opts, "CoordinatorUpdated", coordinatorRule) + if err != nil { + return nil, err + } + return &BeaconVRFConsumerCoordinatorUpdatedIterator{contract: _BeaconVRFConsumer.contract, event: "CoordinatorUpdated", logs: logs, sub: sub}, nil +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerFilterer) WatchCoordinatorUpdated(opts *bind.WatchOpts, sink chan<- *BeaconVRFConsumerCoordinatorUpdated, coordinator []common.Address) (event.Subscription, error) { + + var coordinatorRule []interface{} + for _, coordinatorItem := range coordinator { + coordinatorRule = append(coordinatorRule, coordinatorItem) + } + + logs, sub, err := _BeaconVRFConsumer.contract.WatchLogs(opts, "CoordinatorUpdated", coordinatorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BeaconVRFConsumerCoordinatorUpdated) + if err := _BeaconVRFConsumer.contract.UnpackLog(event, "CoordinatorUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerFilterer) ParseCoordinatorUpdated(log types.Log) (*BeaconVRFConsumerCoordinatorUpdated, error) { + event := new(BeaconVRFConsumerCoordinatorUpdated) + if err := _BeaconVRFConsumer.contract.UnpackLog(event, "CoordinatorUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BeaconVRFConsumerOwnershipTransferRequestedIterator struct { + Event *BeaconVRFConsumerOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BeaconVRFConsumerOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BeaconVRFConsumerOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BeaconVRFConsumerOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BeaconVRFConsumerOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *BeaconVRFConsumerOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BeaconVRFConsumerOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BeaconVRFConsumerOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BeaconVRFConsumer.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &BeaconVRFConsumerOwnershipTransferRequestedIterator{contract: _BeaconVRFConsumer.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *BeaconVRFConsumerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BeaconVRFConsumer.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BeaconVRFConsumerOwnershipTransferRequested) + if err := _BeaconVRFConsumer.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerFilterer) ParseOwnershipTransferRequested(log types.Log) (*BeaconVRFConsumerOwnershipTransferRequested, error) { + event := new(BeaconVRFConsumerOwnershipTransferRequested) + if err := _BeaconVRFConsumer.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BeaconVRFConsumerOwnershipTransferredIterator struct { + Event *BeaconVRFConsumerOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BeaconVRFConsumerOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BeaconVRFConsumerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(BeaconVRFConsumerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *BeaconVRFConsumerOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *BeaconVRFConsumerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BeaconVRFConsumerOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BeaconVRFConsumerOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BeaconVRFConsumer.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &BeaconVRFConsumerOwnershipTransferredIterator{contract: _BeaconVRFConsumer.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *BeaconVRFConsumerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _BeaconVRFConsumer.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BeaconVRFConsumerOwnershipTransferred) + if err := _BeaconVRFConsumer.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_BeaconVRFConsumer *BeaconVRFConsumerFilterer) ParseOwnershipTransferred(log types.Log) (*BeaconVRFConsumerOwnershipTransferred, error) { + event := new(BeaconVRFConsumerOwnershipTransferred) + if err := _BeaconVRFConsumer.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type SMyBeaconRequests struct { + SlotNumber uint32 + ConfirmationDelay *big.Int + NumWords uint16 + Requester common.Address +} + +func (_BeaconVRFConsumer *BeaconVRFConsumer) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _BeaconVRFConsumer.abi.Events["CoordinatorUpdated"].ID: + return _BeaconVRFConsumer.ParseCoordinatorUpdated(log) + case _BeaconVRFConsumer.abi.Events["OwnershipTransferRequested"].ID: + return _BeaconVRFConsumer.ParseOwnershipTransferRequested(log) + case _BeaconVRFConsumer.abi.Events["OwnershipTransferred"].ID: + return _BeaconVRFConsumer.ParseOwnershipTransferred(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (BeaconVRFConsumerCoordinatorUpdated) Topic() common.Hash { + return common.HexToHash("0xc258faa9a17ddfdf4130b4acff63a289202e7d5f9e42f366add65368575486bc") +} + +func (BeaconVRFConsumerOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (BeaconVRFConsumerOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (_BeaconVRFConsumer *BeaconVRFConsumer) Address() common.Address { + return _BeaconVRFConsumer.address +} + +type BeaconVRFConsumerInterface interface { + Fail(opts *bind.CallOpts) (bool, error) + + IBeaconPeriodBlocks(opts *bind.CallOpts) (*big.Int, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + SReceivedRandomnessByRequestID(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) + + SArguments(opts *bind.CallOpts) ([]byte, error) + + SGasAvailable(opts *bind.CallOpts) (*big.Int, error) + + SMostRecentRequestID(opts *bind.CallOpts) (*big.Int, error) + + SMyBeaconRequests(opts *bind.CallOpts, arg0 *big.Int) (SMyBeaconRequests, + + error) + + SRandomWords(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) + + SRequestsIDs(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) + + SSubId(opts *bind.CallOpts) (uint64, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + RawFulfillRandomWords(opts *bind.TransactOpts, requestID *big.Int, randomWords []*big.Int, arguments []byte) (*types.Transaction, error) + + SetCoordinator(opts *bind.TransactOpts, coordinator common.Address) (*types.Transaction, error) + + SetFail(opts *bind.TransactOpts, shouldFail bool) (*types.Transaction, error) + + StoreBeaconRequest(opts *bind.TransactOpts, reqId *big.Int, height *big.Int, delay *big.Int, numWords uint16) (*types.Transaction, error) + + TestRedeemRandomness(opts *bind.TransactOpts, subID *big.Int, requestID *big.Int) (*types.Transaction, error) + + TestRequestRandomness(opts *bind.TransactOpts, numWords uint16, subID *big.Int, confirmationDelayArg *big.Int) (*types.Transaction, error) + + TestRequestRandomnessFulfillment(opts *bind.TransactOpts, subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterCoordinatorUpdated(opts *bind.FilterOpts, coordinator []common.Address) (*BeaconVRFConsumerCoordinatorUpdatedIterator, error) + + WatchCoordinatorUpdated(opts *bind.WatchOpts, sink chan<- *BeaconVRFConsumerCoordinatorUpdated, coordinator []common.Address) (event.Subscription, error) + + ParseCoordinatorUpdated(log types.Log) (*BeaconVRFConsumerCoordinatorUpdated, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BeaconVRFConsumerOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *BeaconVRFConsumerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*BeaconVRFConsumerOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*BeaconVRFConsumerOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *BeaconVRFConsumerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*BeaconVRFConsumerOwnershipTransferred, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ocr2vrf/generated/vrf_coordinator/vrf_coordinator.go b/core/gethwrappers/ocr2vrf/generated/vrf_coordinator/vrf_coordinator.go new file mode 100644 index 00000000000..f20d5494452 --- /dev/null +++ b/core/gethwrappers/ocr2vrf/generated/vrf_coordinator/vrf_coordinator.go @@ -0,0 +1,3870 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package vrf_coordinator + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +type ECCArithmeticG1Point struct { + P [2]*big.Int +} + +type VRFBeaconTypesCallback struct { + RequestID *big.Int + NumWords uint16 + Requester common.Address + Arguments []byte + GasAllowance *big.Int + SubID *big.Int + GasPrice *big.Int + WeiPerUnitLink *big.Int +} + +type VRFBeaconTypesCoordinatorConfig struct { + UseReasonableGasPrice bool + ReentrancyLock bool + Paused bool + PremiumPercentage uint8 + UnusedGasPenaltyPercent uint8 + StalenessSeconds uint32 + RedeemableRequestGasOverhead uint32 + CallbackRequestGasOverhead uint32 + ReasonableGasPriceStalenessBlocks uint32 + FallbackWeiPerUnitLink *big.Int +} + +type VRFBeaconTypesCostedCallback struct { + Callback VRFBeaconTypesCallback + Price *big.Int +} + +type VRFBeaconTypesOutputServed struct { + Height uint64 + ConfirmationDelay *big.Int + ProofG1X *big.Int + ProofG1Y *big.Int +} + +type VRFBeaconTypesVRFOutput struct { + BlockHeight uint64 + ConfirmationDelay *big.Int + VrfOutput ECCArithmeticG1Point + Callbacks []VRFBeaconTypesCostedCallback + ShouldStore bool +} + +type VRFCoordinatorCallbackConfig struct { + MaxCallbackGasLimit uint32 + MaxCallbackArgumentsLength uint32 +} + +var VRFCoordinatorMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"beaconPeriodBlocksArg\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BeaconPeriodMustBePositive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestHeight\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"earliestAllowed\",\"type\":\"uint256\"}],\"name\":\"BlockTooRecent\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16[10]\",\"name\":\"confirmationDelays\",\"type\":\"uint16[10]\"},{\"internalType\":\"uint8\",\"name\":\"violatingIndex\",\"type\":\"uint8\"}],\"name\":\"ConfirmationDelaysNotIncreasing\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ContractPaused\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorNotRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gasAllowance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLeft\",\"type\":\"uint256\"}],\"name\":\"GasAllowanceExceedsGasLeft\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"reportHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"separatorHeight\",\"type\":\"uint64\"}],\"name\":\"HistoryDomainSeparatorTooOld\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"actualBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredBalance\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"expectedLength\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"actualLength\",\"type\":\"uint256\"}],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCoordinatorConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidJuelsConversion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numRecipients\",\"type\":\"uint256\"}],\"name\":\"InvalidNumberOfRecipients\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestedSubID\",\"type\":\"uint256\"}],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"requestedVersion\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"coordinatorVersion\",\"type\":\"uint8\"}],\"name\":\"MigrationVersionMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProducer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeRequestedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NativePaymentGiven\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoWordsRequested\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16[10]\",\"name\":\"confDelays\",\"type\":\"uint16[10]\"}],\"name\":\"NonZeroDelayAfterZeroDelay\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnMigrationNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"producer\",\"type\":\"address\"}],\"name\":\"ProducerAlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestHeight\",\"type\":\"uint256\"}],\"name\":\"RandomnessNotAvailable\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestHeight\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"confDelay\",\"type\":\"uint256\"}],\"name\":\"RandomnessSeedNotFoundForCallbacks\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numRecipients\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"numPayments\",\"type\":\"uint256\"}],\"name\":\"RecipientsPaymentsMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrant\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"expected\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"actual\",\"type\":\"address\"}],\"name\":\"ResponseMustBeRetrievedByRequester\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyRequestsReplaceContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManySlotsReplaceContract\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"max\",\"type\":\"uint256\"}],\"name\":\"TooManyWords\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockHeight\",\"type\":\"uint256\"}],\"name\":\"UniverseHasEndedBangBangBang\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCallbackArgumentsLength\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structVRFCoordinator.CallbackConfig\",\"name\":\"newConfig\",\"type\":\"tuple\"}],\"name\":\"CallbackConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"useReasonableGasPrice\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"reentrancyLock\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"premiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"unusedGasPenaltyPercent\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"redeemableRequestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"callbackRequestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"reasonableGasPriceStalenessBlocks\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structVRFBeaconTypes.CoordinatorConfig\",\"name\":\"coordinatorConfig\",\"type\":\"tuple\"}],\"name\":\"CoordinatorConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorDeregistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint8\",\"name\":\"newVersion\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"}],\"name\":\"MigrationCompleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"recentBlockHeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint192\",\"name\":\"juelsPerFeeCoin\",\"type\":\"uint192\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"reasonableGasPrice\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"height\",\"type\":\"uint64\"},{\"internalType\":\"uint24\",\"name\":\"confirmationDelay\",\"type\":\"uint24\"},{\"internalType\":\"uint256\",\"name\":\"proofG1X\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofG1Y\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structVRFBeaconTypes.OutputServed[]\",\"name\":\"outputsServed\",\"type\":\"tuple[]\"}],\"name\":\"OutputsServed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"PauseFlagChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"requestIDs\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"successfulFulfillment\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes[]\",\"name\":\"truncatedErrorData\",\"type\":\"bytes[]\"},{\"indexed\":false,\"internalType\":\"uint96[]\",\"name\":\"subBalances\",\"type\":\"uint96[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"subIDs\",\"type\":\"uint256[]\"}],\"name\":\"RandomWordsFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nextBeaconOutputHeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint24\",\"name\":\"confDelay\",\"type\":\"uint24\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasAllowance\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"weiPerUnitLink\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"arguments\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"costJuels\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSubBalance\",\"type\":\"uint256\"}],\"name\":\"RandomnessFulfillmentRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"}],\"name\":\"RandomnessRedeemed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nextBeaconOutputHeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint24\",\"name\":\"confDelay\",\"type\":\"uint24\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"costJuels\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSubBalance\",\"type\":\"uint256\"}],\"name\":\"RandomnessRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CONSUMERS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_NUM_WORDS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"NUM_CONF_DELAYS\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"recipients\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"paymentsInJuels\",\"type\":\"uint256[]\"}],\"name\":\"batchTransferLink\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"deregisterMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"name\":\"getCallbackMemo\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfirmationDelays\",\"outputs\":[{\"internalType\":\"uint24[8]\",\"name\":\"\",\"type\":\"uint24[8]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"arguments\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"getFulfillmentFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"pendingFulfillments\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSubscriptionLinkBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_beaconPeriodBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_link\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIVRFMigration\",\"name\":\"newCoordinator\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"encodedRequest\",\"type\":\"bytes\"}],\"name\":\"migrate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"migrationVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onMigration\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"blockHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint24\",\"name\":\"confirmationDelay\",\"type\":\"uint24\"},{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"p\",\"type\":\"uint256[2]\"}],\"internalType\":\"structECCArithmetic.G1Point\",\"name\":\"vrfOutput\",\"type\":\"tuple\"},{\"components\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"arguments\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"gasAllowance\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"weiPerUnitLink\",\"type\":\"uint256\"}],\"internalType\":\"structVRFBeaconTypes.Callback\",\"name\":\"callback\",\"type\":\"tuple\"},{\"internalType\":\"uint96\",\"name\":\"price\",\"type\":\"uint96\"}],\"internalType\":\"structVRFBeaconTypes.CostedCallback[]\",\"name\":\"callbacks\",\"type\":\"tuple[]\"},{\"internalType\":\"bool\",\"name\":\"shouldStore\",\"type\":\"bool\"}],\"internalType\":\"structVRFBeaconTypes.VRFOutput[]\",\"name\":\"vrfOutputs\",\"type\":\"tuple[]\"},{\"internalType\":\"uint192\",\"name\":\"juelsPerFeeCoin\",\"type\":\"uint192\"},{\"internalType\":\"uint64\",\"name\":\"reasonableGasPrice\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"blockHeight\",\"type\":\"uint64\"}],\"name\":\"processVRFOutputs\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"containsNewOutputs\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"redeemRandomness\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"randomness\",\"type\":\"uint256[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"registerMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"uint24\",\"name\":\"confDelay\",\"type\":\"uint24\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"requestRandomness\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"uint24\",\"name\":\"confDelay\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"arguments\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"requestRandomnessFulfillment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"requestSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_callbackConfig\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCallbackArgumentsLength\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_coordinatorConfig\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"useReasonableGasPrice\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"reentrancyLock\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"premiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"unusedGasPenaltyPercent\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"redeemableRequestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"callbackRequestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"reasonableGasPriceStalenessBlocks\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_pendingRequests\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"slotNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"confirmationDelay\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"numWords\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_producer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCallbackArgumentsLength\",\"type\":\"uint32\"}],\"internalType\":\"structVRFCoordinator.CallbackConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setCallbackConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint24[8]\",\"name\":\"confDelays\",\"type\":\"uint24[8]\"}],\"name\":\"setConfirmationDelays\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"useReasonableGasPrice\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"reentrancyLock\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"premiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"unusedGasPenaltyPercent\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"redeemableRequestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"callbackRequestGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"reasonableGasPriceStalenessBlocks\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"uint96\"}],\"internalType\":\"structVRFBeaconTypes.CoordinatorConfig\",\"name\":\"coordinatorConfig\",\"type\":\"tuple\"}],\"name\":\"setCoordinatorConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"pause\",\"type\":\"bool\"}],\"name\":\"setPauseFlag\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"producer\",\"type\":\"address\"}],\"name\":\"setProducer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"juelsAmount\",\"type\":\"uint256\"}],\"name\":\"transferLink\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60c06040523480156200001157600080fd5b50604051620062f5380380620062f5833981016040819052620000349162000239565b8033806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf816200018e565b5050506001600160a01b03166080908152604080519182018152600080835260208301819052908201819052662386f26fc10000606090920191909152642386f26fc160b01b6006556004805463ffffffff60281b191668ffffffff00000000001790558290036200014457604051632abc297960e01b815260040160405180910390fd5b60a0829052600e805465ffffffffffff16906000620001638362000278565b91906101000a81548165ffffffffffff021916908365ffffffffffff160217905550505050620002ac565b336001600160a01b03821603620001e85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080604083850312156200024d57600080fd5b825160208401519092506001600160a01b03811681146200026d57600080fd5b809150509250929050565b600065ffffffffffff808316818103620002a257634e487b7160e01b600052601160045260246000fd5b6001019392505050565b60805160a051615fdd620003186000396000818161075f01528181611ca301528181613cb301528181613ce201528181613d1a015261430e01526000818161047501528181610bb501528181611a410152818161237b01528181612d610152612df60152615fdd6000f3fe6080604052600436106101d65760003560e01c806304104edb146101db5780630ae09540146101fd57806316f6ee9a1461021d578063294daa491461025d5780632b38bafc1461027f5780632f7527cc1461029f5780633e79167f146102b457806340d6bb82146102d457806347c3e2cb146102ea5780634ffac83a14610385578063597d2f3c146103985780635d06b4ab146103b657806364d51a2a146103d657806373433a2f146103fe57806376f2e3f41461041e57806379ba50971461044e5780637d253aff1461046357806385c64e11146104a45780638c7cba66146104c65780638da5cb5b146104e65780638da92e71146105045780638eef585f146105245780639e20103614610544578063a21a23e414610564578063a4c0ed3614610579578063acfc6cdd14610599578063b2a7cac5146105c6578063b79fa6f7146105e6578063bd58017f146106cd578063bec4c08c146106ed578063c3fbb6fd1461070d578063cb6317971461072d578063cd0593df1461074d578063ce3f471914610781578063dac83d29146107a1578063db972c8b146107c1578063dc311dd3146107d4578063e30afa4a14610804578063f2fde38b14610849578063f99b1d6814610869578063f9c45ced14610889575b600080fd5b3480156101e757600080fd5b506101fb6101f6366004614abd565b6108a9565b005b34801561020957600080fd5b506101fb610218366004614ae1565b610a5e565b34801561022957600080fd5b5061024a610238366004614b11565b6000908152600c602052604090205490565b6040519081526020015b60405180910390f35b34801561026957600080fd5b5060015b60405160ff9091168152602001610254565b34801561028b57600080fd5b506101fb61029a366004614abd565b610cc0565b3480156102ab57600080fd5b5061026d600881565b3480156102c057600080fd5b506101fb6102cf366004614b2a565b610d21565b3480156102e057600080fd5b5061024a6103e881565b3480156102f657600080fd5b50610348610305366004614b11565b60106020526000908152604090205463ffffffff811690600160201b810462ffffff1690600160381b810461ffff1690600160481b90046001600160a01b031684565b6040805163ffffffff909516855262ffffff909316602085015261ffff909116918301919091526001600160a01b03166060820152608001610254565b61024a610393366004614cac565b610dd2565b3480156103a457600080fd5b506002546001600160601b031661024a565b3480156103c257600080fd5b506101fb6103d1366004614abd565b610f7e565b3480156103e257600080fd5b506103eb606481565b60405161ffff9091168152602001610254565b34801561040a57600080fd5b506101fb610419366004614d57565b61102a565b34801561042a57600080fd5b5061043e610439366004614dd9565b611115565b6040519015158152602001610254565b34801561045a57600080fd5b506101fb611453565b34801561046f57600080fd5b506104977f000000000000000000000000000000000000000000000000000000000000000081565b6040516102549190614e5b565b3480156104b057600080fd5b506104b96114fd565b6040516102549190614e6f565b3480156104d257600080fd5b506101fb6104e1366004614ec3565b611562565b3480156104f257600080fd5b506000546001600160a01b0316610497565b34801561051057600080fd5b506101fb61051f366004614f1d565b6115d6565b34801561053057600080fd5b506101fb61053f366004614f3a565b611640565b34801561055057600080fd5b5061024a61055f366004614f65565b61167c565b34801561057057600080fd5b5061024a61179d565b34801561058557600080fd5b506101fb610594366004615019565b6119e3565b3480156105a557600080fd5b506105b96105b4366004615068565b611bce565b60405161025491906150f2565b3480156105d257600080fd5b506101fb6105e1366004614b11565b611dd2565b3480156105f257600080fd5b506004546005546106629160ff80821692610100830482169262010000810483169263010000008204811692600160201b83049091169163ffffffff600160281b8204811692600160481b8304821692600160681b8104831692600160881b90910416906001600160601b03168a565b604080519a15158b5298151560208b01529615159789019790975260ff948516606089015292909316608087015263ffffffff90811660a087015291821660c0860152811660e08501529091166101008301526001600160601b031661012082015261014001610254565b3480156106d957600080fd5b50600a54610497906001600160a01b031681565b3480156106f957600080fd5b506101fb610708366004614ae1565b611f03565b34801561071957600080fd5b506101fb610728366004615105565b6120bf565b34801561073957600080fd5b506101fb610748366004614ae1565b6125ac565b34801561075957600080fd5b5061024a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561078d57600080fd5b506101fb61079c366004615159565b612899565b3480156107ad57600080fd5b506101fb6107bc366004614ae1565b6128b2565b61024a6107cf36600461519a565b6129c3565b3480156107e057600080fd5b506107f46107ef366004614b11565b612c21565b6040516102549493929190615272565b34801561081057600080fd5b50600b5461082c9063ffffffff80821691600160201b90041682565b6040805163ffffffff938416815292909116602083015201610254565b34801561085557600080fd5b506101fb610864366004614abd565b612d0e565b34801561087557600080fd5b506101fb6108843660046152be565b612d1f565b34801561089557600080fd5b5061024a6108a43660046152ea565b612e88565b6108b1612f9f565b60095460005b81811015610a3657826001600160a01b0316600982815481106108dc576108dc615330565b6000918252602090912001546001600160a01b031603610a2457600961090360018461535c565b8154811061091357610913615330565b600091825260209091200154600980546001600160a01b03909216918390811061093f5761093f615330565b600091825260209091200180546001600160a01b0319166001600160a01b039290921691909117905582600961097660018561535c565b8154811061098657610986615330565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060098054806109c5576109c561536f565b600082815260209020810160001990810180546001600160a01b03191690550190556040517ff80a1a97fd42251f3c33cda98635e7399253033a6774fe37cd3f650b5282af3790610a17908590614e5b565b60405180910390a1505050565b80610a2e81615385565b9150506108b7565b5081604051635428d44960e01b8152600401610a529190614e5b565b60405180910390fd5b50565b60008281526007602052604090205482906001600160a01b031680610a995760405163c5171ee960e01b815260048101839052602401610a52565b336001600160a01b03821614610ac45780604051636c51fda960e11b8152600401610a529190614e5b565b600454610100900460ff1615610aed5760405163769dd35360e11b815260040160405180910390fd5b600084815260086020526040902054600160601b90046001600160401b031615610b2a57604051631685ecdd60e31b815260040160405180910390fd5b6000848152600860209081526040918290208251808401909352546001600160601b038116808452600160601b9091046001600160401b031691830191909152610b7386612ff4565b600280546001600160601b03169082906000610b8f838561539e565b92506101000a8154816001600160601b0302191690836001600160601b031602179055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb87846001600160601b03166040518363ffffffff1660e01b8152600401610c0a9291906153c5565b6020604051808303816000875af1158015610c29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4d91906153de565b610c7d5760405163cf47918160e01b81526001600160601b03808316600483015283166024820152604401610a52565b867f3784f77e8e883de95b5d47cd713ced01229fa74d118c0a462224bcb0516d43f18784604051610caf9291906153fb565b60405180910390a250505050505050565b610cc8612f9f565b600a546001600160a01b031615610cff57600a5460405163ea6d390560e01b8152610a52916001600160a01b031690600401614e5b565b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b610d29612f9f565b6064610d3b60a0830160808401615437565b60ff161180610d555750610d556040820160208301614f1d565b80610d6b5750610d6b6060820160408301614f1d565b15610d895760405163b0e7bd8360e01b815260040160405180910390fd5b806004610d96828261549d565b9050507e28d3a46e95e67def989d41c66eb331add9809460b95b5fb4eb006157728fc581604051610dc79190615670565b60405180910390a150565b60045460009062010000900460ff1615610dff5760405163ab35696f60e01b815260040160405180910390fd5b600454610100900460ff1615610e285760405163769dd35360e11b815260040160405180910390fd5b3415610e4957604051630b829bad60e21b8152346004820152602401610a52565b6000806000610e5a88338989613143565b925092509250600080610e6d338b61328e565b600087815260106020908152604091829020885181548a8401518b8601516060808e015163ffffffff90951666ffffffffffffff1990941693909317600160201b62ffffff9384160217600160381b600160e81b031916600160381b61ffff92831602600160481b600160e81b03191617600160481b6001600160a01b03909516949094029390931790935584513381526001600160401b038b1694810194909452918e169383019390935281018e9052908c16608082015260a081018390526001600160601b03821660c0820152919350915085907fb7933fba96b6b452eb44f99fdc08052a45dff82363d59abaff0456931c3d24599060e00160405180910390a2509298975050505050505050565b610f86612f9f565b610f8f8161346a565b15610faf578060405163ac8a27ef60e01b8152600401610a529190614e5b565b600980546001810182556000919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0180546001600160a01b0319166001600160a01b0383161790556040517fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af0162590610dc7908390614e5b565b600a546001600160a01b0316331461105557604051634bea32db60e11b815260040160405180910390fd5b828015806110635750601f81115b1561108457604051634ecc4fef60e01b815260048101829052602401610a52565b8082146110a85760405163339f8a9d60e01b8152610a529082908490600401615758565b60005b8181101561110d576110fb8686838181106110c8576110c8615330565b90506020020160208101906110dd9190614abd565b8585848181106110ef576110ef615330565b90506020020135612d1f565b8061110581615385565b9150506110ab565b505050505050565b600a546000906001600160a01b0316331461114357604051634bea32db60e11b815260040160405180910390fd5b60045462010000900460ff161561116d5760405163ab35696f60e01b815260040160405180910390fd5b6001600160c01b038416156111aa57600680546001600160601b038616600160a01b02600160201b600160a01b0390911663ffffffff4216171790555b6001600160401b038316156111ff5760068054436001600160401b03908116600160201b02600160201b600160601b0319918716600160601b0291909116600160201b600160a01b0319909216919091171790555b600080866001600160401b0381111561121a5761121a614b68565b60405190808252806020026020018201604052801561125357816020015b6112406148f6565b8152602001906001900390816112385790505b50905060005b8781101561135557600089898381811061127557611275615330565b90506020028101906112879190615766565b611290906158ea565b9050600061129f82888b6134d3565b905085806112aa5750805b604083015151519096501515806112c957506040820151516020015115155b15611340576040805160808101825283516001600160401b0316815260208085015162ffffff168183015284830180515151938301939093529151519091015160608201528451859061ffff881690811061132657611326615330565b6020026020010181905250848061133c906159d0565b9550505b5050808061134d90615385565b915050611259565b5060008261ffff166001600160401b0381111561137457611374614b68565b6040519080825280602002602001820160405280156113ad57816020015b61139a6148f6565b8152602001906001900390816113925790505b50905060005b8361ffff16811015611409578281815181106113d1576113d1615330565b60200260200101518282815181106113eb576113eb615330565b6020026020010181905250808061140190615385565b9150506113b3565b507ff10ea936d00579b4c52035ee33bf46929646b3aa87554c565d8fb2c7aa549c448588888460405161143f94939291906159f1565b60405180910390a150505095945050505050565b6001546001600160a01b031633146114a65760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b6044820152606401610a52565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61150561492c565b6040805161010081019182905290600f90600890826000855b82829054906101000a900462ffffff1662ffffff168152602001906003019060208260020104928301926001038202915080841161151e5790505050505050905090565b61156a612f9f565b8051600b80546020808501805163ffffffff908116600160201b026001600160401b031990941695811695861793909317909355604080519485529251909116908301527f0cc54509a45ab33cd67614d4a2892c083ecf8fb43b9d29f6ea8130b9023e51df9101610dc7565b6115de612f9f565b60045460ff6201000090910416151581151514610a5b5760048054821515620100000262ff0000199091161790556040517f49ba7c1de2d8853088b6270e43df2118516b217f38b917dd2b80dea360860fbe90610dc790831515815260200190565b600a546001600160a01b0316331461166b57604051634bea32db60e11b815260040160405180910390fd5b611678600f82600861494b565b5050565b604080516101408101825260045460ff80821615158352610100808304821615156020808601919091526201000084048316151585870152630100000084048316606080870191909152600160201b808604909416608080880191909152600160281b860463ffffffff90811660a0890152600160481b8704811660c0890152600160681b8704811660e0890152600160881b9096048616938701939093526005546001600160601b039081166101208801528751938401885260065480871685526001600160401b03958104861693850193909352600160601b830490941696830196909652600160a01b90049091169381019390935260009283926117889288169187919061366b565b50506001600160601b03169695505050505050565b600454600090610100900460ff16156117c95760405163769dd35360e11b815260040160405180910390fd5b60045462010000900460ff16156117f35760405163ab35696f60e01b815260040160405180910390fd5b60003361180160014361535c565b6001546040516001600160601b0319606094851b81166020830152924060348201523090931b90911660548301526001600160c01b0319600160a01b90910460c01b16606882015260700160408051808303601f19018152919052805160209091012060018054919250600160a01b9091046001600160401b031690601461188883615a86565b91906101000a8154816001600160401b0302191690836001600160401b03160217905550506000806001600160401b038111156118c7576118c7614b68565b6040519080825280602002602001820160405280156118f0578160200160208202803683370190505b5060408051808201825260008082526020808301828152878352600882528483209351845491516001600160601b039091166001600160a01b031992831617600160601b6001600160401b039092169190910217909355835160608101855233815280820183815281860187815289855260078452959093208151815486166001600160a01b03918216178255935160018201805490961694169390931790935592518051949550919390926119ad9260028501929101906149e9565b505060405133915083907f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d90600090a350905090565b600454610100900460ff1615611a0c5760405163769dd35360e11b815260040160405180910390fd5b60045462010000900460ff1615611a365760405163ab35696f60e01b815260040160405180910390fd5b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a7f576040516344b0e3c360e01b815260040160405180910390fd5b60208114611aa557604051636865567560e01b8152610a52906020908390600401615aaa565b6000611ab382840184614b11565b6000818152600760205260409020549091506001600160a01b0316611aee5760405163c5171ee960e01b815260048101829052602401610a52565b600081815260086020526040812080546001600160601b031691869190611b158385615abe565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600260008282829054906101000a90046001600160601b0316611b5d9190615abe565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a828784611bb09190615ade565b604051611bbe929190615758565b60405180910390a2505050505050565b600454606090610100900460ff1615611bfa5760405163769dd35360e11b815260040160405180910390fd5b60008381526010602081815260408084208151608081018352815463ffffffff8116825262ffffff600160201b8204168286015261ffff600160381b820416938201939093526001600160a01b03600160481b8404811660608301908152968a9052949093526001600160e81b031990911690559151163314611c9857806060015133604051638e30e82360e01b8152600401610a52929190615af1565b8051600090611cce907f00000000000000000000000000000000000000000000000000000000000000009063ffffffff16615b0b565b90506000611cda613715565b90506000836020015162ffffff1682611cf3919061535c565b9050808310611d385782846020015162ffffff1684611d129190615ade565b611d1d906001615ade565b6040516315ad27c360e01b8152600401610a52929190615758565b6001600160401b03831115611d63576040516302c6ef8160e11b815260048101849052602401610a52565b604051888152339088907f16f3f633197fafab10a5df69e6f3f2f7f20092f08d8d47de0a91c0f4b96a1a259060200160405180910390a3611dc68785600d6000611db1888a6020015161379f565b815260200190815260200160002054866137ae565b98975050505050505050565b600454610100900460ff1615611dfb5760405163769dd35360e11b815260040160405180910390fd5b6000818152600760205260409020546001600160a01b0316611e335760405163c5171ee960e01b815260048101829052602401610a52565b6000818152600760205260409020600101546001600160a01b03163314611e8a576000818152600760205260409081902060010154905163d084e97560e01b8152610a52916001600160a01b031690600401614e5b565b6000818152600760205260409081902080546001600160a01b031980821633908117845560019093018054909116905591516001600160a01b039092169183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c938691611ef7918591615af1565b60405180910390a25050565b60008281526007602052604090205482906001600160a01b031680611f3e5760405163c5171ee960e01b815260048101839052602401610a52565b336001600160a01b03821614611f695780604051636c51fda960e11b8152600401610a529190614e5b565b600454610100900460ff1615611f925760405163769dd35360e11b815260040160405180910390fd5b60045462010000900460ff1615611fbc5760405163ab35696f60e01b815260040160405180910390fd5b60008481526007602052604090206002015460631901611fef576040516305a48e0f60e01b815260040160405180910390fd5b60036000611ffd8587613967565b815260208101919091526040016000205460ff166120b9576001600360006120258688613967565b815260208082019290925260409081016000908120805460ff191694151594909417909355868352600782528083206002018054600181018255908452919092200180546001600160a01b0319166001600160a01b0386161790555184907f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e1906120b0908690614e5b565b60405180910390a25b50505050565b600454610100900460ff16156120e85760405163769dd35360e11b815260040160405180910390fd5b6120f18361346a565b6121105782604051635428d44960e01b8152600401610a529190614e5b565b604081146121355760408051636865567560e01b8152610a5291908390600401615aaa565b600061214382840184615b22565b90506000806000806121588560200151612c21565b9350935093509350816001600160a01b0316336001600160a01b0316146121945781604051636c51fda960e11b8152600401610a529190614e5b565b876001600160a01b031663294daa496040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121f69190615b5c565b60ff16856000015160ff1614612293578460000151886001600160a01b031663294daa496040518163ffffffff1660e01b8152600401602060405180830381865afa158015612249573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061226d9190615b5c565b60405163e7aada9560e01b815260ff928316600482015291166024820152604401610a52565b6001600160401b038316156122bb57604051631685ecdd60e31b815260040160405180910390fd5b60006040518060a001604052806122d0600190565b60ff16815260200187602001518152602001846001600160a01b03168152602001838152602001866001600160601b031681525090506000816040516020016123199190615b79565b60405160208183030381529060405290506123378760200151612ff4565b600280548791906000906123559084906001600160601b031661539e565b92506101000a8154816001600160601b0302191690836001600160601b031602179055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb8b886040518363ffffffff1660e01b81526004016123c79291906153fb565b6020604051808303816000875af11580156123e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061240a91906153de565b61244b5760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b6044820152606401610a52565b60405163ce3f471960e01b81526001600160a01b038b169063ce3f471990612477908490600401615c25565b600060405180830381600087803b15801561249157600080fd5b505af11580156124a5573d6000803e3d6000fd5b50506004805461ff00191661010017905550600090505b835181101561254f578381815181106124d7576124d7615330565b60200260200101516001600160a01b0316638ea981178c6040518263ffffffff1660e01b815260040161250a9190614e5b565b600060405180830381600087803b15801561252457600080fd5b505af1158015612538573d6000803e3d6000fd5b50505050808061254790615385565b9150506124bc565b506004805461ff00191690556020870151875160405160ff909116907fbd89b747474d3fc04664dfbd1d56ae7ffbe46ee097cdb9979c13916bb76269ce90612598908e90614e5b565b60405180910390a350505050505050505050565b60008281526007602052604090205482906001600160a01b0316806125e75760405163c5171ee960e01b815260048101839052602401610a52565b336001600160a01b038216146126125780604051636c51fda960e11b8152600401610a529190614e5b565b600454610100900460ff161561263b5760405163769dd35360e11b815260040160405180910390fd5b600084815260086020526040902054600160601b90046001600160401b03161561267857604051631685ecdd60e31b815260040160405180910390fd5b600360006126868587613967565b815260208101919091526040016000205460ff166126bb5783836040516379bfd40160e01b8152600401610a52929190615c38565b60008481526007602090815260408083206002018054825181850281018501909352808352919290919083018282801561271e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612700575b50505050509050600060018251612735919061535c565b905060005b825181101561284057856001600160a01b031683828151811061275f5761275f615330565b60200260200101516001600160a01b03160361282e57600083838151811061278957612789615330565b6020026020010151905080600760008a815260200190815260200160002060020183815481106127bb576127bb615330565b600091825260208083209190910180546001600160a01b0319166001600160a01b0394909416939093179092558981526007909152604090206002018054806128065761280661536f565b600082815260209020810160001990810180546001600160a01b031916905501905550612840565b8061283881615385565b91505061273a565b506003600061284f8789613967565b815260208101919091526040908101600020805460ff191690555186907f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a790611bbe908890614e5b565b604051632cb6686f60e01b815260040160405180910390fd5b60008281526007602052604090205482906001600160a01b0316806128ed5760405163c5171ee960e01b815260048101839052602401610a52565b336001600160a01b038216146129185780604051636c51fda960e11b8152600401610a529190614e5b565b600454610100900460ff16156129415760405163769dd35360e11b815260040160405180910390fd5b6000848152600760205260409020600101546001600160a01b038481169116146120b9576000848152600760205260409081902060010180546001600160a01b0319166001600160a01b0386161790555184907f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a1906120b09033908790615af1565b60045460009062010000900460ff16156129f05760405163ab35696f60e01b815260040160405180910390fd5b600454610100900460ff1615612a195760405163769dd35360e11b815260040160405180910390fd5b3415612a3a57604051630b829bad60e21b8152346004820152602401610a52565b600080612a4989338a8a613143565b925050915060006040518061010001604052808481526020018a61ffff168152602001336001600160a01b031681526020018781526020018863ffffffff166001600160601b031681526020018b81526020016000815260200160008152509050600080612ab68361397d565b60c087019190915260e08601919091526040519193509150612ae29085908c908f908790602001615c4f565b60405160208183030381529060405280519060200120600c6000878152602001908152602001600020819055506000604051806101600160405280878152602001336001600160a01b03168152602001866001600160401b031681526020018c62ffffff1681526020018e81526020018d61ffff1681526020018b63ffffffff1681526020018581526020018a8152602001848152602001836001600160601b0316815250905080600001517f01872fb9c7d6d68af06a17347935e04412da302a377224c205e672c26e18c37f82602001518360400151846060015185608001518660a001518760c001518860e0015160c001518960e0015160e001518a61010001518b61012001518c6101400151604051612c089b9a99989796959493929190615d02565b60405180910390a250939b9a5050505050505050505050565b600081815260076020526040812054819081906060906001600160a01b0316612c605760405163c5171ee960e01b815260048101869052602401610a52565b60008581526008602090815260408083205460078352928190208054600290910180548351818602810186019094528084526001600160601b03861695600160601b90046001600160401b0316946001600160a01b03909316939192839190830182828015612cf857602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612cda575b5050505050905093509350935093509193509193565b612d16612f9f565b610a5b81613bb4565b600a546001600160a01b03163314612d4a57604051634bea32db60e11b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90612d9890859085906004016153c5565b6020604051808303816000875af1158015612db7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ddb91906153de565b611678576040516370a0823160e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190612e2b903090600401614e5b565b602060405180830381865afa158015612e48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e6c9190615d98565b8160405163cf47918160e01b8152600401610a52929190615758565b604080516101408101825260045460ff80821615158352610100808304821615156020808601919091526201000084048316151585870152630100000084048316606080870191909152600160201b80860490941660808088019190915263ffffffff600160281b8704811660a0890152600160481b8704811660c0890152600160681b8704811660e0890152600160881b9096048616938701939093526005546001600160601b039081166101208801528751938401885260065495861684526001600160401b03948604851692840192909252600160601b850490931695820195909552600160a01b90920490931692810192909252600091612f8d9190613c57565b6001600160601b031690505b92915050565b6000546001600160a01b03163314612ff25760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b6044820152606401610a52565b565b6000818152600760209081526040808320815160608101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181529295939486019383018282801561307a57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161305c575b505050505081525050905060005b8160400151518110156130ea57600360006130c0846040015184815181106130b2576130b2615330565b602002602001015186613967565b81526020810191909152604001600020805460ff19169055806130e281615385565b915050613088565b50600082815260076020526040812080546001600160a01b031990811682556001820180549091169055906131226002830182614a3e565b505050600090815260086020526040902080546001600160a01b0319169055565b600061314d614a5c565b60006103e88561ffff16111561317c57846103e8604051634a90778560e01b8152600401610a52929190615aaa565b8461ffff166000036131a1576040516308fad2a760e01b815260040160405180910390fd5b6000806131ac613c9d565b600e54919350915065ffffffffffff1660006132178b8b84604080513060208201529081018490526001600160a01b038316606082015265ffffffffffff8216608082015260009060a00160408051601f198184030181529190528051602090910120949350505050565b9050613224826001615db1565b600e805465ffffffffffff9290921665ffffffffffff199092169190911790556040805160808101825263ffffffff909416845262ffffff8916602085015261ffff8a16908401526001600160a01b038a1660608401529550909350909150509450945094915050565b604080516080808201835260065463ffffffff8082168452600160201b8083046001600160401b03908116602080880191909152600160601b850490911686880152600160a01b9093046001600160601b0390811660608088019190915287516101408101895260045460ff808216151583526101008083048216151598840198909852620100008204811615159a83019a909a52630100000081048a169282019290925292810490971694820194909452600160281b8604821660a0820152600160481b8604821660c0820152600160681b8604821660e0820152600160881b9095041690840152600554166101208301526000918291906003836133948888613967565b815260208101919091526040016000205460ff166133c95784866040516379bfd40160e01b8152600401610a52929190615c38565b60006133d58284613c57565b600087815260086020526040902080546001600160601b0392831693509091168281101561342457815460405163cf47918160e01b8152610a52916001600160601b0316908590600401615dd0565b81546001600160601b0319908116918490036001600160601b038181169390931790935560028054918216918316859003909216179055909450925050505b9250929050565b6000805b6009548110156134ca57826001600160a01b03166009828154811061349557613495615330565b6000918252602090912001546001600160a01b0316036134b85750600192915050565b806134c281615385565b91505061346e565b50600092915050565b6000826001600160401b031684600001516001600160401b0316111561352257835160405163012d824d60e01b81526001600160401b0380861660048301529091166024820152604401610a52565b606084015151604080860151905160009161353f91602001615de9565b60405160208183030381529060405280519060200120905085604001516000015160006002811061357257613572615330565b602002015115801561358b575060408601515160200151155b156135c557600d60006135af88600001516001600160401b0316896020015161379f565b8152602001908152602001600020549050613648565b856080015115613648576000600d60006135f089600001516001600160401b03168a6020015161379f565b81526020810191909152604001600020549050806136425781600d60006136288a600001516001600160401b03168b6020015161379f565b815260208101919091526040016000205560019350613646565b8091505b505b6000613655838389613d70565b905083806136605750805b979650505050505050565b60008060008061367b8686614189565b6001600160401b031690506000613693826010615b0b565b9050600060146136a4836015615b0b565b6136ae9190615e29565b89516136ba9190615b0b565b838960e0015163ffffffff168c6136d19190615abe565b6001600160601b03166136e49190615b0b565b6136ee9190615ade565b90506000806137008360008c8c614202565b909d909c50949a509398505050505050505050565b60004661a4b181148061372a575062066eed81145b156137985760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561376e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137929190615d98565b91505090565b4391505090565b62ffffff1660189190911b1790565b6060826137e05760405163220a34e960e11b8152600481018690526001600160401b0383166024820152604401610a52565b604080516020808201889052865163ffffffff168284015286015162ffffff166060808301919091529186015161ffff166080820152908501516001600160a01b031660a082015260c0810184905260009060e0016040516020818303038152906040528051906020012090506103e8856040015161ffff1611156138825784604001516103e8604051634a90778560e01b8152600401610a52929190615aaa565b6000856040015161ffff166001600160401b038111156138a4576138a4614b68565b6040519080825280602002602001820160405280156138cd578160200160208202803683370190505b50905060005b866040015161ffff168161ffff16101561395c57828160405160200161391092919091825260f01b6001600160f01b031916602082015260220190565b6040516020818303038152906040528051906020012060001c828261ffff168151811061393f5761393f615330565b602090810291909101015280613954816159d0565b9150506138d3565b509695505050505050565b60a081901b6001600160a01b0383161792915050565b6000806000806003600061399987604001518860a00151613967565b815260208101919091526040016000205460ff166139d6578460a0015185604001516040516379bfd40160e01b8152600401610a52929190615c38565b604080516080808201835260065463ffffffff80821684526001600160401b03600160201b8084048216602080880191909152600160601b8504909216868801526001600160601b03600160a01b909404841660608088019190915287516101408101895260045460ff808216151583526101008083048216151596840196909652620100008204811615159a83019a909a52630100000081048a168284015292830490981688870152600160281b8204841660a0890152600160481b8204841660c0890152600160681b8204841660e0890152600160881b90910490921690860152600554909116610120850152908801519088015191929160009182918291613ae291868861366b565b60a08d0151600090815260086020526040902080546001600160601b0394851697509295509093509116841115613b3a57805460405163cf47918160e01b8152610a52916001600160601b0316908690600401615dd0565b80546001600160601b0360016001600160401b03600160601b8085048216929092011602818116828416178790038083166001600160601b03199283166001600160a01b03199095169490941793909317909355600280548083168890039092169190931617909155929a91995097509095509350505050565b336001600160a01b03821603613c065760405162461bcd60e51b815260206004820152601760248201527621b0b73737ba103a3930b739b332b9103a379039b2b63360491b6044820152606401610a52565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080613c648484614189565b8460c0015163ffffffff16613c799190615e3d565b6001600160401b031690506000613c938260008787614202565b5095945050505050565b6000806000613caa613715565b90506000613cd87f000000000000000000000000000000000000000000000000000000000000000083615e60565b9050600081613d077f000000000000000000000000000000000000000000000000000000000000000085615ade565b613d11919061535c565b90506000613d3f7f000000000000000000000000000000000000000000000000000000000000000083615e29565b905063ffffffff8110613d65576040516307b2a52360e41b815260040160405180910390fd5b909590945092505050565b6000806040518060c00160405280866001600160401b03811115613d9657613d96614b68565b604051908082528060200260200182016040528015613dbf578160200160208202803683370190505b508152602001866001600160401b03811115613ddd57613ddd614b68565b6040519080825280601f01601f191660200182016040528015613e07576020820181803683370190505b508152602001866001600160401b03811115613e2557613e25614b68565b604051908082528060200260200182016040528015613e5857816020015b6060815260200190600190039081613e435790505b50815260006020820152604001866001600160401b03811115613e7d57613e7d614b68565b604051908082528060200260200182016040528015613ea6578160200160208202803683370190505b508152602001866001600160401b03811115613ec457613ec4614b68565b604051908082528060200260200182016040528015613eed578160200160208202803683370190505b509052905060005b8581101561406c57600084606001518281518110613f1557613f15615330565b60200260200101519050600080600080613f3989600001518a602001518c8861424d565b93509350935093508315613f8d57828760400151886060015161ffff1681518110613f6657613f66615330565b602090810291909101015260608701805190613f81826159d0565b61ffff16905250613fc0565b600160f81b87602001518781518110613fa857613fa8615330565b60200101906001600160f81b031916908160001a9053505b8780613fca575080155b85515188518051929a50909188908110613fe657613fe6615330565b602002602001018181525050818760800151878151811061400957614009615330565b60200260200101906001600160601b031690816001600160601b031681525050846000015160a001518760a00151878151811061404857614048615330565b6020026020010181815250505050505050808061406490615385565b915050613ef5565b5060608301515115614181576000816060015161ffff166001600160401b0381111561409a5761409a614b68565b6040519080825280602002602001820160405280156140cd57816020015b60608152602001906001900390816140b85790505b50905060005b826060015161ffff1681101561413157826040015181815181106140f9576140f9615330565b602002602001015182828151811061411357614113615330565b6020026020010181905250808061412990615385565b9150506140d3565b5081516020830151608084015160a08501516040517f8f79f730779e875ce76c428039cc2052b5b5918c2a55c598fab251c1198aec549461417794909390928792615ead565b60405180910390a1505b509392505050565b815160009080156141a6575060408201516001600160401b031615155b156141fa5761010083015163ffffffff16431080806141e757506101008401516141d69063ffffffff164361535c565b83602001516001600160401b031610155b156141f85750506040810151612f99565b505b503a92915050565b600080600060648560600151606461421a9190615f50565b6142279060ff1689615b0b565b6142319190615e29565b905061423f818787876145bc565b925092505094509492505050565b805160a09081015160009081526008602090815260408083208551948501519151939460609486948594859261428b928e928e929091879101615c4f565b60408051601f19818403018152918152815160209283012084516000908152600c90935291205490915081146142fe5750505460408051808201909152601081526f756e6b6e6f776e2063616c6c6261636b60801b60208201526001955093506001600160601b031691508390506145b1565b50614307614a5c565b600061433c7f00000000000000000000000000000000000000000000000000000000000000006001600160401b038e16615e29565b6040805160808101825263ffffffff909216825262ffffff8d1660208084019190915285015161ffff16828201528401516001600160a01b0316606082015291508990506143d0575050604080518082019091526016815275756e617661696c61626c652072616e646f6d6e65737360501b60208201529054600195509093506001600160601b03169150600090506145b1565b60006143e28360000151838c8f6137ae565b606080840151855191860151604051939450909260009263d21ea8fd60e01b9261441192879190602401615f69565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526004805461ff00191661010017905590506000805a9050600061447c8e60000151608001516001600160601b0316896040015186614630565b9093509050806144b1578d516080015160405163aad1598360e01b8152610a52916001600160601b0316908490600401615758565b506000610bb85a6144c29190615ade565b6004805461ff00191690559050818110156144eb576144eb6144e4828461535c565b8f5161466f565b8854600160601b90046001600160401b031689600c61450983615f94565b82546001600160401b039182166101009390930a92830291909202199091161790555087516000908152600c60205260408120558261457f5760408051808201909152601081526f195e1958dd5d1a5bdb8819985a5b195960821b60208201528954600191906001600160601b0316600061459f565b604080516020810190915260008082528a549091906001600160601b0316825b9c509c509c509c505050505050505050505b945094509450949050565b6000808085156145cc57856145d6565b6145d6858561489b565b90506000816145ed89670de0b6b3a7640000615b0b565b6145f79190615e29565b9050676765c793fa10079d601b1b8111156146245760405162de437160e81b815260040160405180910390fd5b97909650945050505050565b6000805a610bb8811061466657610bb881039050856040820482031115614666576000808551602087016000898bf19250600191505b50935093915050565b80608001516001600160601b0316821115614688575050565b6004546000906064906146a590600160201b900460ff1682615fb7565b60ff168360c001518585608001516001600160601b03166146c6919061535c565b6146d09190615b0b565b6146da9190615b0b565b6146e49190615e29565b60e080840151604080516101408101825260045460ff80821615158352610100808304821615156020808601919091526201000084048316151585870152630100000084048316606080870191909152600160201b80860490941660808088019190915263ffffffff600160281b8704811660a0890152600160481b8704811660c0890152600160681b870481169a88019a909a52600160881b9095048916928601929092526005546001600160601b039081166101208701528651948501875260065498891685526001600160401b03938904841691850191909152600160601b880490921694830194909452600160a01b909504909416918401919091529293506000926147f792859291906145bc565b5060a08401516000908152600860205260408120805492935083929091906148299084906001600160601b0316615abe565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600260008282829054906101000a90046001600160601b03166148719190615abe565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555050505050565b60a0820151606082015160009190600163ffffffff831611908180156148d7575084516148ce9063ffffffff164261535c565b8363ffffffff16105b156148e457506101208501515b6001600160601b031695945050505050565b604051806080016040528060006001600160401b03168152602001600062ffffff16815260200160008152602001600081525090565b6040518061010001604052806008906020820280368337509192915050565b6001830191839082156149d95791602002820160005b838211156149a857833562ffffff1683826101000a81548162ffffff021916908362ffffff1602179055509260200192600301602081600201049283019260010302614961565b80156149d75782816101000a81549062ffffff02191690556003016020816002010492830192600103026149a8565b505b506149e5929150614a83565b5090565b8280548282559060005260206000209081019282156149d9579160200282015b828111156149d957825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614a09565b5080546000825590600052602060002090810190610a5b9190614a83565b60408051608081018252600080825260208201819052918101829052606081019190915290565b5b808211156149e55760008155600101614a84565b6001600160a01b0381168114610a5b57600080fd5b8035614ab881614a98565b919050565b600060208284031215614acf57600080fd5b8135614ada81614a98565b9392505050565b60008060408385031215614af457600080fd5b823591506020830135614b0681614a98565b809150509250929050565b600060208284031215614b2357600080fd5b5035919050565b60006101408284031215614b3d57600080fd5b50919050565b803561ffff81168114614ab857600080fd5b803562ffffff81168114614ab857600080fd5b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715614ba057614ba0614b68565b60405290565b60405161010081016001600160401b0381118282101715614ba057614ba0614b68565b60405160a081016001600160401b0381118282101715614ba057614ba0614b68565b604051602081016001600160401b0381118282101715614ba057614ba0614b68565b604051601f8201601f191681016001600160401b0381118282101715614c3557614c35614b68565b604052919050565b600082601f830112614c4e57600080fd5b81356001600160401b03811115614c6757614c67614b68565b614c7a601f8201601f1916602001614c0d565b818152846020838601011115614c8f57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215614cc257600080fd5b84359350614cd260208601614b43565b9250614ce060408601614b55565b915060608501356001600160401b03811115614cfb57600080fd5b614d0787828801614c3d565b91505092959194509250565b60008083601f840112614d2557600080fd5b5081356001600160401b03811115614d3c57600080fd5b6020830191508360208260051b850101111561346357600080fd5b60008060008060408587031215614d6d57600080fd5b84356001600160401b0380821115614d8457600080fd5b614d9088838901614d13565b90965094506020870135915080821115614da957600080fd5b50614db687828801614d13565b95989497509550505050565b80356001600160401b0381168114614ab857600080fd5b600080600080600060808688031215614df157600080fd5b85356001600160401b03811115614e0757600080fd5b614e1388828901614d13565b90965094505060208601356001600160c01b0381168114614e3357600080fd5b9250614e4160408701614dc2565b9150614e4f60608701614dc2565b90509295509295909350565b6001600160a01b0391909116815260200190565b6101008101818360005b6008811015614e9d57815162ffffff16835260209283019290910190600101614e79565b50505092915050565b63ffffffff81168114610a5b57600080fd5b8035614ab881614ea6565b600060408284031215614ed557600080fd5b614edd614b7e565b8235614ee881614ea6565b81526020830135614ef881614ea6565b60208201529392505050565b8015158114610a5b57600080fd5b8035614ab881614f04565b600060208284031215614f2f57600080fd5b8135614ada81614f04565b6000610100808385031215614f4e57600080fd5b838184011115614f5d57600080fd5b509092915050565b60008060008060808587031215614f7b57600080fd5b843593506020850135614f8d81614ea6565b925060408501356001600160401b0380821115614fa957600080fd5b614fb588838901614c3d565b93506060870135915080821115614fcb57600080fd5b50614d0787828801614c3d565b60008083601f840112614fea57600080fd5b5081356001600160401b0381111561500157600080fd5b60208301915083602082850101111561346357600080fd5b6000806000806060858703121561502f57600080fd5b843561503a81614a98565b93506020850135925060408501356001600160401b0381111561505c57600080fd5b614db687828801614fd8565b60008060006060848603121561507d57600080fd5b833592506020840135915060408401356001600160401b038111156150a157600080fd5b6150ad86828701614c3d565b9150509250925092565b600081518084526020808501945080840160005b838110156150e7578151875295820195908201906001016150cb565b509495945050505050565b602081526000614ada60208301846150b7565b60008060006040848603121561511a57600080fd5b833561512581614a98565b925060208401356001600160401b0381111561514057600080fd5b61514c86828701614fd8565b9497909650939450505050565b6000806020838503121561516c57600080fd5b82356001600160401b0381111561518257600080fd5b61518e85828601614fd8565b90969095509350505050565b60008060008060008060c087890312156151b357600080fd5b863595506151c360208801614b43565b94506151d160408801614b55565b935060608701356151e181614ea6565b925060808701356001600160401b03808211156151fd57600080fd5b6152098a838b01614c3d565b935060a089013591508082111561521f57600080fd5b5061522c89828a01614c3d565b9150509295509295509295565b600081518084526020808501945080840160005b838110156150e75781516001600160a01b03168752958201959082019060010161524d565b6001600160601b03851681526001600160401b03841660208201526001600160a01b03831660408201526080606082018190526000906152b490830184615239565b9695505050505050565b600080604083850312156152d157600080fd5b82356152dc81614a98565b946020939093013593505050565b600080604083850312156152fd57600080fd5b8235915060208301356001600160401b0381111561531a57600080fd5b61532685828601614c3d565b9150509250929050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b81810381811115612f9957612f99615346565b634e487b7160e01b600052603160045260246000fd5b60006001820161539757615397615346565b5060010190565b6001600160601b038281168282160390808211156153be576153be615346565b5092915050565b6001600160a01b03929092168252602082015260400190565b6000602082840312156153f057600080fd5b8151614ada81614f04565b6001600160a01b039290921682526001600160601b0316602082015260400190565b60ff81168114610a5b57600080fd5b8035614ab88161541d565b60006020828403121561544957600080fd5b8135614ada8161541d565b60008135612f9981614f04565b60008135612f998161541d565b60008135612f9981614ea6565b6001600160601b0381168114610a5b57600080fd5b60008135612f998161547b565b81356154a881614f04565b815490151560ff1660ff19919091161781556154e36154c960208401615454565b82805461ff00191691151560081b61ff0016919091179055565b61550e6154f260408401615454565b82805462ff0000191691151560101b62ff000016919091179055565b61553761551d60608401615461565b825463ff000000191660189190911b63ff00000016178255565b61556461554660808401615461565b82805460ff60201b191660209290921b60ff60201b16919091179055565b61559761557360a0840161546e565b82805463ffffffff60281b191660289290921b63ffffffff60281b16919091179055565b6155ca6155a660c0840161546e565b82805463ffffffff60481b191660489290921b63ffffffff60481b16919091179055565b6155fd6155d960e0840161546e565b82805463ffffffff60681b191660689290921b63ffffffff60681b16919091179055565b61563161560d610100840161546e565b82805463ffffffff60881b191660889290921b63ffffffff60881b16919091179055565b6116786156416101208401615490565b6001830180546001600160601b0319166001600160601b0392909216919091179055565b8035614ab88161547b565b61014081016156888261568285614f12565b15159052565b61569460208401614f12565b151560208301526156a760408401614f12565b151560408301526156ba6060840161542c565b60ff1660608301526156ce6080840161542c565b60ff1660808301526156e260a08401614eb8565b63ffffffff1660a08301526156f960c08401614eb8565b63ffffffff1660c083015261571060e08401614eb8565b63ffffffff1660e0830152610100615729848201614eb8565b63ffffffff1690830152610120615741848201615665565b6001600160601b038116848301525b505092915050565b918252602082015260400190565b6000823560be1983360301811261577c57600080fd5b9190910192915050565b600082601f83011261579757600080fd5b813560206001600160401b03808311156157b3576157b3614b68565b8260051b6157c2838201614c0d565b93845285810183019383810190888611156157dc57600080fd5b84880192505b85831015611dc6578235848111156157f957600080fd5b8801601f196040828c038201121561581057600080fd5b615818614b7e565b878301358781111561582957600080fd5b8301610100818e038401121561583e57600080fd5b615846614ba6565b925088810135835261585a60408201614b43565b8984015261586a60608201614aad565b604084015260808101358881111561588157600080fd5b61588f8e8b83850101614c3d565b6060850152506158a160a08201615665565b608084015260c081013560a084015260e081013560c084015261010081013560e0840152508181526158d560408401615665565b818901528452505091840191908401906157e2565b600081360360c08112156158fd57600080fd5b615905614bc9565b61590e84614dc2565b8152602061591d818601614b55565b828201526040603f198401121561593357600080fd5b61593b614beb565b925036605f86011261594c57600080fd5b615954614b7e565b80608087013681111561596657600080fd5b604088015b81811015615982578035845292840192840161596b565b50908552604084019490945250509035906001600160401b038211156159a757600080fd5b6159b336838601615786565b60608201526159c460a08501614f12565b60808201529392505050565b600061ffff8083168181036159e7576159e7615346565b6001019392505050565b6000608080830160018060401b038089168552602060018060c01b038916818701526040828916818801526060858189015284895180875260a08a019150848b01965060005b81811015615a735787518051881684528681015162ffffff16878501528581015186850152840151848401529685019691880191600101615a37565b50909d9c50505050505050505050505050565b60006001600160401b038281166002600160401b031981016159e7576159e7615346565b61ffff929092168252602082015260400190565b6001600160601b038181168382160190808211156153be576153be615346565b80820180821115612f9957612f99615346565b6001600160a01b0392831681529116602082015260400190565b8082028115828204841417612f9957612f99615346565b600060408284031215615b3457600080fd5b615b3c614b7e565b8235615b478161541d565b81526020928301359281019290925250919050565b600060208284031215615b6e57600080fd5b8151614ada8161541d565b6020815260ff82511660208201526020820151604082015260018060a01b0360408301511660608201526000606083015160a06080840152615bbe60c0840182615239565b608094909401516001600160601b031660a093909301929092525090919050565b6000815180845260005b81811015615c0557602081850181015186830182015201615be9565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000614ada6020830184615bdf565b9182526001600160a01b0316602082015260400190565b60018060401b038516815262ffffff84166020820152826040820152608060608201528151608082015261ffff60208301511660a082015260018060a01b0360408301511660c0820152600060608301516101008060e0850152615cb7610180850183615bdf565b91506080850151615cd2828601826001600160601b03169052565b505060a084015161012084015260c084015161014084015260e08401516101608401528091505095945050505050565b6001600160a01b038c1681526001600160401b038b16602082015262ffffff8a1660408201526060810189905261ffff8816608082015263ffffffff871660a082015260c0810186905260e081018590526101606101008201819052600090615d6d83820187615bdf565b61012084019590955250506001600160601b0391909116610140909101529998505050505050505050565b600060208284031215615daa57600080fd5b5051919050565b65ffffffffffff8181168382160190808211156153be576153be615346565b6001600160601b03929092168252602082015260400190565b815160408201908260005b6002811015614e9d578251825260209283019290910190600101615df4565b634e487b7160e01b600052601260045260246000fd5b600082615e3857615e38615e13565b500490565b6001600160401b0381811683821602808216919082811461575057615750615346565b600082615e6f57615e6f615e13565b500690565b600081518084526020808501945080840160005b838110156150e75781516001600160601b031687529582019590820190600101615e88565b60a081526000615ec060a08301886150b7565b602083820381850152615ed38289615bdf565b915083820360408501528187518084528284019150828160051b850101838a0160005b83811015615f2457601f19878403018552615f12838351615bdf565b94860194925090850190600101615ef6565b50508681036060880152615f38818a615e74565b9450505050508281036080840152611dc681856150b7565b60ff8181168382160190811115612f9957612f99615346565b838152606060208201526000615f8260608301856150b7565b82810360408401526152b48185615bdf565b60006001600160401b03821680615fad57615fad615346565b6000190192915050565b60ff8281168282160390811115612f9957612f9961534656fea164736f6c6343000813000a", +} + +var VRFCoordinatorABI = VRFCoordinatorMetaData.ABI + +var VRFCoordinatorBin = VRFCoordinatorMetaData.Bin + +func DeployVRFCoordinator(auth *bind.TransactOpts, backend bind.ContractBackend, beaconPeriodBlocksArg *big.Int, linkToken common.Address) (common.Address, *types.Transaction, *VRFCoordinator, error) { + parsed, err := VRFCoordinatorMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(VRFCoordinatorBin), backend, beaconPeriodBlocksArg, linkToken) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &VRFCoordinator{VRFCoordinatorCaller: VRFCoordinatorCaller{contract: contract}, VRFCoordinatorTransactor: VRFCoordinatorTransactor{contract: contract}, VRFCoordinatorFilterer: VRFCoordinatorFilterer{contract: contract}}, nil +} + +type VRFCoordinator struct { + address common.Address + abi abi.ABI + VRFCoordinatorCaller + VRFCoordinatorTransactor + VRFCoordinatorFilterer +} + +type VRFCoordinatorCaller struct { + contract *bind.BoundContract +} + +type VRFCoordinatorTransactor struct { + contract *bind.BoundContract +} + +type VRFCoordinatorFilterer struct { + contract *bind.BoundContract +} + +type VRFCoordinatorSession struct { + Contract *VRFCoordinator + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type VRFCoordinatorCallerSession struct { + Contract *VRFCoordinatorCaller + CallOpts bind.CallOpts +} + +type VRFCoordinatorTransactorSession struct { + Contract *VRFCoordinatorTransactor + TransactOpts bind.TransactOpts +} + +type VRFCoordinatorRaw struct { + Contract *VRFCoordinator +} + +type VRFCoordinatorCallerRaw struct { + Contract *VRFCoordinatorCaller +} + +type VRFCoordinatorTransactorRaw struct { + Contract *VRFCoordinatorTransactor +} + +func NewVRFCoordinator(address common.Address, backend bind.ContractBackend) (*VRFCoordinator, error) { + abi, err := abi.JSON(strings.NewReader(VRFCoordinatorABI)) + if err != nil { + return nil, err + } + contract, err := bindVRFCoordinator(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &VRFCoordinator{address: address, abi: abi, VRFCoordinatorCaller: VRFCoordinatorCaller{contract: contract}, VRFCoordinatorTransactor: VRFCoordinatorTransactor{contract: contract}, VRFCoordinatorFilterer: VRFCoordinatorFilterer{contract: contract}}, nil +} + +func NewVRFCoordinatorCaller(address common.Address, caller bind.ContractCaller) (*VRFCoordinatorCaller, error) { + contract, err := bindVRFCoordinator(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &VRFCoordinatorCaller{contract: contract}, nil +} + +func NewVRFCoordinatorTransactor(address common.Address, transactor bind.ContractTransactor) (*VRFCoordinatorTransactor, error) { + contract, err := bindVRFCoordinator(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &VRFCoordinatorTransactor{contract: contract}, nil +} + +func NewVRFCoordinatorFilterer(address common.Address, filterer bind.ContractFilterer) (*VRFCoordinatorFilterer, error) { + contract, err := bindVRFCoordinator(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &VRFCoordinatorFilterer{contract: contract}, nil +} + +func bindVRFCoordinator(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := VRFCoordinatorMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_VRFCoordinator *VRFCoordinatorRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _VRFCoordinator.Contract.VRFCoordinatorCaller.contract.Call(opts, result, method, params...) +} + +func (_VRFCoordinator *VRFCoordinatorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFCoordinator.Contract.VRFCoordinatorTransactor.contract.Transfer(opts) +} + +func (_VRFCoordinator *VRFCoordinatorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VRFCoordinator.Contract.VRFCoordinatorTransactor.contract.Transact(opts, method, params...) +} + +func (_VRFCoordinator *VRFCoordinatorCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _VRFCoordinator.Contract.contract.Call(opts, result, method, params...) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFCoordinator.Contract.contract.Transfer(opts) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VRFCoordinator.Contract.contract.Transact(opts, method, params...) +} + +func (_VRFCoordinator *VRFCoordinatorCaller) MAXCONSUMERS(opts *bind.CallOpts) (uint16, error) { + var out []interface{} + err := _VRFCoordinator.contract.Call(opts, &out, "MAX_CONSUMERS") + + if err != nil { + return *new(uint16), err + } + + out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + + return out0, err + +} + +func (_VRFCoordinator *VRFCoordinatorSession) MAXCONSUMERS() (uint16, error) { + return _VRFCoordinator.Contract.MAXCONSUMERS(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCallerSession) MAXCONSUMERS() (uint16, error) { + return _VRFCoordinator.Contract.MAXCONSUMERS(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCaller) MAXNUMWORDS(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFCoordinator.contract.Call(opts, &out, "MAX_NUM_WORDS") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFCoordinator *VRFCoordinatorSession) MAXNUMWORDS() (*big.Int, error) { + return _VRFCoordinator.Contract.MAXNUMWORDS(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCallerSession) MAXNUMWORDS() (*big.Int, error) { + return _VRFCoordinator.Contract.MAXNUMWORDS(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCaller) NUMCONFDELAYS(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _VRFCoordinator.contract.Call(opts, &out, "NUM_CONF_DELAYS") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_VRFCoordinator *VRFCoordinatorSession) NUMCONFDELAYS() (uint8, error) { + return _VRFCoordinator.Contract.NUMCONFDELAYS(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCallerSession) NUMCONFDELAYS() (uint8, error) { + return _VRFCoordinator.Contract.NUMCONFDELAYS(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCaller) GetCallbackMemo(opts *bind.CallOpts, requestId *big.Int) ([32]byte, error) { + var out []interface{} + err := _VRFCoordinator.contract.Call(opts, &out, "getCallbackMemo", requestId) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_VRFCoordinator *VRFCoordinatorSession) GetCallbackMemo(requestId *big.Int) ([32]byte, error) { + return _VRFCoordinator.Contract.GetCallbackMemo(&_VRFCoordinator.CallOpts, requestId) +} + +func (_VRFCoordinator *VRFCoordinatorCallerSession) GetCallbackMemo(requestId *big.Int) ([32]byte, error) { + return _VRFCoordinator.Contract.GetCallbackMemo(&_VRFCoordinator.CallOpts, requestId) +} + +func (_VRFCoordinator *VRFCoordinatorCaller) GetConfirmationDelays(opts *bind.CallOpts) ([8]*big.Int, error) { + var out []interface{} + err := _VRFCoordinator.contract.Call(opts, &out, "getConfirmationDelays") + + if err != nil { + return *new([8]*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new([8]*big.Int)).(*[8]*big.Int) + + return out0, err + +} + +func (_VRFCoordinator *VRFCoordinatorSession) GetConfirmationDelays() ([8]*big.Int, error) { + return _VRFCoordinator.Contract.GetConfirmationDelays(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCallerSession) GetConfirmationDelays() ([8]*big.Int, error) { + return _VRFCoordinator.Contract.GetConfirmationDelays(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCaller) GetFee(opts *bind.CallOpts, arg0 *big.Int, arg1 []byte) (*big.Int, error) { + var out []interface{} + err := _VRFCoordinator.contract.Call(opts, &out, "getFee", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFCoordinator *VRFCoordinatorSession) GetFee(arg0 *big.Int, arg1 []byte) (*big.Int, error) { + return _VRFCoordinator.Contract.GetFee(&_VRFCoordinator.CallOpts, arg0, arg1) +} + +func (_VRFCoordinator *VRFCoordinatorCallerSession) GetFee(arg0 *big.Int, arg1 []byte) (*big.Int, error) { + return _VRFCoordinator.Contract.GetFee(&_VRFCoordinator.CallOpts, arg0, arg1) +} + +func (_VRFCoordinator *VRFCoordinatorCaller) GetFulfillmentFee(opts *bind.CallOpts, arg0 *big.Int, callbackGasLimit uint32, arguments []byte, arg3 []byte) (*big.Int, error) { + var out []interface{} + err := _VRFCoordinator.contract.Call(opts, &out, "getFulfillmentFee", arg0, callbackGasLimit, arguments, arg3) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFCoordinator *VRFCoordinatorSession) GetFulfillmentFee(arg0 *big.Int, callbackGasLimit uint32, arguments []byte, arg3 []byte) (*big.Int, error) { + return _VRFCoordinator.Contract.GetFulfillmentFee(&_VRFCoordinator.CallOpts, arg0, callbackGasLimit, arguments, arg3) +} + +func (_VRFCoordinator *VRFCoordinatorCallerSession) GetFulfillmentFee(arg0 *big.Int, callbackGasLimit uint32, arguments []byte, arg3 []byte) (*big.Int, error) { + return _VRFCoordinator.Contract.GetFulfillmentFee(&_VRFCoordinator.CallOpts, arg0, callbackGasLimit, arguments, arg3) +} + +func (_VRFCoordinator *VRFCoordinatorCaller) GetSubscription(opts *bind.CallOpts, subId *big.Int) (GetSubscription, + + error) { + var out []interface{} + err := _VRFCoordinator.contract.Call(opts, &out, "getSubscription", subId) + + outstruct := new(GetSubscription) + if err != nil { + return *outstruct, err + } + + outstruct.Balance = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.PendingFulfillments = *abi.ConvertType(out[1], new(uint64)).(*uint64) + outstruct.Owner = *abi.ConvertType(out[2], new(common.Address)).(*common.Address) + outstruct.Consumers = *abi.ConvertType(out[3], new([]common.Address)).(*[]common.Address) + + return *outstruct, err + +} + +func (_VRFCoordinator *VRFCoordinatorSession) GetSubscription(subId *big.Int) (GetSubscription, + + error) { + return _VRFCoordinator.Contract.GetSubscription(&_VRFCoordinator.CallOpts, subId) +} + +func (_VRFCoordinator *VRFCoordinatorCallerSession) GetSubscription(subId *big.Int) (GetSubscription, + + error) { + return _VRFCoordinator.Contract.GetSubscription(&_VRFCoordinator.CallOpts, subId) +} + +func (_VRFCoordinator *VRFCoordinatorCaller) GetSubscriptionLinkBalance(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFCoordinator.contract.Call(opts, &out, "getSubscriptionLinkBalance") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFCoordinator *VRFCoordinatorSession) GetSubscriptionLinkBalance() (*big.Int, error) { + return _VRFCoordinator.Contract.GetSubscriptionLinkBalance(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCallerSession) GetSubscriptionLinkBalance() (*big.Int, error) { + return _VRFCoordinator.Contract.GetSubscriptionLinkBalance(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCaller) IBeaconPeriodBlocks(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFCoordinator.contract.Call(opts, &out, "i_beaconPeriodBlocks") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFCoordinator *VRFCoordinatorSession) IBeaconPeriodBlocks() (*big.Int, error) { + return _VRFCoordinator.Contract.IBeaconPeriodBlocks(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCallerSession) IBeaconPeriodBlocks() (*big.Int, error) { + return _VRFCoordinator.Contract.IBeaconPeriodBlocks(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCaller) ILink(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFCoordinator.contract.Call(opts, &out, "i_link") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFCoordinator *VRFCoordinatorSession) ILink() (common.Address, error) { + return _VRFCoordinator.Contract.ILink(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCallerSession) ILink() (common.Address, error) { + return _VRFCoordinator.Contract.ILink(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCaller) MigrationVersion(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _VRFCoordinator.contract.Call(opts, &out, "migrationVersion") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_VRFCoordinator *VRFCoordinatorSession) MigrationVersion() (uint8, error) { + return _VRFCoordinator.Contract.MigrationVersion(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCallerSession) MigrationVersion() (uint8, error) { + return _VRFCoordinator.Contract.MigrationVersion(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCaller) OnMigration(opts *bind.CallOpts, arg0 []byte) error { + var out []interface{} + err := _VRFCoordinator.contract.Call(opts, &out, "onMigration", arg0) + + if err != nil { + return err + } + + return err + +} + +func (_VRFCoordinator *VRFCoordinatorSession) OnMigration(arg0 []byte) error { + return _VRFCoordinator.Contract.OnMigration(&_VRFCoordinator.CallOpts, arg0) +} + +func (_VRFCoordinator *VRFCoordinatorCallerSession) OnMigration(arg0 []byte) error { + return _VRFCoordinator.Contract.OnMigration(&_VRFCoordinator.CallOpts, arg0) +} + +func (_VRFCoordinator *VRFCoordinatorCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFCoordinator.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFCoordinator *VRFCoordinatorSession) Owner() (common.Address, error) { + return _VRFCoordinator.Contract.Owner(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCallerSession) Owner() (common.Address, error) { + return _VRFCoordinator.Contract.Owner(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCaller) SCallbackConfig(opts *bind.CallOpts) (SCallbackConfig, + + error) { + var out []interface{} + err := _VRFCoordinator.contract.Call(opts, &out, "s_callbackConfig") + + outstruct := new(SCallbackConfig) + if err != nil { + return *outstruct, err + } + + outstruct.MaxCallbackGasLimit = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.MaxCallbackArgumentsLength = *abi.ConvertType(out[1], new(uint32)).(*uint32) + + return *outstruct, err + +} + +func (_VRFCoordinator *VRFCoordinatorSession) SCallbackConfig() (SCallbackConfig, + + error) { + return _VRFCoordinator.Contract.SCallbackConfig(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCallerSession) SCallbackConfig() (SCallbackConfig, + + error) { + return _VRFCoordinator.Contract.SCallbackConfig(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCaller) SCoordinatorConfig(opts *bind.CallOpts) (SCoordinatorConfig, + + error) { + var out []interface{} + err := _VRFCoordinator.contract.Call(opts, &out, "s_coordinatorConfig") + + outstruct := new(SCoordinatorConfig) + if err != nil { + return *outstruct, err + } + + outstruct.UseReasonableGasPrice = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.ReentrancyLock = *abi.ConvertType(out[1], new(bool)).(*bool) + outstruct.Paused = *abi.ConvertType(out[2], new(bool)).(*bool) + outstruct.PremiumPercentage = *abi.ConvertType(out[3], new(uint8)).(*uint8) + outstruct.UnusedGasPenaltyPercent = *abi.ConvertType(out[4], new(uint8)).(*uint8) + outstruct.StalenessSeconds = *abi.ConvertType(out[5], new(uint32)).(*uint32) + outstruct.RedeemableRequestGasOverhead = *abi.ConvertType(out[6], new(uint32)).(*uint32) + outstruct.CallbackRequestGasOverhead = *abi.ConvertType(out[7], new(uint32)).(*uint32) + outstruct.ReasonableGasPriceStalenessBlocks = *abi.ConvertType(out[8], new(uint32)).(*uint32) + outstruct.FallbackWeiPerUnitLink = *abi.ConvertType(out[9], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_VRFCoordinator *VRFCoordinatorSession) SCoordinatorConfig() (SCoordinatorConfig, + + error) { + return _VRFCoordinator.Contract.SCoordinatorConfig(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCallerSession) SCoordinatorConfig() (SCoordinatorConfig, + + error) { + return _VRFCoordinator.Contract.SCoordinatorConfig(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCaller) SPendingRequests(opts *bind.CallOpts, arg0 *big.Int) (SPendingRequests, + + error) { + var out []interface{} + err := _VRFCoordinator.contract.Call(opts, &out, "s_pendingRequests", arg0) + + outstruct := new(SPendingRequests) + if err != nil { + return *outstruct, err + } + + outstruct.SlotNumber = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.ConfirmationDelay = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.NumWords = *abi.ConvertType(out[2], new(uint16)).(*uint16) + outstruct.Requester = *abi.ConvertType(out[3], new(common.Address)).(*common.Address) + + return *outstruct, err + +} + +func (_VRFCoordinator *VRFCoordinatorSession) SPendingRequests(arg0 *big.Int) (SPendingRequests, + + error) { + return _VRFCoordinator.Contract.SPendingRequests(&_VRFCoordinator.CallOpts, arg0) +} + +func (_VRFCoordinator *VRFCoordinatorCallerSession) SPendingRequests(arg0 *big.Int) (SPendingRequests, + + error) { + return _VRFCoordinator.Contract.SPendingRequests(&_VRFCoordinator.CallOpts, arg0) +} + +func (_VRFCoordinator *VRFCoordinatorCaller) SProducer(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFCoordinator.contract.Call(opts, &out, "s_producer") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFCoordinator *VRFCoordinatorSession) SProducer() (common.Address, error) { + return _VRFCoordinator.Contract.SProducer(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorCallerSession) SProducer() (common.Address, error) { + return _VRFCoordinator.Contract.SProducer(&_VRFCoordinator.CallOpts) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "acceptOwnership") +} + +func (_VRFCoordinator *VRFCoordinatorSession) AcceptOwnership() (*types.Transaction, error) { + return _VRFCoordinator.Contract.AcceptOwnership(&_VRFCoordinator.TransactOpts) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _VRFCoordinator.Contract.AcceptOwnership(&_VRFCoordinator.TransactOpts) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) AcceptSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "acceptSubscriptionOwnerTransfer", subId) +} + +func (_VRFCoordinator *VRFCoordinatorSession) AcceptSubscriptionOwnerTransfer(subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinator.Contract.AcceptSubscriptionOwnerTransfer(&_VRFCoordinator.TransactOpts, subId) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) AcceptSubscriptionOwnerTransfer(subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinator.Contract.AcceptSubscriptionOwnerTransfer(&_VRFCoordinator.TransactOpts, subId) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) AddConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "addConsumer", subId, consumer) +} + +func (_VRFCoordinator *VRFCoordinatorSession) AddConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinator.Contract.AddConsumer(&_VRFCoordinator.TransactOpts, subId, consumer) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) AddConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinator.Contract.AddConsumer(&_VRFCoordinator.TransactOpts, subId, consumer) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) BatchTransferLink(opts *bind.TransactOpts, recipients []common.Address, paymentsInJuels []*big.Int) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "batchTransferLink", recipients, paymentsInJuels) +} + +func (_VRFCoordinator *VRFCoordinatorSession) BatchTransferLink(recipients []common.Address, paymentsInJuels []*big.Int) (*types.Transaction, error) { + return _VRFCoordinator.Contract.BatchTransferLink(&_VRFCoordinator.TransactOpts, recipients, paymentsInJuels) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) BatchTransferLink(recipients []common.Address, paymentsInJuels []*big.Int) (*types.Transaction, error) { + return _VRFCoordinator.Contract.BatchTransferLink(&_VRFCoordinator.TransactOpts, recipients, paymentsInJuels) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) CancelSubscription(opts *bind.TransactOpts, subId *big.Int, to common.Address) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "cancelSubscription", subId, to) +} + +func (_VRFCoordinator *VRFCoordinatorSession) CancelSubscription(subId *big.Int, to common.Address) (*types.Transaction, error) { + return _VRFCoordinator.Contract.CancelSubscription(&_VRFCoordinator.TransactOpts, subId, to) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) CancelSubscription(subId *big.Int, to common.Address) (*types.Transaction, error) { + return _VRFCoordinator.Contract.CancelSubscription(&_VRFCoordinator.TransactOpts, subId, to) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "createSubscription") +} + +func (_VRFCoordinator *VRFCoordinatorSession) CreateSubscription() (*types.Transaction, error) { + return _VRFCoordinator.Contract.CreateSubscription(&_VRFCoordinator.TransactOpts) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) CreateSubscription() (*types.Transaction, error) { + return _VRFCoordinator.Contract.CreateSubscription(&_VRFCoordinator.TransactOpts) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) DeregisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "deregisterMigratableCoordinator", target) +} + +func (_VRFCoordinator *VRFCoordinatorSession) DeregisterMigratableCoordinator(target common.Address) (*types.Transaction, error) { + return _VRFCoordinator.Contract.DeregisterMigratableCoordinator(&_VRFCoordinator.TransactOpts, target) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) DeregisterMigratableCoordinator(target common.Address) (*types.Transaction, error) { + return _VRFCoordinator.Contract.DeregisterMigratableCoordinator(&_VRFCoordinator.TransactOpts, target) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) Migrate(opts *bind.TransactOpts, newCoordinator common.Address, encodedRequest []byte) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "migrate", newCoordinator, encodedRequest) +} + +func (_VRFCoordinator *VRFCoordinatorSession) Migrate(newCoordinator common.Address, encodedRequest []byte) (*types.Transaction, error) { + return _VRFCoordinator.Contract.Migrate(&_VRFCoordinator.TransactOpts, newCoordinator, encodedRequest) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) Migrate(newCoordinator common.Address, encodedRequest []byte) (*types.Transaction, error) { + return _VRFCoordinator.Contract.Migrate(&_VRFCoordinator.TransactOpts, newCoordinator, encodedRequest) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) OnTokenTransfer(opts *bind.TransactOpts, arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "onTokenTransfer", arg0, amount, data) +} + +func (_VRFCoordinator *VRFCoordinatorSession) OnTokenTransfer(arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _VRFCoordinator.Contract.OnTokenTransfer(&_VRFCoordinator.TransactOpts, arg0, amount, data) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) OnTokenTransfer(arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _VRFCoordinator.Contract.OnTokenTransfer(&_VRFCoordinator.TransactOpts, arg0, amount, data) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) ProcessVRFOutputs(opts *bind.TransactOpts, vrfOutputs []VRFBeaconTypesVRFOutput, juelsPerFeeCoin *big.Int, reasonableGasPrice uint64, blockHeight uint64) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "processVRFOutputs", vrfOutputs, juelsPerFeeCoin, reasonableGasPrice, blockHeight) +} + +func (_VRFCoordinator *VRFCoordinatorSession) ProcessVRFOutputs(vrfOutputs []VRFBeaconTypesVRFOutput, juelsPerFeeCoin *big.Int, reasonableGasPrice uint64, blockHeight uint64) (*types.Transaction, error) { + return _VRFCoordinator.Contract.ProcessVRFOutputs(&_VRFCoordinator.TransactOpts, vrfOutputs, juelsPerFeeCoin, reasonableGasPrice, blockHeight) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) ProcessVRFOutputs(vrfOutputs []VRFBeaconTypesVRFOutput, juelsPerFeeCoin *big.Int, reasonableGasPrice uint64, blockHeight uint64) (*types.Transaction, error) { + return _VRFCoordinator.Contract.ProcessVRFOutputs(&_VRFCoordinator.TransactOpts, vrfOutputs, juelsPerFeeCoin, reasonableGasPrice, blockHeight) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) RedeemRandomness(opts *bind.TransactOpts, subID *big.Int, requestID *big.Int, arg2 []byte) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "redeemRandomness", subID, requestID, arg2) +} + +func (_VRFCoordinator *VRFCoordinatorSession) RedeemRandomness(subID *big.Int, requestID *big.Int, arg2 []byte) (*types.Transaction, error) { + return _VRFCoordinator.Contract.RedeemRandomness(&_VRFCoordinator.TransactOpts, subID, requestID, arg2) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) RedeemRandomness(subID *big.Int, requestID *big.Int, arg2 []byte) (*types.Transaction, error) { + return _VRFCoordinator.Contract.RedeemRandomness(&_VRFCoordinator.TransactOpts, subID, requestID, arg2) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) RegisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "registerMigratableCoordinator", target) +} + +func (_VRFCoordinator *VRFCoordinatorSession) RegisterMigratableCoordinator(target common.Address) (*types.Transaction, error) { + return _VRFCoordinator.Contract.RegisterMigratableCoordinator(&_VRFCoordinator.TransactOpts, target) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) RegisterMigratableCoordinator(target common.Address) (*types.Transaction, error) { + return _VRFCoordinator.Contract.RegisterMigratableCoordinator(&_VRFCoordinator.TransactOpts, target) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) RemoveConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "removeConsumer", subId, consumer) +} + +func (_VRFCoordinator *VRFCoordinatorSession) RemoveConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinator.Contract.RemoveConsumer(&_VRFCoordinator.TransactOpts, subId, consumer) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) RemoveConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinator.Contract.RemoveConsumer(&_VRFCoordinator.TransactOpts, subId, consumer) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) RequestRandomness(opts *bind.TransactOpts, subID *big.Int, numWords uint16, confDelay *big.Int, arg3 []byte) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "requestRandomness", subID, numWords, confDelay, arg3) +} + +func (_VRFCoordinator *VRFCoordinatorSession) RequestRandomness(subID *big.Int, numWords uint16, confDelay *big.Int, arg3 []byte) (*types.Transaction, error) { + return _VRFCoordinator.Contract.RequestRandomness(&_VRFCoordinator.TransactOpts, subID, numWords, confDelay, arg3) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) RequestRandomness(subID *big.Int, numWords uint16, confDelay *big.Int, arg3 []byte) (*types.Transaction, error) { + return _VRFCoordinator.Contract.RequestRandomness(&_VRFCoordinator.TransactOpts, subID, numWords, confDelay, arg3) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) RequestRandomnessFulfillment(opts *bind.TransactOpts, subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte, arg5 []byte) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "requestRandomnessFulfillment", subID, numWords, confDelay, callbackGasLimit, arguments, arg5) +} + +func (_VRFCoordinator *VRFCoordinatorSession) RequestRandomnessFulfillment(subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte, arg5 []byte) (*types.Transaction, error) { + return _VRFCoordinator.Contract.RequestRandomnessFulfillment(&_VRFCoordinator.TransactOpts, subID, numWords, confDelay, callbackGasLimit, arguments, arg5) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) RequestRandomnessFulfillment(subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte, arg5 []byte) (*types.Transaction, error) { + return _VRFCoordinator.Contract.RequestRandomnessFulfillment(&_VRFCoordinator.TransactOpts, subID, numWords, confDelay, callbackGasLimit, arguments, arg5) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) RequestSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int, newOwner common.Address) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "requestSubscriptionOwnerTransfer", subId, newOwner) +} + +func (_VRFCoordinator *VRFCoordinatorSession) RequestSubscriptionOwnerTransfer(subId *big.Int, newOwner common.Address) (*types.Transaction, error) { + return _VRFCoordinator.Contract.RequestSubscriptionOwnerTransfer(&_VRFCoordinator.TransactOpts, subId, newOwner) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) RequestSubscriptionOwnerTransfer(subId *big.Int, newOwner common.Address) (*types.Transaction, error) { + return _VRFCoordinator.Contract.RequestSubscriptionOwnerTransfer(&_VRFCoordinator.TransactOpts, subId, newOwner) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) SetCallbackConfig(opts *bind.TransactOpts, config VRFCoordinatorCallbackConfig) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "setCallbackConfig", config) +} + +func (_VRFCoordinator *VRFCoordinatorSession) SetCallbackConfig(config VRFCoordinatorCallbackConfig) (*types.Transaction, error) { + return _VRFCoordinator.Contract.SetCallbackConfig(&_VRFCoordinator.TransactOpts, config) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) SetCallbackConfig(config VRFCoordinatorCallbackConfig) (*types.Transaction, error) { + return _VRFCoordinator.Contract.SetCallbackConfig(&_VRFCoordinator.TransactOpts, config) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) SetConfirmationDelays(opts *bind.TransactOpts, confDelays [8]*big.Int) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "setConfirmationDelays", confDelays) +} + +func (_VRFCoordinator *VRFCoordinatorSession) SetConfirmationDelays(confDelays [8]*big.Int) (*types.Transaction, error) { + return _VRFCoordinator.Contract.SetConfirmationDelays(&_VRFCoordinator.TransactOpts, confDelays) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) SetConfirmationDelays(confDelays [8]*big.Int) (*types.Transaction, error) { + return _VRFCoordinator.Contract.SetConfirmationDelays(&_VRFCoordinator.TransactOpts, confDelays) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) SetCoordinatorConfig(opts *bind.TransactOpts, coordinatorConfig VRFBeaconTypesCoordinatorConfig) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "setCoordinatorConfig", coordinatorConfig) +} + +func (_VRFCoordinator *VRFCoordinatorSession) SetCoordinatorConfig(coordinatorConfig VRFBeaconTypesCoordinatorConfig) (*types.Transaction, error) { + return _VRFCoordinator.Contract.SetCoordinatorConfig(&_VRFCoordinator.TransactOpts, coordinatorConfig) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) SetCoordinatorConfig(coordinatorConfig VRFBeaconTypesCoordinatorConfig) (*types.Transaction, error) { + return _VRFCoordinator.Contract.SetCoordinatorConfig(&_VRFCoordinator.TransactOpts, coordinatorConfig) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) SetPauseFlag(opts *bind.TransactOpts, pause bool) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "setPauseFlag", pause) +} + +func (_VRFCoordinator *VRFCoordinatorSession) SetPauseFlag(pause bool) (*types.Transaction, error) { + return _VRFCoordinator.Contract.SetPauseFlag(&_VRFCoordinator.TransactOpts, pause) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) SetPauseFlag(pause bool) (*types.Transaction, error) { + return _VRFCoordinator.Contract.SetPauseFlag(&_VRFCoordinator.TransactOpts, pause) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) SetProducer(opts *bind.TransactOpts, producer common.Address) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "setProducer", producer) +} + +func (_VRFCoordinator *VRFCoordinatorSession) SetProducer(producer common.Address) (*types.Transaction, error) { + return _VRFCoordinator.Contract.SetProducer(&_VRFCoordinator.TransactOpts, producer) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) SetProducer(producer common.Address) (*types.Transaction, error) { + return _VRFCoordinator.Contract.SetProducer(&_VRFCoordinator.TransactOpts, producer) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) TransferLink(opts *bind.TransactOpts, recipient common.Address, juelsAmount *big.Int) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "transferLink", recipient, juelsAmount) +} + +func (_VRFCoordinator *VRFCoordinatorSession) TransferLink(recipient common.Address, juelsAmount *big.Int) (*types.Transaction, error) { + return _VRFCoordinator.Contract.TransferLink(&_VRFCoordinator.TransactOpts, recipient, juelsAmount) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) TransferLink(recipient common.Address, juelsAmount *big.Int) (*types.Transaction, error) { + return _VRFCoordinator.Contract.TransferLink(&_VRFCoordinator.TransactOpts, recipient, juelsAmount) +} + +func (_VRFCoordinator *VRFCoordinatorTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _VRFCoordinator.contract.Transact(opts, "transferOwnership", to) +} + +func (_VRFCoordinator *VRFCoordinatorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _VRFCoordinator.Contract.TransferOwnership(&_VRFCoordinator.TransactOpts, to) +} + +func (_VRFCoordinator *VRFCoordinatorTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _VRFCoordinator.Contract.TransferOwnership(&_VRFCoordinator.TransactOpts, to) +} + +type VRFCoordinatorCallbackConfigSetIterator struct { + Event *VRFCoordinatorCallbackConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorCallbackConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorCallbackConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorCallbackConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorCallbackConfigSetIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorCallbackConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorCallbackConfigSet struct { + NewConfig VRFCoordinatorCallbackConfig + Raw types.Log +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) FilterCallbackConfigSet(opts *bind.FilterOpts) (*VRFCoordinatorCallbackConfigSetIterator, error) { + + logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "CallbackConfigSet") + if err != nil { + return nil, err + } + return &VRFCoordinatorCallbackConfigSetIterator{contract: _VRFCoordinator.contract, event: "CallbackConfigSet", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) WatchCallbackConfigSet(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorCallbackConfigSet) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "CallbackConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorCallbackConfigSet) + if err := _VRFCoordinator.contract.UnpackLog(event, "CallbackConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) ParseCallbackConfigSet(log types.Log) (*VRFCoordinatorCallbackConfigSet, error) { + event := new(VRFCoordinatorCallbackConfigSet) + if err := _VRFCoordinator.contract.UnpackLog(event, "CallbackConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorCoordinatorConfigSetIterator struct { + Event *VRFCoordinatorCoordinatorConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorCoordinatorConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorCoordinatorConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorCoordinatorConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorCoordinatorConfigSetIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorCoordinatorConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorCoordinatorConfigSet struct { + CoordinatorConfig VRFBeaconTypesCoordinatorConfig + Raw types.Log +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) FilterCoordinatorConfigSet(opts *bind.FilterOpts) (*VRFCoordinatorCoordinatorConfigSetIterator, error) { + + logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "CoordinatorConfigSet") + if err != nil { + return nil, err + } + return &VRFCoordinatorCoordinatorConfigSetIterator{contract: _VRFCoordinator.contract, event: "CoordinatorConfigSet", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) WatchCoordinatorConfigSet(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorCoordinatorConfigSet) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "CoordinatorConfigSet") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorCoordinatorConfigSet) + if err := _VRFCoordinator.contract.UnpackLog(event, "CoordinatorConfigSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) ParseCoordinatorConfigSet(log types.Log) (*VRFCoordinatorCoordinatorConfigSet, error) { + event := new(VRFCoordinatorCoordinatorConfigSet) + if err := _VRFCoordinator.contract.UnpackLog(event, "CoordinatorConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorCoordinatorDeregisteredIterator struct { + Event *VRFCoordinatorCoordinatorDeregistered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorCoordinatorDeregisteredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorCoordinatorDeregistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorCoordinatorDeregistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorCoordinatorDeregisteredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorCoordinatorDeregisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorCoordinatorDeregistered struct { + CoordinatorAddress common.Address + Raw types.Log +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) FilterCoordinatorDeregistered(opts *bind.FilterOpts) (*VRFCoordinatorCoordinatorDeregisteredIterator, error) { + + logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "CoordinatorDeregistered") + if err != nil { + return nil, err + } + return &VRFCoordinatorCoordinatorDeregisteredIterator{contract: _VRFCoordinator.contract, event: "CoordinatorDeregistered", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) WatchCoordinatorDeregistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorCoordinatorDeregistered) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "CoordinatorDeregistered") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorCoordinatorDeregistered) + if err := _VRFCoordinator.contract.UnpackLog(event, "CoordinatorDeregistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) ParseCoordinatorDeregistered(log types.Log) (*VRFCoordinatorCoordinatorDeregistered, error) { + event := new(VRFCoordinatorCoordinatorDeregistered) + if err := _VRFCoordinator.contract.UnpackLog(event, "CoordinatorDeregistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorCoordinatorRegisteredIterator struct { + Event *VRFCoordinatorCoordinatorRegistered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorCoordinatorRegisteredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorCoordinatorRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorCoordinatorRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorCoordinatorRegisteredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorCoordinatorRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorCoordinatorRegistered struct { + CoordinatorAddress common.Address + Raw types.Log +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) FilterCoordinatorRegistered(opts *bind.FilterOpts) (*VRFCoordinatorCoordinatorRegisteredIterator, error) { + + logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "CoordinatorRegistered") + if err != nil { + return nil, err + } + return &VRFCoordinatorCoordinatorRegisteredIterator{contract: _VRFCoordinator.contract, event: "CoordinatorRegistered", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) WatchCoordinatorRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorCoordinatorRegistered) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "CoordinatorRegistered") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorCoordinatorRegistered) + if err := _VRFCoordinator.contract.UnpackLog(event, "CoordinatorRegistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) ParseCoordinatorRegistered(log types.Log) (*VRFCoordinatorCoordinatorRegistered, error) { + event := new(VRFCoordinatorCoordinatorRegistered) + if err := _VRFCoordinator.contract.UnpackLog(event, "CoordinatorRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorMigrationCompletedIterator struct { + Event *VRFCoordinatorMigrationCompleted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorMigrationCompletedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorMigrationCompleted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorMigrationCompleted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorMigrationCompletedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorMigrationCompletedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorMigrationCompleted struct { + NewVersion uint8 + NewCoordinator common.Address + SubID *big.Int + Raw types.Log +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) FilterMigrationCompleted(opts *bind.FilterOpts, newVersion []uint8, subID []*big.Int) (*VRFCoordinatorMigrationCompletedIterator, error) { + + var newVersionRule []interface{} + for _, newVersionItem := range newVersion { + newVersionRule = append(newVersionRule, newVersionItem) + } + + var subIDRule []interface{} + for _, subIDItem := range subID { + subIDRule = append(subIDRule, subIDItem) + } + + logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "MigrationCompleted", newVersionRule, subIDRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorMigrationCompletedIterator{contract: _VRFCoordinator.contract, event: "MigrationCompleted", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) WatchMigrationCompleted(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorMigrationCompleted, newVersion []uint8, subID []*big.Int) (event.Subscription, error) { + + var newVersionRule []interface{} + for _, newVersionItem := range newVersion { + newVersionRule = append(newVersionRule, newVersionItem) + } + + var subIDRule []interface{} + for _, subIDItem := range subID { + subIDRule = append(subIDRule, subIDItem) + } + + logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "MigrationCompleted", newVersionRule, subIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorMigrationCompleted) + if err := _VRFCoordinator.contract.UnpackLog(event, "MigrationCompleted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) ParseMigrationCompleted(log types.Log) (*VRFCoordinatorMigrationCompleted, error) { + event := new(VRFCoordinatorMigrationCompleted) + if err := _VRFCoordinator.contract.UnpackLog(event, "MigrationCompleted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorOutputsServedIterator struct { + Event *VRFCoordinatorOutputsServed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorOutputsServedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorOutputsServed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorOutputsServed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorOutputsServedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorOutputsServedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorOutputsServed struct { + RecentBlockHeight uint64 + JuelsPerFeeCoin *big.Int + ReasonableGasPrice uint64 + OutputsServed []VRFBeaconTypesOutputServed + Raw types.Log +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) FilterOutputsServed(opts *bind.FilterOpts) (*VRFCoordinatorOutputsServedIterator, error) { + + logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "OutputsServed") + if err != nil { + return nil, err + } + return &VRFCoordinatorOutputsServedIterator{contract: _VRFCoordinator.contract, event: "OutputsServed", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) WatchOutputsServed(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorOutputsServed) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "OutputsServed") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorOutputsServed) + if err := _VRFCoordinator.contract.UnpackLog(event, "OutputsServed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) ParseOutputsServed(log types.Log) (*VRFCoordinatorOutputsServed, error) { + event := new(VRFCoordinatorOutputsServed) + if err := _VRFCoordinator.contract.UnpackLog(event, "OutputsServed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorOwnershipTransferRequestedIterator struct { + Event *VRFCoordinatorOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorOwnershipTransferRequestedIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorOwnershipTransferRequestedIterator{contract: _VRFCoordinator.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorOwnershipTransferRequested) + if err := _VRFCoordinator.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) ParseOwnershipTransferRequested(log types.Log) (*VRFCoordinatorOwnershipTransferRequested, error) { + event := new(VRFCoordinatorOwnershipTransferRequested) + if err := _VRFCoordinator.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorOwnershipTransferredIterator struct { + Event *VRFCoordinatorOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorOwnershipTransferredIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorOwnershipTransferredIterator{contract: _VRFCoordinator.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorOwnershipTransferred) + if err := _VRFCoordinator.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) ParseOwnershipTransferred(log types.Log) (*VRFCoordinatorOwnershipTransferred, error) { + event := new(VRFCoordinatorOwnershipTransferred) + if err := _VRFCoordinator.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorPauseFlagChangedIterator struct { + Event *VRFCoordinatorPauseFlagChanged + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorPauseFlagChangedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorPauseFlagChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorPauseFlagChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorPauseFlagChangedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorPauseFlagChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorPauseFlagChanged struct { + Paused bool + Raw types.Log +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) FilterPauseFlagChanged(opts *bind.FilterOpts) (*VRFCoordinatorPauseFlagChangedIterator, error) { + + logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "PauseFlagChanged") + if err != nil { + return nil, err + } + return &VRFCoordinatorPauseFlagChangedIterator{contract: _VRFCoordinator.contract, event: "PauseFlagChanged", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) WatchPauseFlagChanged(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorPauseFlagChanged) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "PauseFlagChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorPauseFlagChanged) + if err := _VRFCoordinator.contract.UnpackLog(event, "PauseFlagChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) ParsePauseFlagChanged(log types.Log) (*VRFCoordinatorPauseFlagChanged, error) { + event := new(VRFCoordinatorPauseFlagChanged) + if err := _VRFCoordinator.contract.UnpackLog(event, "PauseFlagChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorRandomWordsFulfilledIterator struct { + Event *VRFCoordinatorRandomWordsFulfilled + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorRandomWordsFulfilledIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorRandomWordsFulfilled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorRandomWordsFulfilled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorRandomWordsFulfilledIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorRandomWordsFulfilledIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorRandomWordsFulfilled struct { + RequestIDs []*big.Int + SuccessfulFulfillment []byte + TruncatedErrorData [][]byte + SubBalances []*big.Int + SubIDs []*big.Int + Raw types.Log +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) FilterRandomWordsFulfilled(opts *bind.FilterOpts) (*VRFCoordinatorRandomWordsFulfilledIterator, error) { + + logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "RandomWordsFulfilled") + if err != nil { + return nil, err + } + return &VRFCoordinatorRandomWordsFulfilledIterator{contract: _VRFCoordinator.contract, event: "RandomWordsFulfilled", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorRandomWordsFulfilled) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "RandomWordsFulfilled") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorRandomWordsFulfilled) + if err := _VRFCoordinator.contract.UnpackLog(event, "RandomWordsFulfilled", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) ParseRandomWordsFulfilled(log types.Log) (*VRFCoordinatorRandomWordsFulfilled, error) { + event := new(VRFCoordinatorRandomWordsFulfilled) + if err := _VRFCoordinator.contract.UnpackLog(event, "RandomWordsFulfilled", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorRandomnessFulfillmentRequestedIterator struct { + Event *VRFCoordinatorRandomnessFulfillmentRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorRandomnessFulfillmentRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorRandomnessFulfillmentRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorRandomnessFulfillmentRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorRandomnessFulfillmentRequestedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorRandomnessFulfillmentRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorRandomnessFulfillmentRequested struct { + RequestID *big.Int + Requester common.Address + NextBeaconOutputHeight uint64 + ConfDelay *big.Int + SubID *big.Int + NumWords uint16 + GasAllowance uint32 + GasPrice *big.Int + WeiPerUnitLink *big.Int + Arguments []byte + CostJuels *big.Int + NewSubBalance *big.Int + Raw types.Log +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) FilterRandomnessFulfillmentRequested(opts *bind.FilterOpts, requestID []*big.Int) (*VRFCoordinatorRandomnessFulfillmentRequestedIterator, error) { + + var requestIDRule []interface{} + for _, requestIDItem := range requestID { + requestIDRule = append(requestIDRule, requestIDItem) + } + + logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "RandomnessFulfillmentRequested", requestIDRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorRandomnessFulfillmentRequestedIterator{contract: _VRFCoordinator.contract, event: "RandomnessFulfillmentRequested", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) WatchRandomnessFulfillmentRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorRandomnessFulfillmentRequested, requestID []*big.Int) (event.Subscription, error) { + + var requestIDRule []interface{} + for _, requestIDItem := range requestID { + requestIDRule = append(requestIDRule, requestIDItem) + } + + logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "RandomnessFulfillmentRequested", requestIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorRandomnessFulfillmentRequested) + if err := _VRFCoordinator.contract.UnpackLog(event, "RandomnessFulfillmentRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) ParseRandomnessFulfillmentRequested(log types.Log) (*VRFCoordinatorRandomnessFulfillmentRequested, error) { + event := new(VRFCoordinatorRandomnessFulfillmentRequested) + if err := _VRFCoordinator.contract.UnpackLog(event, "RandomnessFulfillmentRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorRandomnessRedeemedIterator struct { + Event *VRFCoordinatorRandomnessRedeemed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorRandomnessRedeemedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorRandomnessRedeemed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorRandomnessRedeemed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorRandomnessRedeemedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorRandomnessRedeemedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorRandomnessRedeemed struct { + RequestID *big.Int + Requester common.Address + SubID *big.Int + Raw types.Log +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) FilterRandomnessRedeemed(opts *bind.FilterOpts, requestID []*big.Int, requester []common.Address) (*VRFCoordinatorRandomnessRedeemedIterator, error) { + + var requestIDRule []interface{} + for _, requestIDItem := range requestID { + requestIDRule = append(requestIDRule, requestIDItem) + } + var requesterRule []interface{} + for _, requesterItem := range requester { + requesterRule = append(requesterRule, requesterItem) + } + + logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "RandomnessRedeemed", requestIDRule, requesterRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorRandomnessRedeemedIterator{contract: _VRFCoordinator.contract, event: "RandomnessRedeemed", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) WatchRandomnessRedeemed(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorRandomnessRedeemed, requestID []*big.Int, requester []common.Address) (event.Subscription, error) { + + var requestIDRule []interface{} + for _, requestIDItem := range requestID { + requestIDRule = append(requestIDRule, requestIDItem) + } + var requesterRule []interface{} + for _, requesterItem := range requester { + requesterRule = append(requesterRule, requesterItem) + } + + logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "RandomnessRedeemed", requestIDRule, requesterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorRandomnessRedeemed) + if err := _VRFCoordinator.contract.UnpackLog(event, "RandomnessRedeemed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) ParseRandomnessRedeemed(log types.Log) (*VRFCoordinatorRandomnessRedeemed, error) { + event := new(VRFCoordinatorRandomnessRedeemed) + if err := _VRFCoordinator.contract.UnpackLog(event, "RandomnessRedeemed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorRandomnessRequestedIterator struct { + Event *VRFCoordinatorRandomnessRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorRandomnessRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorRandomnessRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorRandomnessRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorRandomnessRequestedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorRandomnessRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorRandomnessRequested struct { + RequestID *big.Int + Requester common.Address + NextBeaconOutputHeight uint64 + ConfDelay *big.Int + SubID *big.Int + NumWords uint16 + CostJuels *big.Int + NewSubBalance *big.Int + Raw types.Log +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) FilterRandomnessRequested(opts *bind.FilterOpts, requestID []*big.Int) (*VRFCoordinatorRandomnessRequestedIterator, error) { + + var requestIDRule []interface{} + for _, requestIDItem := range requestID { + requestIDRule = append(requestIDRule, requestIDItem) + } + + logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "RandomnessRequested", requestIDRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorRandomnessRequestedIterator{contract: _VRFCoordinator.contract, event: "RandomnessRequested", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) WatchRandomnessRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorRandomnessRequested, requestID []*big.Int) (event.Subscription, error) { + + var requestIDRule []interface{} + for _, requestIDItem := range requestID { + requestIDRule = append(requestIDRule, requestIDItem) + } + + logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "RandomnessRequested", requestIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorRandomnessRequested) + if err := _VRFCoordinator.contract.UnpackLog(event, "RandomnessRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) ParseRandomnessRequested(log types.Log) (*VRFCoordinatorRandomnessRequested, error) { + event := new(VRFCoordinatorRandomnessRequested) + if err := _VRFCoordinator.contract.UnpackLog(event, "RandomnessRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorSubscriptionCanceledIterator struct { + Event *VRFCoordinatorSubscriptionCanceled + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorSubscriptionCanceledIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorSubscriptionCanceled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorSubscriptionCanceled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorSubscriptionCanceledIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorSubscriptionCanceledIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorSubscriptionCanceled struct { + SubId *big.Int + To common.Address + Amount *big.Int + Raw types.Log +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) FilterSubscriptionCanceled(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionCanceledIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "SubscriptionCanceled", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorSubscriptionCanceledIterator{contract: _VRFCoordinator.contract, event: "SubscriptionCanceled", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) WatchSubscriptionCanceled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionCanceled, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "SubscriptionCanceled", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorSubscriptionCanceled) + if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionCanceled", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) ParseSubscriptionCanceled(log types.Log) (*VRFCoordinatorSubscriptionCanceled, error) { + event := new(VRFCoordinatorSubscriptionCanceled) + if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionCanceled", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorSubscriptionConsumerAddedIterator struct { + Event *VRFCoordinatorSubscriptionConsumerAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorSubscriptionConsumerAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorSubscriptionConsumerAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorSubscriptionConsumerAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorSubscriptionConsumerAddedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorSubscriptionConsumerAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorSubscriptionConsumerAdded struct { + SubId *big.Int + Consumer common.Address + Raw types.Log +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) FilterSubscriptionConsumerAdded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionConsumerAddedIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "SubscriptionConsumerAdded", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorSubscriptionConsumerAddedIterator{contract: _VRFCoordinator.contract, event: "SubscriptionConsumerAdded", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) WatchSubscriptionConsumerAdded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionConsumerAdded, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "SubscriptionConsumerAdded", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorSubscriptionConsumerAdded) + if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionConsumerAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) ParseSubscriptionConsumerAdded(log types.Log) (*VRFCoordinatorSubscriptionConsumerAdded, error) { + event := new(VRFCoordinatorSubscriptionConsumerAdded) + if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionConsumerAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorSubscriptionConsumerRemovedIterator struct { + Event *VRFCoordinatorSubscriptionConsumerRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorSubscriptionConsumerRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorSubscriptionConsumerRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorSubscriptionConsumerRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorSubscriptionConsumerRemovedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorSubscriptionConsumerRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorSubscriptionConsumerRemoved struct { + SubId *big.Int + Consumer common.Address + Raw types.Log +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) FilterSubscriptionConsumerRemoved(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionConsumerRemovedIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "SubscriptionConsumerRemoved", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorSubscriptionConsumerRemovedIterator{contract: _VRFCoordinator.contract, event: "SubscriptionConsumerRemoved", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) WatchSubscriptionConsumerRemoved(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionConsumerRemoved, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "SubscriptionConsumerRemoved", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorSubscriptionConsumerRemoved) + if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionConsumerRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) ParseSubscriptionConsumerRemoved(log types.Log) (*VRFCoordinatorSubscriptionConsumerRemoved, error) { + event := new(VRFCoordinatorSubscriptionConsumerRemoved) + if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionConsumerRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorSubscriptionCreatedIterator struct { + Event *VRFCoordinatorSubscriptionCreated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorSubscriptionCreatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorSubscriptionCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorSubscriptionCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorSubscriptionCreatedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorSubscriptionCreatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorSubscriptionCreated struct { + SubId *big.Int + Owner common.Address + Raw types.Log +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) FilterSubscriptionCreated(opts *bind.FilterOpts, subId []*big.Int, owner []common.Address) (*VRFCoordinatorSubscriptionCreatedIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "SubscriptionCreated", subIdRule, ownerRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorSubscriptionCreatedIterator{contract: _VRFCoordinator.contract, event: "SubscriptionCreated", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) WatchSubscriptionCreated(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionCreated, subId []*big.Int, owner []common.Address) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "SubscriptionCreated", subIdRule, ownerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorSubscriptionCreated) + if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionCreated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) ParseSubscriptionCreated(log types.Log) (*VRFCoordinatorSubscriptionCreated, error) { + event := new(VRFCoordinatorSubscriptionCreated) + if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionCreated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorSubscriptionFundedIterator struct { + Event *VRFCoordinatorSubscriptionFunded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorSubscriptionFundedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorSubscriptionFunded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorSubscriptionFunded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorSubscriptionFundedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorSubscriptionFundedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorSubscriptionFunded struct { + SubId *big.Int + OldBalance *big.Int + NewBalance *big.Int + Raw types.Log +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) FilterSubscriptionFunded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionFundedIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "SubscriptionFunded", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorSubscriptionFundedIterator{contract: _VRFCoordinator.contract, event: "SubscriptionFunded", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) WatchSubscriptionFunded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionFunded, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "SubscriptionFunded", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorSubscriptionFunded) + if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionFunded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) ParseSubscriptionFunded(log types.Log) (*VRFCoordinatorSubscriptionFunded, error) { + event := new(VRFCoordinatorSubscriptionFunded) + if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionFunded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorSubscriptionOwnerTransferRequestedIterator struct { + Event *VRFCoordinatorSubscriptionOwnerTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorSubscriptionOwnerTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorSubscriptionOwnerTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorSubscriptionOwnerTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorSubscriptionOwnerTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorSubscriptionOwnerTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorSubscriptionOwnerTransferRequested struct { + SubId *big.Int + From common.Address + To common.Address + Raw types.Log +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) FilterSubscriptionOwnerTransferRequested(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionOwnerTransferRequestedIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "SubscriptionOwnerTransferRequested", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorSubscriptionOwnerTransferRequestedIterator{contract: _VRFCoordinator.contract, event: "SubscriptionOwnerTransferRequested", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) WatchSubscriptionOwnerTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionOwnerTransferRequested, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "SubscriptionOwnerTransferRequested", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorSubscriptionOwnerTransferRequested) + if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionOwnerTransferRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) ParseSubscriptionOwnerTransferRequested(log types.Log) (*VRFCoordinatorSubscriptionOwnerTransferRequested, error) { + event := new(VRFCoordinatorSubscriptionOwnerTransferRequested) + if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionOwnerTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorSubscriptionOwnerTransferredIterator struct { + Event *VRFCoordinatorSubscriptionOwnerTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorSubscriptionOwnerTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorSubscriptionOwnerTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorSubscriptionOwnerTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorSubscriptionOwnerTransferredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorSubscriptionOwnerTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorSubscriptionOwnerTransferred struct { + SubId *big.Int + From common.Address + To common.Address + Raw types.Log +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) FilterSubscriptionOwnerTransferred(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionOwnerTransferredIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinator.contract.FilterLogs(opts, "SubscriptionOwnerTransferred", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorSubscriptionOwnerTransferredIterator{contract: _VRFCoordinator.contract, event: "SubscriptionOwnerTransferred", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) WatchSubscriptionOwnerTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionOwnerTransferred, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinator.contract.WatchLogs(opts, "SubscriptionOwnerTransferred", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorSubscriptionOwnerTransferred) + if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionOwnerTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinator *VRFCoordinatorFilterer) ParseSubscriptionOwnerTransferred(log types.Log) (*VRFCoordinatorSubscriptionOwnerTransferred, error) { + event := new(VRFCoordinatorSubscriptionOwnerTransferred) + if err := _VRFCoordinator.contract.UnpackLog(event, "SubscriptionOwnerTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetSubscription struct { + Balance *big.Int + PendingFulfillments uint64 + Owner common.Address + Consumers []common.Address +} +type SCallbackConfig struct { + MaxCallbackGasLimit uint32 + MaxCallbackArgumentsLength uint32 +} +type SCoordinatorConfig struct { + UseReasonableGasPrice bool + ReentrancyLock bool + Paused bool + PremiumPercentage uint8 + UnusedGasPenaltyPercent uint8 + StalenessSeconds uint32 + RedeemableRequestGasOverhead uint32 + CallbackRequestGasOverhead uint32 + ReasonableGasPriceStalenessBlocks uint32 + FallbackWeiPerUnitLink *big.Int +} +type SPendingRequests struct { + SlotNumber uint32 + ConfirmationDelay *big.Int + NumWords uint16 + Requester common.Address +} + +func (_VRFCoordinator *VRFCoordinator) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _VRFCoordinator.abi.Events["CallbackConfigSet"].ID: + return _VRFCoordinator.ParseCallbackConfigSet(log) + case _VRFCoordinator.abi.Events["CoordinatorConfigSet"].ID: + return _VRFCoordinator.ParseCoordinatorConfigSet(log) + case _VRFCoordinator.abi.Events["CoordinatorDeregistered"].ID: + return _VRFCoordinator.ParseCoordinatorDeregistered(log) + case _VRFCoordinator.abi.Events["CoordinatorRegistered"].ID: + return _VRFCoordinator.ParseCoordinatorRegistered(log) + case _VRFCoordinator.abi.Events["MigrationCompleted"].ID: + return _VRFCoordinator.ParseMigrationCompleted(log) + case _VRFCoordinator.abi.Events["OutputsServed"].ID: + return _VRFCoordinator.ParseOutputsServed(log) + case _VRFCoordinator.abi.Events["OwnershipTransferRequested"].ID: + return _VRFCoordinator.ParseOwnershipTransferRequested(log) + case _VRFCoordinator.abi.Events["OwnershipTransferred"].ID: + return _VRFCoordinator.ParseOwnershipTransferred(log) + case _VRFCoordinator.abi.Events["PauseFlagChanged"].ID: + return _VRFCoordinator.ParsePauseFlagChanged(log) + case _VRFCoordinator.abi.Events["RandomWordsFulfilled"].ID: + return _VRFCoordinator.ParseRandomWordsFulfilled(log) + case _VRFCoordinator.abi.Events["RandomnessFulfillmentRequested"].ID: + return _VRFCoordinator.ParseRandomnessFulfillmentRequested(log) + case _VRFCoordinator.abi.Events["RandomnessRedeemed"].ID: + return _VRFCoordinator.ParseRandomnessRedeemed(log) + case _VRFCoordinator.abi.Events["RandomnessRequested"].ID: + return _VRFCoordinator.ParseRandomnessRequested(log) + case _VRFCoordinator.abi.Events["SubscriptionCanceled"].ID: + return _VRFCoordinator.ParseSubscriptionCanceled(log) + case _VRFCoordinator.abi.Events["SubscriptionConsumerAdded"].ID: + return _VRFCoordinator.ParseSubscriptionConsumerAdded(log) + case _VRFCoordinator.abi.Events["SubscriptionConsumerRemoved"].ID: + return _VRFCoordinator.ParseSubscriptionConsumerRemoved(log) + case _VRFCoordinator.abi.Events["SubscriptionCreated"].ID: + return _VRFCoordinator.ParseSubscriptionCreated(log) + case _VRFCoordinator.abi.Events["SubscriptionFunded"].ID: + return _VRFCoordinator.ParseSubscriptionFunded(log) + case _VRFCoordinator.abi.Events["SubscriptionOwnerTransferRequested"].ID: + return _VRFCoordinator.ParseSubscriptionOwnerTransferRequested(log) + case _VRFCoordinator.abi.Events["SubscriptionOwnerTransferred"].ID: + return _VRFCoordinator.ParseSubscriptionOwnerTransferred(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (VRFCoordinatorCallbackConfigSet) Topic() common.Hash { + return common.HexToHash("0x0cc54509a45ab33cd67614d4a2892c083ecf8fb43b9d29f6ea8130b9023e51df") +} + +func (VRFCoordinatorCoordinatorConfigSet) Topic() common.Hash { + return common.HexToHash("0x0028d3a46e95e67def989d41c66eb331add9809460b95b5fb4eb006157728fc5") +} + +func (VRFCoordinatorCoordinatorDeregistered) Topic() common.Hash { + return common.HexToHash("0xf80a1a97fd42251f3c33cda98635e7399253033a6774fe37cd3f650b5282af37") +} + +func (VRFCoordinatorCoordinatorRegistered) Topic() common.Hash { + return common.HexToHash("0xb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af01625") +} + +func (VRFCoordinatorMigrationCompleted) Topic() common.Hash { + return common.HexToHash("0xbd89b747474d3fc04664dfbd1d56ae7ffbe46ee097cdb9979c13916bb76269ce") +} + +func (VRFCoordinatorOutputsServed) Topic() common.Hash { + return common.HexToHash("0xf10ea936d00579b4c52035ee33bf46929646b3aa87554c565d8fb2c7aa549c44") +} + +func (VRFCoordinatorOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (VRFCoordinatorOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (VRFCoordinatorPauseFlagChanged) Topic() common.Hash { + return common.HexToHash("0x49ba7c1de2d8853088b6270e43df2118516b217f38b917dd2b80dea360860fbe") +} + +func (VRFCoordinatorRandomWordsFulfilled) Topic() common.Hash { + return common.HexToHash("0x8f79f730779e875ce76c428039cc2052b5b5918c2a55c598fab251c1198aec54") +} + +func (VRFCoordinatorRandomnessFulfillmentRequested) Topic() common.Hash { + return common.HexToHash("0x01872fb9c7d6d68af06a17347935e04412da302a377224c205e672c26e18c37f") +} + +func (VRFCoordinatorRandomnessRedeemed) Topic() common.Hash { + return common.HexToHash("0x16f3f633197fafab10a5df69e6f3f2f7f20092f08d8d47de0a91c0f4b96a1a25") +} + +func (VRFCoordinatorRandomnessRequested) Topic() common.Hash { + return common.HexToHash("0xb7933fba96b6b452eb44f99fdc08052a45dff82363d59abaff0456931c3d2459") +} + +func (VRFCoordinatorSubscriptionCanceled) Topic() common.Hash { + return common.HexToHash("0x3784f77e8e883de95b5d47cd713ced01229fa74d118c0a462224bcb0516d43f1") +} + +func (VRFCoordinatorSubscriptionConsumerAdded) Topic() common.Hash { + return common.HexToHash("0x1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e1") +} + +func (VRFCoordinatorSubscriptionConsumerRemoved) Topic() common.Hash { + return common.HexToHash("0x32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a7") +} + +func (VRFCoordinatorSubscriptionCreated) Topic() common.Hash { + return common.HexToHash("0x1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d") +} + +func (VRFCoordinatorSubscriptionFunded) Topic() common.Hash { + return common.HexToHash("0x1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a") +} + +func (VRFCoordinatorSubscriptionOwnerTransferRequested) Topic() common.Hash { + return common.HexToHash("0x21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a1") +} + +func (VRFCoordinatorSubscriptionOwnerTransferred) Topic() common.Hash { + return common.HexToHash("0xd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c9386") +} + +func (_VRFCoordinator *VRFCoordinator) Address() common.Address { + return _VRFCoordinator.address +} + +type VRFCoordinatorInterface interface { + MAXCONSUMERS(opts *bind.CallOpts) (uint16, error) + + MAXNUMWORDS(opts *bind.CallOpts) (*big.Int, error) + + NUMCONFDELAYS(opts *bind.CallOpts) (uint8, error) + + GetCallbackMemo(opts *bind.CallOpts, requestId *big.Int) ([32]byte, error) + + GetConfirmationDelays(opts *bind.CallOpts) ([8]*big.Int, error) + + GetFee(opts *bind.CallOpts, arg0 *big.Int, arg1 []byte) (*big.Int, error) + + GetFulfillmentFee(opts *bind.CallOpts, arg0 *big.Int, callbackGasLimit uint32, arguments []byte, arg3 []byte) (*big.Int, error) + + GetSubscription(opts *bind.CallOpts, subId *big.Int) (GetSubscription, + + error) + + GetSubscriptionLinkBalance(opts *bind.CallOpts) (*big.Int, error) + + IBeaconPeriodBlocks(opts *bind.CallOpts) (*big.Int, error) + + ILink(opts *bind.CallOpts) (common.Address, error) + + MigrationVersion(opts *bind.CallOpts) (uint8, error) + + OnMigration(opts *bind.CallOpts, arg0 []byte) error + + Owner(opts *bind.CallOpts) (common.Address, error) + + SCallbackConfig(opts *bind.CallOpts) (SCallbackConfig, + + error) + + SCoordinatorConfig(opts *bind.CallOpts) (SCoordinatorConfig, + + error) + + SPendingRequests(opts *bind.CallOpts, arg0 *big.Int) (SPendingRequests, + + error) + + SProducer(opts *bind.CallOpts) (common.Address, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + AcceptSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) + + AddConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) + + BatchTransferLink(opts *bind.TransactOpts, recipients []common.Address, paymentsInJuels []*big.Int) (*types.Transaction, error) + + CancelSubscription(opts *bind.TransactOpts, subId *big.Int, to common.Address) (*types.Transaction, error) + + CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error) + + DeregisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) + + Migrate(opts *bind.TransactOpts, newCoordinator common.Address, encodedRequest []byte) (*types.Transaction, error) + + OnTokenTransfer(opts *bind.TransactOpts, arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) + + ProcessVRFOutputs(opts *bind.TransactOpts, vrfOutputs []VRFBeaconTypesVRFOutput, juelsPerFeeCoin *big.Int, reasonableGasPrice uint64, blockHeight uint64) (*types.Transaction, error) + + RedeemRandomness(opts *bind.TransactOpts, subID *big.Int, requestID *big.Int, arg2 []byte) (*types.Transaction, error) + + RegisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) + + RemoveConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) + + RequestRandomness(opts *bind.TransactOpts, subID *big.Int, numWords uint16, confDelay *big.Int, arg3 []byte) (*types.Transaction, error) + + RequestRandomnessFulfillment(opts *bind.TransactOpts, subID *big.Int, numWords uint16, confDelay *big.Int, callbackGasLimit uint32, arguments []byte, arg5 []byte) (*types.Transaction, error) + + RequestSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int, newOwner common.Address) (*types.Transaction, error) + + SetCallbackConfig(opts *bind.TransactOpts, config VRFCoordinatorCallbackConfig) (*types.Transaction, error) + + SetConfirmationDelays(opts *bind.TransactOpts, confDelays [8]*big.Int) (*types.Transaction, error) + + SetCoordinatorConfig(opts *bind.TransactOpts, coordinatorConfig VRFBeaconTypesCoordinatorConfig) (*types.Transaction, error) + + SetPauseFlag(opts *bind.TransactOpts, pause bool) (*types.Transaction, error) + + SetProducer(opts *bind.TransactOpts, producer common.Address) (*types.Transaction, error) + + TransferLink(opts *bind.TransactOpts, recipient common.Address, juelsAmount *big.Int) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterCallbackConfigSet(opts *bind.FilterOpts) (*VRFCoordinatorCallbackConfigSetIterator, error) + + WatchCallbackConfigSet(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorCallbackConfigSet) (event.Subscription, error) + + ParseCallbackConfigSet(log types.Log) (*VRFCoordinatorCallbackConfigSet, error) + + FilterCoordinatorConfigSet(opts *bind.FilterOpts) (*VRFCoordinatorCoordinatorConfigSetIterator, error) + + WatchCoordinatorConfigSet(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorCoordinatorConfigSet) (event.Subscription, error) + + ParseCoordinatorConfigSet(log types.Log) (*VRFCoordinatorCoordinatorConfigSet, error) + + FilterCoordinatorDeregistered(opts *bind.FilterOpts) (*VRFCoordinatorCoordinatorDeregisteredIterator, error) + + WatchCoordinatorDeregistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorCoordinatorDeregistered) (event.Subscription, error) + + ParseCoordinatorDeregistered(log types.Log) (*VRFCoordinatorCoordinatorDeregistered, error) + + FilterCoordinatorRegistered(opts *bind.FilterOpts) (*VRFCoordinatorCoordinatorRegisteredIterator, error) + + WatchCoordinatorRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorCoordinatorRegistered) (event.Subscription, error) + + ParseCoordinatorRegistered(log types.Log) (*VRFCoordinatorCoordinatorRegistered, error) + + FilterMigrationCompleted(opts *bind.FilterOpts, newVersion []uint8, subID []*big.Int) (*VRFCoordinatorMigrationCompletedIterator, error) + + WatchMigrationCompleted(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorMigrationCompleted, newVersion []uint8, subID []*big.Int) (event.Subscription, error) + + ParseMigrationCompleted(log types.Log) (*VRFCoordinatorMigrationCompleted, error) + + FilterOutputsServed(opts *bind.FilterOpts) (*VRFCoordinatorOutputsServedIterator, error) + + WatchOutputsServed(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorOutputsServed) (event.Subscription, error) + + ParseOutputsServed(log types.Log) (*VRFCoordinatorOutputsServed, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*VRFCoordinatorOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*VRFCoordinatorOwnershipTransferred, error) + + FilterPauseFlagChanged(opts *bind.FilterOpts) (*VRFCoordinatorPauseFlagChangedIterator, error) + + WatchPauseFlagChanged(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorPauseFlagChanged) (event.Subscription, error) + + ParsePauseFlagChanged(log types.Log) (*VRFCoordinatorPauseFlagChanged, error) + + FilterRandomWordsFulfilled(opts *bind.FilterOpts) (*VRFCoordinatorRandomWordsFulfilledIterator, error) + + WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorRandomWordsFulfilled) (event.Subscription, error) + + ParseRandomWordsFulfilled(log types.Log) (*VRFCoordinatorRandomWordsFulfilled, error) + + FilterRandomnessFulfillmentRequested(opts *bind.FilterOpts, requestID []*big.Int) (*VRFCoordinatorRandomnessFulfillmentRequestedIterator, error) + + WatchRandomnessFulfillmentRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorRandomnessFulfillmentRequested, requestID []*big.Int) (event.Subscription, error) + + ParseRandomnessFulfillmentRequested(log types.Log) (*VRFCoordinatorRandomnessFulfillmentRequested, error) + + FilterRandomnessRedeemed(opts *bind.FilterOpts, requestID []*big.Int, requester []common.Address) (*VRFCoordinatorRandomnessRedeemedIterator, error) + + WatchRandomnessRedeemed(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorRandomnessRedeemed, requestID []*big.Int, requester []common.Address) (event.Subscription, error) + + ParseRandomnessRedeemed(log types.Log) (*VRFCoordinatorRandomnessRedeemed, error) + + FilterRandomnessRequested(opts *bind.FilterOpts, requestID []*big.Int) (*VRFCoordinatorRandomnessRequestedIterator, error) + + WatchRandomnessRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorRandomnessRequested, requestID []*big.Int) (event.Subscription, error) + + ParseRandomnessRequested(log types.Log) (*VRFCoordinatorRandomnessRequested, error) + + FilterSubscriptionCanceled(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionCanceledIterator, error) + + WatchSubscriptionCanceled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionCanceled, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionCanceled(log types.Log) (*VRFCoordinatorSubscriptionCanceled, error) + + FilterSubscriptionConsumerAdded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionConsumerAddedIterator, error) + + WatchSubscriptionConsumerAdded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionConsumerAdded, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionConsumerAdded(log types.Log) (*VRFCoordinatorSubscriptionConsumerAdded, error) + + FilterSubscriptionConsumerRemoved(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionConsumerRemovedIterator, error) + + WatchSubscriptionConsumerRemoved(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionConsumerRemoved, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionConsumerRemoved(log types.Log) (*VRFCoordinatorSubscriptionConsumerRemoved, error) + + FilterSubscriptionCreated(opts *bind.FilterOpts, subId []*big.Int, owner []common.Address) (*VRFCoordinatorSubscriptionCreatedIterator, error) + + WatchSubscriptionCreated(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionCreated, subId []*big.Int, owner []common.Address) (event.Subscription, error) + + ParseSubscriptionCreated(log types.Log) (*VRFCoordinatorSubscriptionCreated, error) + + FilterSubscriptionFunded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionFundedIterator, error) + + WatchSubscriptionFunded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionFunded, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionFunded(log types.Log) (*VRFCoordinatorSubscriptionFunded, error) + + FilterSubscriptionOwnerTransferRequested(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionOwnerTransferRequestedIterator, error) + + WatchSubscriptionOwnerTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionOwnerTransferRequested, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionOwnerTransferRequested(log types.Log) (*VRFCoordinatorSubscriptionOwnerTransferRequested, error) + + FilterSubscriptionOwnerTransferred(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorSubscriptionOwnerTransferredIterator, error) + + WatchSubscriptionOwnerTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorSubscriptionOwnerTransferred, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionOwnerTransferred(log types.Log) (*VRFCoordinatorSubscriptionOwnerTransferred, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/ocr2vrf/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ocr2vrf/generation/generated-wrapper-dependency-versions-do-not-edit.txt new file mode 100644 index 00000000000..ce0b1a09702 --- /dev/null +++ b/core/gethwrappers/ocr2vrf/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -0,0 +1,7 @@ +GETH_VERSION: 1.12.0 +dkg: ../../../contracts/solc/v0.8.19/DKG.abi ../../../contracts/solc/v0.8.19/DKG.bin 02549733c46e50ba393c2521e39d4ec55b6a5d9a66baf4406b1a515b20470425 +load_test_beacon_consumer: ../../../contracts/solc/v0.8.19/LoadTestBeaconVRFConsumer.abi ../../../contracts/solc/v0.8.19/LoadTestBeaconVRFConsumer.bin 7306576bc1db6c0a4f0a8a83dd4c08e3078afa73b72858f7d1eaa410d1128fd2 +vrf_beacon: ../../../contracts/solc/v0.8.19/VRFBeacon.abi ../../../contracts/solc/v0.8.19/VRFBeacon.bin 63107992adf02024afccbe77fdf973777548dcd4d9af1484c8449aca6de30f4c +vrf_beacon_consumer: ../../../contracts/solc/v0.8.19/BeaconVRFConsumer.abi ../../../contracts/solc/v0.8.19/BeaconVRFConsumer.bin 520f1c24e4d926a4eb6c9504506b55b79a35ae8cc65ee02d28309a7d5b735a53 +vrf_beacon_coordinator: ../../../contracts/solc/v0.8.15/VRFBeaconCoordinator.abi ../../../contracts/solc/v0.8.15/VRFBeaconCoordinator.bin 08da747a3488fcd318ddc0db75fd0df7c07a100b2e19061f0efcb12a7180ecde +vrf_coordinator: ../../../contracts/solc/v0.8.19/VRFCoordinator.abi ../../../contracts/solc/v0.8.19/VRFCoordinator.bin 295bec795ab8c1ef08b6b27a67bab7f06233660e8a2f389211e470cc2b58c5ea diff --git a/core/gethwrappers/ocr2vrf/go_generate.go b/core/gethwrappers/ocr2vrf/go_generate.go new file mode 100644 index 00000000000..475bf7e8f67 --- /dev/null +++ b/core/gethwrappers/ocr2vrf/go_generate.go @@ -0,0 +1,10 @@ +// Package gethwrappers provides tools for wrapping solidity contracts with +// golang packages, using abigen. +package gethwrappers + +// OCR2VRF - remove the _disabled tag to run these locally. +//go:generate_disabled go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/DKG.abi ../../../contracts/solc/v0.8.19/DKG.bin DKG dkg +//go:generate_disabled go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/VRFCoordinator.abi ../../../contracts/solc/v0.8.19/VRFCoordinator.bin VRFCoordinator vrf_coordinator +//go:generate_disabled go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/VRFBeacon.abi ../../../contracts/solc/v0.8.19/VRFBeacon.bin VRFBeacon vrf_beacon +//go:generate_disabled go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/BeaconVRFConsumer.abi ../../../contracts/solc/v0.8.19/BeaconVRFConsumer.bin BeaconVRFConsumer vrf_beacon_consumer +//go:generate_disabled go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/LoadTestBeaconVRFConsumer.abi ../../../contracts/solc/v0.8.19/LoadTestBeaconVRFConsumer.bin LoadTestBeaconVRFConsumer load_test_beacon_consumer diff --git a/core/internal/mocks/go_generate.go b/core/internal/mocks/go_generate.go index 8402f71158d..f3f5f0ae2ca 100644 --- a/core/internal/mocks/go_generate.go +++ b/core/internal/mocks/go_generate.go @@ -4,5 +4,5 @@ package mocks //go:generate mockery --quiet --srcpkg github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/flags_wrapper --name FlagsInterface --output . --case=underscore --structname Flags --filename flags.go //go:generate mockery --quiet --srcpkg github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/aggregator_v3_interface --name AggregatorV3InterfaceInterface --output ../../services/vrf/mocks/ --case=underscore --structname AggregatorV3Interface --filename aggregator_v3_interface.go //go:generate mockery --quiet --srcpkg github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2 --name VRFCoordinatorV2Interface --output ../../services/vrf/mocks/ --case=underscore --structname VRFCoordinatorV2Interface --filename vrf_coordinator_v2.go -//go:generate mockery --quiet --srcpkg github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon --name VRFBeaconInterface --output ../../services/ocr2/plugins/ocr2vrf/coordinator/mocks --case=underscore --structname VRFBeaconInterface --filename vrf_beacon.go -//go:generate mockery --quiet --srcpkg github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator --name VRFCoordinatorInterface --output ../../services/ocr2/plugins/ocr2vrf/coordinator/mocks --case=underscore --structname VRFCoordinatorInterface --filename vrf_coordinator.go +//go:generate mockery --quiet --srcpkg github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon --name VRFBeaconInterface --output ../../services/ocr2/plugins/ocr2vrf/coordinator/mocks --case=underscore --structname VRFBeaconInterface --filename vrf_beacon.go +//go:generate mockery --quiet --srcpkg github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator --name VRFCoordinatorInterface --output ../../services/ocr2/plugins/ocr2vrf/coordinator/mocks --case=underscore --structname VRFCoordinatorInterface --filename vrf_coordinator.go diff --git a/core/scripts/ocr2vrf/util.go b/core/scripts/ocr2vrf/util.go index a11c799d9a3..e57f349f1fd 100644 --- a/core/scripts/ocr2vrf/util.go +++ b/core/scripts/ocr2vrf/util.go @@ -27,15 +27,15 @@ import ( "github.com/smartcontractkit/chainlink-vrf/ocr2vrf" ocr2vrftypes "github.com/smartcontractkit/chainlink-vrf/types" - dkgContract "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/dkg" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/load_test_beacon_consumer" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon_consumer" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/cmd" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/authorized_forwarder" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" + dkgContract "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/dkg" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/load_test_beacon_consumer" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon_consumer" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator" helpers "github.com/smartcontractkit/chainlink/core/scripts/common" ) diff --git a/core/scripts/ocr2vrf/verify.go b/core/scripts/ocr2vrf/verify.go index 36ecda83b5a..7d7fb94496a 100644 --- a/core/scripts/ocr2vrf/verify.go +++ b/core/scripts/ocr2vrf/verify.go @@ -16,10 +16,10 @@ import ( "github.com/smartcontractkit/chainlink-vrf/altbn_128" ocr2vrftypes "github.com/smartcontractkit/chainlink-vrf/types" - dkgContract "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/dkg" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator" helpers "github.com/smartcontractkit/chainlink/core/scripts/common" + dkgContract "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/dkg" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator" ) func getDKGLatestConfigDetails(e helpers.Environment, dkgAddress string) dkgContract.LatestConfigDetails { diff --git a/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator.go b/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator.go index 4adede8d121..e7688556124 100644 --- a/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator.go +++ b/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator.go @@ -28,13 +28,13 @@ import ( "github.com/smartcontractkit/chainlink-vrf/dkg" ocr2vrftypes "github.com/smartcontractkit/chainlink-vrf/types" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator" - vrf_wrapper "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator" - dkg_wrapper "github.com/smartcontractkit/chainlink-vrf/gethwrappers/dkg" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + dkg_wrapper "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/dkg" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator" + vrf_wrapper "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" ocr2vrfconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2vrf/config" diff --git a/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator_test.go b/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator_test.go index 1e21227a11e..beee01eaf7a 100644 --- a/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator_test.go +++ b/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator_test.go @@ -29,12 +29,12 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/utils/mathutil" - dkg_wrapper "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/dkg" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator" evmclimocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" lp_mocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + dkg_wrapper "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/dkg" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" diff --git a/core/services/ocr2/plugins/ocr2vrf/coordinator/mocks/vrf_beacon.go b/core/services/ocr2/plugins/ocr2vrf/coordinator/mocks/vrf_beacon.go index 278fe573439..1aeb0ea85c4 100644 --- a/core/services/ocr2/plugins/ocr2vrf/coordinator/mocks/vrf_beacon.go +++ b/core/services/ocr2/plugins/ocr2vrf/coordinator/mocks/vrf_beacon.go @@ -16,7 +16,7 @@ import ( types "github.com/ethereum/go-ethereum/core/types" - vrf_beacon "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon" + vrf_beacon "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon" ) // VRFBeaconInterface is an autogenerated mock type for the VRFBeaconInterface type diff --git a/core/services/ocr2/plugins/ocr2vrf/coordinator/mocks/vrf_coordinator.go b/core/services/ocr2/plugins/ocr2vrf/coordinator/mocks/vrf_coordinator.go index 7dddf15a322..268dff05237 100644 --- a/core/services/ocr2/plugins/ocr2vrf/coordinator/mocks/vrf_coordinator.go +++ b/core/services/ocr2/plugins/ocr2vrf/coordinator/mocks/vrf_coordinator.go @@ -16,7 +16,7 @@ import ( types "github.com/ethereum/go-ethereum/core/types" - vrf_coordinator "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator" + vrf_coordinator "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator" ) // VRFCoordinatorInterface is an autogenerated mock type for the VRFCoordinatorInterface type diff --git a/core/services/ocr2/plugins/ocr2vrf/coordinator/router.go b/core/services/ocr2/plugins/ocr2vrf/coordinator/router.go index dd7fd5e1ec2..77384a085ab 100644 --- a/core/services/ocr2/plugins/ocr2vrf/coordinator/router.go +++ b/core/services/ocr2/plugins/ocr2vrf/coordinator/router.go @@ -8,10 +8,10 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/pkg/errors" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator" "github.com/smartcontractkit/chainlink/v2/core/logger" ) diff --git a/core/services/ocr2/plugins/ocr2vrf/coordinator/router_test.go b/core/services/ocr2/plugins/ocr2vrf/coordinator/router_test.go index c65dcb15a8f..7135fa862e3 100644 --- a/core/services/ocr2/plugins/ocr2vrf/coordinator/router_test.go +++ b/core/services/ocr2/plugins/ocr2vrf/coordinator/router_test.go @@ -9,8 +9,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2vrf/coordinator/mocks" ) diff --git a/core/services/ocr2/plugins/ocr2vrf/coordinator/topics.go b/core/services/ocr2/plugins/ocr2vrf/coordinator/topics.go index f8fae150c06..370f0c5fd00 100644 --- a/core/services/ocr2/plugins/ocr2vrf/coordinator/topics.go +++ b/core/services/ocr2/plugins/ocr2vrf/coordinator/topics.go @@ -3,8 +3,8 @@ package coordinator import ( "github.com/ethereum/go-ethereum/common" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator" ) type topics struct { diff --git a/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go b/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go index ac2695dc632..2e1e15fd058 100644 --- a/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go +++ b/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go @@ -32,11 +32,6 @@ import ( commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" commonutils "github.com/smartcontractkit/chainlink-common/pkg/utils" - dkg_wrapper "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/dkg" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/load_test_beacon_consumer" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon_consumer" - vrf_wrapper "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/forwarders" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" @@ -44,6 +39,11 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/authorized_forwarder" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_v3_aggregator_contract" + dkg_wrapper "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/dkg" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/load_test_beacon_consumer" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon_consumer" + vrf_wrapper "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" diff --git a/go.mod b/go.mod index 0a09e3d9693..6e081467bc0 100644 --- a/go.mod +++ b/go.mod @@ -78,7 +78,7 @@ require ( github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595 - github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 + github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 diff --git a/go.sum b/go.sum index 68cd0abbd7f..50cb9f3b44f 100644 --- a/go.sum +++ b/go.sum @@ -1192,8 +1192,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba5 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58/go.mod h1:oV5gIuSKrPEcjQ6uB6smBsm5kXHxyydVLNyAs4V9CoQ= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595 h1:y6ks0HsSOhPUueOmTcoxDQ50RCS1XINlRDTemZyHjFw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595/go.mod h1:vV6WfnVIbK5Q1JsIru4YcTG0T1uRpLJm6t2BgCnCSsg= -github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 h1:LQmRsrzzaYYN3wEU1l5tWiccznhvbyGnu2N+wHSXZAo= -github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772/go.mod h1:Kn1Hape05UzFZ7bOUnm3GVsHzP0TNrVmpfXYNHdqGGs= +github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= +github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868/go.mod h1:Kn1Hape05UzFZ7bOUnm3GVsHzP0TNrVmpfXYNHdqGGs= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= diff --git a/integration-tests/contracts/contract_vrf_models.go b/integration-tests/contracts/contract_vrf_models.go index aaccbad0602..f54d1a25936 100644 --- a/integration-tests/contracts/contract_vrf_models.go +++ b/integration-tests/contracts/contract_vrf_models.go @@ -8,8 +8,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/dkg" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_5" @@ -20,6 +18,8 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_upgraded_version" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2_wrapper_load_test_consumer" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper_load_test_consumer" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/dkg" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon" ) type VRF interface { diff --git a/integration-tests/contracts/ethereum_ocr2vrf_contracts.go b/integration-tests/contracts/ethereum_ocr2vrf_contracts.go index 260af44019f..473b308dc42 100644 --- a/integration-tests/contracts/ethereum_ocr2vrf_contracts.go +++ b/integration-tests/contracts/ethereum_ocr2vrf_contracts.go @@ -13,12 +13,12 @@ import ( "github.com/rs/zerolog/log" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/dkg" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_beacon_consumer" - "github.com/smartcontractkit/chainlink-vrf/archive/gethwrappers/vrf_coordinator" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/batch_blockhash_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/solidity_vrf_coordinator_interface" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/dkg" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon_consumer" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator" ) // EthereumDKG represents DKG contract diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 24a5d1ee7a6..69c09244ef8 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -27,7 +27,7 @@ require ( github.com/smartcontractkit/chainlink-automation v1.0.3 github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 github.com/smartcontractkit/chainlink-testing-framework v1.28.4 - github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 + github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c github.com/smartcontractkit/seth v0.1.6 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 8c66ce7ca8c..e2be6f36438 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1531,8 +1531,8 @@ github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.202403 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595/go.mod h1:vV6WfnVIbK5Q1JsIru4YcTG0T1uRpLJm6t2BgCnCSsg= github.com/smartcontractkit/chainlink-testing-framework v1.28.4 h1:/OOPH76VFQlG5HEXrXgBVDv1fjuasQzMV1EyeaaXWzM= github.com/smartcontractkit/chainlink-testing-framework v1.28.4/go.mod h1:jN+HgXbriq6fKRlIqLw9F3I81aYImV6kBJkIfz0mdIA= -github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 h1:LQmRsrzzaYYN3wEU1l5tWiccznhvbyGnu2N+wHSXZAo= -github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772/go.mod h1:Kn1Hape05UzFZ7bOUnm3GVsHzP0TNrVmpfXYNHdqGGs= +github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= +github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868/go.mod h1:Kn1Hape05UzFZ7bOUnm3GVsHzP0TNrVmpfXYNHdqGGs= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 13a8e2f4f34..128c611c04d 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -372,7 +372,7 @@ require ( github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58 // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595 // indirect github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240227164431-18a7065e23ea // indirect - github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 // indirect + github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/wsrpc v0.8.1 // indirect github.com/soheilhy/cmux v0.1.5 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 5720d19de02..291f221f4b8 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1516,8 +1516,8 @@ github.com/smartcontractkit/chainlink-testing-framework v1.28.4 h1:/OOPH76VFQlG5 github.com/smartcontractkit/chainlink-testing-framework v1.28.4/go.mod h1:jN+HgXbriq6fKRlIqLw9F3I81aYImV6kBJkIfz0mdIA= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240227164431-18a7065e23ea h1:ZdLmNAfKRjH8AYUvjiiDGUgiWQfq/7iNpxyTkvjx/ko= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240227164431-18a7065e23ea/go.mod h1:gCKC9w6XpNk6jm+XIk2psrkkfxhi421N9NSiFceXW88= -github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 h1:LQmRsrzzaYYN3wEU1l5tWiccznhvbyGnu2N+wHSXZAo= -github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772/go.mod h1:Kn1Hape05UzFZ7bOUnm3GVsHzP0TNrVmpfXYNHdqGGs= +github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= +github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868/go.mod h1:Kn1Hape05UzFZ7bOUnm3GVsHzP0TNrVmpfXYNHdqGGs= github.com/smartcontractkit/go-plugin v0.0.0-20231003134350-e49dad63b306 h1:ko88+ZznniNJZbZPWAvHQU8SwKAdHngdDZ+pvVgB5ss= github.com/smartcontractkit/go-plugin v0.0.0-20231003134350-e49dad63b306/go.mod h1:w1sAEES3g3PuV/RzUrgow20W2uErMly84hhD3um1WL4= github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU= From a293dfe7975b035a71eff7a6197e3ce5a25f1887 Mon Sep 17 00:00:00 2001 From: Lei Date: Wed, 24 Apr 2024 15:39:00 -0700 Subject: [PATCH 26/77] add getters (#12903) * support decimals * address comments * add getters --- .changeset/tasty-lions-rhyme.md | 5 ++ contracts/.changeset/kind-snakes-invent.md | 5 ++ .../v2_3/IAutomationRegistryMaster2_3.sol | 16 +++- .../dev/test/AutomationRegistry2_3.t.sol | 17 ++++ .../dev/v2_3/AutomationRegistryBase2_3.sol | 7 +- .../dev/v2_3/AutomationRegistryLogicC2_3.sol | 31 ++++++++ ..._automation_registry_master_wrapper_2_3.go | 79 ++++++++++++++++++- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 8 files changed, 157 insertions(+), 5 deletions(-) create mode 100644 .changeset/tasty-lions-rhyme.md create mode 100644 contracts/.changeset/kind-snakes-invent.md diff --git a/.changeset/tasty-lions-rhyme.md b/.changeset/tasty-lions-rhyme.md new file mode 100644 index 00000000000..b80f1337bce --- /dev/null +++ b/.changeset/tasty-lions-rhyme.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +add getters #internal diff --git a/contracts/.changeset/kind-snakes-invent.md b/contracts/.changeset/kind-snakes-invent.md new file mode 100644 index 00000000000..abd00ce9c85 --- /dev/null +++ b/contracts/.changeset/kind-snakes-invent.md @@ -0,0 +1,5 @@ +--- +"@chainlink/contracts": patch +--- + +add getters #internal diff --git a/contracts/src/v0.8/automation/dev/interfaces/v2_3/IAutomationRegistryMaster2_3.sol b/contracts/src/v0.8/automation/dev/interfaces/v2_3/IAutomationRegistryMaster2_3.sol index 90fdd82bfe7..c0952963366 100644 --- a/contracts/src/v0.8/automation/dev/interfaces/v2_3/IAutomationRegistryMaster2_3.sol +++ b/contracts/src/v0.8/automation/dev/interfaces/v2_3/IAutomationRegistryMaster2_3.sol @@ -1,4 +1,4 @@ -// abi-checksum: 0x8860e73056784b47ec03fe67533e66ebf1a6d8e6e708c8046a71ecbe3b9334d9 +// abi-checksum: 0x2cc33080c864676d572ad7ae658ea4a4621b3fd4c4664d84f9945b2324348434 // SPDX-License-Identifier: MIT // !! THIS FILE WAS AUTOGENERATED BY abi-to-sol v0.6.6. SEE SOURCE BELOW. !! pragma solidity ^0.8.4; @@ -229,6 +229,12 @@ interface IAutomationRegistryMaster2_3 { function getAllowedReadOnlyAddress() external view returns (address); function getAutomationForwarderLogic() external view returns (address); function getBalance(uint256 id) external view returns (uint96 balance); + function getBillingConfig( + address billingToken + ) external view returns (AutomationRegistryBase2_3.BillingConfig memory); + function getBillingOverrides( + uint256 upkeepID + ) external view returns (AutomationRegistryBase2_3.BillingOverrides memory); function getBillingToken(uint256 upkeepID) external view returns (address); function getBillingTokenConfig(address token) external view returns (AutomationRegistryBase2_3.BillingConfig memory); function getBillingTokens() external view returns (address[] memory); @@ -276,6 +282,7 @@ interface IAutomationRegistryMaster2_3 { function getTransmitterInfo( address query ) external view returns (bool active, uint8 index, uint96 balance, uint96 lastCollected, address payee); + function getTransmittersWithPayees() external view returns (AutomationRegistryBase2_3.TransmitterPayeeInfo[] memory); function getTriggerType(uint256 upkeepId) external pure returns (uint8); function getUpkeep(uint256 id) external view returns (IAutomationV21PlusCommon.UpkeepInfoLegacy memory upkeepInfo); function getUpkeepPrivilegeConfig(uint256 upkeepId) external view returns (bytes memory); @@ -355,6 +362,11 @@ interface AutomationRegistryBase2_3 { uint32 maxPerformDataSize; uint32 maxRevertDataSize; } + + struct TransmitterPayeeInfo { + address transmitterAddress; + address payeeAddress; + } } interface IAutomationV21PlusCommon { @@ -405,5 +417,5 @@ interface IAutomationV21PlusCommon { // THIS FILE WAS AUTOGENERATED FROM THE FOLLOWING ABI JSON: /* -[{"inputs":[{"internalType":"contract AutomationRegistryLogicA2_3","name":"logicA","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ArrayHasNoEntries","type":"error"},{"inputs":[],"name":"CannotCancel","type":"error"},{"inputs":[],"name":"CheckDataExceedsLimit","type":"error"},{"inputs":[],"name":"ConfigDigestMismatch","type":"error"},{"inputs":[],"name":"DuplicateEntry","type":"error"},{"inputs":[],"name":"DuplicateSigners","type":"error"},{"inputs":[],"name":"GasLimitCanOnlyIncrease","type":"error"},{"inputs":[],"name":"GasLimitOutsideRange","type":"error"},{"inputs":[],"name":"IncorrectNumberOfFaultyOracles","type":"error"},{"inputs":[],"name":"IncorrectNumberOfSignatures","type":"error"},{"inputs":[],"name":"IncorrectNumberOfSigners","type":"error"},{"inputs":[],"name":"IndexOutOfRange","type":"error"},{"inputs":[{"internalType":"uint256","name":"available","type":"uint256"},{"internalType":"uint256","name":"requested","type":"uint256"}],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"InsufficientLinkLiquidity","type":"error"},{"inputs":[],"name":"InvalidDataLength","type":"error"},{"inputs":[],"name":"InvalidFeed","type":"error"},{"inputs":[],"name":"InvalidPayee","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"InvalidReport","type":"error"},{"inputs":[],"name":"InvalidSigner","type":"error"},{"inputs":[],"name":"InvalidToken","type":"error"},{"inputs":[],"name":"InvalidTransmitter","type":"error"},{"inputs":[],"name":"InvalidTrigger","type":"error"},{"inputs":[],"name":"InvalidTriggerType","type":"error"},{"inputs":[],"name":"MigrationNotPermitted","type":"error"},{"inputs":[],"name":"MustSettleOffchain","type":"error"},{"inputs":[],"name":"MustSettleOnchain","type":"error"},{"inputs":[],"name":"NotAContract","type":"error"},{"inputs":[],"name":"OnlyActiveSigners","type":"error"},{"inputs":[],"name":"OnlyActiveTransmitters","type":"error"},{"inputs":[],"name":"OnlyCallableByAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByLINKToken","type":"error"},{"inputs":[],"name":"OnlyCallableByOwnerOrAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByOwnerOrRegistrar","type":"error"},{"inputs":[],"name":"OnlyCallableByPayee","type":"error"},{"inputs":[],"name":"OnlyCallableByProposedAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByProposedPayee","type":"error"},{"inputs":[],"name":"OnlyCallableByUpkeepPrivilegeManager","type":"error"},{"inputs":[],"name":"OnlyFinanceAdmin","type":"error"},{"inputs":[],"name":"OnlyPausedUpkeep","type":"error"},{"inputs":[],"name":"OnlySimulatedBackend","type":"error"},{"inputs":[],"name":"OnlyUnpausedUpkeep","type":"error"},{"inputs":[],"name":"ParameterLengthError","type":"error"},{"inputs":[],"name":"ReentrantCall","type":"error"},{"inputs":[],"name":"RegistryPaused","type":"error"},{"inputs":[],"name":"RepeatedSigner","type":"error"},{"inputs":[],"name":"RepeatedTransmitter","type":"error"},{"inputs":[{"internalType":"bytes","name":"reason","type":"bytes"}],"name":"TargetCheckReverted","type":"error"},{"inputs":[],"name":"TooManyOracles","type":"error"},{"inputs":[],"name":"TranscoderNotSet","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"UpkeepAlreadyExists","type":"error"},{"inputs":[],"name":"UpkeepCancelled","type":"error"},{"inputs":[],"name":"UpkeepNotCanceled","type":"error"},{"inputs":[],"name":"UpkeepNotNeeded","type":"error"},{"inputs":[],"name":"ValueNotChanged","type":"error"},{"inputs":[],"name":"ZeroAddressNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"bytes","name":"privilegeConfig","type":"bytes"}],"name":"AdminPrivilegeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"}],"indexed":false,"internalType":"struct AutomationRegistryBase2_3.BillingOverrides","name":"overrides","type":"tuple"}],"name":"BillingConfigOverridden","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"BillingConfigOverrideRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IERC20Metadata","name":"token","type":"address"},{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"},{"internalType":"contract AggregatorV3Interface","name":"priceFeed","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"fallbackPrice","type":"uint256"},{"internalType":"uint96","name":"minSpend","type":"uint96"}],"indexed":false,"internalType":"struct AutomationRegistryBase2_3.BillingConfig","name":"config","type":"tuple"}],"name":"BillingConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"CancelledUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newModule","type":"address"}],"name":"ChainSpecificModuleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"previousConfigBlockNumber","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"configCount","type":"uint64"},{"indexed":false,"internalType":"address[]","name":"signers","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"uint8","name":"f","type":"uint8"},{"indexed":false,"internalType":"bytes","name":"onchainConfig","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"ConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"dedupKey","type":"bytes32"}],"name":"DedupKeyAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"assetAddress","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FeesWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint96","name":"amount","type":"uint96"}],"name":"FundsAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"FundsWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"InsufficientFundsUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"payees","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"payments","type":"uint256[]"}],"name":"NOPsSettledOffchain","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"payees","type":"address[]"}],"name":"PayeesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PayeeshipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PayeeshipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"payee","type":"address"}],"name":"PaymentWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"ReorgedUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"StaleUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"epoch","type":"uint32"}],"name":"Transmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"UpkeepAdminTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"UpkeepAdminTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"uint64","name":"atBlockHeight","type":"uint64"}],"name":"UpkeepCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"newCheckData","type":"bytes"}],"name":"UpkeepCheckDataSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint96","name":"gasLimit","type":"uint96"}],"name":"UpkeepGasLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"remainingBalance","type":"uint256"},{"indexed":false,"internalType":"address","name":"destination","type":"address"}],"name":"UpkeepMigrated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"UpkeepOffchainConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"UpkeepPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"bool","name":"success","type":"bool"},{"indexed":false,"internalType":"uint96","name":"totalPayment","type":"uint96"},{"indexed":false,"internalType":"uint256","name":"gasUsed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasOverhead","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"UpkeepPerformed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"privilegeConfig","type":"bytes"}],"name":"UpkeepPrivilegeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startingBalance","type":"uint256"},{"indexed":false,"internalType":"address","name":"importedFrom","type":"address"}],"name":"UpkeepReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"performGas","type":"uint32"},{"indexed":false,"internalType":"address","name":"admin","type":"address"}],"name":"UpkeepRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"triggerConfig","type":"bytes"}],"name":"UpkeepTriggerConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"UpkeepUnpaused","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fallbackTo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDetails","outputs":[{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"blockNumber","type":"uint32"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDigestAndEpoch","outputs":[{"internalType":"bool","name":"scanLogs","type":"bool"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"internalType":"uint32","name":"epoch","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onTokenTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"internalType":"bytes","name":"onchainConfigBytes","type":"bytes"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"components":[{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"address","name":"financeAdmin","type":"address"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackNativePrice","type":"uint256"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"internalType":"struct AutomationRegistryBase2_3.OnchainConfig","name":"onchainConfig","type":"tuple"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"},{"internalType":"contract IERC20Metadata[]","name":"billingTokens","type":"address[]"},{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"},{"internalType":"contract AggregatorV3Interface","name":"priceFeed","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"fallbackPrice","type":"uint256"},{"internalType":"uint96","name":"minSpend","type":"uint96"}],"internalType":"struct AutomationRegistryBase2_3.BillingConfig[]","name":"billingConfigs","type":"tuple[]"}],"name":"setConfigTypeSafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[3]","name":"reportContext","type":"bytes32[3]"},{"internalType":"bytes","name":"rawReport","type":"bytes"},{"internalType":"bytes32[]","name":"rs","type":"bytes32[]"},{"internalType":"bytes32[]","name":"ss","type":"bytes32[]"},{"internalType":"bytes32","name":"rawVs","type":"bytes32"}],"name":"transmit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"typeAndVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract AutomationRegistryLogicB2_3","name":"logicB","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"cancelUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"address","name":"destination","type":"address"}],"name":"migrateUpkeeps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedUpkeeps","type":"bytes"}],"name":"receiveUpkeeps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"enum AutomationRegistryBase2_3.Trigger","name":"triggerType","type":"uint8"},{"internalType":"contract IERC20Metadata","name":"billingToken","type":"address"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"bytes","name":"triggerConfig","type":"bytes"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"registerUpkeep","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract AutomationRegistryLogicC2_3","name":"logicC","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"acceptUpkeepAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint96","name":"amount","type":"uint96"}],"name":"addFunds","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes[]","name":"values","type":"bytes[]"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"checkCallback","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"triggerData","type":"bytes"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"fastGasWei","type":"uint256"},{"internalType":"uint256","name":"linkUSD","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"fastGasWei","type":"uint256"},{"internalType":"uint256","name":"linkUSD","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"executeCallback","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"pauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"removeBillingOverrides","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"}],"internalType":"struct AutomationRegistryBase2_3.BillingOverrides","name":"billingOverrides","type":"tuple"}],"name":"setBillingOverrides","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"newCheckData","type":"bytes"}],"name":"setUpkeepCheckData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint32","name":"gasLimit","type":"uint32"}],"name":"setUpkeepGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"config","type":"bytes"}],"name":"setUpkeepOffchainConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"triggerConfig","type":"bytes"}],"name":"setUpkeepTriggerConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"performData","type":"bytes"}],"name":"simulatePerformUpkeep","outputs":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"proposed","type":"address"}],"name":"transferUpkeepAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"unpauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Metadata","name":"asset","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawERC20Fees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawLink","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"link","type":"address"},{"internalType":"address","name":"linkUSDFeed","type":"address"},{"internalType":"address","name":"nativeUSDFeed","type":"address"},{"internalType":"address","name":"fastGasFeed","type":"address"},{"internalType":"address","name":"automationForwarderLogic","type":"address"},{"internalType":"address","name":"allowedReadOnlyAddress","type":"address"},{"internalType":"enum AutomationRegistryBase2_3.PayoutMode","name":"payoutMode","type":"uint8"},{"internalType":"address","name":"wrappedNativeTokenAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"transmitter","type":"address"}],"name":"acceptPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"disableOffchainPayments","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"maxCount","type":"uint256"}],"name":"getActiveUpkeepIDs","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"getAdminPrivilegeConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllowedReadOnlyAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAutomationForwarderLogic","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getBalance","outputs":[{"internalType":"uint96","name":"balance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepID","type":"uint256"}],"name":"getBillingToken","outputs":[{"internalType":"contract IERC20Metadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Metadata","name":"token","type":"address"}],"name":"getBillingTokenConfig","outputs":[{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"},{"internalType":"contract AggregatorV3Interface","name":"priceFeed","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"fallbackPrice","type":"uint256"},{"internalType":"uint96","name":"minSpend","type":"uint96"}],"internalType":"struct AutomationRegistryBase2_3.BillingConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBillingTokens","outputs":[{"internalType":"contract IERC20Metadata[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCancellationDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getChainModule","outputs":[{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConditionalGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getConfig","outputs":[{"components":[{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"address","name":"financeAdmin","type":"address"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackNativePrice","type":"uint256"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"internalType":"struct AutomationRegistryBase2_3.OnchainConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFallbackNativePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFastGasFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepID","type":"uint256"}],"name":"getForwarder","outputs":[{"internalType":"contract IAutomationForwarder","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getHotVars","outputs":[{"components":[{"internalType":"uint96","name":"totalPremium","type":"uint96"},{"internalType":"uint32","name":"latestEpoch","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint8","name":"f","type":"uint8"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"reentrancyGuard","type":"bool"},{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"},{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"internalType":"struct AutomationRegistryBase2_3.HotVars","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkUSDFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLogGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"enum AutomationRegistryBase2_3.Trigger","name":"triggerType","type":"uint8"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"contract IERC20Metadata","name":"billingToken","type":"address"}],"name":"getMaxPaymentForGas","outputs":[{"internalType":"uint96","name":"maxPayment","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getMinBalance","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getMinBalanceForUpkeep","outputs":[{"internalType":"uint96","name":"minBalance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNativeUSDFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumUpkeeps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPayoutMode","outputs":[{"internalType":"enum AutomationRegistryBase2_3.PayoutMode","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"peer","type":"address"}],"name":"getPeerRegistryMigrationPermission","outputs":[{"internalType":"enum AutomationRegistryBase2_3.MigrationPermission","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPerPerformByteGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getPerSignerGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getReorgProtectionEnabled","outputs":[{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Metadata","name":"billingToken","type":"address"}],"name":"getReserveAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"query","type":"address"}],"name":"getSignerInfo","outputs":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint8","name":"index","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getState","outputs":[{"components":[{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"uint96","name":"ownerLinkBalance","type":"uint96"},{"internalType":"uint256","name":"expectedLinkBalance","type":"uint256"},{"internalType":"uint96","name":"totalPremium","type":"uint96"},{"internalType":"uint256","name":"numUpkeeps","type":"uint256"},{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"latestConfigBlockNumber","type":"uint32"},{"internalType":"bytes32","name":"latestConfigDigest","type":"bytes32"},{"internalType":"uint32","name":"latestEpoch","type":"uint32"},{"internalType":"bool","name":"paused","type":"bool"}],"internalType":"struct IAutomationV21PlusCommon.StateLegacy","name":"state","type":"tuple"},{"components":[{"internalType":"uint32","name":"paymentPremiumPPB","type":"uint32"},{"internalType":"uint32","name":"flatFeeMicroLink","type":"uint32"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint96","name":"minUpkeepSpend","type":"uint96"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"}],"internalType":"struct IAutomationV21PlusCommon.OnchainConfigLegacy","name":"config","type":"tuple"},{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStorage","outputs":[{"components":[{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"},{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"latestConfigBlockNumber","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"address","name":"financeAdmin","type":"address"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"}],"internalType":"struct AutomationRegistryBase2_3.Storage","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTransmitCalldataFixedBytesOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getTransmitCalldataPerSignerBytesOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"query","type":"address"}],"name":"getTransmitterInfo","outputs":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint8","name":"index","type":"uint8"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"uint96","name":"lastCollected","type":"uint96"},{"internalType":"address","name":"payee","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getTriggerType","outputs":[{"internalType":"enum AutomationRegistryBase2_3.Trigger","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getUpkeep","outputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"performGas","type":"uint32"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"uint64","name":"maxValidBlocknumber","type":"uint64"},{"internalType":"uint32","name":"lastPerformedBlockNumber","type":"uint32"},{"internalType":"uint96","name":"amountSpent","type":"uint96"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"internalType":"struct IAutomationV21PlusCommon.UpkeepInfoLegacy","name":"upkeepInfo","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getUpkeepPrivilegeConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getUpkeepTriggerConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWrappedNativeTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"dedupKey","type":"bytes32"}],"name":"hasDedupKey","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"linkAvailableForPayment","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"bytes","name":"newPrivilegeConfig","type":"bytes"}],"name":"setAdminPrivilegeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"payees","type":"address[]"}],"name":"setPayees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"peer","type":"address"},{"internalType":"enum AutomationRegistryBase2_3.MigrationPermission","name":"permission","type":"uint8"}],"name":"setPeerRegistryMigrationPermission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"},{"internalType":"bytes","name":"newPrivilegeConfig","type":"bytes"}],"name":"setUpkeepPrivilegeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"settleNOPsOffchain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Metadata","name":"token","type":"address"}],"name":"supportsBillingToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"transmitter","type":"address"},{"internalType":"address","name":"proposed","type":"address"}],"name":"transferPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"upkeepVersion","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawPayment","outputs":[],"stateMutability":"nonpayable","type":"function"}] +[{"inputs":[{"internalType":"contract AutomationRegistryLogicA2_3","name":"logicA","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ArrayHasNoEntries","type":"error"},{"inputs":[],"name":"CannotCancel","type":"error"},{"inputs":[],"name":"CheckDataExceedsLimit","type":"error"},{"inputs":[],"name":"ConfigDigestMismatch","type":"error"},{"inputs":[],"name":"DuplicateEntry","type":"error"},{"inputs":[],"name":"DuplicateSigners","type":"error"},{"inputs":[],"name":"GasLimitCanOnlyIncrease","type":"error"},{"inputs":[],"name":"GasLimitOutsideRange","type":"error"},{"inputs":[],"name":"IncorrectNumberOfFaultyOracles","type":"error"},{"inputs":[],"name":"IncorrectNumberOfSignatures","type":"error"},{"inputs":[],"name":"IncorrectNumberOfSigners","type":"error"},{"inputs":[],"name":"IndexOutOfRange","type":"error"},{"inputs":[{"internalType":"uint256","name":"available","type":"uint256"},{"internalType":"uint256","name":"requested","type":"uint256"}],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"InsufficientLinkLiquidity","type":"error"},{"inputs":[],"name":"InvalidDataLength","type":"error"},{"inputs":[],"name":"InvalidFeed","type":"error"},{"inputs":[],"name":"InvalidPayee","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"InvalidReport","type":"error"},{"inputs":[],"name":"InvalidSigner","type":"error"},{"inputs":[],"name":"InvalidToken","type":"error"},{"inputs":[],"name":"InvalidTransmitter","type":"error"},{"inputs":[],"name":"InvalidTrigger","type":"error"},{"inputs":[],"name":"InvalidTriggerType","type":"error"},{"inputs":[],"name":"MigrationNotPermitted","type":"error"},{"inputs":[],"name":"MustSettleOffchain","type":"error"},{"inputs":[],"name":"MustSettleOnchain","type":"error"},{"inputs":[],"name":"NotAContract","type":"error"},{"inputs":[],"name":"OnlyActiveSigners","type":"error"},{"inputs":[],"name":"OnlyActiveTransmitters","type":"error"},{"inputs":[],"name":"OnlyCallableByAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByLINKToken","type":"error"},{"inputs":[],"name":"OnlyCallableByOwnerOrAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByOwnerOrRegistrar","type":"error"},{"inputs":[],"name":"OnlyCallableByPayee","type":"error"},{"inputs":[],"name":"OnlyCallableByProposedAdmin","type":"error"},{"inputs":[],"name":"OnlyCallableByProposedPayee","type":"error"},{"inputs":[],"name":"OnlyCallableByUpkeepPrivilegeManager","type":"error"},{"inputs":[],"name":"OnlyFinanceAdmin","type":"error"},{"inputs":[],"name":"OnlyPausedUpkeep","type":"error"},{"inputs":[],"name":"OnlySimulatedBackend","type":"error"},{"inputs":[],"name":"OnlyUnpausedUpkeep","type":"error"},{"inputs":[],"name":"ParameterLengthError","type":"error"},{"inputs":[],"name":"ReentrantCall","type":"error"},{"inputs":[],"name":"RegistryPaused","type":"error"},{"inputs":[],"name":"RepeatedSigner","type":"error"},{"inputs":[],"name":"RepeatedTransmitter","type":"error"},{"inputs":[{"internalType":"bytes","name":"reason","type":"bytes"}],"name":"TargetCheckReverted","type":"error"},{"inputs":[],"name":"TooManyOracles","type":"error"},{"inputs":[],"name":"TranscoderNotSet","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"UpkeepAlreadyExists","type":"error"},{"inputs":[],"name":"UpkeepCancelled","type":"error"},{"inputs":[],"name":"UpkeepNotCanceled","type":"error"},{"inputs":[],"name":"UpkeepNotNeeded","type":"error"},{"inputs":[],"name":"ValueNotChanged","type":"error"},{"inputs":[],"name":"ZeroAddressNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"bytes","name":"privilegeConfig","type":"bytes"}],"name":"AdminPrivilegeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"}],"indexed":false,"internalType":"struct AutomationRegistryBase2_3.BillingOverrides","name":"overrides","type":"tuple"}],"name":"BillingConfigOverridden","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"BillingConfigOverrideRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IERC20Metadata","name":"token","type":"address"},{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"},{"internalType":"contract AggregatorV3Interface","name":"priceFeed","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"fallbackPrice","type":"uint256"},{"internalType":"uint96","name":"minSpend","type":"uint96"}],"indexed":false,"internalType":"struct AutomationRegistryBase2_3.BillingConfig","name":"config","type":"tuple"}],"name":"BillingConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"CancelledUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newModule","type":"address"}],"name":"ChainSpecificModuleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"previousConfigBlockNumber","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"configCount","type":"uint64"},{"indexed":false,"internalType":"address[]","name":"signers","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"uint8","name":"f","type":"uint8"},{"indexed":false,"internalType":"bytes","name":"onchainConfig","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"ConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"dedupKey","type":"bytes32"}],"name":"DedupKeyAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"assetAddress","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FeesWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint96","name":"amount","type":"uint96"}],"name":"FundsAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"FundsWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"InsufficientFundsUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"payees","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"payments","type":"uint256[]"}],"name":"NOPsSettledOffchain","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"payees","type":"address[]"}],"name":"PayeesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PayeeshipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PayeeshipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"transmitter","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"payee","type":"address"}],"name":"PaymentWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"ReorgedUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"StaleUpkeepReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"epoch","type":"uint32"}],"name":"Transmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"UpkeepAdminTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"UpkeepAdminTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"uint64","name":"atBlockHeight","type":"uint64"}],"name":"UpkeepCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"newCheckData","type":"bytes"}],"name":"UpkeepCheckDataSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint96","name":"gasLimit","type":"uint96"}],"name":"UpkeepGasLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"remainingBalance","type":"uint256"},{"indexed":false,"internalType":"address","name":"destination","type":"address"}],"name":"UpkeepMigrated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"UpkeepOffchainConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"UpkeepPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"bool","name":"success","type":"bool"},{"indexed":false,"internalType":"uint96","name":"totalPayment","type":"uint96"},{"indexed":false,"internalType":"uint256","name":"gasUsed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasOverhead","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"trigger","type":"bytes"}],"name":"UpkeepPerformed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"privilegeConfig","type":"bytes"}],"name":"UpkeepPrivilegeConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startingBalance","type":"uint256"},{"indexed":false,"internalType":"address","name":"importedFrom","type":"address"}],"name":"UpkeepReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"performGas","type":"uint32"},{"indexed":false,"internalType":"address","name":"admin","type":"address"}],"name":"UpkeepRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"triggerConfig","type":"bytes"}],"name":"UpkeepTriggerConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"UpkeepUnpaused","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fallbackTo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDetails","outputs":[{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"blockNumber","type":"uint32"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDigestAndEpoch","outputs":[{"internalType":"bool","name":"scanLogs","type":"bool"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"internalType":"uint32","name":"epoch","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onTokenTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"internalType":"bytes","name":"onchainConfigBytes","type":"bytes"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"components":[{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"address","name":"financeAdmin","type":"address"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackNativePrice","type":"uint256"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"internalType":"struct AutomationRegistryBase2_3.OnchainConfig","name":"onchainConfig","type":"tuple"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"},{"internalType":"contract IERC20Metadata[]","name":"billingTokens","type":"address[]"},{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"},{"internalType":"contract AggregatorV3Interface","name":"priceFeed","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"fallbackPrice","type":"uint256"},{"internalType":"uint96","name":"minSpend","type":"uint96"}],"internalType":"struct AutomationRegistryBase2_3.BillingConfig[]","name":"billingConfigs","type":"tuple[]"}],"name":"setConfigTypeSafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[3]","name":"reportContext","type":"bytes32[3]"},{"internalType":"bytes","name":"rawReport","type":"bytes"},{"internalType":"bytes32[]","name":"rs","type":"bytes32[]"},{"internalType":"bytes32[]","name":"ss","type":"bytes32[]"},{"internalType":"bytes32","name":"rawVs","type":"bytes32"}],"name":"transmit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"typeAndVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract AutomationRegistryLogicB2_3","name":"logicB","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"cancelUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"address","name":"destination","type":"address"}],"name":"migrateUpkeeps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedUpkeeps","type":"bytes"}],"name":"receiveUpkeeps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"enum AutomationRegistryBase2_3.Trigger","name":"triggerType","type":"uint8"},{"internalType":"contract IERC20Metadata","name":"billingToken","type":"address"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"bytes","name":"triggerConfig","type":"bytes"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"registerUpkeep","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract AutomationRegistryLogicC2_3","name":"logicC","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"acceptUpkeepAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint96","name":"amount","type":"uint96"}],"name":"addFunds","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes[]","name":"values","type":"bytes[]"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"checkCallback","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"triggerData","type":"bytes"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"fastGasWei","type":"uint256"},{"internalType":"uint256","name":"linkUSD","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"fastGasWei","type":"uint256"},{"internalType":"uint256","name":"linkUSD","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"executeCallback","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"enum AutomationRegistryBase2_3.UpkeepFailureReason","name":"upkeepFailureReason","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"pauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"removeBillingOverrides","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"}],"internalType":"struct AutomationRegistryBase2_3.BillingOverrides","name":"billingOverrides","type":"tuple"}],"name":"setBillingOverrides","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"newCheckData","type":"bytes"}],"name":"setUpkeepCheckData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint32","name":"gasLimit","type":"uint32"}],"name":"setUpkeepGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"config","type":"bytes"}],"name":"setUpkeepOffchainConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"triggerConfig","type":"bytes"}],"name":"setUpkeepTriggerConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"performData","type":"bytes"}],"name":"simulatePerformUpkeep","outputs":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"proposed","type":"address"}],"name":"transferUpkeepAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"unpauseUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Metadata","name":"asset","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawERC20Fees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawLink","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"link","type":"address"},{"internalType":"address","name":"linkUSDFeed","type":"address"},{"internalType":"address","name":"nativeUSDFeed","type":"address"},{"internalType":"address","name":"fastGasFeed","type":"address"},{"internalType":"address","name":"automationForwarderLogic","type":"address"},{"internalType":"address","name":"allowedReadOnlyAddress","type":"address"},{"internalType":"enum AutomationRegistryBase2_3.PayoutMode","name":"payoutMode","type":"uint8"},{"internalType":"address","name":"wrappedNativeTokenAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"transmitter","type":"address"}],"name":"acceptPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"disableOffchainPayments","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"maxCount","type":"uint256"}],"name":"getActiveUpkeepIDs","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"getAdminPrivilegeConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllowedReadOnlyAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAutomationForwarderLogic","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getBalance","outputs":[{"internalType":"uint96","name":"balance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Metadata","name":"billingToken","type":"address"}],"name":"getBillingConfig","outputs":[{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"},{"internalType":"contract AggregatorV3Interface","name":"priceFeed","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"fallbackPrice","type":"uint256"},{"internalType":"uint96","name":"minSpend","type":"uint96"}],"internalType":"struct AutomationRegistryBase2_3.BillingConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepID","type":"uint256"}],"name":"getBillingOverrides","outputs":[{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"}],"internalType":"struct AutomationRegistryBase2_3.BillingOverrides","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepID","type":"uint256"}],"name":"getBillingToken","outputs":[{"internalType":"contract IERC20Metadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Metadata","name":"token","type":"address"}],"name":"getBillingTokenConfig","outputs":[{"components":[{"internalType":"uint32","name":"gasFeePPB","type":"uint32"},{"internalType":"uint24","name":"flatFeeMilliCents","type":"uint24"},{"internalType":"contract AggregatorV3Interface","name":"priceFeed","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"fallbackPrice","type":"uint256"},{"internalType":"uint96","name":"minSpend","type":"uint96"}],"internalType":"struct AutomationRegistryBase2_3.BillingConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBillingTokens","outputs":[{"internalType":"contract IERC20Metadata[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCancellationDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getChainModule","outputs":[{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConditionalGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getConfig","outputs":[{"components":[{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"address","name":"financeAdmin","type":"address"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackNativePrice","type":"uint256"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"internalType":"struct AutomationRegistryBase2_3.OnchainConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFallbackNativePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFastGasFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepID","type":"uint256"}],"name":"getForwarder","outputs":[{"internalType":"contract IAutomationForwarder","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getHotVars","outputs":[{"components":[{"internalType":"uint96","name":"totalPremium","type":"uint96"},{"internalType":"uint32","name":"latestEpoch","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint8","name":"f","type":"uint8"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"reentrancyGuard","type":"bool"},{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"},{"internalType":"contract IChainModule","name":"chainModule","type":"address"}],"internalType":"struct AutomationRegistryBase2_3.HotVars","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLinkUSDFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLogGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"enum AutomationRegistryBase2_3.Trigger","name":"triggerType","type":"uint8"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"contract IERC20Metadata","name":"billingToken","type":"address"}],"name":"getMaxPaymentForGas","outputs":[{"internalType":"uint96","name":"maxPayment","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getMinBalance","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getMinBalanceForUpkeep","outputs":[{"internalType":"uint96","name":"minBalance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNativeUSDFeedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumUpkeeps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPayoutMode","outputs":[{"internalType":"enum AutomationRegistryBase2_3.PayoutMode","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"peer","type":"address"}],"name":"getPeerRegistryMigrationPermission","outputs":[{"internalType":"enum AutomationRegistryBase2_3.MigrationPermission","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPerPerformByteGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getPerSignerGasOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getReorgProtectionEnabled","outputs":[{"internalType":"bool","name":"reorgProtectionEnabled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Metadata","name":"billingToken","type":"address"}],"name":"getReserveAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"query","type":"address"}],"name":"getSignerInfo","outputs":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint8","name":"index","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getState","outputs":[{"components":[{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"uint96","name":"ownerLinkBalance","type":"uint96"},{"internalType":"uint256","name":"expectedLinkBalance","type":"uint256"},{"internalType":"uint96","name":"totalPremium","type":"uint96"},{"internalType":"uint256","name":"numUpkeeps","type":"uint256"},{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"latestConfigBlockNumber","type":"uint32"},{"internalType":"bytes32","name":"latestConfigDigest","type":"bytes32"},{"internalType":"uint32","name":"latestEpoch","type":"uint32"},{"internalType":"bool","name":"paused","type":"bool"}],"internalType":"struct IAutomationV21PlusCommon.StateLegacy","name":"state","type":"tuple"},{"components":[{"internalType":"uint32","name":"paymentPremiumPPB","type":"uint32"},{"internalType":"uint32","name":"flatFeeMicroLink","type":"uint32"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint96","name":"minUpkeepSpend","type":"uint96"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"},{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"address[]","name":"registrars","type":"address[]"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"}],"internalType":"struct IAutomationV21PlusCommon.OnchainConfigLegacy","name":"config","type":"tuple"},{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStorage","outputs":[{"components":[{"internalType":"address","name":"transcoder","type":"address"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint32","name":"maxPerformGas","type":"uint32"},{"internalType":"uint32","name":"nonce","type":"uint32"},{"internalType":"address","name":"upkeepPrivilegeManager","type":"address"},{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"latestConfigBlockNumber","type":"uint32"},{"internalType":"uint32","name":"maxCheckDataSize","type":"uint32"},{"internalType":"address","name":"financeAdmin","type":"address"},{"internalType":"uint32","name":"maxPerformDataSize","type":"uint32"},{"internalType":"uint32","name":"maxRevertDataSize","type":"uint32"}],"internalType":"struct AutomationRegistryBase2_3.Storage","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTransmitCalldataFixedBytesOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getTransmitCalldataPerSignerBytesOverhead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"query","type":"address"}],"name":"getTransmitterInfo","outputs":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint8","name":"index","type":"uint8"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"uint96","name":"lastCollected","type":"uint96"},{"internalType":"address","name":"payee","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTransmittersWithPayees","outputs":[{"components":[{"internalType":"address","name":"transmitterAddress","type":"address"},{"internalType":"address","name":"payeeAddress","type":"address"}],"internalType":"struct AutomationRegistryBase2_3.TransmitterPayeeInfo[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getTriggerType","outputs":[{"internalType":"enum AutomationRegistryBase2_3.Trigger","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getUpkeep","outputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"performGas","type":"uint32"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"uint64","name":"maxValidBlocknumber","type":"uint64"},{"internalType":"uint32","name":"lastPerformedBlockNumber","type":"uint32"},{"internalType":"uint96","name":"amountSpent","type":"uint96"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"internalType":"struct IAutomationV21PlusCommon.UpkeepInfoLegacy","name":"upkeepInfo","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getUpkeepPrivilegeConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"}],"name":"getUpkeepTriggerConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWrappedNativeTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"dedupKey","type":"bytes32"}],"name":"hasDedupKey","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"linkAvailableForPayment","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"bytes","name":"newPrivilegeConfig","type":"bytes"}],"name":"setAdminPrivilegeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"payees","type":"address[]"}],"name":"setPayees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"peer","type":"address"},{"internalType":"enum AutomationRegistryBase2_3.MigrationPermission","name":"permission","type":"uint8"}],"name":"setPeerRegistryMigrationPermission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"upkeepId","type":"uint256"},{"internalType":"bytes","name":"newPrivilegeConfig","type":"bytes"}],"name":"setUpkeepPrivilegeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"settleNOPsOffchain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Metadata","name":"token","type":"address"}],"name":"supportsBillingToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"transmitter","type":"address"},{"internalType":"address","name":"proposed","type":"address"}],"name":"transferPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"upkeepVersion","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawPayment","outputs":[],"stateMutability":"nonpayable","type":"function"}] */ diff --git a/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol b/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol index 19e1cdc7460..3e7e489379e 100644 --- a/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol +++ b/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol @@ -703,6 +703,23 @@ contract SetConfig is SetUp { ); } + function testSetConfigOnTransmittersAndPayees() public { + AutomationRegistryBase2_3.TransmitterPayeeInfo[] memory transmitterPayeeInfos = registry + .getTransmittersWithPayees(); + assertEq(transmitterPayeeInfos.length, TRANSMITTERS.length); + + for (uint256 i = 0; i < transmitterPayeeInfos.length; i++) { + address transmitterAddress = transmitterPayeeInfos[i].transmitterAddress; + address payeeAddress = transmitterPayeeInfos[i].payeeAddress; + + address expectedTransmitter = TRANSMITTERS[i]; + address expectedPayee = PAYEES[i]; + + assertEq(transmitterAddress, expectedTransmitter); + assertEq(payeeAddress, expectedPayee); + } + } + function testSetConfigWithNewTransmittersSuccess() public { registry = deployRegistry(AutoBase.PayoutMode.OFF_CHAIN); diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol index 275b25b28d0..62c72adffc4 100644 --- a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol +++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol @@ -331,7 +331,7 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner { * @member index of oracle in s_signersList/s_transmittersList * @member balance a node's balance in LINK * @member lastCollected the total balance at which the node last withdrew - @ @dev uint96 is safe for balance / last collected because transmitters are only ever paid in LINK + * @dev uint96 is safe for balance / last collected because transmitters are only ever paid in LINK */ struct Transmitter { bool active; @@ -340,6 +340,11 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner { uint96 lastCollected; } + struct TransmitterPayeeInfo { + address transmitterAddress; + address payeeAddress; + } + struct Signer { bool active; // Index of oracle in s_signersList/s_transmittersList diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicC2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicC2_3.sol index 546c85454f7..92a9ca1a648 100644 --- a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicC2_3.sol +++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicC2_3.sol @@ -582,4 +582,35 @@ contract AutomationRegistryLogicC2_3 is AutomationRegistryBase2_3 { function linkAvailableForPayment() public view returns (int256) { return _linkAvailableForPayment(); } + + /** + * @notice returns the BillingOverrides config for a given upkeep + */ + function getBillingOverrides(uint256 upkeepID) external view returns (BillingOverrides memory) { + return s_billingOverrides[upkeepID]; + } + + /** + * @notice returns the BillingConfig for a given billing token, this includes decimals and price feed etc + */ + function getBillingConfig(IERC20 billingToken) external view returns (BillingConfig memory) { + return s_billingConfigs[billingToken]; + } + + /** + * @notice returns all active transmitters with their associated payees + */ + function getTransmittersWithPayees() external view returns (TransmitterPayeeInfo[] memory) { + uint256 transmitterCount = s_transmittersList.length; + TransmitterPayeeInfo[] memory transmitters = new TransmitterPayeeInfo[](transmitterCount); + + for (uint256 i = 0; i < transmitterCount; i++) { + address transmitterAddress = s_transmittersList[i]; + address payeeAddress = s_transmitterPayees[transmitterAddress]; + + transmitters[i] = TransmitterPayeeInfo(transmitterAddress, payeeAddress); + } + + return transmitters; + } } diff --git a/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_3/i_automation_registry_master_wrapper_2_3.go b/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_3/i_automation_registry_master_wrapper_2_3.go index a72ff506c90..cdbb52883ff 100644 --- a/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_3/i_automation_registry_master_wrapper_2_3.go +++ b/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_3/i_automation_registry_master_wrapper_2_3.go @@ -89,6 +89,11 @@ type AutomationRegistryBase23Storage struct { MaxRevertDataSize uint32 } +type AutomationRegistryBase23TransmitterPayeeInfo struct { + TransmitterAddress common.Address + PayeeAddress common.Address +} + type IAutomationV21PlusCommonOnchainConfigLegacy struct { PaymentPremiumPPB uint32 FlatFeeMicroLink uint32 @@ -134,7 +139,7 @@ type IAutomationV21PlusCommonUpkeepInfoLegacy struct { } var IAutomationRegistryMaster23MetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLinkLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFeed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOffchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOnchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyFinanceAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"overrides\",\"type\":\"tuple\"}],\"name\":\"BillingConfigOverridden\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"BillingConfigOverrideRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"address\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"BillingConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeesWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"payments\",\"type\":\"uint256[]\"}],\"name\":\"NOPsSettledOffchain\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"acceptPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"acceptUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkUSD\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkUSD\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"disableOffchainPayments\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"executeCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"getAdminPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedReadOnlyAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAutomationForwarderLogic\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getBillingToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getBillingTokenConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"address\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBillingTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCancellationDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainModule\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConditionalGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"financeAdmin\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackNativePrice\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.OnchainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFallbackNativePrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFastGasFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getForwarder\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getHotVars\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"totalPremium\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"latestEpoch\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"reentrancyGuard\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.HotVars\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkUSDFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLogGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"billingToken\",\"type\":\"address\"}],\"name\":\"getMaxPaymentForGas\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"maxPayment\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalanceForUpkeep\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"minBalance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNativeUSDFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNumUpkeeps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPayoutMode\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"}],\"name\":\"getPeerRegistryMigrationPermission\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerPerformByteGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerSignerGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getReorgProtectionEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"billingToken\",\"type\":\"address\"}],\"name\":\"getReserveAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getSignerInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"ownerLinkBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"expectedLinkBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"totalPremium\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"numUpkeeps\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"latestConfigBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"latestConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"latestEpoch\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"internalType\":\"structIAutomationV21PlusCommon.StateLegacy\",\"name\":\"state\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"}],\"internalType\":\"structIAutomationV21PlusCommon.OnchainConfigLegacy\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStorage\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"latestConfigBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"financeAdmin\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"}],\"internalType\":\"structAutomationRegistryBase2_3.Storage\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitCalldataFixedBytesOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitCalldataPerSignerBytesOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getTransmitterInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"lastCollected\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getTriggerType\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getUpkeep\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"maxValidBlocknumber\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"lastPerformedBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"amountSpent\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structIAutomationV21PlusCommon.UpkeepInfoLegacy\",\"name\":\"upkeepInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWrappedNativeTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"hasDedupKey\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"migrateUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"pauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedUpkeeps\",\"type\":\"bytes\"}],\"name\":\"receiveUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"billingToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"removeBillingOverrides\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setAdminPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"billingOverrides\",\"type\":\"tuple\"}],\"name\":\"setBillingOverrides\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfigBytes\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"financeAdmin\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackNativePrice\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"address[]\",\"name\":\"billingTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"address\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig[]\",\"name\":\"billingConfigs\",\"type\":\"tuple[]\"}],\"name\":\"setConfigTypeSafe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"setPayees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"permission\",\"type\":\"uint8\"}],\"name\":\"setPeerRegistryMigrationPermission\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"setUpkeepCheckData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"setUpkeepOffchainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"settleNOPsOffchain\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"simulatePerformUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"supportsBillingToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"unpauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC20Fees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLink\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLinkLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFeed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOffchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOnchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyFinanceAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"overrides\",\"type\":\"tuple\"}],\"name\":\"BillingConfigOverridden\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"BillingConfigOverrideRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"address\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"BillingConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeesWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"payments\",\"type\":\"uint256[]\"}],\"name\":\"NOPsSettledOffchain\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"acceptPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"acceptUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkUSD\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkUSD\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"disableOffchainPayments\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"executeCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"upkeepFailureReason\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"getAdminPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedReadOnlyAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAutomationForwarderLogic\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"billingToken\",\"type\":\"address\"}],\"name\":\"getBillingConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"address\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getBillingOverrides\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getBillingToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getBillingTokenConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"address\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBillingTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCancellationDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainModule\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConditionalGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"financeAdmin\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackNativePrice\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.OnchainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFallbackNativePrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFastGasFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getForwarder\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getHotVars\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"totalPremium\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"latestEpoch\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"reentrancyGuard\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.HotVars\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLinkUSDFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLogGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"billingToken\",\"type\":\"address\"}],\"name\":\"getMaxPaymentForGas\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"maxPayment\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getMinBalanceForUpkeep\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"minBalance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNativeUSDFeedAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNumUpkeeps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPayoutMode\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"}],\"name\":\"getPeerRegistryMigrationPermission\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerPerformByteGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPerSignerGasOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getReorgProtectionEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"billingToken\",\"type\":\"address\"}],\"name\":\"getReserveAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getSignerInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"ownerLinkBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"expectedLinkBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"totalPremium\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"numUpkeeps\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"latestConfigBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"latestConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"latestEpoch\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"internalType\":\"structIAutomationV21PlusCommon.StateLegacy\",\"name\":\"state\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"}],\"internalType\":\"structIAutomationV21PlusCommon.OnchainConfigLegacy\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStorage\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"latestConfigBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"financeAdmin\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"}],\"internalType\":\"structAutomationRegistryBase2_3.Storage\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitCalldataFixedBytesOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitCalldataPerSignerBytesOverhead\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"query\",\"type\":\"address\"}],\"name\":\"getTransmitterInfo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"},{\"internalType\":\"uint8\",\"name\":\"index\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"lastCollected\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmittersWithPayees\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"transmitterAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"payeeAddress\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.TransmitterPayeeInfo[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getTriggerType\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getUpkeep\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"maxValidBlocknumber\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"lastPerformedBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"amountSpent\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structIAutomationV21PlusCommon.UpkeepInfoLegacy\",\"name\":\"upkeepInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWrappedNativeTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"hasDedupKey\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"migrateUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"pauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedUpkeeps\",\"type\":\"bytes\"}],\"name\":\"receiveUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"billingToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"removeBillingOverrides\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setAdminPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"billingOverrides\",\"type\":\"tuple\"}],\"name\":\"setBillingOverrides\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfigBytes\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"financeAdmin\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackNativePrice\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"chainModule\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"address[]\",\"name\":\"billingTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"address\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig[]\",\"name\":\"billingConfigs\",\"type\":\"tuple[]\"}],\"name\":\"setConfigTypeSafe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"setPayees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"peer\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"permission\",\"type\":\"uint8\"}],\"name\":\"setPeerRegistryMigrationPermission\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"setUpkeepCheckData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"setUpkeepOffchainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"newPrivilegeConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"setUpkeepTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"settleNOPsOffchain\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"simulatePerformUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"supportsBillingToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferPayeeship\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"proposed\",\"type\":\"address\"}],\"name\":\"transferUpkeepAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"unpauseUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC20Fees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLink\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawPayment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", } var IAutomationRegistryMaster23ABI = IAutomationRegistryMaster23MetaData.ABI @@ -489,6 +494,50 @@ func (_IAutomationRegistryMaster23 *IAutomationRegistryMaster23CallerSession) Ge return _IAutomationRegistryMaster23.Contract.GetBalance(&_IAutomationRegistryMaster23.CallOpts, id) } +func (_IAutomationRegistryMaster23 *IAutomationRegistryMaster23Caller) GetBillingConfig(opts *bind.CallOpts, billingToken common.Address) (AutomationRegistryBase23BillingConfig, error) { + var out []interface{} + err := _IAutomationRegistryMaster23.contract.Call(opts, &out, "getBillingConfig", billingToken) + + if err != nil { + return *new(AutomationRegistryBase23BillingConfig), err + } + + out0 := *abi.ConvertType(out[0], new(AutomationRegistryBase23BillingConfig)).(*AutomationRegistryBase23BillingConfig) + + return out0, err + +} + +func (_IAutomationRegistryMaster23 *IAutomationRegistryMaster23Session) GetBillingConfig(billingToken common.Address) (AutomationRegistryBase23BillingConfig, error) { + return _IAutomationRegistryMaster23.Contract.GetBillingConfig(&_IAutomationRegistryMaster23.CallOpts, billingToken) +} + +func (_IAutomationRegistryMaster23 *IAutomationRegistryMaster23CallerSession) GetBillingConfig(billingToken common.Address) (AutomationRegistryBase23BillingConfig, error) { + return _IAutomationRegistryMaster23.Contract.GetBillingConfig(&_IAutomationRegistryMaster23.CallOpts, billingToken) +} + +func (_IAutomationRegistryMaster23 *IAutomationRegistryMaster23Caller) GetBillingOverrides(opts *bind.CallOpts, upkeepID *big.Int) (AutomationRegistryBase23BillingOverrides, error) { + var out []interface{} + err := _IAutomationRegistryMaster23.contract.Call(opts, &out, "getBillingOverrides", upkeepID) + + if err != nil { + return *new(AutomationRegistryBase23BillingOverrides), err + } + + out0 := *abi.ConvertType(out[0], new(AutomationRegistryBase23BillingOverrides)).(*AutomationRegistryBase23BillingOverrides) + + return out0, err + +} + +func (_IAutomationRegistryMaster23 *IAutomationRegistryMaster23Session) GetBillingOverrides(upkeepID *big.Int) (AutomationRegistryBase23BillingOverrides, error) { + return _IAutomationRegistryMaster23.Contract.GetBillingOverrides(&_IAutomationRegistryMaster23.CallOpts, upkeepID) +} + +func (_IAutomationRegistryMaster23 *IAutomationRegistryMaster23CallerSession) GetBillingOverrides(upkeepID *big.Int) (AutomationRegistryBase23BillingOverrides, error) { + return _IAutomationRegistryMaster23.Contract.GetBillingOverrides(&_IAutomationRegistryMaster23.CallOpts, upkeepID) +} + func (_IAutomationRegistryMaster23 *IAutomationRegistryMaster23Caller) GetBillingToken(opts *bind.CallOpts, upkeepID *big.Int) (common.Address, error) { var out []interface{} err := _IAutomationRegistryMaster23.contract.Call(opts, &out, "getBillingToken", upkeepID) @@ -1201,6 +1250,28 @@ func (_IAutomationRegistryMaster23 *IAutomationRegistryMaster23CallerSession) Ge return _IAutomationRegistryMaster23.Contract.GetTransmitterInfo(&_IAutomationRegistryMaster23.CallOpts, query) } +func (_IAutomationRegistryMaster23 *IAutomationRegistryMaster23Caller) GetTransmittersWithPayees(opts *bind.CallOpts) ([]AutomationRegistryBase23TransmitterPayeeInfo, error) { + var out []interface{} + err := _IAutomationRegistryMaster23.contract.Call(opts, &out, "getTransmittersWithPayees") + + if err != nil { + return *new([]AutomationRegistryBase23TransmitterPayeeInfo), err + } + + out0 := *abi.ConvertType(out[0], new([]AutomationRegistryBase23TransmitterPayeeInfo)).(*[]AutomationRegistryBase23TransmitterPayeeInfo) + + return out0, err + +} + +func (_IAutomationRegistryMaster23 *IAutomationRegistryMaster23Session) GetTransmittersWithPayees() ([]AutomationRegistryBase23TransmitterPayeeInfo, error) { + return _IAutomationRegistryMaster23.Contract.GetTransmittersWithPayees(&_IAutomationRegistryMaster23.CallOpts) +} + +func (_IAutomationRegistryMaster23 *IAutomationRegistryMaster23CallerSession) GetTransmittersWithPayees() ([]AutomationRegistryBase23TransmitterPayeeInfo, error) { + return _IAutomationRegistryMaster23.Contract.GetTransmittersWithPayees(&_IAutomationRegistryMaster23.CallOpts) +} + func (_IAutomationRegistryMaster23 *IAutomationRegistryMaster23Caller) GetTriggerType(opts *bind.CallOpts, upkeepId *big.Int) (uint8, error) { var out []interface{} err := _IAutomationRegistryMaster23.contract.Call(opts, &out, "getTriggerType", upkeepId) @@ -7239,6 +7310,10 @@ type IAutomationRegistryMaster23Interface interface { GetBalance(opts *bind.CallOpts, id *big.Int) (*big.Int, error) + GetBillingConfig(opts *bind.CallOpts, billingToken common.Address) (AutomationRegistryBase23BillingConfig, error) + + GetBillingOverrides(opts *bind.CallOpts, upkeepID *big.Int) (AutomationRegistryBase23BillingOverrides, error) + GetBillingToken(opts *bind.CallOpts, upkeepID *big.Int) (common.Address, error) GetBillingTokenConfig(opts *bind.CallOpts, token common.Address) (AutomationRegistryBase23BillingConfig, error) @@ -7307,6 +7382,8 @@ type IAutomationRegistryMaster23Interface interface { error) + GetTransmittersWithPayees(opts *bind.CallOpts) ([]AutomationRegistryBase23TransmitterPayeeInfo, error) + GetTriggerType(opts *bind.CallOpts, upkeepId *big.Int) (uint8, error) GetUpkeep(opts *bind.CallOpts, id *big.Int) (IAutomationV21PlusCommonUpkeepInfoLegacy, error) diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 6af70fd8f03..461b083fbfb 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -31,7 +31,7 @@ dummy_protocol_wrapper: ../../contracts/solc/v0.8.16/DummyProtocol/DummyProtocol gas_wrapper: ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.abi ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.bin 4a5dcdac486d18fcd58e3488c15c1710ae76b977556a3f3191bd269a4bc75723 gas_wrapper_mock: ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.abi ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.bin a9b08f18da59125c6fc305855710241f3d35161b8b9f3e3f635a7b1d5c6da9c8 i_automation_registry_master_wrapper_2_2: ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.bin 9ff7087179f89f9b05964ebc3e71332fce11f1b8e85058f7b16b3bc0dd6fb96b -i_automation_registry_master_wrapper_2_3: ../../contracts/solc/v0.8.19/IAutomationRegistryMaster2_3/IAutomationRegistryMaster2_3.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster2_3/IAutomationRegistryMaster2_3.bin fbfa3f5d78a357ecb7a1bc597c629ff30d42fedc48ba7f57e1622a6302d36523 +i_automation_registry_master_wrapper_2_3: ../../contracts/solc/v0.8.19/IAutomationRegistryMaster2_3/IAutomationRegistryMaster2_3.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster2_3/IAutomationRegistryMaster2_3.bin 19f51996d05341f1229f21be26b5d72ff58e321f0b6da69c260f768e4622ae8e i_automation_v21_plus_common: ../../contracts/solc/v0.8.19/IAutomationV21PlusCommon/IAutomationV21PlusCommon.abi ../../contracts/solc/v0.8.19/IAutomationV21PlusCommon/IAutomationV21PlusCommon.bin e8a601ec382c0a2e83c49759de13b0622b5e04e6b95901e96a1e9504329e594c i_chain_module: ../../contracts/solc/v0.8.19/IChainModule/IChainModule.abi ../../contracts/solc/v0.8.19/IChainModule/IChainModule.bin 383611981c86c70522f41b8750719faacc7d7933a22849d5004799ebef3371fa i_keeper_registry_master_wrapper_2_1: ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.abi ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.bin ee0f150b3afbab2df3d24ff3f4c87851efa635da30db04cd1f70cb4e185a1781 From 7ec1d5b7abb51e100f7a6a48662e33703a589ecb Mon Sep 17 00:00:00 2001 From: Lei Date: Wed, 24 Apr 2024 16:46:16 -0700 Subject: [PATCH 27/77] update reserve amount of LINK after offchain settlement (#12916) --- .changeset/witty-icons-rhyme.md | 5 +++++ contracts/.changeset/poor-panthers-build.md | 5 +++++ .../v0.8/automation/dev/test/AutomationRegistry2_3.t.sol | 6 ++++++ .../automation/dev/v2_3/AutomationRegistryLogicC2_3.sol | 7 +++++++ 4 files changed, 23 insertions(+) create mode 100644 .changeset/witty-icons-rhyme.md create mode 100644 contracts/.changeset/poor-panthers-build.md diff --git a/.changeset/witty-icons-rhyme.md b/.changeset/witty-icons-rhyme.md new file mode 100644 index 00000000000..25d9cf3b1d3 --- /dev/null +++ b/.changeset/witty-icons-rhyme.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +offchain settlement fix #bugfix diff --git a/contracts/.changeset/poor-panthers-build.md b/contracts/.changeset/poor-panthers-build.md new file mode 100644 index 00000000000..2c21cae5d7a --- /dev/null +++ b/contracts/.changeset/poor-panthers-build.md @@ -0,0 +1,5 @@ +--- +"@chainlink/contracts": patch +--- + +Offchain settlement fix #bugfix diff --git a/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol b/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol index 3e7e489379e..03138696436 100644 --- a/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol +++ b/contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol @@ -940,6 +940,9 @@ contract NOPsSettlement is SetUp { assertEq(i, index); assertEq(0, balance); } + + // after the offchain settlement, the total reserve amount of LINK should be 0 + assertEq(registry.getReserveAmount(address(linkToken)), 0); } function testSettleNOPsOffchainForDeactivatedTransmittersSuccess() public { @@ -1035,6 +1038,9 @@ contract NOPsSettlement is SetUp { assertEq(i, index); assertEq(0, balance); } + + // after the offchain settlement, the total reserve amount of LINK should be 0 + assertEq(registry.getReserveAmount(address(linkToken)), 0); } function testDisableOffchainPaymentsRevertDueToUnauthorizedCaller() public { diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicC2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicC2_3.sol index 92a9ca1a648..4048227f111 100644 --- a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicC2_3.sol +++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicC2_3.sol @@ -166,6 +166,7 @@ contract AutomationRegistryLogicC2_3 is AutomationRegistryBase2_3 { uint256 length = activeTransmittersLength + deactivatedTransmittersLength; uint256[] memory payments = new uint256[](length); address[] memory payees = new address[](length); + for (uint256 i = 0; i < activeTransmittersLength; i++) { address transmitterAddr = s_transmittersList[i]; uint96 balance = _updateTransmitterBalanceFromPool( @@ -173,18 +174,24 @@ contract AutomationRegistryLogicC2_3 is AutomationRegistryBase2_3 { s_hotVars.totalPremium, uint96(activeTransmittersLength) ); + payments[i] = balance; payees[i] = s_transmitterPayees[transmitterAddr]; s_transmitters[transmitterAddr].balance = 0; } + for (uint256 i = 0; i < deactivatedTransmittersLength; i++) { address deactivatedAddr = s_deactivatedTransmitters.at(i); Transmitter memory transmitter = s_transmitters[deactivatedAddr]; + payees[i + activeTransmittersLength] = s_transmitterPayees[deactivatedAddr]; payments[i + activeTransmittersLength] = transmitter.balance; s_transmitters[deactivatedAddr].balance = 0; } + // reserve amount of LINK is reset to 0 since no user deposits of LINK are expected in offchain mode + s_reserveAmounts[IERC20(address(i_link))] = 0; + for (uint256 idx = s_deactivatedTransmitters.length(); idx > 0; idx--) { s_deactivatedTransmitters.remove(s_deactivatedTransmitters.at(idx - 1)); } From b65f2e09602f4a85e6d968193cf31eb4105949c0 Mon Sep 17 00:00:00 2001 From: Radek Scheibinger Date: Thu, 25 Apr 2024 10:54:07 +0200 Subject: [PATCH 28/77] Cleanup chainlink-cluster chart (#12950) * Cleanup chainlink-cluster chart CRIB chainlink-cluster chart has moved to internal repo. Deleting chart and integrating devspace config with internal repo via required ENV variable CHAINLINK_CLUSTER_HELM_CHART_URI * Delete helm related workflows and helm lint configs * fix reference to the go code which is now under crib directory * login to helm registry --- .ct.yml | 10 - .github/workflows/helm-chart-publish.yml | 41 -- .github/workflows/helm-chart.yml | 37 -- .gitignore | 1 - GNUmakefile | 4 +- charts/chainlink-cluster/.gitignore | 7 - charts/chainlink-cluster/.helmignore | 25 - charts/chainlink-cluster/Chart.lock | 15 - charts/chainlink-cluster/Chart.yaml | 22 - charts/chainlink-cluster/README.md | 174 ------- .../templates/chainlink-cm.yaml | 77 --- .../templates/chainlink-db-deployment.yaml | 154 ------ .../templates/chainlink-db-networkpolicy.yaml | 21 - .../templates/chainlink-db-service.yaml | 18 - .../templates/chainlink-node-deployment.yaml | 130 ------ .../chainlink-node-networkpolicy.yaml | 18 - .../templates/chainlink-node-service.yaml | 20 - .../templates/chainlink-pod-monitor.yaml | 18 - .../templates/chainlink-secret.yaml | 14 - .../templates/geth-config-map.yaml | 155 ------- .../templates/geth-deployment.yaml | 130 ------ .../templates/geth-networkpolicy.yaml | 25 - .../templates/geth-service.yaml | 21 - .../chainlink-cluster/templates/ingress.yaml | 43 -- .../templates/mockserver-networkpolicy.yaml | 21 - .../templates/networkpolicy-default.yaml | 43 -- .../templates/tests/test-connection.yaml | 15 - charts/chainlink-cluster/values.yaml | 439 ------------------ crib/.env.example | 4 + crib/devspace.yaml | 4 +- crib/scripts/check_env_vars.sh | 1 + crib/setup.sh | 27 +- .../values-profiles/README.md | 0 .../values-profiles/values-dev.yaml.example | 0 lintconf.yaml | 46 -- 35 files changed, 33 insertions(+), 1747 deletions(-) delete mode 100644 .ct.yml delete mode 100644 .github/workflows/helm-chart-publish.yml delete mode 100644 .github/workflows/helm-chart.yml delete mode 100644 charts/chainlink-cluster/.gitignore delete mode 100644 charts/chainlink-cluster/.helmignore delete mode 100644 charts/chainlink-cluster/Chart.lock delete mode 100644 charts/chainlink-cluster/Chart.yaml delete mode 100644 charts/chainlink-cluster/README.md delete mode 100644 charts/chainlink-cluster/templates/chainlink-cm.yaml delete mode 100644 charts/chainlink-cluster/templates/chainlink-db-deployment.yaml delete mode 100644 charts/chainlink-cluster/templates/chainlink-db-networkpolicy.yaml delete mode 100644 charts/chainlink-cluster/templates/chainlink-db-service.yaml delete mode 100644 charts/chainlink-cluster/templates/chainlink-node-deployment.yaml delete mode 100644 charts/chainlink-cluster/templates/chainlink-node-networkpolicy.yaml delete mode 100644 charts/chainlink-cluster/templates/chainlink-node-service.yaml delete mode 100644 charts/chainlink-cluster/templates/chainlink-pod-monitor.yaml delete mode 100644 charts/chainlink-cluster/templates/chainlink-secret.yaml delete mode 100644 charts/chainlink-cluster/templates/geth-config-map.yaml delete mode 100644 charts/chainlink-cluster/templates/geth-deployment.yaml delete mode 100644 charts/chainlink-cluster/templates/geth-networkpolicy.yaml delete mode 100644 charts/chainlink-cluster/templates/geth-service.yaml delete mode 100644 charts/chainlink-cluster/templates/ingress.yaml delete mode 100644 charts/chainlink-cluster/templates/mockserver-networkpolicy.yaml delete mode 100644 charts/chainlink-cluster/templates/networkpolicy-default.yaml delete mode 100644 charts/chainlink-cluster/templates/tests/test-connection.yaml delete mode 100644 charts/chainlink-cluster/values.yaml rename {charts/chainlink-cluster => crib}/values-profiles/README.md (100%) rename {charts/chainlink-cluster => crib}/values-profiles/values-dev.yaml.example (100%) delete mode 100644 lintconf.yaml diff --git a/.ct.yml b/.ct.yml deleted file mode 100644 index 18a6afe861d..00000000000 --- a/.ct.yml +++ /dev/null @@ -1,10 +0,0 @@ -# See: https://github.com/helm/chart-testing -target-branch: develop -chart-dirs: 'charts' -check-version-increment: false -validate-maintainers: false -charts-repos: - - mockserver=https://www.mock-server.com - - opentelemetry-collector=https://open-telemetry.github.io/opentelemetry-helm-charts - - tempo=https://grafana.github.io/helm-charts - - grafana=https://grafana.github.io/helm-charts diff --git a/.github/workflows/helm-chart-publish.yml b/.github/workflows/helm-chart-publish.yml deleted file mode 100644 index 927ed4b0166..00000000000 --- a/.github/workflows/helm-chart-publish.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: Helm Publish - -on: - workflow_dispatch: - -jobs: - helm_release: - runs-on: ubuntu-latest - environment: build-develop - permissions: - id-token: write - contents: read - steps: - - name: Checkout repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - - - name: Configure aws credentials - uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 - with: - role-to-assume: ${{ secrets.AWS_ROLE_ARN_GATI }} - role-duration-seconds: ${{ secrets.AWS_ROLE_DURATION_SECONDS }} - aws-region: ${{ secrets.AWS_REGION }} - mask-aws-account-id: true - role-session-name: helm-publish.helm-release - - - name: Get Github Token - id: get-gh-token - uses: smartcontractkit/chainlink-github-actions/github-app-token-issuer@5874ff7211cf5a5a2670bb010fbff914eaaae138 # v2.3.12 - with: - url: ${{ secrets.GATI_LAMBDA_FUNCTION_URL }} - - - name: Install Helm - uses: azure/setup-helm@b7246b12e77f7134dc2d460a3d5bad15bbe29390 # v4.1.0 - - - name: Run chart-releaser - uses: helm/chart-releaser-action@a917fd15b20e8b64b94d9158ad54cd6345335584 # v1.6.0 - with: - charts_dir: charts - config: .github/cr.yaml - env: - CR_TOKEN: "${{ steps.get-gh-token.outputs.access-token }}" diff --git a/.github/workflows/helm-chart.yml b/.github/workflows/helm-chart.yml deleted file mode 100644 index f0dd25c5dbb..00000000000 --- a/.github/workflows/helm-chart.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Helm Chart - -on: - pull_request: - paths: - - "charts/**" - - ".github/workflows/helm-chart.yml" - -jobs: - ci-lint-helm-charts: - runs-on: ubuntu-latest - steps: - - name: ci-lint-helm-charts - uses: smartcontractkit/.github/actions/ci-lint-charts@7fa39741b11e66ed59f8aad786d4b9356c389f3f # ci-lint-charts@0.2.0 - with: - # chart testing inputs - chart-testing-extra-args: "--lint-conf=lintconf.yaml" - charts-dir: charts/chainlink-cluster - # grafana inputs - metrics-job-name: ci-lint-helm-charts - gc-basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - gc-host: ${{ secrets.GRAFANA_INTERNAL_HOST }} - gc-org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - - ci-kubeconform: - runs-on: ubuntu-latest - steps: - - name: ci-kubeconform - uses: smartcontractkit/.github/actions/ci-kubeconform@1ae8a9a984814c4daf50aa96f03be2cba0ef3fec # ci-kubeconform@0.2.0 - with: - # kubeform inputs - charts-dir: charts/chainlink-cluster - # grafana inputs - metrics-job-name: ci-kubeconform - gc-basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - gc-host: ${{ secrets.GRAFANA_INTERNAL_HOST }} - gc-org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} diff --git a/.gitignore b/.gitignore index b286c329292..ca388c85c2b 100644 --- a/.gitignore +++ b/.gitignore @@ -24,7 +24,6 @@ tools/clroot/db.sqlite3-wal .envrc .env* .dbenv -!charts/chainlink-cluster/.env.example !crib/.env.example !.github/actions/setup-postgres/.env .direnv diff --git a/GNUmakefile b/GNUmakefile index 524786585e9..48e15e39fb4 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -33,7 +33,7 @@ gomodtidy: ## Run go mod tidy on all modules. cd ./integration-tests && go mod tidy cd ./integration-tests/load && go mod tidy cd ./dashboard-lib && go mod tidy - cd ./charts/chainlink-cluster && go mod tidy + cd ./crib && go mod tidy .PHONY: docs docs: ## Install and run pkgsite to view Go docs @@ -96,7 +96,7 @@ generate: abigen codecgen mockery protoc ## Execute all go:generate commands. cd ./integration-tests && go generate -x ./... cd ./integration-tests/load && go generate -x ./... cd ./dashboard-lib && go generate -x ./... - cd ./charts/chainlink-cluster && go generate -x ./... + cd ./crib && go generate -x ./... .PHONY: testscripts testscripts: chainlink-test ## Install and run testscript against testdata/scripts/* files. diff --git a/charts/chainlink-cluster/.gitignore b/charts/chainlink-cluster/.gitignore deleted file mode 100644 index 9e704020530..00000000000 --- a/charts/chainlink-cluster/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -# Helm -charts/ -requirements.lock -.rendered -values-profiles/* -!values-profiles/values-dev.yaml.example -!values-profiles/README.md \ No newline at end of file diff --git a/charts/chainlink-cluster/.helmignore b/charts/chainlink-cluster/.helmignore deleted file mode 100644 index b88381301b2..00000000000 --- a/charts/chainlink-cluster/.helmignore +++ /dev/null @@ -1,25 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*.orig -*~ -# Various IDEs -.project -.idea/ -*.tmproj -.vscode/ -.devspace/ -scripts/ diff --git a/charts/chainlink-cluster/Chart.lock b/charts/chainlink-cluster/Chart.lock deleted file mode 100644 index 11ebdfdf691..00000000000 --- a/charts/chainlink-cluster/Chart.lock +++ /dev/null @@ -1,15 +0,0 @@ -dependencies: -- name: mockserver - repository: https://www.mock-server.com - version: 5.14.0 -- name: opentelemetry-collector - repository: https://open-telemetry.github.io/opentelemetry-helm-charts - version: 0.82.0 -- name: tempo - repository: https://grafana.github.io/helm-charts - version: 1.7.2 -- name: grafana - repository: https://grafana.github.io/helm-charts - version: 7.3.2 -digest: sha256:37722063f68689c42ac1d6549ddfae4756370c1659b8ac1c0d7da8916c6fad3d -generated: "2024-04-23T17:49:50.347667-04:00" diff --git a/charts/chainlink-cluster/Chart.yaml b/charts/chainlink-cluster/Chart.yaml deleted file mode 100644 index d8d3dd98b22..00000000000 --- a/charts/chainlink-cluster/Chart.yaml +++ /dev/null @@ -1,22 +0,0 @@ -apiVersion: v2 -name: chainlink-cluster -description: Chainlink nodes cluster -version: 0.4.2 -appVersion: "2.6.0" -dependencies: - - name: mockserver - version: "5.14.0" - repository: "https://www.mock-server.com" - condition: mockserver.enabled - - name: opentelemetry-collector - version: "0.82.0" - repository: "https://open-telemetry.github.io/opentelemetry-helm-charts" - condition: opentelemetry-collector.enabled - - name: tempo - version: "1.7.2" - repository: "https://grafana.github.io/helm-charts" - condition: tempo.enabled - - name: grafana - version: "7.3.2" - repository: "https://grafana.github.io/helm-charts" - condition: grafana.enabled diff --git a/charts/chainlink-cluster/README.md b/charts/chainlink-cluster/README.md deleted file mode 100644 index 403ab9b876a..00000000000 --- a/charts/chainlink-cluster/README.md +++ /dev/null @@ -1,174 +0,0 @@ -# Chainlink cluster - -Example CL nodes cluster for system level tests -Install `kubefwd` (no nixpkg for it yet, planned) - -```sh -brew install txn2/tap/kubefwd -``` - -If you want to build images you need [docker](https://docs.docker.com/engine/install/) service running - -Enter the shell (from the root project dir) - -```sh -nix develop -``` - -# Develop - -## New cluster - -We are using [devspace](https://www.devspace.sh/docs/getting-started/installation?x0=3) - -Configure the cluster, see `deployments.app.helm.values` and [values.yaml](./values.yaml) comments for more details - -Set up your K8s access - -```sh -export DEVSPACE_IMAGE="..." -./setup.sh ${my-personal-namespace-name-crib} -``` - -Create a .env file based on the .env.sample file - -```sh -cp .env.sample .env -# Fill in the required values in .env -``` - -Build and deploy the current state of your repository - -```sh -devspace deploy -``` - -Default `ttl` is `72h`, use `ttl` command to update if you need more time - -Valid values are `1h`, `2m`, `3s`, etc. Go time format is invalid `1h2m3s` - -```sh -devspace run ttl ${namespace} 120h -``` - -If you want to deploy an image tag that is already available in ECR, use: - -```sh -devspace deploy --override-image-tag "" -``` - -If you want to deploy an image tag from a public ECR repo, use: - -```sh -export DEVSPACE_IMAGE=public.ecr.aws/chainlink/chainlink -devspace deploy --override-image-tag 2.9.0 -``` - -To apply custom TOML configuration specific for your nodes, create a `values-dev.yaml` file in the `./values-profiles` directory. Start by copying the example file: - -```sh -cp values-profiles/values-dev.yaml.example values-profiles/values-dev.yaml - -``` - -Then customize the values-dev.yaml file as needed. To use this configuration during deployment, pass the --profile local-dev flag: - -```sh -devspace deploy --profile local-dev -``` - -Forward ports to check UI or run tests - -```sh -devspace run connect ${my-personal-namespace-name-crib} -``` - -List ingress hostnames - -```sh -devspace run ingress-hosts -``` - -Destroy the cluster - -```sh -devspace purge -``` - -## Running load tests - -Check this [doc](../../integration-tests/load/ocr/README.md) - -If you used `devspace dev ...` always use `devspace reset pods` to switch the pods back - -# Helm - -If you would like to use `helm` directly, please uncomment data in `values.yaml` - -## Install from local files - -```sh -helm install -f values.yaml cl-cluster . -``` - -Forward all apps (in another terminal) - -```sh -sudo kubefwd svc -n cl-cluster -``` - -Then you can connect and run your tests - -## Install from release - -Add the repository - -```sh -helm repo add chainlink-cluster https://raw.githubusercontent.com/smartcontractkit/chainlink/helm-release/ -helm repo update -``` - -Set default namespace - -```sh -kubectl create ns cl-cluster -kubectl config set-context --current --namespace cl-cluster -``` - -## Create a new release - -Bump version in `Chart.yml` add your changes and add `helm_release` label to any PR to trigger a release - -## Helm Test - -```sh -helm test cl-cluster -``` - -## Uninstall - -```sh -helm uninstall cl-cluster -``` - -# Grafana dashboard - -We are using [Grabana](https://github.com/K-Phoen/grabana) lib to create dashboards programmatically - -You can also select dashboard platform in `INFRA_PLATFORM` either `kubernetes` or `docker` - -```sh -export LOKI_TENANT_ID=promtail -export LOKI_URL=... -export GRAFANA_URL=... -export GRAFANA_TOKEN=... -export PROMETHEUS_DATA_SOURCE_NAME=Thanos -export LOKI_DATA_SOURCE_NAME=Loki -export INFRA_PLATFORM=kubernetes -export GRAFANA_FOLDER=CRIB -export DASHBOARD_NAME=Core-Cluster-Load - -devspace run dashboard_deploy -``` - -Open Grafana folder `DashboardCoreDebug` and find dashboard `ChainlinkClusterDebug` diff --git a/charts/chainlink-cluster/templates/chainlink-cm.yaml b/charts/chainlink-cluster/templates/chainlink-cm.yaml deleted file mode 100644 index bd0c911331c..00000000000 --- a/charts/chainlink-cluster/templates/chainlink-cm.yaml +++ /dev/null @@ -1,77 +0,0 @@ -{{- if .Values.chainlink.enabled }} -{{- range $cfg := .Values.chainlink.nodes }} -apiVersion: v1 -kind: ConfigMap -metadata: - labels: - app: {{ $.Release.Name }}-{{ $cfg.name }}-cm - release: {{ $.Release.Name }} - name: {{ $.Release.Name }}-{{ $cfg.name }}-cm -data: - apicredentials: | - notreal@fakeemail.ch - fj293fbBnlQ!f9vNs - node-password: T.tLHkcmwePT/p,]sYuntjwHKAsrhm#4eRs4LuKHwvHejWYAC2JP4M8HimwgmbaZ - init.sql: | - CREATE - EXTENSION pg_stat_statements; - default.toml: | - {{- if (hasKey $cfg "toml") }} - {{ $cfg.toml | nindent 4 }} - {{- else if and (hasKey $.Values.chainlink.global "toml") $.Values.chainlink.global.toml }} - {{ $.Values.chainlink.global.toml | nindent 4 }} - {{- else }} - RootDir = './clroot' - [Log] - JSONConsole = true - Level = 'debug' - [WebServer] - AllowOrigins = '*' - SecureCookies = false - SessionTimeout = '999h0m0s' - [Feature] - FeedsManager = true - LogPoller = true - UICSAKeys = true - [OCR] - Enabled = true - DefaultTransactionQueueDepth = 0 - [P2P] - [P2P.V2] - Enabled = true - ListenAddresses = ['0.0.0.0:6690'] - AnnounceAddresses = ['0.0.0.0:6690'] - DeltaDial = '500ms' - DeltaReconcile = '5s' - {{- range $chainCfg := $.Values.geth.chains }} - [[EVM]] - ChainID = {{ $chainCfg.networkId | quote }} - MinContractPayment = '0' - AutoCreateKey = true - FinalityDepth = 1 - {{- if (hasKey $chainCfg "customEVMConfigToml") }} - {{- $chainCfg.customEVMConfigToml | nindent 4 }} - {{- end }} - [[EVM.Nodes]] - Name = 'node-{{ $chainCfg.networkId }}' - WSURL = 'ws://geth-{{ $chainCfg.networkId }}:8546' - HTTPURL = 'http://geth-{{ $chainCfg.networkId }}:8544' - {{- end }} - [WebServer.TLS] - HTTPSPort = 0 - {{- end }} - overrides.toml: | - {{- if (hasKey $cfg "overridesToml") }} - {{- $cfg.overridesToml | nindent 4 }} - {{- else if and (hasKey $.Values.chainlink.global "overridesToml") $.Values.chainlink.global.overridesToml }} - {{- $.Values.chainlink.global.overridesToml | nindent 4 }} - {{ else }} - {{- end }} - secrets.toml: | - {{ if (hasKey $cfg "secretsToml") }} - {{ $cfg.secretsToml | nindent 4 }} - {{ else }} - {{ end }} ---- -{{- end }} -{{- end }} diff --git a/charts/chainlink-cluster/templates/chainlink-db-deployment.yaml b/charts/chainlink-cluster/templates/chainlink-db-deployment.yaml deleted file mode 100644 index 0ca7c4afd71..00000000000 --- a/charts/chainlink-cluster/templates/chainlink-db-deployment.yaml +++ /dev/null @@ -1,154 +0,0 @@ -{{- if .Values.db.enabled }} -{{- range $cfg := .Values.chainlink.nodes }} -apiVersion: apps/v1 -{{ if $.Values.db.stateful }} -kind: StatefulSet -{{ else }} -kind: Deployment -{{ end }} -metadata: - name: {{ $.Release.Name }}-{{ $cfg.name }}-db - labels: - app: {{ $.Release.Name }}-db - instance: {{ $cfg.name }}-db - release: {{ $.Release.Name }} -spec: - {{ if $.Values.db.stateful }} - serviceName: {{ $.Release.Name }}-db-${{ $cfg.name }} - podManagementPolicy: Parallel - volumeClaimTemplates: - - metadata: - name: postgres - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: {{ .Values.db.capacity }} - {{ end }} - selector: - matchLabels: - app: {{ $.Release.Name }}-db - # Used for testing. - # havoc-component-group and havoc-network-group are used by "havoc" chaos testing tool - havoc-component-group: db - havoc-network-group: db - instance: {{ $cfg.name }}-db - release: {{ $.Release.Name }} - template: - metadata: - labels: - app: {{ $.Release.Name }}-db - # Used for testing. - # havoc-component-group and havoc-network-group are used by "havoc" chaos testing tool - havoc-component-group: db - havoc-network-group: db - instance: {{ $cfg.name }}-db - release: {{ $.Release.Name }} - {{- range $key, $value := $.Values.labels }} - {{ $key }}: {{ $value | quote }} - {{- end }} - annotations: - prometheus.io/scrape: 'true' - app.kubernetes.io/managed-by: "Helm" - meta.helm.sh/release-namespace: "{{ $.Release.Namespace }}" - {{- range $key, $value := $.Values.podAnnotations }} - {{ $key }}: {{ $value | quote }} - {{- end }} - spec: - volumes: - # TODO: breakout this config map into a separate one for the db. - - name: {{ $.Release.Name }}-{{ $cfg.name }}-cm - configMap: - name: {{ $.Release.Name }}-{{ $cfg.name }}-cm - securityContext: - {{- toYaml $.Values.db.podSecurityContext | nindent 8 }} - containers: - - name: chainlink-db - securityContext: - {{- toYaml $.Values.db.securityContext | nindent 12 }} - image: {{ default "postgres:11.15" $.Values.db.image }} - command: - - docker-entrypoint.sh - args: - - "-c" - - "shared_preload_libraries=pg_stat_statements" - - "-c" - - "pg_stat_statements.track=all" - ports: - - name: postgres - containerPort: 5432 - env: - - name: POSTGRES_DB - value: chainlink - - name: POSTGRES_PASSWORD - value: verylongdatabasepassword - - name: PGPASSWORD - value: verylongdatabasepassword - - name: PGUSER - value: postgres - lifecycle: - preStop: - exec: - command: [ "/bin/sh", "-c", "while $(psql -d chainlink -c \"SELECT COUNT(*) FROM pg_stat_activity WHERE datname = 'chainlink' AND state = 'active';\" -tA ); echo \"waiting for connection to become 0\"; sleep 10; fi; done" ] - livenessProbe: - exec: - command: - - pg_isready - - -U - - postgres - initialDelaySeconds: 1 - periodSeconds: 5 - timeoutSeconds: 10 - readinessProbe: - exec: - command: - - pg_isready - - -U - - postgres - initialDelaySeconds: 1 - periodSeconds: 5 - timeoutSeconds: 10 - startupProbe: - exec: - command: - - pg_isready - - -U - - postgres - initialDelaySeconds: 15 - periodSeconds: 5 - failureThreshold: 20 - {{ if (hasKey $.Values.db "resources") }} - resources: - requests: - memory: {{ default "256Mi" $.Values.db.resources.requests.memory }} - cpu: {{ default "250m" $.Values.db.resources.requests.cpu }} - limits: - memory: {{ default "256Mi" $.Values.db.resources.limits.memory }} - cpu: {{ default "250m" $.Values.db.resources.limits.cpu }} - {{ else }} - {{ end }} - volumeMounts: - - mountPath: /docker-entrypoint-initdb.d/init.sql - name: {{ $.Release.Name }}-{{ $cfg.name }}-cm - subPath: init.sql - {{ if $.Values.db.stateful }} - - mountPath: /var/lib/postgresql/data - name: postgres - subPath: postgres-db - {{ end }} -{{- with $.Values.nodeSelector }} - nodeSelector: - {{ toYaml . | indent 8 }} -{{- end }} -{{- with $.Values.affinity }} - affinity: - {{ toYaml . | indent 8 }} -{{- end }} -{{- with $.Values.tolerations }} - tolerations: -{{ toYaml . | indent 8 }} -{{- end }} ---- -{{- end }} -{{- end }} diff --git a/charts/chainlink-cluster/templates/chainlink-db-networkpolicy.yaml b/charts/chainlink-cluster/templates/chainlink-db-networkpolicy.yaml deleted file mode 100644 index 53664884f26..00000000000 --- a/charts/chainlink-cluster/templates/chainlink-db-networkpolicy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if and .Values.db.enabled .Values.networkPolicies.enabled }} -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: {{ $.Release.Name }}-db -spec: - podSelector: - matchLabels: - app: {{ $.Release.Name }}-db - policyTypes: - - Ingress - ingress: - - from: - # Allow all node pods to access the database pods. - - podSelector: - matchLabels: - app: {{ $.Release.Name }} - ports: - - protocol: TCP - port: 5432 -{{- end }} diff --git a/charts/chainlink-cluster/templates/chainlink-db-service.yaml b/charts/chainlink-cluster/templates/chainlink-db-service.yaml deleted file mode 100644 index 5ed7d0ca4dd..00000000000 --- a/charts/chainlink-cluster/templates/chainlink-db-service.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if .Values.db.enabled }} -{{- range $cfg := .Values.chainlink.nodes }} -apiVersion: v1 -kind: Service -metadata: - name: {{ $.Release.Name }}-db-{{ $cfg.name }} -spec: - selector: - app: {{ $.Release.Name }}-db - instance: {{ $cfg.name }}-db - release: {{ $.Release.Name }} - ports: - - protocol: TCP - port: 5432 - targetPort: 5432 ---- -{{- end }} -{{- end }} diff --git a/charts/chainlink-cluster/templates/chainlink-node-deployment.yaml b/charts/chainlink-cluster/templates/chainlink-node-deployment.yaml deleted file mode 100644 index e91a400967a..00000000000 --- a/charts/chainlink-cluster/templates/chainlink-node-deployment.yaml +++ /dev/null @@ -1,130 +0,0 @@ -{{- if .Values.chainlink.enabled }} -{{- range $index, $cfg := .Values.chainlink.nodes }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ if eq $index 0 }}{{ $.Release.Name }}-{{ $cfg.name }}-bootstrap{{ else }}{{ $.Release.Name }}-{{ $cfg.name }}{{ end }} - labels: - app: {{ $.Release.Name }} - instance: {{ $cfg.name }} - release: {{ $.Release.Name }} - {{- range $key, $value := $.Values.labels }} - {{ $key }}: {{ $value | quote }} - {{- end }} -spec: - strategy: - # Need to recreate the pod to deal with lease lock held by old pod. - type: Recreate - selector: - matchLabels: - app: {{ $.Release.Name }} - # Used for testing. - # havoc-component-group and havoc-network-group are used by "havoc" chaos testing tool - {{ if eq $index 0 }}{{ else }} - havoc-component-group: node - {{ end }} - {{ if eq $index 0 }}{{ else }} - havoc-network-group: {{ if gt $index 2 }}"1"{{ else }}"2"{{ end }} - {{ end }} - instance: {{ $cfg.name }} - release: {{ $.Release.Name }} - template: - metadata: - labels: - app: {{ $.Release.Name }} - # Used for testing. - # havoc-component-group and havoc-network-group are used by "havoc" chaos testing tool - {{ if eq $index 0 }}{{ else }} - havoc-component-group: node - {{ end }} - {{ if eq $index 0 }}{{ else }} - havoc-network-group: {{ if gt $index 2 }}"1"{{ else }}"2"{{ end }} - {{ end }} - - instance: {{ $cfg.name }} - release: {{ $.Release.Name }} - {{- range $key, $value := $.Values.labels }} - {{ $key }}: {{ $value | quote }} - {{- end }} - annotations: - prometheus.io/scrape: 'true' - {{- range $key, $value := $.Values.podAnnotations }} - {{ $key }}: {{ $value | quote }} - {{- end }} - spec: - volumes: - - name: {{ $.Release.Name }}-{{ $cfg.name }}-cm - configMap: - name: {{ $.Release.Name }}-{{ $cfg.name }}-cm - securityContext: - {{- toYaml $.Values.chainlink.podSecurityContext | nindent 8 }} - containers: - - name: node - securityContext: - {{- toYaml $.Values.chainlink.securityContext | nindent 12 }} - image: {{ default "public.ecr.aws/chainlink/chainlink" $cfg.image }} - imagePullPolicy: Always - command: [ "bash", "-c", "while ! pg_isready -U postgres --host {{ $.Release.Name }}-db-{{ $cfg.name }} --port 5432; do echo \"waiting for database to start\"; sleep 1; done && chainlink -c /etc/node-secrets-volume/default.toml -c /etc/node-secrets-volume/overrides.toml -secrets /etc/node-secrets-volume/secrets.toml node start -d -p /etc/node-secrets-volume/node-password -a /etc/node-secrets-volume/apicredentials --vrfpassword=/etc/node-secrets-volume/apicredentials" ] - ports: - - name: access - containerPort: {{ $.Values.chainlink.web_port }} - - name: p2p - containerPort: {{ $.Values.chainlink.p2p_port }} - env: - - name: CL_DATABASE_URL - value: postgresql://postgres:verylongdatabasepassword@{{ $.Release.Name }}-db-{{ $cfg.name }}/chainlink?sslmode=disable - - name: CL_DEV - value: "false" - {{- range $name, $value := $.Values.chainlink.extraEnvVars }} - - name: "{{ $name }}" - value: "{{ $value }}" - {{- end }} - volumeMounts: - - name: {{ $.Release.Name }}-{{ $cfg.name }}-cm - mountPath: /etc/node-secrets-volume/ - livenessProbe: - httpGet: - path: /health - port: {{ $.Values.chainlink.web_port }} - initialDelaySeconds: 1 - periodSeconds: 5 - timeoutSeconds: 10 - readinessProbe: - httpGet: - path: /health - port: {{ $.Values.chainlink.web_port }} - initialDelaySeconds: 1 - periodSeconds: 5 - timeoutSeconds: 10 - startupProbe: - httpGet: - path: / - port: {{ $.Values.chainlink.web_port }} - initialDelaySeconds: 15 - periodSeconds: 5 - failureThreshold: 20 - {{ if (hasKey $cfg "resources") }} - resources: - requests: - memory: {{ default "1024Mi" $cfg.resources.requests.memory }} - cpu: {{ default "300m" $cfg.resources.requests.cpu }} - limits: - memory: {{ default "1024Mi" $cfg.resources.limits.memory }} - cpu: {{ default "300m" $cfg.resources.limits.cpu }} - {{ else }} - {{ end }} -{{- with $.Values.nodeSelector }} - nodeSelector: - {{ toYaml . | indent 8 }} -{{- end }} -{{- with $.Values.affinity }} - affinity: - {{ toYaml . | indent 8 }} -{{- end }} -{{- with $.Values.tolerations }} - tolerations: -{{ toYaml . | indent 8 }} -{{- end }} ---- -{{- end }} -{{- end }} diff --git a/charts/chainlink-cluster/templates/chainlink-node-networkpolicy.yaml b/charts/chainlink-cluster/templates/chainlink-node-networkpolicy.yaml deleted file mode 100644 index 8f465288767..00000000000 --- a/charts/chainlink-cluster/templates/chainlink-node-networkpolicy.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if and .Values.chainlink.enabled .Values.networkPolicies.enabled }} -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: {{ $.Release.Name }}-node -spec: - podSelector: - matchLabels: - app: {{ $.Release.Name }} - policyTypes: - - Ingress - ingress: - # Allow all ingress traffic between the node pods. - - from: - - podSelector: - matchLabels: - app: {{ $.Release.Name }} -{{- end }} diff --git a/charts/chainlink-cluster/templates/chainlink-node-service.yaml b/charts/chainlink-cluster/templates/chainlink-node-service.yaml deleted file mode 100644 index 71b9ca498d2..00000000000 --- a/charts/chainlink-cluster/templates/chainlink-node-service.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if .Values.chainlink.enabled }} -{{- range $cfg := .Values.chainlink.nodes }} -apiVersion: v1 -kind: Service -metadata: - name: {{ $.Release.Name }}-{{ $cfg.name }} -spec: - ports: - - name: node-port - port: {{ $.Values.chainlink.web_port }} - targetPort: {{ $.Values.chainlink.web_port }} - - name: p2p-port - port: {{ $.Values.chainlink.p2p_port }} - targetPort: {{ $.Values.chainlink.p2p_port }} - selector: - instance: {{ $cfg.name }} - type: ClusterIP ---- -{{- end }} -{{- end }} diff --git a/charts/chainlink-cluster/templates/chainlink-pod-monitor.yaml b/charts/chainlink-cluster/templates/chainlink-pod-monitor.yaml deleted file mode 100644 index bb8c5d2b1a6..00000000000 --- a/charts/chainlink-cluster/templates/chainlink-pod-monitor.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if and .Values.chainlink.enabled .Values.prometheusMonitor }} -apiVersion: monitoring.coreos.com/v1 -kind: PodMonitor -metadata: - name: {{ $.Release.Name }}-pod-monitor - labels: - release: grafana-agent -spec: - namespaceSelector: - matchNames: - - {{ $.Release.Namespace }} - podMetricsEndpoints: - - port: access - selector: - matchLabels: - app: {{ $.Release.Name }} -{{- end }} ---- \ No newline at end of file diff --git a/charts/chainlink-cluster/templates/chainlink-secret.yaml b/charts/chainlink-cluster/templates/chainlink-secret.yaml deleted file mode 100644 index f0531b16511..00000000000 --- a/charts/chainlink-cluster/templates/chainlink-secret.yaml +++ /dev/null @@ -1,14 +0,0 @@ -{{- if .Values.chainlink.enabled }} -{{- range $cfg := .Values.chainlink.nodes }} -apiVersion: v1 -kind: Secret -metadata: - name: {{ $.Release.Name }}-{{ $cfg.name }}node-creds-secret -type: Opaque -data: - nodepassword: VC50TEhrY213ZVBUL3AsXXNZdW50andIS0FzcmhtIzRlUnM0THVLSHd2SGVqV1lBQzJKUDRNOEhpbXdnbWJhWgo= - apicredentials: bm90cmVhbEBmYWtlZW1haWwuY2hudHdvY2hhaW5zCg== - node-password: VC50TEhrY213ZVBUL3AsXXNZdW50andIS0FzcmhtIzRlUnM0THVLSHd2SGVqV1lBQzJKUDRNOEhpbXdnbWJhWgo= ---- -{{- end }} -{{- end }} diff --git a/charts/chainlink-cluster/templates/geth-config-map.yaml b/charts/chainlink-cluster/templates/geth-config-map.yaml deleted file mode 100644 index 6a5f4bacc0d..00000000000 --- a/charts/chainlink-cluster/templates/geth-config-map.yaml +++ /dev/null @@ -1,155 +0,0 @@ -{{ if and (hasKey .Values "geth") .Values.geth.enabled }} -{{- range $cfg := .Values.geth.chains }} -apiVersion: v1 -kind: ConfigMap -metadata: - labels: - app: geth-{{ $cfg.networkId }}-cm - release: {{ $.Release.Name }} - name: geth-{{ $cfg.networkId }}-cm -data: - key1: | - {"address":"f39fd6e51aad88f6f4ce6ab8827279cfffb92266","crypto":{"cipher":"aes-128-ctr","ciphertext":"c36afd6e60b82d6844530bd6ab44dbc3b85a53e826c3a7f6fc6a75ce38c1e4c6","cipherparams":{"iv":"f69d2bb8cd0cb6274535656553b61806"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"80d5f5e38ba175b6b89acfc8ea62a6f163970504af301292377ff7baafedab53"},"mac":"f2ecec2c4d05aacc10eba5235354c2fcc3776824f81ec6de98022f704efbf065"},"id":"e5c124e9-e280-4b10-a27b-d7f3e516b408","version":3} - key2: | - {"address":"70997970c51812dc3a010c7d01b50e0d17dc79c8","crypto":{"cipher":"aes-128-ctr","ciphertext":"f8183fa00bc112645d3e23e29a233e214f7c708bf49d72750c08af88ad76c980","cipherparams":{"iv":"796d08e3e1f71bde89ed826abda96cda"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"03c864a22a1f7b06b1da12d8b93e024ac144f898285907c58b2abc135fc8a35c"},"mac":"5fe91b1a1821c0d9f85dfd582354ead9612e9a7e9adc38b06a2beff558c119ac"},"id":"d2cab765-5e30-42ae-bb91-f090d9574fae","version":3} - key3: | - {"address":"3c44cdddb6a900fa2b585dd299e03d12fa4293bc","crypto":{"cipher":"aes-128-ctr","ciphertext":"2cd6ab87086c47f343f2c4d957eace7986f3b3c87fc35a2aafbefb57a06d9f1c","cipherparams":{"iv":"4e16b6cd580866c1aa642fb4d7312c9b"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"0cabde93877f6e9a59070f9992f7a01848618263124835c90d4d07a0041fc57c"},"mac":"94b7776ea95b0ecd8406c7755acf17b389b7ebe489a8942e32082dfdc1f04f57"},"id":"ade1484b-a3bb-426f-9223-a1f5e3bde2e8","version":3} - key4: | - {"address":"90f79bf6eb2c4f870365e785982e1f101e93b906","crypto":{"cipher":"aes-128-ctr","ciphertext":"15144214d323871e00f7b205368128061c91b77a27b7deec935f8f5b734f0d42","cipherparams":{"iv":"bb22ba8051ef9f60abded7a9f4f2c6ae"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"07331ef3035567c00830b4e50d5dd68bc877974b4ce38cd42fef755be01556c9"},"mac":"2294eacadaf2761851814451d8c7dcca20a606a0344335d98f09403aba4e82ca"},"id":"96af8cc7-97e1-4bba-8968-632b034986c2","version":3} - key5: | - {"address":"15d34aaf54267db7d7c367839aaf71a00a2c6a65","crypto":{"cipher":"aes-128-ctr","ciphertext":"057878284a6c74d3ad99910adddd6b477b383837dbf2280efea585f0f0fdb012","cipherparams":{"iv":"e6eab29d60b526f305f8d47badf48687"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"dfdca8066d2486da5cb9a909d03744e2a8c6537930271e85e7cd8a5d952c0f22"},"mac":"f8352be41c9a06d69111ca4d8fcff0eef079b68b1173cad99803538991716c5d"},"id":"a35bb452-0d57-42d5-8d25-5a00a40a4db8","version":3} - key6: | - {"address":"9965507d1a55bcc2695c58ba16fb37d819b0a4dc","crypto":{"cipher":"aes-128-ctr","ciphertext":"5a73201500307c6aa98edd44d962b344a893768331454a61595ec848e738e9d2","cipherparams":{"iv":"5282de2b3e2b305019a2fed5c62f3383"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"6ad001831d097f175fff7d6cf61301e9620b32afd9a7a6437e6030af14576a96"},"mac":"0a55eddbd13c713aa8b8c4106b2fb62bc1d1e18e7177207a444f83a4d8426ed5"},"id":"27aed2b2-cb94-4d37-8819-b15219187bb5","version":3} - key7: | - {"address":"976ea74026e726554db657fa54763abd0c3a0aa9","crypto":{"cipher":"aes-128-ctr","ciphertext":"a6edf11e81b38e60a549696236cb9efc026e87adc45a9521ea7b2c45a2a9fbb9","cipherparams":{"iv":"82f4c79cd4b28a8585a9c78d758f832b"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"87400e16ecc320dadff85eccbf4dbaaea2dd91e50047e4aa391799bb319c1fd8"},"mac":"80c83dad05998db6c673a97096fcfad54636458f4a3c82483686b253f8cc9b69"},"id":"fc7d7694-6206-48fc-bb25-36b523f90df6","version":3} - key8: | - {"address":"14dc79964da2c08b23698b3d3cc7ca32193d9955","crypto":{"cipher":"aes-128-ctr","ciphertext":"410f258bc8b12a0250cba22cbc5e413534fcf90bf322ced6943189ad9e43b4b9","cipherparams":{"iv":"1dd6077a8bee9b3bf2ca90e6abc8a237"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"5d3358bf99bbcb82354f40e5501abf4336bc141ee05d8feed4fbe7eb8c08c917"},"mac":"9cd959fa1e8129a8deb86e0264ec81d6cde79b5a19ae259b7d00543c9037908a"},"id":"689d7ad2-fe46-4c09-9c2a-a50e607989b8","version":3} - key9: | - {"address":"23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f","crypto":{"cipher":"aes-128-ctr","ciphertext":"13dccac740314edea20d44e6f3592575bbcb739ec5892d635326cff3c386eb86","cipherparams":{"iv":"bf42d811cd41fa97ddcae3425f8c3211"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"d2fa67cbb5e86d5bf9a90e27b8747bac493614b45778d43e9da1c14e06b2401d"},"mac":"7d2797cf344704d8f36265238d3938e06952c78ab7dfcbac53dc7f472c93d933"},"id":"4c8e899e-80f0-4417-9b1e-c5e29049f1e7","version":3} - key10: | - {"address":"a0ee7a142d267c1f36714e4a8f75612f20a79720","crypto":{"cipher":"aes-128-ctr","ciphertext":"56bc8766f47aeafae74eea333e1e890a3776d7fae6c48cbdbffb270655ce050d","cipherparams":{"iv":"a66129e6a110b3ddf93b4355aa147c58"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"15c4e8bcc80920139eb236d91194825f1fce27dd2af281e0f2752d8a5dbc48bd"},"mac":"db01e720866ce8bb7897dfc7773e064003ad53429a79732ee769cf6d02273570"},"id":"87b2d76f-1b70-4e4f-8b2a-5d1915c1177c","version":3} - key11: | - {"address":"bcd4042de499d14e55001ccbb24a551f3b954096","crypto":{"cipher":"aes-128-ctr","ciphertext":"e455eda6e38d246c03b930f845adfc8721ca75e9f47135cd4c18dbc3e5c5440a","cipherparams":{"iv":"0b1a0a24acc1ad25b0f170f751c2cb27"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"69f324ed0787794878bf5f84d4dbbc70dec1274cad666399edc48640605f64c8"},"mac":"f07da09c460a69f943f5639545d2b3f72c1e9789f0421ad41d3078ea3db12c96"},"id":"7ec7bb3c-c486-4785-a4fc-f8f4b2fc7764","version":3} - key12: | - {"address":"71be63f3384f5fb98995898a86b02fb2426c5788","crypto":{"cipher":"aes-128-ctr","ciphertext":"4194377a05fd3d13e0a3155dad974a003fe5f7a3b5acb35d7d97c50daa8990d4","cipherparams":{"iv":"607670778baf62b1e86394cf1980487a"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"d63b890ad7f4fcc857681faabe9319dffc53893966ef0810bf64c4f319b0ffc5"},"mac":"bfaf924959e65c8030ece259d52ed52d5d21bd74f1a67ae545d4bb289a479e16"},"id":"0c6af842-384f-49b6-b5b7-199a1e05486b","version":3} - key13: | - {"address":"fabb0ac9d68b0b445fb7357272ff202c5651694a","crypto":{"cipher":"aes-128-ctr","ciphertext":"6bad79e57a9b80e1b2aa7292a2f72613615a43da2796abeac071ad06a2decff6","cipherparams":{"iv":"91f24b0da7179a0e62803cb2cba6bb49"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"153a063a0dcf7abe7fd730ba908d00856783f0814e1b684a6a08b519d5dbadda"},"mac":"b007d01324b2d05c9a0333e4fbf826681ee2f5ddb4007c6fab20ef923481ba8f"},"id":"fb09dfff-ac3b-46c5-8d88-f4549007977b","version":3} - key14: | - {"address":"1cbd3b2770909d4e10f157cabc84c7264073c9ec","crypto":{"cipher":"aes-128-ctr","ciphertext":"3a7b9d84afb8d6241974cf35a34cbce077aae04f4c0aea1730167c9d8266bd74","cipherparams":{"iv":"329b510bce6e63a53827a0c307c041b5"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"6648c7f4ed24d1134dcf5983a5ca4bc5ae16787f0813530d5ae4c9c61dd3623f"},"mac":"65098dcdaabfb404539aeeea20f41b24886f9d3a55b9a841e2769692e19b75e8"},"id":"2053c6ce-da95-44d2-af1f-1939319aaa45","version":3} - key15: | - {"address":"df3e18d64bc6a983f673ab319ccae4f1a57c7097","crypto":{"cipher":"aes-128-ctr","ciphertext":"ab5802ecd849b0931d822a59597f9b59277526c13dcf792d1f6771ff0a63c902","cipherparams":{"iv":"c10e50c9f7359d281bfddd90ffeee967"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"97848515d8c93caab641882fea9b1428de32a8cf006d998893d01c03a0c2f48c"},"mac":"a2c5fbf7f78e498ee4a8bb242b4a03d4fb77f4135218a5af1d4b99ebd8991c9d"},"id":"83fa51c4-48f7-4d1d-b368-c9bd9d8841ee","version":3} - key16: | - {"address":"cd3b766ccdd6ae721141f452c550ca635964ce71","crypto":{"cipher":"aes-128-ctr","ciphertext":"05f18b7afa63c3748f3c5c99c8f036df1295f7660380e3c6a3fc6252f40566aa","cipherparams":{"iv":"3346ffa57c1b04f678d373cce4e4383a"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"c21f4d22a2324039b3f7cd6dbfa757bc489fa676d700b3ee88d0e3b334698720"},"mac":"7762c08bb673333946e87c33108349d10850c559104e863c5b0826cd6e64df78"},"id":"67b3c79c-d696-4e1b-a381-d67553bc674b","version":3} - key17: | - {"address":"2546bcd3c84621e976d8185a91a922ae77ecec30","crypto":{"cipher":"aes-128-ctr","ciphertext":"accd54a6b3969a4aed305baa0cd35ce4b54dcc92d866ff8b3d23536609a282eb","cipherparams":{"iv":"93be3f925ddea06113b3dcac650e9b6b"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"092f7823a668981e14f715ae7352fa176461cddd94267f9dd6f23f9fe663ba9a"},"mac":"bb4792148205a4f0d8dfc5cd04725d0a4785a6d7e6ca0c208ffc0b005947821b"},"id":"368b24f6-6d1b-4fd5-a506-d73b5bb4aac8","version":3} - key18: | - {"address":"bda5747bfd65f08deb54cb465eb87d40e51b197e","crypto":{"cipher":"aes-128-ctr","ciphertext":"8bc3bf720dce7d010617edaf6db4ed35701c13ff67cd9dce742de77b4b4b3df0","cipherparams":{"iv":"50075ca52dd388719b27e3029f01a484"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"8e365100caeda20cc0a13c28517d62fc41d5cae1da4dae3fef51daf4b323da81"},"mac":"5ed7ad5aca897fd03ebeb08a7fcfa38d2eadc240b6eb6ad53f7c06c6ee9085de"},"id":"8b627671-46e5-4081-a25a-c928b135a87e","version":3} - key19: | - {"address":"dd2fd4581271e230360230f9337d5c0430bf44c0","crypto":{"cipher":"aes-128-ctr","ciphertext":"39c1bbd9c070465fb7828be95b3b0978482aab16b8b1f11db0022321bcaa9172","cipherparams":{"iv":"35bd60a818c50e65fee00031f0a33d8e"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"eecd539685126cfc1f444070d7528c5f570d71c48994118af8c50c316ef72a99"},"mac":"93224b4767a57a8cd394c37087f0dfc9393b381f09c45c5abc55cec5d719181f"},"id":"321978cb-f1bf-4790-8a29-5e5878f8dbb9","version":3} - key20: | - {"address":"8626f6940e2eb28930efb4cef49b2d1f2c9c1199","crypto":{"cipher":"aes-128-ctr","ciphertext":"8a3f1dc7b110c5ce59007f6e55fd7f055b41e518b1f34e93b4185aa44d8a1f92","cipherparams":{"iv":"02fe1b25039baf5abbdd448b932b2ab5"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"a75a6b250851f76f36132aad3ca944493b7d20a07bd4c7b1d8574596a240b35f"},"mac":"679d96ef17c9ac86960e61ced85eb551ba1895cfde2c8bb099e38dc1251a44f0"},"id":"5d3a08df-78f3-43e8-8978-75652502c962","version":3} - password.txt: | - init.sh: | - #!/bin/bash - if [ ! -d /chain/chain-data/keystore ]; then - echo "/chain/chain-data/keystore not found, running 'geth init'..." - geth init --datadir /chain/chain-data/ /chain/genesis.json - echo "...done!" - cp /chain/config/key* /chain/chain-data/keystore - fi - - cd /chain/chain-data && geth "$@" - genesis.json: | - { - "config": { - "chainId": {{ $cfg.networkId }}, - "homesteadBlock": 0, - "eip150Block": 0, - "eip155Block": 0, - "eip158Block": 0, - "eip160Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "muirGlacierBlock": 0, - "berlinBlock": 0, - "londonBlock": 0, - "clique": { - "period": 2, - "epoch": 30000 - } - }, - "nonce": "0x0000000000000042", - "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "difficulty": "1", - "coinbase": "0x3333333333333333333333333333333333333333", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb922660000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "8000000000", - "alloc": { - "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266": { - "balance": "20000000000000000000000" - }, - "0x70997970C51812dc3A010C7d01b50e0d17dc79C8": { - "balance": "20000000000000000000000" - }, - "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC": { - "balance": "20000000000000000000000" - }, - "0x90F79bf6EB2c4f870365E785982E1f101E93b906": { - "balance": "20000000000000000000000" - }, - "0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65": { - "balance": "20000000000000000000000" - }, - "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc": { - "balance": "20000000000000000000000" - }, - "0x976EA74026E726554dB657fA54763abd0C3a0aa9": { - "balance": "20000000000000000000000" - }, - "0x14dC79964da2C08b23698B3D3cc7Ca32193d9955": { - "balance": "20000000000000000000000" - }, - "0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f": { - "balance": "20000000000000000000000" - }, - "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720": { - "balance": "20000000000000000000000" - }, - "0xBcd4042DE499D14e55001CcbB24a551F3b954096": { - "balance": "20000000000000000000000" - }, - "0x71bE63f3384f5fb98995898A86B02Fb2426c5788": { - "balance": "20000000000000000000000" - }, - "0xFABB0ac9d68B0B445fB7357272Ff202C5651694a": { - "balance": "20000000000000000000000" - }, - "0x1CBd3b2770909D4e10f157cABC84C7264073C9Ec": { - "balance": "20000000000000000000000" - }, - "0xdF3e18d64BC6A983f673Ab319CCaE4f1a57C7097": { - "balance": "20000000000000000000000" - }, - "0xcd3B766CCDd6AE721141F452C550Ca635964ce71": { - "balance": "20000000000000000000000" - }, - "0x2546BcD3c84621e976D8185a91A922aE77ECEc30": { - "balance": "20000000000000000000000" - }, - "0xbDA5747bFD65F08deb54cb465eB87D40e51B197E": { - "balance": "20000000000000000000000" - }, - "0xdD2FD4581271e230360230F9337D5c0430Bf44C0": { - "balance": "20000000000000000000000" - }, - "0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199": { - "balance": "20000000000000000000000" - } - } - } ---- -{{- end }} -{{- end }} diff --git a/charts/chainlink-cluster/templates/geth-deployment.yaml b/charts/chainlink-cluster/templates/geth-deployment.yaml deleted file mode 100644 index 6eccdbd20b4..00000000000 --- a/charts/chainlink-cluster/templates/geth-deployment.yaml +++ /dev/null @@ -1,130 +0,0 @@ -{{ if and (hasKey .Values "geth") .Values.geth.enabled }} -{{- range $cfg := .Values.geth.chains }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: geth-{{ $cfg.networkId }} - labels: - app: geth - release: {{ $.Release.Name }} - instance: geth-{{ $cfg.networkId }} -spec: - selector: - matchLabels: - app: geth - release: {{ $.Release.Name }} - instance: geth-{{ $cfg.networkId }} - # Used for testing. - # havoc-component-group and havoc-network-group are used by "havoc" chaos testing tool - havoc-component-group: "blockchain" - havoc-network-group: "blockchain" - template: - metadata: - labels: - app: geth - instance: geth-{{ $cfg.networkId }} - release: {{ $.Release.Name }} - # Used for testing. - # havoc-component-group and havoc-network-group are used by "havoc" chaos testing tool - havoc-component-group: "blockchain" - havoc-network-group: "blockchain" - annotations: - {{- range $key, $value := $.Values.podAnnotations }} - {{ $key }}: {{ $value | quote }} - {{- end }} - spec: - volumes: - - name: configmap-volume - configMap: - name: geth-{{ $cfg.networkId }}-cm - - name: devchain-volume - emptyDir: {} - securityContext: - {{- toYaml $.Values.geth.podSecurityContext | nindent 8 }} - containers: - - name: geth-network - securityContext: - {{- toYaml $.Values.geth.securityContext | nindent 12 }} - image: "{{ default "ethereum/client-go" $.Values.geth.image }}:{{ default "stable" $.Values.geth.version }}" - command: [ "sh", "/chain/init.sh" ] - volumeMounts: - - name: devchain-volume - mountPath: /chain/chain-data - - name : configmap-volume - mountPath: /chain/genesis.json - subPath: genesis.json - - name : configmap-volume - mountPath: /chain/init.sh - subPath: init.sh - - name: configmap-volume - mountPath: /chain/config - args: - - '--password' - - '/chain/config/password.txt' - - '--datadir' - - '/chain/chain-data/' - - '--unlock' - - '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266' - - '--mine' - - '--miner.etherbase' - - '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266' - - '--ipcdisable' - - '--http.api' - - 'admin,debug,clique,eth,miner,net,personal,txpool,web3' - - '--http' - - '--http.vhosts' - - '*' - - '--http.addr' - - '0.0.0.0' - - '--http.port=8544' - - '--ws' - - '--ws.origins' - - '*' - - '--ws.addr' - - '0.0.0.0' - - '--ws.port=8546' - - '--graphql' - - '-graphql.corsdomain' - - '*' - - '--allow-insecure-unlock' - - '--rpc.allow-unprotected-txs' - - '--http.corsdomain' - - '*' - - '--vmdebug' - - '--networkid={{ $cfg.networkId }}' - - '--rpc.txfeecap' - - '0' - - '--dev.period' - - '{{ $.Values.geth.blocktime }}' - - '--miner.gasprice' - - '10000000000' - ports: - - name: http-rpc - containerPort: 8544 - - name: ws-rpc - containerPort: 8546 - {{ if (hasKey $.Values.geth "resources") }} - resources: - requests: - memory: {{ default "1024Mi" $.Values.geth.resources.requests.memory }} - cpu: {{ default "1000m" $.Values.geth.resources.requests.cpu }} - limits: - memory: {{ default "1024Mi" $.Values.geth.resources.limits.memory }} - cpu: {{ default "1000m" $.Values.geth.resources.limits.cpu }} - {{ else }} - {{ end }} -{{- with $.Values.nodeSelector }} - nodeSelector: - {{ toYaml . | indent 8 }} -{{- end }} -{{- with $.Values.affinity }} - affinity: - {{ toYaml . | indent 8 }} -{{- end }} -{{- with $.Values.tolerations }} - tolerations: -{{ toYaml . | indent 8 }} -{{- end }} ---- -{{- end }} -{{- end }} diff --git a/charts/chainlink-cluster/templates/geth-networkpolicy.yaml b/charts/chainlink-cluster/templates/geth-networkpolicy.yaml deleted file mode 100644 index 2a37a92aaaa..00000000000 --- a/charts/chainlink-cluster/templates/geth-networkpolicy.yaml +++ /dev/null @@ -1,25 +0,0 @@ -{{ if and (hasKey .Values "geth") .Values.geth.enabled }} -{{- if .Values.networkPolicies.enabled }} -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: {{ $.Release.Name }}-geth -spec: - podSelector: - matchLabels: - app: geth - policyTypes: - - Ingress - ingress: - - from: - # Allow http and websocket connections from the node pods. - - podSelector: - matchLabels: - app: {{ $.Release.Name }} - ports: - - protocol: TCP - port: 8544 - - protocol: TCP - port: 8546 -{{- end }} -{{- end }} diff --git a/charts/chainlink-cluster/templates/geth-service.yaml b/charts/chainlink-cluster/templates/geth-service.yaml deleted file mode 100644 index 63a86a3d1d7..00000000000 --- a/charts/chainlink-cluster/templates/geth-service.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{ if and (hasKey .Values "geth") .Values.geth.enabled }} -{{- range $cfg := .Values.geth.chains }} -apiVersion: v1 -kind: Service -metadata: - name: geth-{{ $cfg.networkId }} -spec: - selector: - instance: geth-{{ $cfg.networkId }} - release: {{ $.Release.Name }} - ports: - - name: ws-rpc - port: {{ default "8546" $.Values.geth.wsrpc_port}} - targetPort: ws-rpc - - name: http-rpc - port: {{ default "8544" $.Values.geth.httprpc_port}} - targetPort: http-rpc - type: ClusterIP ---- -{{- end }} -{{- end }} diff --git a/charts/chainlink-cluster/templates/ingress.yaml b/charts/chainlink-cluster/templates/ingress.yaml deleted file mode 100644 index 9573ac54eb9..00000000000 --- a/charts/chainlink-cluster/templates/ingress.yaml +++ /dev/null @@ -1,43 +0,0 @@ -{{- if .Values.ingress.enabled -}} -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: {{ $.Release.Name }} - labels: - app: {{ $.Release.Name }} - release: {{ $.Release.Name }} - {{- range $key, $value := $.Values.labels }} - {{ $key }}: {{ $value | quote }} - {{- end }} - annotations: - alb.ingress.kubernetes.io/backend-protocol: HTTP - alb.ingress.kubernetes.io/certificate-arn: {{ $.Values.ingress.annotation_certificate_arn | quote }} - alb.ingress.kubernetes.io/group.name: {{ $.Values.ingress.annotation_group_name | quote }} - alb.ingress.kubernetes.io/scheme: internal - alb.ingress.kubernetes.io/target-type: ip - external-dns.alpha.kubernetes.io/ttl: "120" - {{- if .Values.ingress.extra_annotations }} - {{- range $key, $value := .Values.ingress.extra_annotations }} - {{ $key }}: {{ $value | quote }} - {{- end }} - {{- end }} -spec: - {{- with .Values.ingress.ingressClassName }} - ingressClassName: {{ . }} - {{- end }} - rules: - {{- range .Values.ingress.hosts }} - - host: {{ .host }} - http: - paths: - {{- range .http.paths }} - - path: "/*" - pathType: ImplementationSpecific - backend: - service: - name: {{ .backend.service.name }} - port: - number: {{ .backend.service.port.number }} - {{- end }} - {{- end }} -{{- end -}} diff --git a/charts/chainlink-cluster/templates/mockserver-networkpolicy.yaml b/charts/chainlink-cluster/templates/mockserver-networkpolicy.yaml deleted file mode 100644 index 0fa48dcfc41..00000000000 --- a/charts/chainlink-cluster/templates/mockserver-networkpolicy.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if and .Values.mockserver.enabled .Values.networkPolicies.enabled }} -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: {{ $.Release.Name }}-mockserver -spec: - podSelector: - matchLabels: - app: mockserver - policyTypes: - - Ingress - ingress: - - from: - # Allow http traffic from the node pods. - - podSelector: - matchLabels: - app: {{ $.Release.Name }} - ports: - - protocol: TCP - port: 1080 -{{- end }} diff --git a/charts/chainlink-cluster/templates/networkpolicy-default.yaml b/charts/chainlink-cluster/templates/networkpolicy-default.yaml deleted file mode 100644 index 10927c26eb6..00000000000 --- a/charts/chainlink-cluster/templates/networkpolicy-default.yaml +++ /dev/null @@ -1,43 +0,0 @@ -{{- if and .Values.mockserver.enabled .Values.networkPolicies.enabled }} -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: default -spec: - podSelector: - matchLabels: {} - policyTypes: - - Ingress - - Egress - ingress: - {{- if and .Values.networkPolicyDefault.ingress.allowCustomCidrs (not (empty .Values.networkPolicyDefault.ingress.customCidrs)) }} - # Using a comma separated list to make it easy to pass in with: - # `helm template ... --set networkPolicyDefault.ingress.customCidrs=...` - {{- $cidrs := splitList "," .Values.networkPolicyDefault.ingress.customCidrs }} - - from: - {{- range $cidr := $cidrs }} - - ipBlock: - cidr: {{ $cidr | quote }} - {{- end }} - {{- else }} - # Deny all ingress if no rules are specified. Rules can still be specified in other templates. - - {} - {{- end }} - egress: - - to: - - namespaceSelector: - matchLabels: - kubernetes.io/metadata.name: "{{ $.Release.Namespace }}" - - to: - - namespaceSelector: - matchLabels: - kubernetes.io/metadata.name: kube-system - podSelector: - matchLabels: - k8s-app: kube-dns - ports: - - protocol: TCP - port: 53 - - protocol: UDP - port: 53 -{{- end }} \ No newline at end of file diff --git a/charts/chainlink-cluster/templates/tests/test-connection.yaml b/charts/chainlink-cluster/templates/tests/test-connection.yaml deleted file mode 100644 index b03b6a570c7..00000000000 --- a/charts/chainlink-cluster/templates/tests/test-connection.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: cl-nodes-connection-test - annotations: - "helm.sh/hook": test -spec: - containers: - {{- range $cfg := .Values.chainlink.nodes }} - - name: curl-{{ $cfg.name }} - image: radial/busyboxplus:curl - command: ['curl'] - args: [ '{{ $.Release.Name }}-{{ $cfg.name }}:{{ $.Values.chainlink.web_port }}' ] - {{- end }} - restartPolicy: Never \ No newline at end of file diff --git a/charts/chainlink-cluster/values.yaml b/charts/chainlink-cluster/values.yaml deleted file mode 100644 index d6315f488fd..00000000000 --- a/charts/chainlink-cluster/values.yaml +++ /dev/null @@ -1,439 +0,0 @@ -# override resources for keys "chainlink", "db", or "geth" if needed -# resources: -# requests: -# cpu: 350m -# memory: 1024Mi -# limits: -# cpu: 350m -# memory: 1024Mi -# images can be overriden for the same keys: -# image: ethereum/client-go -# version: stable -chainlink: - enabled: true - global: - # `toml` is initially set to null. Uncomment and modify the following example as needed. - # Example configuration parameters for all Chainlink nodes. Can be overridden by individual node configurations and via `overridesToml`. - # toml: |- - # [Log] - # Level = 'info' - # [WebServer] - # HTTPPort = 6688 - toml: null - # `overridesToml` is initially set to null. Uncomment and modify the following example as needed. - # Example configuration parameters that override the main configuration. - # overridesToml: |- - # [Log] - # Level = 'debug' - # [WebServer] - # HTTPPort = 6690 - overridesToml: null - podSecurityContext: - fsGroup: 14933 - securityContext: - capabilities: - drop: - - ALL - readOnlyRootFilesystem: false - runAsNonRoot: true - runAsUser: 14933 - runAsGroup: 14933 - web_port: 6688 - p2p_port: 6690 - nodes: - - name: node-1 - image: "public.ecr.aws/chainlink/chainlink:latest" - # default resources are 300m/1Gi - # first node need more resources to build faster inside container - # at least 2Gi of memory is required otherwise build will fail (OOM) - resources: - requests: - cpu: 2000m - memory: 2048Mi - limits: - cpu: 2000m - memory: 2048Mi - # override default config per node - # for example, use OCRv2 P2P setup, the whole config - # toml: | - # RootDir = './clroot' - # [Log] - # JSONConsole = true - # Level = 'debug' - # [WebServer] - # AllowOrigins = '*' - # SecureCookies = false - # SessionTimeout = '999h0m0s' - # [OCR2] - # Enabled = true - # [P2P] - # [P2P.V2] - # Enabled = false - # AnnounceAddresses = [] - # DefaultBootstrappers = [] - # DeltaDial = '15s' - # DeltaReconcile = '1m0s' - # ListenAddresses = [] - # [[EVM]] - # ChainID = '1337' - # MinContractPayment = '0' - # [[EVM.Nodes]] - # Name = 'node-0' - # WSURL = 'ws://geth:8546' - # HTTPURL = 'http://geth:8544' - # [WebServer.TLS] - # HTTPSPort = 0 - # or use overridesToml to override some part of configuration - # overridesToml: | - - name: node-2 - - name: node-3 - - name: node-4 - - name: node-5 - - name: node-6 - -# each CL node have a dedicated PostgreSQL 11.15 -# use StatefulSet by setting: -# -# stateful: true -# capacity 10Gi -# -# if you are running long tests -db: - enabled: true - podSecurityContext: - fsGroup: 999 - securityContext: - capabilities: - drop: - - ALL - readOnlyRootFilesystem: false - runAsNonRoot: true - runAsUser: 999 - runAsGroup: 999 - stateful: false - image: "postgres:15.6" - resources: - requests: - cpu: 1 - memory: 1024Mi - limits: - cpu: 1 - memory: 1024Mi -# default cluster shipped with latest Geth ( dev mode by default ) -geth: - enabled: true - podSecurityContext: - fsGroup: 999 - securityContext: - capabilities: - drop: - - ALL - readOnlyRootFilesystem: false - runAsNonRoot: true - runAsUser: 999 - runAsGroup: 999 - version: v1.12.0 - wsRpcPort: 8546 - httpRpcPort: 8544 - blocktime: 1 - chains: - - networkId: 1337 - # use to inject custom configuration for each chain, e.g. GasEstimator - # - customEVMConfigToml: | - # [EVM.GasEstimator] - # PriceMax = '200 gwei' - # LimitDefault = 6000000 - # FeeCapDefault = '200 gwei' - # [EVM.GasEstimator.BlockHistory] - # BlockHistorySize = 200 - # EIP1559FeeCapBufferBlocks = 0 - - networkId: 2337 - resources: - requests: - cpu: 1 - memory: 1024Mi - limits: - cpu: 1 - memory: 1024Mi -# mockserver is https://www.mock-server.com/where/kubernetes.html -# used to stub External Adapters -mockserver: - enabled: true - releasenameOverride: mockserver - service: - type: ClusterIP - app: - runAsUser: 999 - readOnlyRootFilesystem: false - port: 1080 - resources: - requests: - cpu: 1 - memory: 1024Mi - limits: - cpu: 1 - memory: 1024Mi -opentelemetry-collector: - enabled: true - mode: deployment - image: - repository: otel/opentelemetry-collector - tag: 0.95.0 - command: - name: otelcol - extraVolumes: - - name: trace-data - emptyDir: {} - extraVolumeMounts: - - name: trace-data - mountPath: /tracing - podSecurityContext: - fsGroup: 10001 - securityContext: - runAsNonRoot: true - runAsUser: 10001 - runAsGroup: 10001 - config: - receivers: - otlp: - protocols: - grpc: - endpoint: ${env:MY_POD_IP}:4317 - http: - endpoint: ${env:MY_POD_IP}:4318 - exporters: - otlp: - endpoint: app-tempo:4317 - tls: - insecure: true - service: - telemetry: - logs: - level: "debug" - pipelines: - traces: - receivers: [otlp] - exporters: [otlp] - -tempo: - enabled: true - image: - tag: "1.7.2" - # default storage path: /var/tempo/ - securityContext: - runAsNonRoot: true - runAsUser: 10001 - runAsGroup: 10001 - tempo: - storage: - trace: - backend: local # backend configuration to use - wal: - path: /tmp/tempo/wal # where to store the wal locally - local: - path: /tmp/tempo/blocks - -grafana: - enabled: true - image: - tag: 10.4.1 - rbac: - namespaced: true - datasources: - datasources.yaml: - apiVersion: 1 - datasources: - - name: Tempo - type: tempo - access: proxy - orgId: 1 - url: http://app-tempo:3100 - basicAuth: false - isDefault: true - version: 1 - editable: false - uid: tempo - jsonData: - httpMethod: GET - serviceMap: - datasourceUid: prometheus - env: - GF_AUTH_ANONYMOUS_ENABLED: "true" - GF_AUTH_ANONYMOUS_ORG_ROLE: "Admin" - GF_AUTH_DISABLE_LOGIN_FORM: "true" - GF_FEATURE_TOGGLES_ENABLE: "traceqlEditor tempoSearch tempoServiceGraph" - -ingress: - enabled: false - annotations: {} - ingressClassName: alb - hosts: - - host: chainlink-node-1.local - http: - paths: - - path: / - pathType: ImplementationSpecific - backend: - service: - name: chainlink-node-1 - port: - number: 6688 - - host: chainlink-node-2.local - http: - paths: - - path: / - pathType: ImplementationSpecific - backend: - service: - name: chainlink-node-2 - port: - number: 6688 - - host: chainlink-node-3.local - http: - paths: - - path: / - pathType: ImplementationSpecific - backend: - service: - name: chainlink-node-3 - port: - number: 6688 - - host: chainlink-node-4.local - http: - paths: - - path: / - pathType: ImplementationSpecific - backend: - service: - name: chainlink-node-4 - port: - number: 6688 - - host: chainlink-node-5.local - http: - paths: - - path: / - pathType: ImplementationSpecific - backend: - service: - name: chainlink-node-5 - port: - number: 6688 - - host: chainlink-node-6.local - http: - paths: - - path: / - pathType: ImplementationSpecific - backend: - service: - name: chainlink-node-6 - port: - number: 6688 - - host: chainlink-geth-http.local - http: - paths: - - path: / - pathType: ImplementationSpecific - backend: - service: - name: geth - port: - number: 8544 - - host: chainlink-geth-ws.local - http: - paths: - - path: / - pathType: ImplementationSpecific - backend: - service: - name: geth - port: - number: 8546 - - host: chainlink-mockserver.local - http: - paths: - - path: / - pathType: ImplementationSpecific - backend: - service: - name: mockserver - port: - number: 1080 - - host: chainlink-grafana.local - http: - paths: - - path: / - pathType: ImplementationSpecific - backend: - service: - name: grafana - port: - number: 80 -# monitoring.coreos.com/v1 PodMonitor for each node -prometheusMonitor: true - -# deployment placement, standard helm stuff -podAnnotations: -nodeSelector: -tolerations: -affinity: - -networkPolicies: - enabled: true - customPolicies: - grafanaToTempoEgress: - podSelector: - matchLabels: - app: grafana - egress: - - to: - - podSelector: - matchLabels: - app: tempo - ports: - - protocol: TCP - port: 3100 - tempoIngressFromGrafana: - podSelector: - matchLabels: - app: tempo - ingress: - - from: - - podSelector: - matchLabels: - app: grafana - ports: - - protocol: TCP - port: 3100 - chainlinkToOtelCollectorEgress: - podSelector: - matchLabels: - app: chainlink - egress: - - to: - - podSelector: - matchLabels: - app: otel-collector - ports: - - protocol: TCP - port: 4317 - otelCollectorToTempoEgress: - podSelector: - matchLabels: - app: otel-collector - egress: - - to: - - podSelector: - matchLabels: - app: tempo - ports: - - protocol: TCP - port: 4317 - -# Configure the default network policy. -networkPolicyDefault: - ingress: - allowCustomCidrs: false - # String of comma separated CIDRs - customCidrs: null - # Example: - # customCidrs: "10.0.0.0/16,192.168.0.1/24" diff --git a/crib/.env.example b/crib/.env.example index 703c7bf7f83..e35d0d3e580 100644 --- a/crib/.env.example +++ b/crib/.env.example @@ -13,5 +13,9 @@ DEVSPACE_INGRESS_CERT_ARN= # Time to wait for pods to be in `Ready` condition DEVSPACE_K8S_POD_WAIT_TIMEOUT=600s +# HELM repo URI for the crib-chainlink-cluster helm chart +CHAINLINK_CLUSTER_HELM_CHART_URI= + # The duration that the namespace and all of its associated resources will be kept alive. NS_TTL=72h + diff --git a/crib/devspace.yaml b/crib/devspace.yaml index 9c2895e9ac6..213fe4c24c7 100644 --- a/crib/devspace.yaml +++ b/crib/devspace.yaml @@ -99,8 +99,8 @@ deployments: helm: releaseName: "app" chart: - name: cl-cluster - path: ../charts/chainlink-cluster + name: ${CHAINLINK_CLUSTER_HELM_CHART_URI} + version: 0.5.0 # for simplicity, we define all the values here # they can be defined the same way in values.yml # devspace merges these "values" with the "values.yaml" before deploy diff --git a/crib/scripts/check_env_vars.sh b/crib/scripts/check_env_vars.sh index f26f78e7470..55480313800 100755 --- a/crib/scripts/check_env_vars.sh +++ b/crib/scripts/check_env_vars.sh @@ -7,6 +7,7 @@ required_vars=( "DEVSPACE_INGRESS_BASE_DOMAIN" "DEVSPACE_INGRESS_CERT_ARN" "DEVSPACE_K8S_POD_WAIT_TIMEOUT" + "CHAINLINK_CLUSTER_HELM_CHART_URI" "NS_TTL" ) diff --git a/crib/setup.sh b/crib/setup.sh index 536bef57c75..8e254909655 100755 --- a/crib/setup.sh +++ b/crib/setup.sh @@ -1,6 +1,20 @@ #!/usr/bin/env bash -set -e +set -euo pipefail + +# Function to extract the host URI of the ECR registry from OCI URI +extract_ecr_host_uri() { + local ecr_uri="$1" + # Regex to capture the ECR host URI + if [[ $ecr_uri =~ oci:\/\/([0-9]+\.dkr\.ecr\.[a-zA-Z0-9-]+\.amazonaws\.com) ]]; then + echo "${BASH_REMATCH[1]}" + else + echo "No valid ECR host URI found in the URI." + echo "Have you set CHAINLINK_CLUSTER_HELM_CHART_URI env var?" + exit 1 + fi +} + user_home="$HOME" file_path="$user_home/.aws/config" image="" @@ -33,5 +47,12 @@ else echo "Docker daemon is not running, exiting" exit 1 fi -aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin ${registry_id}.dkr.ecr.us-west-2.amazonaws.com -devspace use namespace $1 + +# Login to docker ECR registry +aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin "${registry_id}".dkr.ecr.us-west-2.amazonaws.com + +# Login to helm ECR registry +helm_registry_uri=$(extract_ecr_host_uri "${CHAINLINK_CLUSTER_HELM_CHART_URI}") +aws ecr get-login-password --region us-west-2 | helm registry login "$helm_registry_uri" --username AWS --password-stdin + +devspace use namespace "$1" diff --git a/charts/chainlink-cluster/values-profiles/README.md b/crib/values-profiles/README.md similarity index 100% rename from charts/chainlink-cluster/values-profiles/README.md rename to crib/values-profiles/README.md diff --git a/charts/chainlink-cluster/values-profiles/values-dev.yaml.example b/crib/values-profiles/values-dev.yaml.example similarity index 100% rename from charts/chainlink-cluster/values-profiles/values-dev.yaml.example rename to crib/values-profiles/values-dev.yaml.example diff --git a/lintconf.yaml b/lintconf.yaml deleted file mode 100644 index ff37371d476..00000000000 --- a/lintconf.yaml +++ /dev/null @@ -1,46 +0,0 @@ ---- -# Copied from: -# https://redhat-cop.github.io/ci/linting-testing-helm-charts.html -# with `min-spaces-from-content` changed to be compatible with prettier. -rules: - braces: - min-spaces-inside: 0 - max-spaces-inside: 0 - min-spaces-inside-empty: -1 - max-spaces-inside-empty: -1 - brackets: - min-spaces-inside: 0 - max-spaces-inside: 0 - min-spaces-inside-empty: -1 - max-spaces-inside-empty: -1 - colons: - max-spaces-before: 0 - max-spaces-after: 1 - commas: - max-spaces-before: 0 - min-spaces-after: 1 - max-spaces-after: 1 - comments: - require-starting-space: true - min-spaces-from-content: 1 - document-end: disable - document-start: disable # No --- to start a file - empty-lines: - max: 2 - max-start: 0 - max-end: 0 - hyphens: - max-spaces-after: 1 - indentation: - spaces: consistent - indent-sequences: whatever # - list indentation will handle both indentation and without - check-multi-line-strings: false - key-duplicates: enable - line-length: disable # Lines can be any length - new-line-at-end-of-file: disable - new-lines: - type: unix - trailing-spaces: enable - truthy: - level: warning - From 7b09076a101b47b731fa1b0ee9ce61f4a98254ab Mon Sep 17 00:00:00 2001 From: Anirudh Warrier <12178754+anirudhwarrier@users.noreply.github.com> Date: Thu, 25 Apr 2024 15:35:52 +0530 Subject: [PATCH 29/77] stream automation tests logs to grafana (AUTO-10273) (#12953) * stream nightly tests logs to loki * stream ondemand tests logs to loki --- .../action.yml | 49 +++++++++++++++++++ .../workflows/automation-nightly-tests.yml | 8 +++ .../workflows/automation-ondemand-tests.yml | 34 ++++++++++++- 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/.github/actions/setup-create-base64-upgrade-config/action.yml b/.github/actions/setup-create-base64-upgrade-config/action.yml index daa2d400262..ed25fd6375f 100644 --- a/.github/actions/setup-create-base64-upgrade-config/action.yml +++ b/.github/actions/setup-create-base64-upgrade-config/action.yml @@ -17,6 +17,23 @@ inputs: default: "public.ecr.aws/chainlink/chainlink" upgradeVersion: description: The git commit sha to use for the image tag + runId: + description: The run id + testLogCollect: + description: Whether to always collect logs, even for passing tests + default: "false" + lokiEndpoint: + description: Loki push endpoint + lokiTenantId: + description: Loki tenant id + lokiBasicAuth: + description: Loki basic auth + logstreamLogTargets: + description: Where to send logs (e.g. file, loki) + grafanaUrl: + description: Grafana URL + grafanaDashboardUrl: + description: Grafana dashboard URL runs: using: composite @@ -31,6 +48,14 @@ runs: CHAINLINK_POSTGRES_VERSION: ${{ inputs.chainlinkPostgresVersion }} UPGRADE_IMAGE: ${{ inputs.upgradeImage }} UPGRADE_VERSION: ${{ inputs.upgradeVersion }} + RUN_ID: ${{ inputs.runId }} + TEST_LOG_COLLECT: ${{ inputs.testLogCollect }} + LOKI_ENDPOINT: ${{ inputs.lokiEndpoint }} + LOKI_TENANT_ID: ${{ inputs.lokiTenantId }} + LOKI_BASIC_AUTH: ${{ inputs.lokiBasicAuth }} + LOGSTREAM_LOG_TARGETS: ${{ inputs.logstreamLogTargets }} + GRAFANA_URL: ${{ inputs.grafanaUrl }} + GRAFANA_DASHBOARD_URL: ${{ inputs.grafanaDashboardUrl }} run: | function convert_to_toml_array() { local IFS=',' @@ -47,6 +72,14 @@ runs: selected_networks=$(convert_to_toml_array "$SELECTED_NETWORKS") + if [ -n "$TEST_LOG_COLLECT" ]; then + test_log_collect=true + else + test_log_collect=false + fi + + log_targets=$(convert_to_toml_array "$LOGSTREAM_LOG_TARGETS") + cat << EOF > config.toml [Network] selected_networks=$selected_networks @@ -59,6 +92,22 @@ runs: [ChainlinkUpgradeImage] image="$UPGRADE_IMAGE" version="$UPGRADE_VERSION" + + [Logging] + test_log_collect=$test_log_collect + run_id="$RUN_ID" + + [Logging.LogStream] + log_targets=$log_targets + + [Logging.Loki] + tenant_id="$LOKI_TENANT_ID" + endpoint="$LOKI_ENDPOINT" + basic_auth_secret="$LOKI_BASIC_AUTH" + + [Logging.Grafana] + base_url="$GRAFANA_URL" + dashboard_url="$GRAFANA_DASHBOARD_URL" EOF BASE64_CONFIG_OVERRIDE=$(cat config.toml | base64 -w 0) diff --git a/.github/workflows/automation-nightly-tests.yml b/.github/workflows/automation-nightly-tests.yml index c3b874548ac..b44a7f56e65 100644 --- a/.github/workflows/automation-nightly-tests.yml +++ b/.github/workflows/automation-nightly-tests.yml @@ -95,6 +95,14 @@ jobs: chainlinkVersion: "latest" upgradeImage: ${{ env.CHAINLINK_IMAGE }} upgradeVersion: ${{ github.sha }} + runId: ${{ github.run_id }} + testLogCollect: "true" + lokiEndpoint: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push + lokiTenantId: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + lokiBasicAuth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} + grafanaUrl: ${{ vars.GRAFANA_URL }} + grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - name: Run Tests uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@5dd916d08c03cb5f9a97304f4f174820421bb946 # v2.3.11 env: diff --git a/.github/workflows/automation-ondemand-tests.yml b/.github/workflows/automation-ondemand-tests.yml index 167dccf3bbf..dade0f331b9 100644 --- a/.github/workflows/automation-ondemand-tests.yml +++ b/.github/workflows/automation-ondemand-tests.yml @@ -226,7 +226,15 @@ jobs: UPGRADE_IMAGE: ${{ steps.determine-build.outputs.upgrade_image }} PYROSCOPE_SERVER: ${{ matrix.tests.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725 PYROSCOPE_ENVIRONMENT: ${{ matrix.tests.pyroscope_env }} - PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + RUN_ID: ${{ github.run_id }} + TEST_LOG_COLLECT: "true" + LOKI_ENDPOINT: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push + LOKI_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + LOKI_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + LOGSTREAM_LOG_TARGETS: ${{ vars.LOGSTREAM_LOG_TARGETS }} + GRAFANA_URL: ${{ vars.GRAFANA_URL }} + GRAFANA_DASHBOARD_URL: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" run: | echo ::add-mask::$UPGRADE_IMAGE echo ::add-mask::$OLD_IMAGE @@ -242,6 +250,14 @@ jobs: pyroscope_enabled=false fi + if [ -n "$TEST_LOG_COLLECT" ]; then + test_log_collect=true + else + test_log_collect=false + fi + + log_targets=$(convert_to_toml_array "$LOGSTREAM_LOG_TARGETS") + cat << EOF > config.toml [Network] selected_networks=$selected_networks @@ -254,6 +270,22 @@ jobs: image="$UPGRADE_IMAGE" version="$UPGRADE_VERSION" + [Logging] + test_log_collect=$test_log_collect + run_id="$RUN_ID" + + [Logging.LogStream] + log_targets=$log_targets + + [Logging.Loki] + tenant_id="$LOKI_TENANT_ID" + endpoint="$LOKI_ENDPOINT" + basic_auth_secret="$LOKI_BASIC_AUTH" + + [Logging.Grafana] + base_url="$GRAFANA_URL" + dashboard_url="$GRAFANA_DASHBOARD_URL" + [Pyroscope] enabled=$pyroscope_enabled server_url="$PYROSCOPE_SERVER" From c91052c9d6faa70f01e3ac695cfd6eacd541b88e Mon Sep 17 00:00:00 2001 From: chainchad <96362174+chainchad@users.noreply.github.com> Date: Thu, 25 Apr 2024 06:24:11 -0400 Subject: [PATCH 30/77] Create new CRIB setup script (#12956) * Add CRIB scripts to nix $PATH * Create new CRIB setup script * Update CRIB README * Clarify comment * Fix typo --------- Co-authored-by: Radek Scheibinger --- crib/.env.example | 6 ++ crib/README.md | 15 ++-- crib/scripts/cribbit.sh | 179 ++++++++++++++++++++++++++++++++++++++++ crib/setup.sh | 58 ------------- shell.nix | 6 ++ 5 files changed, 199 insertions(+), 65 deletions(-) create mode 100755 crib/scripts/cribbit.sh delete mode 100755 crib/setup.sh diff --git a/crib/.env.example b/crib/.env.example index e35d0d3e580..e24473a9a22 100644 --- a/crib/.env.example +++ b/crib/.env.example @@ -19,3 +19,9 @@ CHAINLINK_CLUSTER_HELM_CHART_URI= # The duration that the namespace and all of its associated resources will be kept alive. NS_TTL=72h +## +# These are used by the shell script: cribbit.sh +## +AWS_REGION= +AWS_SSO_ROLE_NAME= +AWS_SSO_START_URL= diff --git a/crib/README.md b/crib/README.md index c9106d401cd..a88eedb5c41 100644 --- a/crib/README.md +++ b/crib/README.md @@ -26,16 +26,17 @@ Configure the cluster, see `deployments.app.helm.values` and [values.yaml](../ch Set up your K8s access -``` -export DEVSPACE_IMAGE="..." -./setup.sh ${my-personal-namespace-name-crib} -``` +Copy the `.env.example` file to `.env` and fill in the required values -Create a .env file based on the .env.sample file +```sh +cp crib/.env.example crib/.env +``` ```sh -cp .env.sample .env -# Fill in the required values in .env +cd crib/ +nix develop +# Pro tip: use `crib-` as a prefix for your namespace. +cribbit.sh ``` Build and deploy the current state of your repository diff --git a/crib/scripts/cribbit.sh b/crib/scripts/cribbit.sh new file mode 100755 index 00000000000..316791b10cb --- /dev/null +++ b/crib/scripts/cribbit.sh @@ -0,0 +1,179 @@ +#!/usr/bin/env bash + +set -euo pipefail + +############################# +# __________ +# < CRIBbit! > +# ---------- +# _ _ / +# (o)--(o) / +# /.______.\ +# \________/ +# ./ \. +# ( . , ) +# \ \_\\//_/ / +# ~~ ~~ ~~ +# +# Initialize your CRIB +# environment. +############################# + +DEVSPACE_NAMESPACE="${1:-}" +if [[ -z "${DEVSPACE_NAMESPACE}" ]]; then + echo "Usage: $0 " + exit 1 +fi + +# Bail if $DEVSPACE_NAMESPACE does not begin with a crib- prefix or does not have an override set. +if [[ ! "${DEVSPACE_NAMESPACE}" =~ ^crib- ]] && [[ -z "${CRIB_IGNORE_NAMESPACE_PREFIX:-}" ]]; then + echo "Error: DEVSPACE_NAMESPACE must begin with 'crib-' prefix." + exit 1 +fi + +# Path to the .env file +repo_root=$(git rev-parse --show-toplevel 2>/dev/null || echo ".") +env_file="${repo_root}/crib/.env" + +# Source .env file if it exists +if [[ -f "${env_file}" ]]; then + # shellcheck disable=SC1090 + source "${env_file}" +else + echo "Error: .env file not found at $env_file" + exit 1 +fi + +# List of required environment variables +required_vars=( + "AWS_REGION" + # Should be the short name and not the full IAM role ARN. + "AWS_SSO_ROLE_NAME" + # The AWS SSO start URL, e.g. https://.awsapps.com/start + "AWS_SSO_START_URL" + "DEVSPACE_IMAGE" + "HOME" +) + +missing_vars=0 # Counter for missing variables + +for var in "${required_vars[@]}"; do + if [[ -z "${!var:-}" ]]; then # If variable is unset or empty + echo "Error: Environment variable ${var} is not set." + missing_vars=$((missing_vars + 1)) + fi +done + +# Exit with an error if any variables were missing +if [[ $missing_vars -ne 0 ]]; then + echo "Error: Total missing environment variables: $missing_vars" + exit 1 +fi + +## +# Setup AWS Profile +## + +path_aws_config="$HOME/.aws/config" +aws_account_id_ecr_registry=$(echo "${DEVSPACE_IMAGE}" | cut -d'.' -f1) +aws_profile_name="staging-crib" + +if grep -q "$aws_profile_name" "$path_aws_config"; then + echo "Info: Skip updating ${path_aws_config}. Profile already set: ${aws_profile_name}" +else + cat <> "$path_aws_config" +[profile $aws_profile_name] +region=${AWS_REGION} +sso_start_url=${AWS_SSO_START_URL} +sso_region=${AWS_REGION} +sso_account_id=${aws_account_id_ecr_registry} +sso_role_name=${AWS_SSO_ROLE_NAME} +EOF + echo "Info: ${path_aws_config} modified. Added profile: ${aws_profile_name}" +fi + +echo "Info: Setting AWS Profile env var: AWS_PROFILE=${aws_profile_name}" +export AWS_PROFILE=${aws_profile_name} + +if aws sts get-caller-identity > /dev/null 2>&1; then + echo "Info: AWS credentials working." +else + echo "Info: AWS credentials not detected. Attempting to login through SSO." + aws sso login +fi + +# Check again and fail this time if not successful +if ! aws sts get-caller-identity > /dev/null 2>&1; then + echo "Error: AWS credentials still not detected. Exiting." + exit 1 +fi + +## +# Setup EKS KUBECONFIG +## + +path_kubeconfig="${KUBECONFIG:-$HOME/.kube/config}" +eks_cluster_name="${CRIB_EKS_CLUSTER_NAME:-main-stage-cluster}" +eks_alias_name="${CRIB_EKS_ALIAS_NAME:-main-stage-cluster-crib}" + +if [[ ! -f "${path_kubeconfig}" ]] || ! grep -q "name: ${eks_alias_name}" "${path_kubeconfig}"; then + echo "Info: KUBECONFIG file (${path_kubeconfig}) not found or alias (${eks_alias_name}) not found. Attempting to update kubeconfig." + aws eks update-kubeconfig \ + --name "${eks_cluster_name}" \ + --alias "${eks_alias_name}" \ + --region "${AWS_REGION}" +else + echo "Info: Alias '${eks_alias_name}' already exists in kubeconfig. No update needed." + echo "Info: Setting kubernetes context to: ${eks_alias_name}" + kubectl config use-context "${eks_alias_name}" +fi + +## +# Check Docker Daemon +## + +if docker info > /dev/null 2>&1; then + echo "Info: Docker daemon is running, authorizing registry" +else + echo "Error: Docker daemon is not running. Exiting." + exit 1 +fi + +## +# AWS ECR Login +## + +# Function to extract the host URI of the ECR registry from OCI URI +extract_ecr_host_uri() { + local ecr_uri="$1" + # Regex to capture the ECR host URI + if [[ $ecr_uri =~ oci:\/\/([0-9]+\.dkr\.ecr\.[a-zA-Z0-9-]+\.amazonaws\.com) ]]; then + echo "${BASH_REMATCH[1]}" + else + echo "No valid ECR host URI found in the URI." + echo "Have you set CHAINLINK_CLUSTER_HELM_CHART_URI env var?" + exit 1 + fi +} + +# Set env var CRIB_SKIP_ECR_LOGIN=true to skip ECR login. +if [[ -n "${CRIB_SKIP_ECR_LOGIN:-}" ]]; then + echo "Info: Skipping ECR login." +else + echo "Info: Logging docker into AWS ECR registry." + aws ecr get-login-password \ + --region "${AWS_REGION}" \ + | docker login --username AWS \ + --password-stdin "${aws_account_id_ecr_registry}.dkr.ecr.${AWS_REGION}.amazonaws.com" + + echo "Info: Logging helm into AWS ECR registry." + helm_registry_uri=$(extract_ecr_host_uri "${CHAINLINK_CLUSTER_HELM_CHART_URI}") + aws ecr get-login-password --region "${AWS_REGION}" \ + | helm registry login "$helm_registry_uri" --username AWS --password-stdin +fi + +## +# Setup DevSpace +## + +devspace use namespace "${DEVSPACE_NAMESPACE}" diff --git a/crib/setup.sh b/crib/setup.sh deleted file mode 100755 index 8e254909655..00000000000 --- a/crib/setup.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# Function to extract the host URI of the ECR registry from OCI URI -extract_ecr_host_uri() { - local ecr_uri="$1" - # Regex to capture the ECR host URI - if [[ $ecr_uri =~ oci:\/\/([0-9]+\.dkr\.ecr\.[a-zA-Z0-9-]+\.amazonaws\.com) ]]; then - echo "${BASH_REMATCH[1]}" - else - echo "No valid ECR host URI found in the URI." - echo "Have you set CHAINLINK_CLUSTER_HELM_CHART_URI env var?" - exit 1 - fi -} - -user_home="$HOME" -file_path="$user_home/.aws/config" -image="" -registry_id=$(echo "$DEVSPACE_IMAGE" | cut -d'.' -f1) - -if grep -q "staging-crib" "$file_path"; then - echo "Staging AWS config is already applied, role is 'staging-crib'" -else - cat <> "$file_path" -[profile staging-crib] -region=us-west-2 -sso_start_url=https://smartcontract.awsapps.com/start -sso_region=us-west-2 -sso_account_id=${registry_id} -sso_role_name=CRIB-ECR-Power -EOF - echo "~/.aws/config modified, added 'staging-crib" -fi - -# Login through SSO -aws sso login --profile staging-crib -# Update kubeconfig and switch context -export AWS_PROFILE=staging-crib -aws eks update-kubeconfig --name main-stage-cluster --alias main-stage-cluster-crib --profile staging-crib - -# Check if the Docker daemon is running -if docker info > /dev/null 2>&1; then - echo "Docker daemon is running, authorizing registry" -else - echo "Docker daemon is not running, exiting" - exit 1 -fi - -# Login to docker ECR registry -aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin "${registry_id}".dkr.ecr.us-west-2.amazonaws.com - -# Login to helm ECR registry -helm_registry_uri=$(extract_ecr_host_uri "${CHAINLINK_CLUSTER_HELM_CHART_URI}") -aws ecr get-login-password --region us-west-2 | helm registry login "$helm_registry_uri" --username AWS --password-stdin - -devspace use namespace "$1" diff --git a/shell.nix b/shell.nix index 69bf202351d..1fde34fcfd8 100644 --- a/shell.nix +++ b/shell.nix @@ -57,4 +57,10 @@ mkShell' { PGDATA = "db"; CL_DATABASE_URL = "postgresql://chainlink:chainlink@localhost:5432/chainlink_test?sslmode=disable"; + + shellHook = '' + # Find the root of the git repository + repo_root=$(git rev-parse --show-toplevel 2>/dev/null || echo ".") + export PATH=$PATH:$repo_root/crib/scripts + ''; } From ac7d3409ed9bc98af970ca75c3b92e41e4fb01cf Mon Sep 17 00:00:00 2001 From: george-dorin <120329946+george-dorin@users.noreply.github.com> Date: Thu, 25 Apr 2024 17:30:02 +0300 Subject: [PATCH 31/77] Enable jpfc cache by default (#12966) * Draft * Check JuelsPerFeeCoinCache before checking Disable param * Add test * Update NewInMemoryDataSourceCache * Update NewInMemoryDataSourceCache --- .changeset/warm-impalas-return.md | 5 +++ .../ocr2/plugins/median/config/config.go | 1 + core/services/ocr2/plugins/median/services.go | 5 +-- core/services/ocr2/validate/validate_test.go | 41 +++++++++++++++++++ core/services/ocrcommon/data_source.go | 17 +++++--- core/services/ocrcommon/data_source_test.go | 6 +-- 6 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 .changeset/warm-impalas-return.md diff --git a/.changeset/warm-impalas-return.md b/.changeset/warm-impalas-return.md new file mode 100644 index 00000000000..167d831692c --- /dev/null +++ b/.changeset/warm-impalas-return.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#added JuelsPerFeeCoinCache is enabled by default for OCR2 jobs, added `Disable` field under [pluginConfig.JuelsPerFeeCoinCache] tag to disable this feature (e.g. Disable=true) diff --git a/core/services/ocr2/plugins/median/config/config.go b/core/services/ocr2/plugins/median/config/config.go index 9cfda641552..310662ef6c0 100644 --- a/core/services/ocr2/plugins/median/config/config.go +++ b/core/services/ocr2/plugins/median/config/config.go @@ -20,6 +20,7 @@ type PluginConfig struct { } type JuelsPerFeeCoinCache struct { + Disable bool `json:"disable"` UpdateInterval models.Interval `json:"updateInterval"` StalenessAlertThreshold models.Interval `json:"stalenessAlertThreshold"` } diff --git a/core/services/ocr2/plugins/median/services.go b/core/services/ocr2/plugins/median/services.go index 779ea4f346c..e2b8da13407 100644 --- a/core/services/ocr2/plugins/median/services.go +++ b/core/services/ocr2/plugins/median/services.go @@ -12,7 +12,6 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/loop" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-feeds/median" - "github.com/smartcontractkit/chainlink/v2/core/config/env" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services" @@ -127,9 +126,9 @@ func NewMedianServices(ctx context.Context, CreatedAt: time.Now(), }, lggr) - if pluginConfig.JuelsPerFeeCoinCache != nil { + if pluginConfig.JuelsPerFeeCoinCache == nil || (pluginConfig.JuelsPerFeeCoinCache != nil && !pluginConfig.JuelsPerFeeCoinCache.Disable) { lggr.Infof("juelsPerFeeCoin data source caching is enabled") - juelsPerFeeCoinSourceCache, err2 := ocrcommon.NewInMemoryDataSourceCache(juelsPerFeeCoinSource, kvStore, *pluginConfig.JuelsPerFeeCoinCache) + juelsPerFeeCoinSourceCache, err2 := ocrcommon.NewInMemoryDataSourceCache(juelsPerFeeCoinSource, kvStore, pluginConfig.JuelsPerFeeCoinCache) if err2 != nil { return nil, err2 } diff --git a/core/services/ocr2/validate/validate_test.go b/core/services/ocr2/validate/validate_test.go index 305a727d030..fad5a36e51f 100644 --- a/core/services/ocr2/validate/validate_test.go +++ b/core/services/ocr2/validate/validate_test.go @@ -693,6 +693,47 @@ Command="some random command" require.Error(t, err) require.ErrorContains(t, err, "failed to find binary") }, + }, { + name: "minimal OCR2 oracle spec with JuelsPerFeeCoinCache", + toml: ` +type = "offchainreporting2" +pluginType = "median" +schemaVersion = 1 +relay = "evm" +contractID = "0x613a38AC1659769640aaE063C651F48E0250454C" +observationSource = """ +ds1 [type=bridge name=voter_turnout]; +ds1_parse [type=jsonparse path="one,two"]; +ds1_multiply [type=multiply times=1.23]; +ds1 -> ds1_parse -> ds1_multiply -> answer1; +answer1 [type=median index=0]; +""" +[relayConfig] +chainID = 1337 +[pluginConfig] +juelsPerFeeCoinSource = """ +ds1 [type=bridge name=voter_turnout]; +ds1_parse [type=jsonparse path="one,two"]; +ds1_multiply [type=multiply times=1.23]; +ds1 -> ds1_parse -> ds1_multiply -> answer1; +answer1 [type=median index=0]; +""" +[pluginConfig.JuelsPerFeeCoinCache] +Disable=false +UpdateInterval="1m" +`, + assertion: func(t *testing.T, os job.Job, err error) { + require.NoError(t, err) + b, err := jsonapi.Marshal(os.OCR2OracleSpec) + require.NoError(t, err) + var r job.OCR2OracleSpec + err = jsonapi.Unmarshal(b, &r) + require.NoError(t, err) + assert.Equal(t, "median", string(r.PluginType)) + var pc medianconfig.PluginConfig + require.NoError(t, json.Unmarshal(r.PluginConfig.Bytes(), &pc)) + require.NoError(t, medianconfig.ValidatePluginConfig(pc)) + }, }, } diff --git a/core/services/ocrcommon/data_source.go b/core/services/ocrcommon/data_source.go index 9ca111dea68..cb544e01639 100644 --- a/core/services/ocrcommon/data_source.go +++ b/core/services/ocrcommon/data_source.go @@ -113,18 +113,23 @@ type DataSourceCacheService interface { median.DataSource } -func NewInMemoryDataSourceCache(ds median.DataSource, kvStore job.KVStore, cacheCfg config.JuelsPerFeeCoinCache) (DataSourceCacheService, error) { +func NewInMemoryDataSourceCache(ds median.DataSource, kvStore job.KVStore, cacheCfg *config.JuelsPerFeeCoinCache) (DataSourceCacheService, error) { inMemoryDS, ok := ds.(*inMemoryDataSource) if !ok { return nil, errors.Errorf("unsupported data source type: %T, only inMemoryDataSource supported", ds) } - - updateInterval, stalenessAlertThreshold := cacheCfg.UpdateInterval.Duration(), cacheCfg.StalenessAlertThreshold.Duration() - if updateInterval == 0 { + var updateInterval, stalenessAlertThreshold time.Duration + if cacheCfg == nil { updateInterval = defaultUpdateInterval - } - if stalenessAlertThreshold == 0 { stalenessAlertThreshold = defaultStalenessAlertThreshold + } else { + updateInterval, stalenessAlertThreshold = cacheCfg.UpdateInterval.Duration(), cacheCfg.StalenessAlertThreshold.Duration() + if updateInterval == 0 { + updateInterval = defaultUpdateInterval + } + if stalenessAlertThreshold == 0 { + stalenessAlertThreshold = defaultStalenessAlertThreshold + } } dsCache := &inMemoryDataSourceCache{ diff --git a/core/services/ocrcommon/data_source_test.go b/core/services/ocrcommon/data_source_test.go index 05ba0f4aa42..a62852eaced 100644 --- a/core/services/ocrcommon/data_source_test.go +++ b/core/services/ocrcommon/data_source_test.go @@ -80,7 +80,7 @@ func Test_CachedInMemoryDataSourceErrHandling(t *testing.T) { mockKVStore := mocks.KVStore{} mockKVStore.On("Store", mock.Anything, mock.Anything, mock.Anything).Return(nil) mockKVStore.On("Get", mock.Anything, mock.Anything).Return(nil, nil) - dsCache, err := ocrcommon.NewInMemoryDataSourceCache(ds, &mockKVStore, config.JuelsPerFeeCoinCache{UpdateInterval: models.Interval(time.Second * 2)}) + dsCache, err := ocrcommon.NewInMemoryDataSourceCache(ds, &mockKVStore, &config.JuelsPerFeeCoinCache{UpdateInterval: models.Interval(time.Second * 2)}) require.NoError(t, err) servicetest.Run(t, dsCache) @@ -114,7 +114,7 @@ func Test_CachedInMemoryDataSourceErrHandling(t *testing.T) { mockKVStore.On("Get", mock.Anything, mock.Anything).Return(result, nil) // set updater to a long time so that it doesn't log errors after the test is done - dsCache, err := ocrcommon.NewInMemoryDataSourceCache(ds, &mockKVStore, config.JuelsPerFeeCoinCache{UpdateInterval: models.Interval(time.Hour * 100)}) + dsCache, err := ocrcommon.NewInMemoryDataSourceCache(ds, &mockKVStore, &config.JuelsPerFeeCoinCache{UpdateInterval: models.Interval(time.Hour * 100)}) require.NoError(t, err) changeResultValue(runner, "-1", true, false) servicetest.Run(t, dsCache) @@ -133,7 +133,7 @@ func Test_CachedInMemoryDataSourceErrHandling(t *testing.T) { mockKVStore.On("Get", mock.Anything, mock.Anything).Return(nil, assert.AnError) // set updater to a long time so that it doesn't log errors after the test is done - dsCache, err := ocrcommon.NewInMemoryDataSourceCache(ds, &mockKVStore, config.JuelsPerFeeCoinCache{UpdateInterval: models.Interval(time.Hour * 100)}) + dsCache, err := ocrcommon.NewInMemoryDataSourceCache(ds, &mockKVStore, &config.JuelsPerFeeCoinCache{UpdateInterval: models.Interval(time.Hour * 100)}) require.NoError(t, err) changeResultValue(runner, "-1", true, false) servicetest.Run(t, dsCache) From 83d6f2004cfb27340158a1e356e4f65c1ad46e43 Mon Sep 17 00:00:00 2001 From: Ryan Tinianov Date: Thu, 25 Apr 2024 11:19:55 -0400 Subject: [PATCH 32/77] Pass client to chain reader instead of the whole chain (#12967) --- core/services/relay/evm/chain_reader.go | 6 ++---- core/services/relay/evm/chain_reader_test.go | 15 ++++++--------- core/services/relay/evm/evm.go | 2 +- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/core/services/relay/evm/chain_reader.go b/core/services/relay/evm/chain_reader.go index e7035f4716f..df46e7636d2 100644 --- a/core/services/relay/evm/chain_reader.go +++ b/core/services/relay/evm/chain_reader.go @@ -16,8 +16,6 @@ import ( commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" - "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services" @@ -41,11 +39,11 @@ type chainReader struct { // NewChainReaderService is a constructor for ChainReader, returns nil if there is any error // Note that the ChainReaderService returned does not support anonymous events. -func NewChainReaderService(ctx context.Context, lggr logger.Logger, lp logpoller.LogPoller, chain legacyevm.Chain, config types.ChainReaderConfig) (ChainReaderService, error) { +func NewChainReaderService(ctx context.Context, lggr logger.Logger, lp logpoller.LogPoller, client evmclient.Client, config types.ChainReaderConfig) (ChainReaderService, error) { cr := &chainReader{ lggr: lggr.Named("ChainReader"), lp: lp, - client: chain.Client(), + client: client, contractBindings: contractBindings{}, parsed: &parsedTypes{encoderDefs: map[string]types.CodecEntry{}, decoderDefs: map[string]types.CodecEntry{}}, } diff --git a/core/services/relay/evm/chain_reader_test.go b/core/services/relay/evm/chain_reader_test.go index edca5c19b60..3a0d45b67c5 100644 --- a/core/services/relay/evm/chain_reader_test.go +++ b/core/services/relay/evm/chain_reader_test.go @@ -32,7 +32,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm/mocks" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/chain_reader_example" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" @@ -120,7 +119,7 @@ func triggerFourTopics(t *testing.T, it *chainReaderInterfaceTester, i1, i2, i3 } type chainReaderInterfaceTester struct { - chain *mocks.Chain + client client.Client address string address2 string chainConfig types.ChainReaderConfig @@ -157,12 +156,11 @@ func (it *chainReaderInterfaceTester) Setup(t *testing.T) { }) // can re-use the same chain for tests, just make new contract for each test - if it.chain != nil { + if it.client != nil { it.deployNewContracts(t) return } - it.chain = &mocks.Chain{} it.setupChainNoClient(t) testStruct := CreateTestStruct(0, it) @@ -240,7 +238,7 @@ func (it *chainReaderInterfaceTester) Setup(t *testing.T) { }, }, } - it.chain.On("Client").Return(client.NewSimulatedBackendClient(t, it.sim, big.NewInt(1337))) + it.client = client.NewSimulatedBackendClient(t, it.sim, big.NewInt(1337)) it.deployNewContracts(t) } @@ -270,10 +268,9 @@ func (it *chainReaderInterfaceTester) GetChainReader(t *testing.T) clcommontypes RpcBatchSize: 1, KeepFinalizedBlocksDepth: 10000, } - lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, db, lggr), it.chain.Client(), lggr, lpOpts) + lp := logpoller.NewLogPoller(logpoller.NewORM(testutils.SimulatedChainID, db, lggr), it.client, lggr, lpOpts) require.NoError(t, lp.Start(ctx)) - it.chain.On("LogPoller").Return(lp) - cr, err := evm.NewChainReaderService(ctx, lggr, lp, it.chain, it.chainConfig) + cr, err := evm.NewChainReaderService(ctx, lggr, lp, it.client, it.chainConfig) require.NoError(t, err) require.NoError(t, cr.Start(ctx)) it.cr = cr @@ -288,7 +285,7 @@ func (it *chainReaderInterfaceTester) TriggerEvent(t *testing.T, testStruct *Tes it.sendTxWithTestStruct(t, testStruct, (*chain_reader_example.LatestValueHolderTransactor).TriggerEvent) } -func (it *chainReaderInterfaceTester) GetBindings(t *testing.T) []clcommontypes.BoundContract { +func (it *chainReaderInterfaceTester) GetBindings(_ *testing.T) []clcommontypes.BoundContract { return []clcommontypes.BoundContract{ {Name: AnyContractName, Address: it.address, Pending: true}, {Name: AnySecondContractName, Address: it.address2, Pending: true}, diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index 2f30d40e28d..9097c217590 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -596,7 +596,7 @@ func (r *Relayer) NewMedianProvider(rargs commontypes.RelayArgs, pargs commontyp // allow fallback until chain reader is default and median contract is removed, but still log just in case var chainReaderService ChainReaderService if relayConfig.ChainReader != nil { - if chainReaderService, err = NewChainReaderService(ctx, lggr, r.chain.LogPoller(), r.chain, *relayConfig.ChainReader); err != nil { + if chainReaderService, err = NewChainReaderService(ctx, lggr, r.chain.LogPoller(), r.chain.Client(), *relayConfig.ChainReader); err != nil { return nil, err } From 274a988985e0530676bdfedbdb35dec4cb9fe8b2 Mon Sep 17 00:00:00 2001 From: Lei Date: Thu, 25 Apr 2024 09:14:48 -0700 Subject: [PATCH 33/77] use safe lib for approve (#12923) --- .changeset/dull-dingos-remember.md | 5 +++++ contracts/.changeset/shiny-dragons-sparkle.md | 5 +++++ .../dev/v2_3/AutomationRegistrar2_3.sol | 19 ++++++++++--------- .../automation_registrar_wrapper2_3.go | 2 +- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 5 files changed, 22 insertions(+), 11 deletions(-) create mode 100644 .changeset/dull-dingos-remember.md create mode 100644 contracts/.changeset/shiny-dragons-sparkle.md diff --git a/.changeset/dull-dingos-remember.md b/.changeset/dull-dingos-remember.md new file mode 100644 index 00000000000..7c1b748cff7 --- /dev/null +++ b/.changeset/dull-dingos-remember.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +use safe lib for approve #bugfix diff --git a/contracts/.changeset/shiny-dragons-sparkle.md b/contracts/.changeset/shiny-dragons-sparkle.md new file mode 100644 index 00000000000..7657b5f1446 --- /dev/null +++ b/contracts/.changeset/shiny-dragons-sparkle.md @@ -0,0 +1,5 @@ +--- +"@chainlink/contracts": patch +--- + +use safe lib for approve #bugfix diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistrar2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistrar2_3.sol index ab9d7ae0b20..4284ba62f9d 100644 --- a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistrar2_3.sol +++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistrar2_3.sol @@ -393,6 +393,8 @@ contract AutomationRegistrar2_3 is TypeAndVersionInterface, ConfirmedOwner, IERC /** * @dev register upkeep on AutomationRegistry contract and emit RegistrationApproved event + * @dev safeApprove is deprecated and removed from the latest (v5) OZ release, Use safeIncreaseAllowance when we upgrade OZ (we are on v4.8) + * @dev we stick to the safeApprove because of the older version (v4.8) of safeIncreaseAllowance can't handle USDT correctly, but newer version can */ function _approve(RegistrationParams memory params, bytes32 hash) private returns (uint256) { IAutomationRegistryMaster2_3 registry = s_registry; @@ -406,18 +408,17 @@ contract AutomationRegistrar2_3 is TypeAndVersionInterface, ConfirmedOwner, IERC params.triggerConfig, params.offchainConfig ); - bool success; + if (address(params.billingToken) == address(i_LINK)) { - success = i_LINK.transferAndCall(address(registry), params.amount, abi.encode(upkeepId)); - } else { - success = params.billingToken.approve(address(registry), params.amount); - if (success) { - registry.addFunds(upkeepId, params.amount); + bool success = i_LINK.transferAndCall(address(registry), params.amount, abi.encode(upkeepId)); + if (!success) { + revert TransferFailed(address(registry)); } + } else { + params.billingToken.safeApprove(address(registry), params.amount); + registry.addFunds(upkeepId, params.amount); } - if (!success) { - revert TransferFailed(address(registry)); - } + emit RegistrationApproved(hash, params.name, upkeepId); return upkeepId; } diff --git a/core/gethwrappers/generated/automation_registrar_wrapper2_3/automation_registrar_wrapper2_3.go b/core/gethwrappers/generated/automation_registrar_wrapper2_3/automation_registrar_wrapper2_3.go index 1f6c763d280..dd16a290b7c 100644 --- a/core/gethwrappers/generated/automation_registrar_wrapper2_3/automation_registrar_wrapper2_3.go +++ b/core/gethwrappers/generated/automation_registrar_wrapper2_3/automation_registrar_wrapper2_3.go @@ -58,7 +58,7 @@ type AutomationRegistrar23TriggerRegistrationStorage struct { var AutomationRegistrarMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"LINKAddress\",\"type\":\"address\"},{\"internalType\":\"contractIAutomationRegistryMaster2_3\",\"name\":\"registry\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"}],\"internalType\":\"structAutomationRegistrar2_3.InitialTriggerConfig[]\",\"name\":\"triggerConfigs\",\"type\":\"tuple[]\"},{\"internalType\":\"contractIERC20Metadata[]\",\"name\":\"billingTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"minRegistrationFees\",\"type\":\"uint256[]\"},{\"internalType\":\"contractIWrappedNative\",\"name\":\"wrappedNativeToken\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HashMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientPayment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAdminAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidBillingToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RequestNotFound\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"AutoApproveAllowedSenderSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"displayName\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"RegistrationApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"RegistrationRejected\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"encryptedEmail\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"RegistrationRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"}],\"name\":\"TriggerConfigSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"contractIERC20Metadata\",\"name\":\"billingToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedEmail\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structAutomationRegistrar2_3.RegistrationParams\",\"name\":\"requestParams\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"cancel\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"}],\"name\":\"getAutoApproveAllowedSender\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20Metadata\",\"name\":\"billingToken\",\"type\":\"address\"}],\"name\":\"getMinimumRegistrationAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"getPendingRequest\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRegistry\",\"outputs\":[{\"internalType\":\"contractIAutomationRegistryMaster2_3\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"}],\"name\":\"getTriggerRegistrationDetails\",\"outputs\":[{\"components\":[{\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"approvedCount\",\"type\":\"uint32\"}],\"internalType\":\"structAutomationRegistrar2_3.TriggerRegistrationStorage\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_LINK\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_WRAPPED_NATIVE_TOKEN\",\"outputs\":[{\"internalType\":\"contractIWrappedNative\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"contractIERC20Metadata\",\"name\":\"billingToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedEmail\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structAutomationRegistrar2_3.RegistrationParams\",\"name\":\"requestParams\",\"type\":\"tuple\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"setAutoApproveAllowedSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIAutomationRegistryMaster2_3\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"contractIERC20Metadata[]\",\"name\":\"billingTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"minBalances\",\"type\":\"uint256[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"}],\"name\":\"setTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60c06040523480156200001157600080fd5b5060405162003483380380620034838339810160408190526200003491620005db565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be8162000183565b5050506001600160a01b03808716608052811660a052620000e18584846200022e565b60005b84518110156200017657620001618582815181106200010757620001076200076d565b6020026020010151600001518683815181106200012857620001286200076d565b6020026020010151602001518784815181106200014957620001496200076d565b6020026020010151604001516200032a60201b60201c565b806200016d8162000783565b915050620000e4565b5050505050505062000804565b336001600160a01b03821603620001dd5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b62000238620003d8565b80518251146200025b57604051630dfe930960e41b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b03851617905560005b8251811015620002fb578181815181106200029857620002986200076d565b602002602001015160046000858481518110620002b957620002b96200076d565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055508080620002f29062000783565b91505062000279565b506040517fb9b6902016bd1219d5fa6161243b61e7e9f7f959526dd94ef8fa3e403bf881c390600090a1505050565b62000334620003d8565b60ff83166000908152600660205260409020805483919060ff19166001836002811115620003665762000366620007ab565b021790555060ff831660009081526006602052604090819020805464ffffffff00191661010063ffffffff851602179055517f830a6d06a4e2caac67eba04323de22bdb04f032dd8b3d6a0c52b503d9a7036a390620003cb90859085908590620007c1565b60405180910390a1505050565b6000546001600160a01b03163314620004345760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b6001600160a01b03811681146200044c57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156200048a576200048a6200044f565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620004bb57620004bb6200044f565b604052919050565b60006001600160401b03821115620004df57620004df6200044f565b5060051b60200190565b600082601f830112620004fb57600080fd5b81516020620005146200050e83620004c3565b62000490565b82815260059290921b840181019181810190868411156200053457600080fd5b8286015b848110156200055c5780516200054e8162000436565b835291830191830162000538565b509695505050505050565b600082601f8301126200057957600080fd5b815160206200058c6200050e83620004c3565b82815260059290921b84018101918181019086841115620005ac57600080fd5b8286015b848110156200055c5780518352918301918301620005b0565b8051620005d68162000436565b919050565b60008060008060008060c08789031215620005f557600080fd5b8651620006028162000436565b80965050602080880151620006178162000436565b60408901519096506001600160401b03808211156200063557600080fd5b818a0191508a601f8301126200064a57600080fd5b81516200065b6200050e82620004c3565b81815260609091028301840190848101908d8311156200067a57600080fd5b938501935b8285101562000701576060858f0312156200069a5760008081fd5b620006a462000465565b855160ff81168114620006b75760008081fd5b81528587015160038110620006cc5760008081fd5b81880152604086015163ffffffff81168114620006e95760008081fd5b6040820152825260609490940193908501906200067f565b60608d015190995094505050808311156200071b57600080fd5b620007298b848c01620004e9565b955060808a01519250808311156200074057600080fd5b50506200075089828a0162000567565b9250506200076160a08801620005c9565b90509295509295509295565b634e487b7160e01b600052603260045260246000fd5b600060018201620007a457634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052602160045260246000fd5b60ff841681526060810160038410620007ea57634e487b7160e01b600052602160045260246000fd5b83602083015263ffffffff83166040830152949350505050565b60805160a051612c2f620008546000396000818161027b015281816105a601526106390152600081816104b301528181610a0301528181610a6c0152818161168501526116dc0152612c2f6000f3fe6080604052600436106101295760003560e01c806388b12d55116100a5578063accb832311610074578063befdae4611610059578063befdae46146104a1578063c4d252f5146104d5578063f2fde38b146104f557600080fd5b8063accb832314610461578063b5ff5b411461048157600080fd5b806388b12d55146103085780638da5cb5b146103d3578063a2b1ff94146103fe578063a4c0ed361461044157600080fd5b80635ab1bd53116100fc5780636bf7d75f116100e15780636bf7d75f1461026957806379ba50971461029d5780637e776f7f146102b257600080fd5b80635ab1bd53146101fd57806366ab87f91461024957600080fd5b8063181f5a771461012e578063212d08841461018d5780632ce3a14a146101ba578063367b9b4f146101db575b600080fd5b34801561013a57600080fd5b506101776040518060400160405280601981526020017f4175746f6d6174696f6e52656769737472617220322e332e300000000000000081525081565b6040516101849190611e6f565b60405180910390f35b34801561019957600080fd5b506101ad6101a8366004611e9f565b610515565b6040516101849190611f24565b6101cd6101c836600461223b565b6105a2565b604051908152602001610184565b3480156101e757600080fd5b506101fb6101f636600461227e565b610710565b005b34801561020957600080fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610184565b34801561025557600080fd5b506101fb610264366004612346565b6107a2565b34801561027557600080fd5b506102247f000000000000000000000000000000000000000000000000000000000000000081565b3480156102a957600080fd5b506101fb6108e9565b3480156102be57600080fd5b506102f86102cd36600461241c565b73ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205460ff1690565b6040519015158152602001610184565b34801561031457600080fd5b5061039a610323366004612439565b6000908152600560209081526040918290208251606081018452815473ffffffffffffffffffffffffffffffffffffffff808216808452740100000000000000000000000000000000000000009092046bffffffffffffffffffffffff169483018590526001909301549092169301929092529091565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526bffffffffffffffffffffffff909116602083015201610184565b3480156103df57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610224565b34801561040a57600080fd5b506101cd61041936600461241c565b73ffffffffffffffffffffffffffffffffffffffff1660009081526004602052604090205490565b34801561044d57600080fd5b506101fb61045c366004612452565b6109eb565b34801561046d57600080fd5b506101fb61047c3660046124db565b610b19565b34801561048d57600080fd5b506101fb61049c366004612526565b610c84565b3480156104ad57600080fd5b506102247f000000000000000000000000000000000000000000000000000000000000000081565b3480156104e157600080fd5b506101fb6104f0366004612439565b610d63565b34801561050157600080fd5b506101fb61051036600461241c565b610f2a565b60408051606080820183526000808352602080840182905283850182905260ff86811683526006909152908490208451928301909452835492939192839116600281111561056557610565611eba565b600281111561057657610576611eba565b8152905463ffffffff610100820481166020840152650100000000009091041660409091015292915050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168260a0015173ffffffffffffffffffffffffffffffffffffffff1614801561060257503415155b156106bd5761061034610f3e565b82602001906bffffffffffffffffffffffff1690816bffffffffffffffffffffffff16815250507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561069f57600080fd5b505af11580156106b3573d6000803e3d6000fd5b5050505050610700565b610700333084602001516bffffffffffffffffffffffff168560a0015173ffffffffffffffffffffffffffffffffffffffff16610fe0909392919063ffffffff16565b61070a82336110c2565b92915050565b610718611529565b73ffffffffffffffffffffffffffffffffffffffff821660008181526003602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915591519182527f20c6237dac83526a849285a9f79d08a483291bdd3a056a0ef9ae94ecee1ad356910160405180910390a25050565b6107aa611529565b80518251146107e5576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851617905560005b82518110156108ba578181815181106108435761084361256f565b6020026020010151600460008584815181106108615761086161256f565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080806108b2906125cd565b915050610828565b506040517fb9b6902016bd1219d5fa6161243b61e7e9f7f959526dd94ef8fa3e403bf881c390600090a1505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461096f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610a5a576040517f018d10be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610a688284018461223b565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168160a0015173ffffffffffffffffffffffffffffffffffffffff1614610af3576040517f018d10be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6bffffffffffffffffffffffff84166020820152610b1181866110c2565b505050505050565b610b21611529565b6000818152600560209081526040918290208251606081018452815473ffffffffffffffffffffffffffffffffffffffff808216808452740100000000000000000000000000000000000000009092046bffffffffffffffffffffffff16948301949094526001909201549092169282019290925290610bcd576040517f4b13b31e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083604051602001610be091906126b9565b604051602081830303815290604052805190602001209050808314610c31576040517f3f4d605300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083815260056020526040812090815560010180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055610c7d610c7785612875565b826115ac565b5050505050565b610c8c611529565b60ff8316600090815260066020526040902080548391907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001836002811115610cd957610cd9611eba565b021790555060ff83166000908152600660205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010063ffffffff851602179055517f830a6d06a4e2caac67eba04323de22bdb04f032dd8b3d6a0c52b503d9a7036a390610d5690859085908590612881565b60405180910390a1505050565b6000818152600560209081526040918290208251606081018452815473ffffffffffffffffffffffffffffffffffffffff808216808452740100000000000000000000000000000000000000009092046bffffffffffffffffffffffff16948301949094526001909201549092169282019290925290331480610dfd575060005473ffffffffffffffffffffffffffffffffffffffff1633145b610e33576040517f61685c2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805173ffffffffffffffffffffffffffffffffffffffff16610e81576040517f4b13b31e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600560209081526040808320928355600190920180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905582519083015191830151610efb9273ffffffffffffffffffffffffffffffffffffffff90911691906bffffffffffffffffffffffff1661198f565b60405182907f3663fb28ebc87645eb972c9dad8521bf665c623f287e79f1c56f1eb374b82a2290600090a25050565b610f32611529565b610f3b816119ea565b50565b60006bffffffffffffffffffffffff821115610fdc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610966565b5090565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526110bc9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611adf565b50505050565b60a082015173ffffffffffffffffffffffffffffffffffffffff166000908152600460209081526040822054908401516bffffffffffffffffffffffff161015611138576040517fcd1c886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604083015173ffffffffffffffffffffffffffffffffffffffff16611189576040517f05bb467c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025460a08401516040517fa538b2eb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063a538b2eb90602401602060405180830381865afa1580156111fd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122191906128ac565b611257576040517f1183afea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008360405160200161126a91906128c9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600590935291205490915073ffffffffffffffffffffffffffffffffffffffff16156112fd576040517f357d0cc400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836000015173ffffffffffffffffffffffffffffffffffffffff16817f7684390ebb103102f7f48c71439c2408713f8d437782a6fab2756acc0e42c1b78660c001518760e00151886060015189604001518a608001518b61012001518c61014001518d61010001518e6020015160405161137f99989796959493929190612a35565b60405180910390a3608084015160ff908116600090815260066020526040808220815160608101909252805492936114029383911660028111156113c5576113c5611eba565b60028111156113d6576113d6611eba565b8152905463ffffffff610100820481166020840152650100000000009091041660409091015285611beb565b1561146a57608085015160ff166000908152600660205260409020805465010000000000900463ffffffff1690600561143a83612af0565b91906101000a81548163ffffffff021916908363ffffffff1602179055505061146385836115ac565b9050611521565b604080516060810182528682015173ffffffffffffffffffffffffffffffffffffffff90811682526020808901516bffffffffffffffffffffffff90811682850190815260a08b01518416858701908152600089815260059094529590922093519151167401000000000000000000000000000000000000000002908216178255915160019091018054919092167fffffffffffffffffffffffff0000000000000000000000000000000000000000919091161790555b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146115aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610966565b565b60025482516060840151604080860151608087015160a08801516101008901516101208a01516101408b015195517fc62cf68400000000000000000000000000000000000000000000000000000000815260009973ffffffffffffffffffffffffffffffffffffffff16988a988a9863c62cf6849861163c98939792969095939492939092909190600401612b13565b6020604051808303816000875af115801561165b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061167f9190612ba1565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168660a0015173ffffffffffffffffffffffffffffffffffffffff16036117a6577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634000aea08488602001518560405160200161172f91815260200190565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161175c93929190612bba565b6020604051808303816000875af115801561177b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061179f91906128ac565b90506118fa565b60a086015160208701516040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86811660048301526bffffffffffffffffffffffff909216602482015291169063095ea7b3906044016020604051808303816000875af1158015611833573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185791906128ac565b905080156118fa5760208601516040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff909116602482015273ffffffffffffffffffffffffffffffffffffffff84169063948108f790604401600060405180830381600087803b1580156118e157600080fd5b505af11580156118f5573d6000803e3d6000fd5b505050505b80611949576040517f39f1c8d900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610966565b81857fb9a292fb7e3edd920cd2d2829a3615a640c43fd7de0a0820aa0668feb4c37d4b8860c0015160405161197e9190611e6f565b60405180910390a350949350505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526119e59084907fa9059cbb000000000000000000000000000000000000000000000000000000009060640161103a565b505050565b3373ffffffffffffffffffffffffffffffffffffffff821603611a69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610966565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611b41826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611c909092919063ffffffff16565b8051909150156119e55780806020019051810190611b5f91906128ac565b6119e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610966565b60008083516002811115611c0157611c01611eba565b03611c0e5750600061070a565b600183516002811115611c2357611c23611eba565b148015611c56575073ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604090205460ff16155b15611c635750600061070a565b826020015163ffffffff16836040015163ffffffff161015611c875750600161070a565b50600092915050565b60606115218484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051611cc49190612c06565b60006040518083038185875af1925050503d8060008114611d01576040519150601f19603f3d011682016040523d82523d6000602084013e611d06565b606091505b5091509150611d1787838387611d22565b979650505050505050565b60608315611db8578251600003611db15773ffffffffffffffffffffffffffffffffffffffff85163b611db1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610966565b5081611521565b6115218383815115611dcd5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109669190611e6f565b60005b83811015611e1c578181015183820152602001611e04565b50506000910152565b60008151808452611e3d816020860160208601611e01565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611e826020830184611e25565b9392505050565b803560ff81168114611e9a57600080fd5b919050565b600060208284031215611eb157600080fd5b611e8282611e89565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110611f20577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b6000606082019050611f37828451611ee9565b602083015163ffffffff8082166020850152806040860151166040850152505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715611fb057611fb0611f5d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611ffd57611ffd611f5d565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f3b57600080fd5b8035611e9a81612005565b80356bffffffffffffffffffffffff81168114611e9a57600080fd5b803563ffffffff81168114611e9a57600080fd5b600082601f83011261207357600080fd5b813567ffffffffffffffff81111561208d5761208d611f5d565b6120be60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611fb6565b8181528460208386010111156120d357600080fd5b816020850160208301376000918101602001919091529392505050565b6000610160828403121561210357600080fd5b61210b611f8c565b905061211682612027565b815261212460208301612032565b602082015261213560408301612027565b60408201526121466060830161204e565b606082015261215760808301611e89565b608082015261216860a08301612027565b60a082015260c082013567ffffffffffffffff8082111561218857600080fd5b61219485838601612062565b60c084015260e08401359150808211156121ad57600080fd5b6121b985838601612062565b60e0840152610100915081840135818111156121d457600080fd5b6121e086828701612062565b8385015250610120915081840135818111156121fb57600080fd5b61220786828701612062565b83850152506101409150818401358181111561222257600080fd5b61222e86828701612062565b8385015250505092915050565b60006020828403121561224d57600080fd5b813567ffffffffffffffff81111561226457600080fd5b611521848285016120f0565b8015158114610f3b57600080fd5b6000806040838503121561229157600080fd5b823561229c81612005565b915060208301356122ac81612270565b809150509250929050565b600067ffffffffffffffff8211156122d1576122d1611f5d565b5060051b60200190565b600082601f8301126122ec57600080fd5b813560206123016122fc836122b7565b611fb6565b82815260059290921b8401810191818101908684111561232057600080fd5b8286015b8481101561233b5780358352918301918301612324565b509695505050505050565b60008060006060848603121561235b57600080fd5b833561236681612005565b925060208481013567ffffffffffffffff8082111561238457600080fd5b818701915087601f83011261239857600080fd5b81356123a66122fc826122b7565b81815260059190911b8301840190848101908a8311156123c557600080fd5b938501935b828510156123ec5784356123dd81612005565b825293850193908501906123ca565b96505050604087013592508083111561240457600080fd5b5050612412868287016122db565b9150509250925092565b60006020828403121561242e57600080fd5b8135611e8281612005565b60006020828403121561244b57600080fd5b5035919050565b6000806000806060858703121561246857600080fd5b843561247381612005565b935060208501359250604085013567ffffffffffffffff8082111561249757600080fd5b818701915087601f8301126124ab57600080fd5b8135818111156124ba57600080fd5b8860208285010111156124cc57600080fd5b95989497505060200194505050565b600080604083850312156124ee57600080fd5b823567ffffffffffffffff81111561250557600080fd5b8301610160818603121561251857600080fd5b946020939093013593505050565b60008060006060848603121561253b57600080fd5b61254484611e89565b925060208401356003811061255857600080fd5b91506125666040850161204e565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036125fe576125fe61259e565b5060010190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261263a57600080fd5b830160208101925035905067ffffffffffffffff81111561265a57600080fd5b80360382131561266957600080fd5b9250929050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526126e7602082016126cd84612027565b73ffffffffffffffffffffffffffffffffffffffff169052565b60006126f560208401612032565b6bffffffffffffffffffffffff811660408401525061271660408401612027565b73ffffffffffffffffffffffffffffffffffffffff811660608401525061273f6060840161204e565b63ffffffff811660808401525061275860808401611e89565b60ff811660a08401525061276e60a08401612027565b73ffffffffffffffffffffffffffffffffffffffff811660c08401525061279860c0840184612605565b6101608060e08601526127b061018086018385612670565b92506127bf60e0870187612605565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06101008188870301818901526127f9868685612670565b9550612807818a018a612605565b9550925050610120818887030181890152612823868685612670565b9550612831818a018a612605565b955092505061014081888703018189015261284d868685612670565b955061285b818a018a612605565b955092505080878603018388015250611d17848483612670565b600061070a36836120f0565b60ff84168152606081016128986020830185611ee9565b63ffffffff83166040830152949350505050565b6000602082840312156128be57600080fd5b8151611e8281612270565b602081526128f060208201835173ffffffffffffffffffffffffffffffffffffffff169052565b6000602083015161291160408401826bffffffffffffffffffffffff169052565b50604083015173ffffffffffffffffffffffffffffffffffffffff8116606084015250606083015163ffffffff8116608084015250608083015160ff811660a08401525060a083015173ffffffffffffffffffffffffffffffffffffffff811660c08401525060c08301516101608060e0850152612993610180850183611e25565b915060e08501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06101008187860301818801526129d18584611e25565b9450808801519250506101208187860301818801526129f08584611e25565b945080880151925050610140818786030181880152612a0f8584611e25565b908801518782039092018488015293509050612a2b8382611e25565b9695505050505050565b6000610120808352612a498184018d611e25565b90508281036020840152612a5d818c611e25565b905063ffffffff8a16604084015273ffffffffffffffffffffffffffffffffffffffff8916606084015260ff8816608084015282810360a0840152612aa28188611e25565b905082810360c0840152612ab68187611e25565b905082810360e0840152612aca8186611e25565b9150506bffffffffffffffffffffffff83166101008301529a9950505050505050505050565b600063ffffffff808316818103612b0957612b0961259e565b6001019392505050565b600061010073ffffffffffffffffffffffffffffffffffffffff808c16845263ffffffff8b166020850152808a16604085015260ff891660608501528088166080850152508060a0840152612b6a81840187611e25565b905082810360c0840152612b7e8186611e25565b905082810360e0840152612b928185611e25565b9b9a5050505050505050505050565b600060208284031215612bb357600080fd5b5051919050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff83166020820152606060408201526000612bfd6060830184611e25565b95945050505050565b60008251612c18818460208701611e01565b919091019291505056fea164736f6c6343000813000a", + Bin: "0x60c06040523480156200001157600080fd5b506040516200358d3803806200358d8339810160408190526200003491620005db565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be8162000183565b5050506001600160a01b03808716608052811660a052620000e18584846200022e565b60005b84518110156200017657620001618582815181106200010757620001076200076d565b6020026020010151600001518683815181106200012857620001286200076d565b6020026020010151602001518784815181106200014957620001496200076d565b6020026020010151604001516200032a60201b60201c565b806200016d8162000783565b915050620000e4565b5050505050505062000804565b336001600160a01b03821603620001dd5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b62000238620003d8565b80518251146200025b57604051630dfe930960e41b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b03851617905560005b8251811015620002fb578181815181106200029857620002986200076d565b602002602001015160046000858481518110620002b957620002b96200076d565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055508080620002f29062000783565b91505062000279565b506040517fb9b6902016bd1219d5fa6161243b61e7e9f7f959526dd94ef8fa3e403bf881c390600090a1505050565b62000334620003d8565b60ff83166000908152600660205260409020805483919060ff19166001836002811115620003665762000366620007ab565b021790555060ff831660009081526006602052604090819020805464ffffffff00191661010063ffffffff851602179055517f830a6d06a4e2caac67eba04323de22bdb04f032dd8b3d6a0c52b503d9a7036a390620003cb90859085908590620007c1565b60405180910390a1505050565b6000546001600160a01b03163314620004345760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b6001600160a01b03811681146200044c57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156200048a576200048a6200044f565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620004bb57620004bb6200044f565b604052919050565b60006001600160401b03821115620004df57620004df6200044f565b5060051b60200190565b600082601f830112620004fb57600080fd5b81516020620005146200050e83620004c3565b62000490565b82815260059290921b840181019181810190868411156200053457600080fd5b8286015b848110156200055c5780516200054e8162000436565b835291830191830162000538565b509695505050505050565b600082601f8301126200057957600080fd5b815160206200058c6200050e83620004c3565b82815260059290921b84018101918181019086841115620005ac57600080fd5b8286015b848110156200055c5780518352918301918301620005b0565b8051620005d68162000436565b919050565b60008060008060008060c08789031215620005f557600080fd5b8651620006028162000436565b80965050602080880151620006178162000436565b60408901519096506001600160401b03808211156200063557600080fd5b818a0191508a601f8301126200064a57600080fd5b81516200065b6200050e82620004c3565b81815260609091028301840190848101908d8311156200067a57600080fd5b938501935b8285101562000701576060858f0312156200069a5760008081fd5b620006a462000465565b855160ff81168114620006b75760008081fd5b81528587015160038110620006cc5760008081fd5b81880152604086015163ffffffff81168114620006e95760008081fd5b6040820152825260609490940193908501906200067f565b60608d015190995094505050808311156200071b57600080fd5b620007298b848c01620004e9565b955060808a01519250808311156200074057600080fd5b50506200075089828a0162000567565b9250506200076160a08801620005c9565b90509295509295509295565b634e487b7160e01b600052603260045260246000fd5b600060018201620007a457634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052602160045260246000fd5b60ff841681526060810160038410620007ea57634e487b7160e01b600052602160045260246000fd5b83602083015263ffffffff83166040830152949350505050565b60805160a051612d39620008546000396000818161027b015281816105a601526106390152600081816104b301528181610a0301528181610a6c0152818161168301526116dc0152612d396000f3fe6080604052600436106101295760003560e01c806388b12d55116100a5578063accb832311610074578063befdae4611610059578063befdae46146104a1578063c4d252f5146104d5578063f2fde38b146104f557600080fd5b8063accb832314610461578063b5ff5b411461048157600080fd5b806388b12d55146103085780638da5cb5b146103d3578063a2b1ff94146103fe578063a4c0ed361461044157600080fd5b80635ab1bd53116100fc5780636bf7d75f116100e15780636bf7d75f1461026957806379ba50971461029d5780637e776f7f146102b257600080fd5b80635ab1bd53146101fd57806366ab87f91461024957600080fd5b8063181f5a771461012e578063212d08841461018d5780632ce3a14a146101ba578063367b9b4f146101db575b600080fd5b34801561013a57600080fd5b506101776040518060400160405280601981526020017f4175746f6d6174696f6e52656769737472617220322e332e300000000000000081525081565b6040516101849190611f79565b60405180910390f35b34801561019957600080fd5b506101ad6101a8366004611fa9565b610515565b604051610184919061202e565b6101cd6101c8366004612345565b6105a2565b604051908152602001610184565b3480156101e757600080fd5b506101fb6101f6366004612388565b610710565b005b34801561020957600080fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610184565b34801561025557600080fd5b506101fb610264366004612450565b6107a2565b34801561027557600080fd5b506102247f000000000000000000000000000000000000000000000000000000000000000081565b3480156102a957600080fd5b506101fb6108e9565b3480156102be57600080fd5b506102f86102cd366004612526565b73ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205460ff1690565b6040519015158152602001610184565b34801561031457600080fd5b5061039a610323366004612543565b6000908152600560209081526040918290208251606081018452815473ffffffffffffffffffffffffffffffffffffffff808216808452740100000000000000000000000000000000000000009092046bffffffffffffffffffffffff169483018590526001909301549092169301929092529091565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526bffffffffffffffffffffffff909116602083015201610184565b3480156103df57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610224565b34801561040a57600080fd5b506101cd610419366004612526565b73ffffffffffffffffffffffffffffffffffffffff1660009081526004602052604090205490565b34801561044d57600080fd5b506101fb61045c36600461255c565b6109eb565b34801561046d57600080fd5b506101fb61047c3660046125e5565b610b19565b34801561048d57600080fd5b506101fb61049c366004612630565b610c84565b3480156104ad57600080fd5b506102247f000000000000000000000000000000000000000000000000000000000000000081565b3480156104e157600080fd5b506101fb6104f0366004612543565b610d63565b34801561050157600080fd5b506101fb610510366004612526565b610f2a565b60408051606080820183526000808352602080840182905283850182905260ff86811683526006909152908490208451928301909452835492939192839116600281111561056557610565611fc4565b600281111561057657610576611fc4565b8152905463ffffffff610100820481166020840152650100000000009091041660409091015292915050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168260a0015173ffffffffffffffffffffffffffffffffffffffff1614801561060257503415155b156106bd5761061034610f3e565b82602001906bffffffffffffffffffffffff1690816bffffffffffffffffffffffff16815250507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561069f57600080fd5b505af11580156106b3573d6000803e3d6000fd5b5050505050610700565b610700333084602001516bffffffffffffffffffffffff168560a0015173ffffffffffffffffffffffffffffffffffffffff16610fe0909392919063ffffffff16565b61070a82336110c2565b92915050565b610718611529565b73ffffffffffffffffffffffffffffffffffffffff821660008181526003602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915591519182527f20c6237dac83526a849285a9f79d08a483291bdd3a056a0ef9ae94ecee1ad356910160405180910390a25050565b6107aa611529565b80518251146107e5576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851617905560005b82518110156108ba5781818151811061084357610843612679565b60200260200101516004600085848151811061086157610861612679565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080806108b2906126d7565b915050610828565b506040517fb9b6902016bd1219d5fa6161243b61e7e9f7f959526dd94ef8fa3e403bf881c390600090a1505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461096f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610a5a576040517f018d10be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610a6882840184612345565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168160a0015173ffffffffffffffffffffffffffffffffffffffff1614610af3576040517f018d10be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6bffffffffffffffffffffffff84166020820152610b1181866110c2565b505050505050565b610b21611529565b6000818152600560209081526040918290208251606081018452815473ffffffffffffffffffffffffffffffffffffffff808216808452740100000000000000000000000000000000000000009092046bffffffffffffffffffffffff16948301949094526001909201549092169282019290925290610bcd576040517f4b13b31e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083604051602001610be091906127c3565b604051602081830303815290604052805190602001209050808314610c31576040517f3f4d605300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083815260056020526040812090815560010180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055610c7d610c778561297f565b826115ac565b5050505050565b610c8c611529565b60ff8316600090815260066020526040902080548391907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001836002811115610cd957610cd9611fc4565b021790555060ff83166000908152600660205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010063ffffffff851602179055517f830a6d06a4e2caac67eba04323de22bdb04f032dd8b3d6a0c52b503d9a7036a390610d569085908590859061298b565b60405180910390a1505050565b6000818152600560209081526040918290208251606081018452815473ffffffffffffffffffffffffffffffffffffffff808216808452740100000000000000000000000000000000000000009092046bffffffffffffffffffffffff16948301949094526001909201549092169282019290925290331480610dfd575060005473ffffffffffffffffffffffffffffffffffffffff1633145b610e33576040517f61685c2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805173ffffffffffffffffffffffffffffffffffffffff16610e81576040517f4b13b31e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600560209081526040808320928355600190920180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905582519083015191830151610efb9273ffffffffffffffffffffffffffffffffffffffff90911691906bffffffffffffffffffffffff16611917565b60405182907f3663fb28ebc87645eb972c9dad8521bf665c623f287e79f1c56f1eb374b82a2290600090a25050565b610f32611529565b610f3b81611972565b50565b60006bffffffffffffffffffffffff821115610fdc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610966565b5090565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526110bc9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611a67565b50505050565b60a082015173ffffffffffffffffffffffffffffffffffffffff166000908152600460209081526040822054908401516bffffffffffffffffffffffff161015611138576040517fcd1c886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604083015173ffffffffffffffffffffffffffffffffffffffff16611189576040517f05bb467c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025460a08401516040517fa538b2eb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063a538b2eb90602401602060405180830381865afa1580156111fd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122191906129b6565b611257576040517f1183afea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008360405160200161126a91906129d3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600590935291205490915073ffffffffffffffffffffffffffffffffffffffff16156112fd576040517f357d0cc400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836000015173ffffffffffffffffffffffffffffffffffffffff16817f7684390ebb103102f7f48c71439c2408713f8d437782a6fab2756acc0e42c1b78660c001518760e00151886060015189604001518a608001518b61012001518c61014001518d61010001518e6020015160405161137f99989796959493929190612b3f565b60405180910390a3608084015160ff908116600090815260066020526040808220815160608101909252805492936114029383911660028111156113c5576113c5611fc4565b60028111156113d6576113d6611fc4565b8152905463ffffffff610100820481166020840152650100000000009091041660409091015285611b73565b1561146a57608085015160ff166000908152600660205260409020805465010000000000900463ffffffff1690600561143a83612bfa565b91906101000a81548163ffffffff021916908363ffffffff1602179055505061146385836115ac565b9050611521565b604080516060810182528682015173ffffffffffffffffffffffffffffffffffffffff90811682526020808901516bffffffffffffffffffffffff90811682850190815260a08b01518416858701908152600089815260059094529590922093519151167401000000000000000000000000000000000000000002908216178255915160019091018054919092167fffffffffffffffffffffffff0000000000000000000000000000000000000000919091161790555b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146115aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610966565b565b60025482516060840151604080860151608087015160a08801516101008901516101208a01516101408b015195517fc62cf68400000000000000000000000000000000000000000000000000000000815260009973ffffffffffffffffffffffffffffffffffffffff16988a988a9863c62cf6849861163c98939792969095939492939092909190600401612c1d565b6020604051808303816000875af115801561165b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061167f9190612cab565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168560a0015173ffffffffffffffffffffffffffffffffffffffff16036117f65760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634000aea08488602001518560405160200161172f91815260200190565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161175c93929190612cc4565b6020604051808303816000875af115801561177b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061179f91906129b6565b9050806117f0576040517f39f1c8d900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610966565b506118d2565b6118378286602001516bffffffffffffffffffffffff168760a0015173ffffffffffffffffffffffffffffffffffffffff16611c189092919063ffffffff16565b60208501516040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018390526bffffffffffffffffffffffff909116602482015273ffffffffffffffffffffffffffffffffffffffff83169063948108f790604401600060405180830381600087803b1580156118b957600080fd5b505af11580156118cd573d6000803e3d6000fd5b505050505b80847fb9a292fb7e3edd920cd2d2829a3615a640c43fd7de0a0820aa0668feb4c37d4b8760c001516040516119079190611f79565b60405180910390a3949350505050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261196d9084907fa9059cbb000000000000000000000000000000000000000000000000000000009060640161103a565b505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036119f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610966565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611ac9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611d9a9092919063ffffffff16565b80519091501561196d5780806020019051810190611ae791906129b6565b61196d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610966565b60008083516002811115611b8957611b89611fc4565b03611b965750600061070a565b600183516002811115611bab57611bab611fc4565b148015611bde575073ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604090205460ff16155b15611beb5750600061070a565b826020015163ffffffff16836040015163ffffffff161015611c0f5750600161070a565b50600092915050565b801580611cb857506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e90604401602060405180830381865afa158015611c92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb69190612cab565b155b611d44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610966565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261196d9084907f095ea7b3000000000000000000000000000000000000000000000000000000009060640161103a565b60606115218484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051611dce9190612d10565b60006040518083038185875af1925050503d8060008114611e0b576040519150601f19603f3d011682016040523d82523d6000602084013e611e10565b606091505b5091509150611e2187838387611e2c565b979650505050505050565b60608315611ec2578251600003611ebb5773ffffffffffffffffffffffffffffffffffffffff85163b611ebb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610966565b5081611521565b6115218383815115611ed75781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109669190611f79565b60005b83811015611f26578181015183820152602001611f0e565b50506000910152565b60008151808452611f47816020860160208601611f0b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611f8c6020830184611f2f565b9392505050565b803560ff81168114611fa457600080fd5b919050565b600060208284031215611fbb57600080fd5b611f8c82611f93565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6003811061202a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b6000606082019050612041828451611ff3565b602083015163ffffffff8082166020850152806040860151166040850152505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff811182821017156120ba576120ba612067565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561210757612107612067565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f3b57600080fd5b8035611fa48161210f565b80356bffffffffffffffffffffffff81168114611fa457600080fd5b803563ffffffff81168114611fa457600080fd5b600082601f83011261217d57600080fd5b813567ffffffffffffffff81111561219757612197612067565b6121c860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016120c0565b8181528460208386010111156121dd57600080fd5b816020850160208301376000918101602001919091529392505050565b6000610160828403121561220d57600080fd5b612215612096565b905061222082612131565b815261222e6020830161213c565b602082015261223f60408301612131565b604082015261225060608301612158565b606082015261226160808301611f93565b608082015261227260a08301612131565b60a082015260c082013567ffffffffffffffff8082111561229257600080fd5b61229e8583860161216c565b60c084015260e08401359150808211156122b757600080fd5b6122c38583860161216c565b60e0840152610100915081840135818111156122de57600080fd5b6122ea8682870161216c565b83850152506101209150818401358181111561230557600080fd5b6123118682870161216c565b83850152506101409150818401358181111561232c57600080fd5b6123388682870161216c565b8385015250505092915050565b60006020828403121561235757600080fd5b813567ffffffffffffffff81111561236e57600080fd5b611521848285016121fa565b8015158114610f3b57600080fd5b6000806040838503121561239b57600080fd5b82356123a68161210f565b915060208301356123b68161237a565b809150509250929050565b600067ffffffffffffffff8211156123db576123db612067565b5060051b60200190565b600082601f8301126123f657600080fd5b8135602061240b612406836123c1565b6120c0565b82815260059290921b8401810191818101908684111561242a57600080fd5b8286015b84811015612445578035835291830191830161242e565b509695505050505050565b60008060006060848603121561246557600080fd5b83356124708161210f565b925060208481013567ffffffffffffffff8082111561248e57600080fd5b818701915087601f8301126124a257600080fd5b81356124b0612406826123c1565b81815260059190911b8301840190848101908a8311156124cf57600080fd5b938501935b828510156124f65784356124e78161210f565b825293850193908501906124d4565b96505050604087013592508083111561250e57600080fd5b505061251c868287016123e5565b9150509250925092565b60006020828403121561253857600080fd5b8135611f8c8161210f565b60006020828403121561255557600080fd5b5035919050565b6000806000806060858703121561257257600080fd5b843561257d8161210f565b935060208501359250604085013567ffffffffffffffff808211156125a157600080fd5b818701915087601f8301126125b557600080fd5b8135818111156125c457600080fd5b8860208285010111156125d657600080fd5b95989497505060200194505050565b600080604083850312156125f857600080fd5b823567ffffffffffffffff81111561260f57600080fd5b8301610160818603121561262257600080fd5b946020939093013593505050565b60008060006060848603121561264557600080fd5b61264e84611f93565b925060208401356003811061266257600080fd5b915061267060408501612158565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612708576127086126a8565b5060010190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261274457600080fd5b830160208101925035905067ffffffffffffffff81111561276457600080fd5b80360382131561277357600080fd5b9250929050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526127f1602082016127d784612131565b73ffffffffffffffffffffffffffffffffffffffff169052565b60006127ff6020840161213c565b6bffffffffffffffffffffffff811660408401525061282060408401612131565b73ffffffffffffffffffffffffffffffffffffffff811660608401525061284960608401612158565b63ffffffff811660808401525061286260808401611f93565b60ff811660a08401525061287860a08401612131565b73ffffffffffffffffffffffffffffffffffffffff811660c0840152506128a260c084018461270f565b6101608060e08601526128ba6101808601838561277a565b92506128c960e087018761270f565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe061010081888703018189015261290386868561277a565b9550612911818a018a61270f565b955092505061012081888703018189015261292d86868561277a565b955061293b818a018a61270f565b955092505061014081888703018189015261295786868561277a565b9550612965818a018a61270f565b955092505080878603018388015250611e2184848361277a565b600061070a36836121fa565b60ff84168152606081016129a26020830185611ff3565b63ffffffff83166040830152949350505050565b6000602082840312156129c857600080fd5b8151611f8c8161237a565b602081526129fa60208201835173ffffffffffffffffffffffffffffffffffffffff169052565b60006020830151612a1b60408401826bffffffffffffffffffffffff169052565b50604083015173ffffffffffffffffffffffffffffffffffffffff8116606084015250606083015163ffffffff8116608084015250608083015160ff811660a08401525060a083015173ffffffffffffffffffffffffffffffffffffffff811660c08401525060c08301516101608060e0850152612a9d610180850183611f2f565b915060e08501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0610100818786030181880152612adb8584611f2f565b945080880151925050610120818786030181880152612afa8584611f2f565b945080880151925050610140818786030181880152612b198584611f2f565b908801518782039092018488015293509050612b358382611f2f565b9695505050505050565b6000610120808352612b538184018d611f2f565b90508281036020840152612b67818c611f2f565b905063ffffffff8a16604084015273ffffffffffffffffffffffffffffffffffffffff8916606084015260ff8816608084015282810360a0840152612bac8188611f2f565b905082810360c0840152612bc08187611f2f565b905082810360e0840152612bd48186611f2f565b9150506bffffffffffffffffffffffff83166101008301529a9950505050505050505050565b600063ffffffff808316818103612c1357612c136126a8565b6001019392505050565b600061010073ffffffffffffffffffffffffffffffffffffffff808c16845263ffffffff8b166020850152808a16604085015260ff891660608501528088166080850152508060a0840152612c7481840187611f2f565b905082810360c0840152612c888186611f2f565b905082810360e0840152612c9c8185611f2f565b9b9a5050505050505050505050565b600060208284031215612cbd57600080fd5b5051919050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff83166020820152606060408201526000612d076060830184611f2f565b95945050505050565b60008251612d22818460208701611f0b565b919091019291505056fea164736f6c6343000813000a", } var AutomationRegistrarABI = AutomationRegistrarMetaData.ABI diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 461b083fbfb..a8dae2092cb 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -8,7 +8,7 @@ automation_compatible_utils: ../../contracts/solc/v0.8.19/AutomationCompatibleUt automation_consumer_benchmark: ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark/AutomationConsumerBenchmark.abi ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark/AutomationConsumerBenchmark.bin f52c76f1aaed4be541d82d97189d70f5aa027fc9838037dd7a7d21910c8c488e automation_forwarder_logic: ../../contracts/solc/v0.8.16/AutomationForwarderLogic/AutomationForwarderLogic.abi ../../contracts/solc/v0.8.16/AutomationForwarderLogic/AutomationForwarderLogic.bin 15ae0c367297955fdab4b552dbb10e1f2be80a8fde0efec4a4d398693e9d72b5 automation_registrar_wrapper2_1: ../../contracts/solc/v0.8.16/AutomationRegistrar2_1/AutomationRegistrar2_1.abi ../../contracts/solc/v0.8.16/AutomationRegistrar2_1/AutomationRegistrar2_1.bin eb06d853aab39d3196c593b03e555851cbe8386e0fe54a74c2479f62d14b3c42 -automation_registrar_wrapper2_3: ../../contracts/solc/v0.8.19/AutomationRegistrar2_3/AutomationRegistrar2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistrar2_3/AutomationRegistrar2_3.bin b42de91c15c7453d8262124e20594819d64a3f23bef8e6db66fa5180d18a8454 +automation_registrar_wrapper2_3: ../../contracts/solc/v0.8.19/AutomationRegistrar2_3/AutomationRegistrar2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistrar2_3/AutomationRegistrar2_3.bin 4d8c1fae4c8bf59ad996a1ac00f2131158ac1d96c3039c2e7deaa502f0317719 automation_registry_logic_a_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.bin 2f267fb8467a15c587ce4586ac56069f7229344ad3936430d7c7624c0528a171 automation_registry_logic_a_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.bin 1163ecd34c575cb17ffbc2f88fa175816f36982e91992d940ed435d306b3418c automation_registry_logic_b_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.bin a6d33dfbbfb0ff253eb59a51f4f6d6d4c22ea5ec95aae52d25d49a312b37a22f From 365c38be8b589d5ffa0b21755dcb40e2e4205652 Mon Sep 17 00:00:00 2001 From: Christopher Dimitri Sastropranoto Date: Thu, 25 Apr 2024 23:33:57 +0700 Subject: [PATCH 34/77] Add functions to add a node operator (#12906) * add functions to add node operator * update gethwrapper --- .changeset/two-countries-lay.md | 5 + contracts/.changeset/tender-jokes-do.md | 5 + .../src/v0.8/keystone/CapabilityRegistry.sol | 72 +++++- .../src/v0.8/keystone/test/BaseTest.t.sol | 22 ++ .../keystone/test/CapabilityRegistry.t.sol | 21 -- ...CapabilityRegistry_AddCapabilityTest.t.sol | 17 ++ ...abilityRegistry_AddNodeOperatorsTest.t.sol | 41 ++++ .../src/v0.8/keystone/test/Constants.t.sol | 13 ++ .../keystone_capability_registry.go | 210 ++++++++++++++++-- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 10 files changed, 361 insertions(+), 47 deletions(-) create mode 100644 .changeset/two-countries-lay.md create mode 100644 contracts/.changeset/tender-jokes-do.md create mode 100644 contracts/src/v0.8/keystone/test/BaseTest.t.sol delete mode 100644 contracts/src/v0.8/keystone/test/CapabilityRegistry.t.sol create mode 100644 contracts/src/v0.8/keystone/test/CapabilityRegistry_AddCapabilityTest.t.sol create mode 100644 contracts/src/v0.8/keystone/test/CapabilityRegistry_AddNodeOperatorsTest.t.sol create mode 100644 contracts/src/v0.8/keystone/test/Constants.t.sol diff --git a/.changeset/two-countries-lay.md b/.changeset/two-countries-lay.md new file mode 100644 index 00000000000..f3d78e6a2e6 --- /dev/null +++ b/.changeset/two-countries-lay.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +update keystone gethwrapper #internal diff --git a/contracts/.changeset/tender-jokes-do.md b/contracts/.changeset/tender-jokes-do.md new file mode 100644 index 00000000000..5500fe0ca00 --- /dev/null +++ b/contracts/.changeset/tender-jokes-do.md @@ -0,0 +1,5 @@ +--- +"@chainlink/contracts": patch +--- + +Implement function to add node operators to the capability registry' diff --git a/contracts/src/v0.8/keystone/CapabilityRegistry.sol b/contracts/src/v0.8/keystone/CapabilityRegistry.sol index 7c870bed7fb..ad452f1606b 100644 --- a/contracts/src/v0.8/keystone/CapabilityRegistry.sol +++ b/contracts/src/v0.8/keystone/CapabilityRegistry.sol @@ -4,25 +4,73 @@ pragma solidity ^0.8.0; import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol"; import {OwnerIsCreator} from "../shared/access/OwnerIsCreator.sol"; -struct Capability { - // Capability type, e.g. "data-streams-reports" - // bytes32(string); validation regex: ^[a-z0-9_\-:]{1,32}$ - // Not "type" because that's a reserved keyword in Solidity. - bytes32 capabilityType; - // Semver, e.g., "1.2.3" - // bytes32(string); must be valid Semver + max 32 characters. - bytes32 version; -} - contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { - mapping(bytes32 => Capability) private s_capabilities; + struct NodeOperator { + /// @notice The address of the admin that can manage a node + /// operator + address admin; + /// @notice Human readable name of a Node Operator managing the node + string name; + } + + struct Capability { + // Capability type, e.g. "data-streams-reports" + // bytes32(string); validation regex: ^[a-z0-9_\-:]{1,32}$ + // Not "type" because that's a reserved keyword in Solidity. + bytes32 capabilityType; + // Semver, e.g., "1.2.3" + // bytes32(string); must be valid Semver + max 32 characters. + bytes32 version; + } + + /// @notice This error is thrown when trying to set a node operator's + /// admin address to the zero address + error InvalidNodeOperatorAdmin(); + + /// @notice This event is emitted when a new node operator is added + /// @param nodeOperatorId The ID of the newly added node operator + /// @param admin The address of the admin that can manage the node + /// operator + /// @param name The human readable name of the node operator + event NodeOperatorAdded(uint256 nodeOperatorId, address indexed admin, string name); + /// @notice This event is emitted when a new capability is added + /// @param capabilityId The ID of the newly added capability event CapabilityAdded(bytes32 indexed capabilityId); + mapping(bytes32 => Capability) private s_capabilities; + + /// @notice Mapping of node operators + mapping(uint256 nodeOperatorId => NodeOperator) private s_nodeOperators; + + /// @notice The latest node operator ID + /// @dev No getter for this as this is an implementation detail + uint256 private s_nodeOperatorId; + function typeAndVersion() external pure override returns (string memory) { return "CapabilityRegistry 1.0.0"; } + /// @notice Adds a list of node operators + /// @param nodeOperators List of node operators to add + function addNodeOperators(NodeOperator[] calldata nodeOperators) external onlyOwner { + for (uint256 i; i < nodeOperators.length; ++i) { + NodeOperator memory nodeOperator = nodeOperators[i]; + if (nodeOperator.admin == address(0)) revert InvalidNodeOperatorAdmin(); + uint256 nodeOperatorId = s_nodeOperatorId; + s_nodeOperators[nodeOperatorId] = NodeOperator({admin: nodeOperator.admin, name: nodeOperator.name}); + ++s_nodeOperatorId; + emit NodeOperatorAdded(nodeOperatorId, nodeOperator.admin, nodeOperator.name); + } + } + + /// @notice Gets a node operator's data + /// @param nodeOperatorId The ID of the node operator to query for + /// @return NodeOperator The node operator data + function getNodeOperator(uint256 nodeOperatorId) external view returns (NodeOperator memory) { + return s_nodeOperators[nodeOperatorId]; + } + function addCapability(Capability calldata capability) external onlyOwner { bytes32 capabilityId = getCapabilityID(capability.capabilityType, capability.version); s_capabilities[capabilityId] = capability; @@ -34,7 +82,7 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { } /// @notice This functions returns a Capability ID packed into a bytes32 for cheaper access - /// @return A unique identifier for the capability + /// @return bytes32 A unique identifier for the capability function getCapabilityID(bytes32 capabilityType, bytes32 version) public pure returns (bytes32) { return keccak256(abi.encodePacked(capabilityType, version)); } diff --git a/contracts/src/v0.8/keystone/test/BaseTest.t.sol b/contracts/src/v0.8/keystone/test/BaseTest.t.sol new file mode 100644 index 00000000000..5c4b4c91809 --- /dev/null +++ b/contracts/src/v0.8/keystone/test/BaseTest.t.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {Test} from "forge-std/Test.sol"; +import {Constants} from "./Constants.t.sol"; +import {CapabilityRegistry} from "../CapabilityRegistry.sol"; + +contract BaseTest is Test, Constants { + CapabilityRegistry internal s_capabilityRegistry; + + function setUp() public virtual { + vm.startPrank(ADMIN); + s_capabilityRegistry = new CapabilityRegistry(); + } + + function _getNodeOperators() internal view returns (CapabilityRegistry.NodeOperator[] memory) { + CapabilityRegistry.NodeOperator[] memory nodeOperators = new CapabilityRegistry.NodeOperator[](2); + nodeOperators[0] = CapabilityRegistry.NodeOperator({admin: NODE_OPERATOR_ONE_ADMIN, name: NODE_OPERATOR_ONE_NAME}); + nodeOperators[1] = CapabilityRegistry.NodeOperator({admin: NODE_OPERATOR_TWO_ADMIN, name: NODE_OPERATOR_TWO_NAME}); + return nodeOperators; + } +} diff --git a/contracts/src/v0.8/keystone/test/CapabilityRegistry.t.sol b/contracts/src/v0.8/keystone/test/CapabilityRegistry.t.sol deleted file mode 100644 index f5d539d8e34..00000000000 --- a/contracts/src/v0.8/keystone/test/CapabilityRegistry.t.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import {Test} from "forge-std/Test.sol"; -import {Capability, CapabilityRegistry} from "../CapabilityRegistry.sol"; - -contract CapabilityRegistryTest is Test { - function setUp() public virtual {} - - function testAddCapability() public { - CapabilityRegistry capabilityRegistry = new CapabilityRegistry(); - - capabilityRegistry.addCapability(Capability("data-streams-reports", "1.0.0")); - - bytes32 capabilityId = capabilityRegistry.getCapabilityID(bytes32("data-streams-reports"), bytes32("1.0.0")); - Capability memory capability = capabilityRegistry.getCapability(capabilityId); - - assertEq(capability.capabilityType, "data-streams-reports"); - assertEq(capability.version, "1.0.0"); - } -} diff --git a/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddCapabilityTest.t.sol b/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddCapabilityTest.t.sol new file mode 100644 index 00000000000..6fbdc43a2c7 --- /dev/null +++ b/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddCapabilityTest.t.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {BaseTest} from "./BaseTest.t.sol"; +import {CapabilityRegistry} from "../CapabilityRegistry.sol"; + +contract CapabilityRegistry_AddCapabilityTest is BaseTest { + function test_AddCapability() public { + s_capabilityRegistry.addCapability(CapabilityRegistry.Capability("data-streams-reports", "1.0.0")); + + bytes32 capabilityId = s_capabilityRegistry.getCapabilityID(bytes32("data-streams-reports"), bytes32("1.0.0")); + CapabilityRegistry.Capability memory capability = s_capabilityRegistry.getCapability(capabilityId); + + assertEq(capability.capabilityType, "data-streams-reports"); + assertEq(capability.version, "1.0.0"); + } +} diff --git a/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddNodeOperatorsTest.t.sol b/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddNodeOperatorsTest.t.sol new file mode 100644 index 00000000000..388c3ca9cdd --- /dev/null +++ b/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddNodeOperatorsTest.t.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {BaseTest} from "./BaseTest.t.sol"; +import {CapabilityRegistry} from "../CapabilityRegistry.sol"; + +contract CapabilityRegistry_AddNodeOperatorsTest is BaseTest { + event NodeOperatorAdded(uint256 nodeOperatorId, address indexed admin, string name); + + function test_RevertWhen_CalledByNonAdmin() public { + changePrank(STRANGER); + vm.expectRevert("Only callable by owner"); + s_capabilityRegistry.addNodeOperators(_getNodeOperators()); + } + + function test_RevertWhen_NodeOperatorAdminAddressZero() public { + changePrank(ADMIN); + CapabilityRegistry.NodeOperator[] memory nodeOperators = _getNodeOperators(); + nodeOperators[0].admin = address(0); + vm.expectRevert(CapabilityRegistry.InvalidNodeOperatorAdmin.selector); + s_capabilityRegistry.addNodeOperators(nodeOperators); + } + + function test_AddNodeOperators() public { + changePrank(ADMIN); + + vm.expectEmit(true, true, true, true, address(s_capabilityRegistry)); + emit NodeOperatorAdded(0, NODE_OPERATOR_ONE_ADMIN, NODE_OPERATOR_ONE_NAME); + vm.expectEmit(true, true, true, true, address(s_capabilityRegistry)); + emit NodeOperatorAdded(1, NODE_OPERATOR_TWO_ADMIN, NODE_OPERATOR_TWO_NAME); + s_capabilityRegistry.addNodeOperators(_getNodeOperators()); + + CapabilityRegistry.NodeOperator memory nodeOperatorOne = s_capabilityRegistry.getNodeOperator(0); + assertEq(nodeOperatorOne.admin, NODE_OPERATOR_ONE_ADMIN); + assertEq(nodeOperatorOne.name, NODE_OPERATOR_ONE_NAME); + + CapabilityRegistry.NodeOperator memory nodeOperatorTwo = s_capabilityRegistry.getNodeOperator(1); + assertEq(nodeOperatorTwo.admin, NODE_OPERATOR_TWO_ADMIN); + assertEq(nodeOperatorTwo.name, NODE_OPERATOR_TWO_NAME); + } +} diff --git a/contracts/src/v0.8/keystone/test/Constants.t.sol b/contracts/src/v0.8/keystone/test/Constants.t.sol new file mode 100644 index 00000000000..b7eb85debb1 --- /dev/null +++ b/contracts/src/v0.8/keystone/test/Constants.t.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {Test} from "forge-std/Test.sol"; + +contract Constants { + address internal ADMIN = address(1); + address internal STRANGER = address(2); + address internal NODE_OPERATOR_ONE_ADMIN = address(3); + string internal NODE_OPERATOR_ONE_NAME = "node-operator-one"; + address internal NODE_OPERATOR_TWO_ADMIN = address(4); + string internal NODE_OPERATOR_TWO_NAME = "node-operator-two"; +} diff --git a/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go b/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go index 45ae103ac56..ef8b252b924 100644 --- a/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go +++ b/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go @@ -30,14 +30,19 @@ var ( _ = abi.ConvertType ) -type Capability struct { +type CapabilityRegistryCapability struct { CapabilityType [32]byte Version [32]byte } +type CapabilityRegistryNodeOperator struct { + Admin common.Address + Name string +} + var CapabilityRegistryMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"internalType\":\"structCapability\",\"name\":\"capability\",\"type\":\"tuple\"}],\"name\":\"addCapability\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityID\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"internalType\":\"structCapability\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"name\":\"getCapabilityID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6105e5806101576000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c806379ba50971161005b57806379ba5097146101275780638da5cb5b1461012f5780639cb7c5f414610157578063f2fde38b146101be57600080fd5b8063181f5a7714610082578063229111f5146100ca5780636e5f286914610112575b600080fd5b604080518082018252601881527f4361706162696c697479526567697374727920312e302e300000000000000000602082015290516100c191906104dc565b60405180910390f35b6101046100d8366004610548565b604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b6040519081526020016100c1565b61012561012036600461056a565b6101d1565b005b61012561024e565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c1565b6101a3610165366004610582565b604080518082019091526000808252602082015250600090815260026020908152604091829020825180840190935280548352600101549082015290565b604080518251815260209283015192810192909252016100c1565b6101256101cc36600461059b565b610350565b6101d9610364565b60408051823560208083018290528085013583850181905284518085038601815260609094018086528451948301949094206000818152600290935294822092835560019092019190915582917f65610e5677eedff94555572640e442f89848a109ef8593fa927ac30b2565ff069190a25050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146102d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610358610364565b610361816103e7565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016102cb565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610466576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016102cb565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208083528351808285015260005b81811015610509578581018301518582016040015282016104ed565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b6000806040838503121561055b57600080fd5b50508035926020909101359150565b60006040828403121561057c57600080fd5b50919050565b60006020828403121561059457600080fd5b5035919050565b6000602082840312156105ad57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146105d157600080fd5b939250505056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[],\"name\":\"InvalidNodeOperatorAdmin\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"capability\",\"type\":\"tuple\"}],\"name\":\"addCapability\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"addNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityID\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"name\":\"getCapabilityID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"getNodeOperator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b610d9e806101576000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80636e5f2869116100765780638da5cb5b1161005b5780638da5cb5b146101885780639cb7c5f4146101b0578063f2fde38b1461021757600080fd5b80636e5f28691461016d57806379ba50971461018057600080fd5b8063181f5a77146100a8578063229111f5146100f0578063398f37731461013857806365c14dc71461014d575b600080fd5b604080518082018252601881527f4361706162696c697479526567697374727920312e302e300000000000000000602082015290516100e7919061081d565b60405180910390f35b61012a6100fe366004610837565b604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b6040519081526020016100e7565b61014b610146366004610859565b61022a565b005b61016061015b3660046108ce565b6103c8565b6040516100e791906108e7565b61014b61017b36600461092a565b6104ae565b61014b61052b565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e7565b6101fc6101be3660046108ce565b604080518082019091526000808252602082015250600090815260026020908152604091829020825180840190935280548352600101549082015290565b604080518251815260209283015192810192909252016100e7565b61014b61022536600461096b565b61062d565b610232610641565b60005b818110156103c357600083838381811061025157610251610986565b905060200281019061026391906109b5565b61026c90610a9a565b805190915073ffffffffffffffffffffffffffffffffffffffff166102bd576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600454604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815260008681526003909252939020825181547fffffffffffffffffffffffff0000000000000000000000000000000000000000169216919091178155915190919060018201906103409082610bff565b5090505060046000815461035390610d19565b909155508151602083015160405173ffffffffffffffffffffffffffffffffffffffff909216917fda6697b182650034bd205cdc2dbfabb06bdb3a0a83a2b45bfefa3c4881284e0b916103a891859190610d78565b60405180910390a25050806103bc90610d19565b9050610235565b505050565b6040805180820190915260008152606060208201526000828152600360209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff168352600181018054919284019161042590610b64565b80601f016020809104026020016040519081016040528092919081815260200182805461045190610b64565b801561049e5780601f106104735761010080835404028352916020019161049e565b820191906000526020600020905b81548152906001019060200180831161048157829003601f168201915b5050505050815250509050919050565b6104b6610641565b60408051823560208083018290528085013583850181905284518085038601815260609094018086528451948301949094206000818152600290935294822092835560019092019190915582917f65610e5677eedff94555572640e442f89848a109ef8593fa927ac30b2565ff069190a25050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610635610641565b61063e816106c4565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016105a8565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610743576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016105a8565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000815180845260005b818110156107df576020818501810151868301820152016107c3565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061083060208301846107b9565b9392505050565b6000806040838503121561084a57600080fd5b50508035926020909101359150565b6000806020838503121561086c57600080fd5b823567ffffffffffffffff8082111561088457600080fd5b818501915085601f83011261089857600080fd5b8135818111156108a757600080fd5b8660208260051b85010111156108bc57600080fd5b60209290920196919550909350505050565b6000602082840312156108e057600080fd5b5035919050565b6020815273ffffffffffffffffffffffffffffffffffffffff82511660208201526000602083015160408084015261092260608401826107b9565b949350505050565b60006040828403121561093c57600080fd5b50919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461096657600080fd5b919050565b60006020828403121561097d57600080fd5b61083082610942565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126109e957600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610a4557610a456109f3565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610a9257610a926109f3565b604052919050565b600060408236031215610aac57600080fd5b610ab4610a22565b610abd83610942565b815260208084013567ffffffffffffffff80821115610adb57600080fd5b9085019036601f830112610aee57600080fd5b813581811115610b0057610b006109f3565b610b30847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610a4b565b91508082523684828501011115610b4657600080fd5b80848401858401376000908201840152918301919091525092915050565b600181811c90821680610b7857607f821691505b60208210810361093c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b601f8211156103c357600081815260208120601f850160051c81016020861015610bd85750805b601f850160051c820191505b81811015610bf757828155600101610be4565b505050505050565b815167ffffffffffffffff811115610c1957610c196109f3565b610c2d81610c278454610b64565b84610bb1565b602080601f831160018114610c805760008415610c4a5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610bf7565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015610ccd57888601518255948401946001909101908401610cae565b5085821015610d0957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d71577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b82815260406020820152600061092260408301846107b956fea164736f6c6343000813000a", } var CapabilityRegistryABI = CapabilityRegistryMetaData.ABI @@ -176,25 +181,25 @@ func (_CapabilityRegistry *CapabilityRegistryTransactorRaw) Transact(opts *bind. return _CapabilityRegistry.Contract.contract.Transact(opts, method, params...) } -func (_CapabilityRegistry *CapabilityRegistryCaller) GetCapability(opts *bind.CallOpts, capabilityID [32]byte) (Capability, error) { +func (_CapabilityRegistry *CapabilityRegistryCaller) GetCapability(opts *bind.CallOpts, capabilityID [32]byte) (CapabilityRegistryCapability, error) { var out []interface{} err := _CapabilityRegistry.contract.Call(opts, &out, "getCapability", capabilityID) if err != nil { - return *new(Capability), err + return *new(CapabilityRegistryCapability), err } - out0 := *abi.ConvertType(out[0], new(Capability)).(*Capability) + out0 := *abi.ConvertType(out[0], new(CapabilityRegistryCapability)).(*CapabilityRegistryCapability) return out0, err } -func (_CapabilityRegistry *CapabilityRegistrySession) GetCapability(capabilityID [32]byte) (Capability, error) { +func (_CapabilityRegistry *CapabilityRegistrySession) GetCapability(capabilityID [32]byte) (CapabilityRegistryCapability, error) { return _CapabilityRegistry.Contract.GetCapability(&_CapabilityRegistry.CallOpts, capabilityID) } -func (_CapabilityRegistry *CapabilityRegistryCallerSession) GetCapability(capabilityID [32]byte) (Capability, error) { +func (_CapabilityRegistry *CapabilityRegistryCallerSession) GetCapability(capabilityID [32]byte) (CapabilityRegistryCapability, error) { return _CapabilityRegistry.Contract.GetCapability(&_CapabilityRegistry.CallOpts, capabilityID) } @@ -220,6 +225,28 @@ func (_CapabilityRegistry *CapabilityRegistryCallerSession) GetCapabilityID(capa return _CapabilityRegistry.Contract.GetCapabilityID(&_CapabilityRegistry.CallOpts, capabilityType, version) } +func (_CapabilityRegistry *CapabilityRegistryCaller) GetNodeOperator(opts *bind.CallOpts, nodeOperatorId *big.Int) (CapabilityRegistryNodeOperator, error) { + var out []interface{} + err := _CapabilityRegistry.contract.Call(opts, &out, "getNodeOperator", nodeOperatorId) + + if err != nil { + return *new(CapabilityRegistryNodeOperator), err + } + + out0 := *abi.ConvertType(out[0], new(CapabilityRegistryNodeOperator)).(*CapabilityRegistryNodeOperator) + + return out0, err + +} + +func (_CapabilityRegistry *CapabilityRegistrySession) GetNodeOperator(nodeOperatorId *big.Int) (CapabilityRegistryNodeOperator, error) { + return _CapabilityRegistry.Contract.GetNodeOperator(&_CapabilityRegistry.CallOpts, nodeOperatorId) +} + +func (_CapabilityRegistry *CapabilityRegistryCallerSession) GetNodeOperator(nodeOperatorId *big.Int) (CapabilityRegistryNodeOperator, error) { + return _CapabilityRegistry.Contract.GetNodeOperator(&_CapabilityRegistry.CallOpts, nodeOperatorId) +} + func (_CapabilityRegistry *CapabilityRegistryCaller) Owner(opts *bind.CallOpts) (common.Address, error) { var out []interface{} err := _CapabilityRegistry.contract.Call(opts, &out, "owner") @@ -276,18 +303,30 @@ func (_CapabilityRegistry *CapabilityRegistryTransactorSession) AcceptOwnership( return _CapabilityRegistry.Contract.AcceptOwnership(&_CapabilityRegistry.TransactOpts) } -func (_CapabilityRegistry *CapabilityRegistryTransactor) AddCapability(opts *bind.TransactOpts, capability Capability) (*types.Transaction, error) { +func (_CapabilityRegistry *CapabilityRegistryTransactor) AddCapability(opts *bind.TransactOpts, capability CapabilityRegistryCapability) (*types.Transaction, error) { return _CapabilityRegistry.contract.Transact(opts, "addCapability", capability) } -func (_CapabilityRegistry *CapabilityRegistrySession) AddCapability(capability Capability) (*types.Transaction, error) { +func (_CapabilityRegistry *CapabilityRegistrySession) AddCapability(capability CapabilityRegistryCapability) (*types.Transaction, error) { return _CapabilityRegistry.Contract.AddCapability(&_CapabilityRegistry.TransactOpts, capability) } -func (_CapabilityRegistry *CapabilityRegistryTransactorSession) AddCapability(capability Capability) (*types.Transaction, error) { +func (_CapabilityRegistry *CapabilityRegistryTransactorSession) AddCapability(capability CapabilityRegistryCapability) (*types.Transaction, error) { return _CapabilityRegistry.Contract.AddCapability(&_CapabilityRegistry.TransactOpts, capability) } +func (_CapabilityRegistry *CapabilityRegistryTransactor) AddNodeOperators(opts *bind.TransactOpts, nodeOperators []CapabilityRegistryNodeOperator) (*types.Transaction, error) { + return _CapabilityRegistry.contract.Transact(opts, "addNodeOperators", nodeOperators) +} + +func (_CapabilityRegistry *CapabilityRegistrySession) AddNodeOperators(nodeOperators []CapabilityRegistryNodeOperator) (*types.Transaction, error) { + return _CapabilityRegistry.Contract.AddNodeOperators(&_CapabilityRegistry.TransactOpts, nodeOperators) +} + +func (_CapabilityRegistry *CapabilityRegistryTransactorSession) AddNodeOperators(nodeOperators []CapabilityRegistryNodeOperator) (*types.Transaction, error) { + return _CapabilityRegistry.Contract.AddNodeOperators(&_CapabilityRegistry.TransactOpts, nodeOperators) +} + func (_CapabilityRegistry *CapabilityRegistryTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { return _CapabilityRegistry.contract.Transact(opts, "transferOwnership", to) } @@ -427,6 +466,135 @@ func (_CapabilityRegistry *CapabilityRegistryFilterer) ParseCapabilityAdded(log return event, nil } +type CapabilityRegistryNodeOperatorAddedIterator struct { + Event *CapabilityRegistryNodeOperatorAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CapabilityRegistryNodeOperatorAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CapabilityRegistryNodeOperatorAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CapabilityRegistryNodeOperatorAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CapabilityRegistryNodeOperatorAddedIterator) Error() error { + return it.fail +} + +func (it *CapabilityRegistryNodeOperatorAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CapabilityRegistryNodeOperatorAdded struct { + NodeOperatorId *big.Int + Admin common.Address + Name string + Raw types.Log +} + +func (_CapabilityRegistry *CapabilityRegistryFilterer) FilterNodeOperatorAdded(opts *bind.FilterOpts, admin []common.Address) (*CapabilityRegistryNodeOperatorAddedIterator, error) { + + var adminRule []interface{} + for _, adminItem := range admin { + adminRule = append(adminRule, adminItem) + } + + logs, sub, err := _CapabilityRegistry.contract.FilterLogs(opts, "NodeOperatorAdded", adminRule) + if err != nil { + return nil, err + } + return &CapabilityRegistryNodeOperatorAddedIterator{contract: _CapabilityRegistry.contract, event: "NodeOperatorAdded", logs: logs, sub: sub}, nil +} + +func (_CapabilityRegistry *CapabilityRegistryFilterer) WatchNodeOperatorAdded(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryNodeOperatorAdded, admin []common.Address) (event.Subscription, error) { + + var adminRule []interface{} + for _, adminItem := range admin { + adminRule = append(adminRule, adminItem) + } + + logs, sub, err := _CapabilityRegistry.contract.WatchLogs(opts, "NodeOperatorAdded", adminRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CapabilityRegistryNodeOperatorAdded) + if err := _CapabilityRegistry.contract.UnpackLog(event, "NodeOperatorAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CapabilityRegistry *CapabilityRegistryFilterer) ParseNodeOperatorAdded(log types.Log) (*CapabilityRegistryNodeOperatorAdded, error) { + event := new(CapabilityRegistryNodeOperatorAdded) + if err := _CapabilityRegistry.contract.UnpackLog(event, "NodeOperatorAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type CapabilityRegistryOwnershipTransferRequestedIterator struct { Event *CapabilityRegistryOwnershipTransferRequested @@ -703,6 +871,8 @@ func (_CapabilityRegistry *CapabilityRegistry) ParseLog(log types.Log) (generate switch log.Topics[0] { case _CapabilityRegistry.abi.Events["CapabilityAdded"].ID: return _CapabilityRegistry.ParseCapabilityAdded(log) + case _CapabilityRegistry.abi.Events["NodeOperatorAdded"].ID: + return _CapabilityRegistry.ParseNodeOperatorAdded(log) case _CapabilityRegistry.abi.Events["OwnershipTransferRequested"].ID: return _CapabilityRegistry.ParseOwnershipTransferRequested(log) case _CapabilityRegistry.abi.Events["OwnershipTransferred"].ID: @@ -717,6 +887,10 @@ func (CapabilityRegistryCapabilityAdded) Topic() common.Hash { return common.HexToHash("0x65610e5677eedff94555572640e442f89848a109ef8593fa927ac30b2565ff06") } +func (CapabilityRegistryNodeOperatorAdded) Topic() common.Hash { + return common.HexToHash("0xda6697b182650034bd205cdc2dbfabb06bdb3a0a83a2b45bfefa3c4881284e0b") +} + func (CapabilityRegistryOwnershipTransferRequested) Topic() common.Hash { return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") } @@ -730,17 +904,21 @@ func (_CapabilityRegistry *CapabilityRegistry) Address() common.Address { } type CapabilityRegistryInterface interface { - GetCapability(opts *bind.CallOpts, capabilityID [32]byte) (Capability, error) + GetCapability(opts *bind.CallOpts, capabilityID [32]byte) (CapabilityRegistryCapability, error) GetCapabilityID(opts *bind.CallOpts, capabilityType [32]byte, version [32]byte) ([32]byte, error) + GetNodeOperator(opts *bind.CallOpts, nodeOperatorId *big.Int) (CapabilityRegistryNodeOperator, error) + Owner(opts *bind.CallOpts) (common.Address, error) TypeAndVersion(opts *bind.CallOpts) (string, error) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) - AddCapability(opts *bind.TransactOpts, capability Capability) (*types.Transaction, error) + AddCapability(opts *bind.TransactOpts, capability CapabilityRegistryCapability) (*types.Transaction, error) + + AddNodeOperators(opts *bind.TransactOpts, nodeOperators []CapabilityRegistryNodeOperator) (*types.Transaction, error) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) @@ -750,6 +928,12 @@ type CapabilityRegistryInterface interface { ParseCapabilityAdded(log types.Log) (*CapabilityRegistryCapabilityAdded, error) + FilterNodeOperatorAdded(opts *bind.FilterOpts, admin []common.Address) (*CapabilityRegistryNodeOperatorAddedIterator, error) + + WatchNodeOperatorAdded(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryNodeOperatorAdded, admin []common.Address) (event.Subscription, error) + + ParseNodeOperatorAdded(log types.Log) (*CapabilityRegistryNodeOperatorAdded, error) + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CapabilityRegistryOwnershipTransferRequestedIterator, error) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) diff --git a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 98fd35e188b..836eb3e68b7 100644 --- a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,4 +1,4 @@ GETH_VERSION: 1.13.8 forwarder: ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.bin b4c900aae9e022f01abbac7993d41f93912247613ac6270b0c4da4ef6f2016e3 -keystone_capability_registry: ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.abi ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.bin fbaf8eceb929494bdfe0028921a0742da525cb4ec1b6d57a1382eda46fa32c64 +keystone_capability_registry: ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.abi ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.bin 579334dfcb59da4221823735dc815116745b488ddde327199367e04457aac808 ocr3_capability: ../../../contracts/solc/v0.8.19/OCR3Capability/OCR3Capability.abi ../../../contracts/solc/v0.8.19/OCR3Capability/OCR3Capability.bin 9dcbdf55bd5729ba266148da3f17733eb592c871c2108ccca546618628fd9ad2 From fa5b22773e52744d3abab1a05cd12ecc2e103d88 Mon Sep 17 00:00:00 2001 From: Vyzaldy Sanchez Date: Thu, 25 Apr 2024 13:16:55 -0400 Subject: [PATCH 35/77] Add `onchainSigningStrategy` job spec field support (#12909) * Adds `onchainSigningStrategy` job spec field support * Makes changeset internal * Fixes typo and remove unnecessary logs * Stores `onchain_signing_strategy` values in the DB * Fixes test error --- .changeset/olive-knives-happen.md | 5 + core/services/job/job_orm_test.go | 5 + core/services/job/models.go | 1 + core/services/job/models_test.go | 7 + core/services/job/orm.go | 4 +- core/services/job/testdata/compact.toml | 7 + core/services/job/testdata/pretty.toml | 7 + core/services/ocr2/database_test.go | 4 +- core/services/ocr2/delegate.go | 8 + core/services/ocr2/validate/validate.go | 48 +++++ core/services/ocr2/validate/validate_test.go | 169 ++++++++++++++++++ ...4_generic_plugin_multichain_keybundle_.sql | 11 ++ 12 files changed, 272 insertions(+), 4 deletions(-) create mode 100644 .changeset/olive-knives-happen.md create mode 100644 core/store/migrate/migrations/0234_generic_plugin_multichain_keybundle_.sql diff --git a/.changeset/olive-knives-happen.md b/.changeset/olive-knives-happen.md new file mode 100644 index 00000000000..7f522c96ff1 --- /dev/null +++ b/.changeset/olive-knives-happen.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal Generic Plugin `onchainSigningStrategy` support diff --git a/core/services/job/job_orm_test.go b/core/services/job/job_orm_test.go index f07b68d9987..3c7d5a7afa5 100644 --- a/core/services/job/job_orm_test.go +++ b/core/services/job/job_orm_test.go @@ -66,6 +66,11 @@ observationSource = """ chainID = 1 fromBlock = 1000 +[onchainSigningStrategy] +strategyName = 'single-chain' +[onchainSigningStrategy.config] +publicKey = '8fa807463ad73f9ee855cfd60ba406dcf98a2855b3dd8af613107b0f6890a707' + [pluginConfig] serverURL = 'wss://localhost:8080' serverPubKey = '8fa807463ad73f9ee855cfd60ba406dcf98a2855b3dd8af613107b0f6890a707' diff --git a/core/services/job/models.go b/core/services/job/models.go index 0c6390b3dbf..3d510efa0d2 100644 --- a/core/services/job/models.go +++ b/core/services/job/models.go @@ -362,6 +362,7 @@ type OCR2OracleSpec struct { BlockchainTimeout models.Interval `toml:"blockchainTimeout"` ContractConfigTrackerPollInterval models.Interval `toml:"contractConfigTrackerPollInterval"` ContractConfigConfirmations uint16 `toml:"contractConfigConfirmations"` + OnchainSigningStrategy JSONConfig `toml:"onchainSigningStrategy"` PluginConfig JSONConfig `toml:"pluginConfig"` PluginType types.OCR2PluginType `toml:"pluginType"` CreatedAt time.Time `toml:"-"` diff --git a/core/services/job/models_test.go b/core/services/job/models_test.go index 4d10fbb43c4..c177b3b81e1 100644 --- a/core/services/job/models_test.go +++ b/core/services/job/models_test.go @@ -219,6 +219,13 @@ func TestOCR2OracleSpec(t *testing.T) { }, }, }, + OnchainSigningStrategy: map[string]interface{}{ + "strategyName": "single-chain", + "config": map[string]interface{}{ + "evm": "", + "publicKey": "0xdeadbeef", + }, + }, PluginConfig: map[string]interface{}{"juelsPerFeeCoinSource": ` // data source 1 ds1 [type=bridge name="%s"]; ds1_parse [type=jsonparse path="data"]; diff --git a/core/services/job/orm.go b/core/services/job/orm.go index 2b2f73396dc..d87b0204263 100644 --- a/core/services/job/orm.go +++ b/core/services/job/orm.go @@ -461,10 +461,10 @@ func (o *orm) insertOCROracleSpec(ctx context.Context, spec *OCROracleSpec) (spe } func (o *orm) insertOCR2OracleSpec(ctx context.Context, spec *OCR2OracleSpec) (specID int32, err error) { - return o.prepareQuerySpecID(ctx, `INSERT INTO ocr2_oracle_specs (contract_id, feed_id, relay, relay_config, plugin_type, plugin_config, p2pv2_bootstrappers, ocr_key_bundle_id, transmitter_id, + return o.prepareQuerySpecID(ctx, `INSERT INTO ocr2_oracle_specs (contract_id, feed_id, relay, relay_config, plugin_type, plugin_config, onchain_signing_strategy, p2pv2_bootstrappers, ocr_key_bundle_id, transmitter_id, blockchain_timeout, contract_config_tracker_poll_interval, contract_config_confirmations, created_at, updated_at) - VALUES (:contract_id, :feed_id, :relay, :relay_config, :plugin_type, :plugin_config, :p2pv2_bootstrappers, :ocr_key_bundle_id, :transmitter_id, + VALUES (:contract_id, :feed_id, :relay, :relay_config, :plugin_type, :plugin_config, :onchain_signing_strategy, :p2pv2_bootstrappers, :ocr_key_bundle_id, :transmitter_id, :blockchain_timeout, :contract_config_tracker_poll_interval, :contract_config_confirmations, NOW(), NOW()) RETURNING id;`, spec) diff --git a/core/services/job/testdata/compact.toml b/core/services/job/testdata/compact.toml index 9f0f54027d2..5517c69ffa1 100644 --- a/core/services/job/testdata/compact.toml +++ b/core/services/job/testdata/compact.toml @@ -30,5 +30,12 @@ LatestTransmissionDetails = "{\n \"chainSpecificName\": \"latestTransmissionDet [relayConfig.codec.configs.MedianReport] typeABI = "[\n {\n \"Name\": \"Timestamp\",\n \"Type\": \"uint32\"\n },\n {\n \"Name\": \"Observers\",\n \"Type\": \"bytes32\"\n },\n {\n \"Name\": \"Observations\",\n \"Type\": \"int192[]\"\n },\n {\n \"Name\": \"JuelsPerFeeCoin\",\n \"Type\": \"int192\"\n }\n]\n" +[onchainSigningStrategy] +strategyName = 'single-chain' + +[onchainSigningStrategy.config] +evm = '' +publicKey = '0xdeadbeef' + [pluginConfig] juelsPerFeeCoinSource = " // data source 1\n ds1 [type=bridge name=\"%s\"];\n ds1_parse [type=jsonparse path=\"data\"];\n ds1_multiply [type=multiply times=2];\n\n // data source 2\n ds2 [type=http method=GET url=\"%s\"];\n ds2_parse [type=jsonparse path=\"data\"];\n ds2_multiply [type=multiply times=2];\n\n ds1 -> ds1_parse -> ds1_multiply -> answer1;\n ds2 -> ds2_parse -> ds2_multiply -> answer1;\n\n answer1 [type=median index=0];\n" diff --git a/core/services/job/testdata/pretty.toml b/core/services/job/testdata/pretty.toml index 88bacff7db2..1bed3efac0d 100644 --- a/core/services/job/testdata/pretty.toml +++ b/core/services/job/testdata/pretty.toml @@ -130,6 +130,13 @@ typeABI = ''' ] ''' +[onchainSigningStrategy] +strategyName = 'single-chain' + +[onchainSigningStrategy.config] +evm = '' +publicKey = '0xdeadbeef' + [pluginConfig] juelsPerFeeCoinSource = """ // data source 1 diff --git a/core/services/ocr2/database_test.go b/core/services/ocr2/database_test.go index 3e78249d087..3d3eec22a6d 100644 --- a/core/services/ocr2/database_test.go +++ b/core/services/ocr2/database_test.go @@ -40,9 +40,9 @@ func MustInsertOCROracleSpec(t *testing.T, db *sqlx.DB, transmitterAddress types require.NoError(t, db.Get(&spec, `INSERT INTO ocr2_oracle_specs ( relay, relay_config, contract_id, p2pv2_bootstrappers, ocr_key_bundle_id, monitoring_endpoint, transmitter_id, -blockchain_timeout, contract_config_tracker_poll_interval, contract_config_confirmations, plugin_type, plugin_config, created_at, updated_at) VALUES ( +blockchain_timeout, contract_config_tracker_poll_interval, contract_config_confirmations, plugin_type, plugin_config, onchain_signing_strategy, created_at, updated_at) VALUES ( 'ethereum', '{}', $1, '{}', $2, $3, $4, -0, 0, 0, 'median', $5, NOW(), NOW() +0, 0, 0, 'median', $5, '{}', NOW(), NOW() ) RETURNING *`, cltest.NewEIP55Address().String(), cltest.DefaultOCR2KeyBundleID, "chain.link:1234", transmitterAddress.String(), jsonConfig)) return spec } diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index 6c76b0ff9c9..2e623ab5467 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -27,6 +27,7 @@ import ( ocr2keepers21 "github.com/smartcontractkit/chainlink-automation/pkg/v3/plugin" "github.com/smartcontractkit/chainlink-common/pkg/loop/reportingplugins/ocr3" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + "github.com/smartcontractkit/chainlink/v2/core/config/env" "github.com/smartcontractkit/chainlink-vrf/altbn_128" @@ -539,6 +540,13 @@ func (d *Delegate) newServicesGenericPlugin( if err != nil { return nil, err } + // NOTE: we don't need to validate the strategy, since that happens as part of creating the job. + // See: validate/validate.go's `validateSpec`. + onchainSigningStrategy := validate.OCR2OnchainSigningStrategy{} + err = json.Unmarshal(spec.OnchainSigningStrategy.Bytes(), &onchainSigningStrategy) + if err != nil { + return nil, err + } plugEnv := env.NewPlugin(pCfg.PluginName) diff --git a/core/services/ocr2/validate/validate.go b/core/services/ocr2/validate/validate.go index 59f7053de56..9a85d7993a4 100644 --- a/core/services/ocr2/validate/validate.go +++ b/core/services/ocr2/validate/validate.go @@ -16,6 +16,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/loop/reportingplugins" "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink/v2/core/config/env" "github.com/smartcontractkit/chainlink/v2/core/services/job" dkgconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/dkg/config" @@ -172,6 +173,40 @@ func (o *OCR2GenericPluginConfig) UnmarshalJSON(data []byte) error { return nil } +type onchainSigningStrategyInner struct { + StrategyName string `json:"strategyName"` + Config job.JSONConfig `json:"config"` +} + +type OCR2OnchainSigningStrategy struct { + onchainSigningStrategyInner +} + +func (o *OCR2OnchainSigningStrategy) UnmarshalJSON(data []byte) error { + err := json.Unmarshal(data, &o.onchainSigningStrategyInner) + if err != nil { + return err + } + + return nil +} + +func (o *OCR2OnchainSigningStrategy) IsMultiChain() bool { + return o.StrategyName == "multi-chain" +} + +func (o *OCR2OnchainSigningStrategy) PublicKey() (string, error) { + pk, ok := o.Config["publicKey"] + if !ok { + return "", nil + } + name, ok := pk.(string) + if !ok { + return "", fmt.Errorf("expected string publicKey value, but got: %T", pk) + } + return name, nil +} + func validateGenericPluginSpec(ctx context.Context, spec *job.OCR2OracleSpec, rc plugins.RegistrarConfig) error { p := OCR2GenericPluginConfig{} err := json.Unmarshal(spec.PluginConfig.Bytes(), &p) @@ -187,6 +222,19 @@ func validateGenericPluginSpec(ctx context.Context, spec *job.OCR2OracleSpec, rc return errors.New("generic config invalid: only OCR version 2 and 3 are supported") } + onchainSigningStrategy := OCR2OnchainSigningStrategy{} + err = json.Unmarshal(spec.OnchainSigningStrategy.Bytes(), &onchainSigningStrategy) + if err != nil { + return err + } + pk, err := onchainSigningStrategy.PublicKey() + if err != nil { + return err + } + if pk == "" { + return errors.New("generic config invalid: must provide public key for the onchain signing strategy") + } + plugEnv := env.NewPlugin(p.PluginName) command := p.Command diff --git a/core/services/ocr2/validate/validate_test.go b/core/services/ocr2/validate/validate_test.go index fad5a36e51f..05881187ba4 100644 --- a/core/services/ocr2/validate/validate_test.go +++ b/core/services/ocr2/validate/validate_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/require" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" @@ -44,6 +45,11 @@ answer1 [type=median index=0]; """ [relayConfig] chainID = 1337 +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] juelsPerFeeCoinSource = """ ds1 [type=bridge name=voter_turnout]; @@ -66,6 +72,8 @@ answer1 [type=median index=0]; var pc medianconfig.PluginConfig require.NoError(t, json.Unmarshal(r.PluginConfig.Bytes(), &pc)) require.NoError(t, medianconfig.ValidatePluginConfig(pc)) + var oss validate.OCR2OnchainSigningStrategy + require.NoError(t, json.Unmarshal(r.OnchainSigningStrategy.Bytes(), &oss)) }, }, { @@ -93,6 +101,11 @@ answer1 [type=median index=0]; """ [relayConfig] chainID = 1337 +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] juelsPerFeeCoinSource = """ ds1 [type=bridge name=voter_turnout]; @@ -133,6 +146,11 @@ answer1 [type=median index=0]; """ [relayConfig] chainID = 1337 +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] `, assertion: func(t *testing.T, os job.Job, err error) { @@ -152,6 +170,11 @@ p2pPeerID = "12D3KooWHfYFQ8hGttAYbMCevQVESEQhzJAqFZokMVtom8bNxwGq" p2pv2Bootstrappers = [] [relayConfig] chainID = 1337 +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] `, assertion: func(t *testing.T, os job.Job, err error) { @@ -173,6 +196,11 @@ observationSource = """ """ [relayConfig] chainID = 1337 +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] `, assertion: func(t *testing.T, os job.Job, err error) { @@ -194,6 +222,11 @@ blah """ [relayConfig] chainID = 1337 +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] `, assertion: func(t *testing.T, os job.Job, err error) { @@ -216,6 +249,11 @@ blah """ [relayConfig] chainID = 1337 +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] `, assertion: func(t *testing.T, os job.Job, err error) { @@ -237,6 +275,11 @@ blah """ [relayConfig] chainID = 1337 +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] `, assertion: func(t *testing.T, os job.Job, err error) { @@ -256,6 +299,11 @@ p2pv2Bootstrappers = [] monitoringEndpoint = "\t/fd\2ff )(*&^%$#@" [relayConfig] chainID = 1337 +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] `, assertion: func(t *testing.T, os job.Job, err error) { @@ -292,6 +340,11 @@ ds1_multiply [type=multiply times=1.23]; ds1 -> ds1_parse -> ds1_multiply -> answer1; answer1 [type=median index=0]; """ +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] juelsPerFeeCoinSource = """ ds1 [type=bridge name=voter_turnout]; @@ -326,6 +379,11 @@ ds1_multiply [type=multiply times=1.23]; ds1 -> ds1_parse -> ds1_multiply -> answer1; answer1 [type=median index=0]; """ +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] juelsPerFeeCoinSource = """ -> @@ -353,6 +411,11 @@ ds1_multiply [type=multiply times=1.23]; ds1 -> ds1_parse -> ds1_multiply -> answer1; answer1 [type=median index=0]; """ +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" [pluginConfig] juelsPerFeeCoinSource = """ ds1 [type=bridge name=voter_turnout]; @@ -386,6 +449,12 @@ transmitterID = "0x74103Cf8b436465870b26aa9Fa2F62AD62b22E35" [relayConfig] chainID = 4 +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" + [pluginConfig] EncryptionPublicKey = "0e86e8cf899ae9a1b43e023bbe8825b103659bb8d6d4e54f6a3cfae7b106069c" SigningPublicKey = "eb62dbd2beb7c1524275a8019022f6ce6a7e86c9e65e3099452a2b96fc2432b1" @@ -415,6 +484,12 @@ transmitterID = "0x74103Cf8b436465870b26aa9Fa2F62AD62b22E35" [relayConfig] chainID = 4 +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" + [pluginConfig] EncryptionPublicKey = "frog" SigningPublicKey = "eb62dbd2beb7c1524275a8019022f6ce6a7e86c9e65e3099452a2b96fc2432b1" @@ -446,6 +521,12 @@ transmitterID = "0x74103Cf8b436465870b26aa9Fa2F62AD62b22E35" [relayConfig] chainID = 4 +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" + [pluginConfig] EncryptionPublicKey = "0e86e8cf899ae9a1b43e023bbe8825b103659bb8d6d4e54f6a3cfae7b10606" SigningPublicKey = "eb62dbd2beb7c1524275a8019022f6ce6a7e86c9e65e3099452a2b96fc2432b1" @@ -477,6 +558,12 @@ transmitterID = "0x74103Cf8b436465870b26aa9Fa2F62AD62b22E35" [relayConfig] chainID = 4 +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" + [pluginConfig] EncryptionPublicKey = "0e86e8cf899ae9a1b43e023bbe8825b103659bb8d6d4e54f6a3cfae7b106069c" SigningPublicKey = "frog" @@ -508,6 +595,12 @@ transmitterID = "0x74103Cf8b436465870b26aa9Fa2F62AD62b22E35" [relayConfig] chainID = 4 +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" + [pluginConfig] EncryptionPublicKey = "0e86e8cf899ae9a1b43e023bbe8825b103659bb8d6d4e54f6a3cfae7b106069c" SigningPublicKey = "eb62dbd2beb7c1524275a8019022f6ce6a7e86c9e65e3099452a2b96fc24" @@ -539,6 +632,12 @@ transmitterID = "0x74103Cf8b436465870b26aa9Fa2F62AD62b22E35" [relayConfig] chainID = 4 +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" + [pluginConfig] EncryptionPublicKey = "0e86e8cf899ae9a1b43e023bbe8825b103659bb8d6d4e54f6a3cfae7b106069c" SigningPublicKey = "eb62dbd2beb7c1524275a8019022f6ce6a7e86c9e65e3099452a2b96fc2432b1" @@ -570,6 +669,12 @@ transmitterID = "0x74103Cf8b436465870b26aa9Fa2F62AD62b22E35" [relayConfig] chainID = 4 +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" + [pluginConfig] EncryptionPublicKey = "0e86e8cf899ae9a1b43e023bbe8825b103659bb8d6d4e54f6a3cfae7b106069c" SigningPublicKey = "eb62dbd2beb7c1524275a8019022f6ce6a7e86c9e65e3099452a2b96fc2432b1" @@ -581,6 +686,46 @@ KeyID = "6f3b82406688b8ddb944c6f2e6d808f014c8fa8d568d639c25019568c require.Contains(t, err.Error(), "validation error for keyID") }, }, + { + name: "Generic public onchain signing strategy with no public key", + toml: ` +type = "offchainreporting2" +pluginType = "plugin" +schemaVersion = 1 +relay = "evm" +contractID = "0x613a38AC1659769640aaE063C651F48E0250454C" +p2pPeerID = "12D3KooWHfYFQ8hGttAYbMCevQVESEQhzJAqFZokMVtom8bNxwGq" +p2pv2Bootstrappers = [ +"12D3KooWHfYFQ8hGttAYbMCevQVESEQhzJAqFZokMVtom8bNxwGq@127.0.0.1:5001", +] +ocrKeyBundleID = "73e8966a78ca09bb912e9565cfb79fbe8a6048fab1f0cf49b18047c3895e0447" +monitoringEndpoint = "chain.link:4321" +transmitterID = "0xF67D0290337bca0847005C7ffD1BC75BA9AAE6e4" +observationTimeout = "10s" +observationSource = """ +ds1 [type=bridge name=voter_turnout]; +ds1_parse [type=jsonparse path="one,two"]; +ds1_multiply [type=multiply times=1.23]; +ds1 -> ds1_parse -> ds1_multiply -> answer1; +answer1 [type=median index=0]; +""" +[relayConfig] +chainID = 1337 +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "" +[pluginConfig] +pluginName = "median" +telemetryType = "median" +OCRVersion=2 +`, + assertion: func(t *testing.T, os job.Job, err error) { + require.Error(t, err) + require.Contains(t, err.Error(), "must provide public key for the onchain signing strategy") + }, + }, { name: "Generic plugin config validation - nothing provided", toml: ` @@ -601,6 +746,12 @@ transmitterID = "0x74103Cf8b436465870b26aa9Fa2F62AD62b22E35" [relayConfig] chainID = 4 +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" + [pluginConfig] `, assertion: func(t *testing.T, os job.Job, err error) { @@ -627,6 +778,12 @@ transmitterID = "0x74103Cf8b436465870b26aa9Fa2F62AD62b22E35" [relayConfig] chainID = 4 +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" + [pluginConfig] PluginName="some random name" `, @@ -655,6 +812,12 @@ transmitterID = "0x74103Cf8b436465870b26aa9Fa2F62AD62b22E35" [relayConfig] chainID = 4 +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" + [pluginConfig] PluginName="some random name" OCRVersion=2 @@ -684,6 +847,12 @@ transmitterID = "0x74103Cf8b436465870b26aa9Fa2F62AD62b22E35" [relayConfig] chainID = 4 +[onchainSigningStrategy] +strategyName = "single-chain" +[onchainSigningStrategy.config] +evm = "" +publicKey = "0x1234567890123456789012345678901234567890" + [pluginConfig] PluginName="some random name" OCRVersion=2 diff --git a/core/store/migrate/migrations/0234_generic_plugin_multichain_keybundle_.sql b/core/store/migrate/migrations/0234_generic_plugin_multichain_keybundle_.sql new file mode 100644 index 00000000000..b29ff9de382 --- /dev/null +++ b/core/store/migrate/migrations/0234_generic_plugin_multichain_keybundle_.sql @@ -0,0 +1,11 @@ +-- +goose Up +-- +goose StatementBegin +ALTER TABLE ocr2_oracle_specs + ADD COLUMN onchain_signing_strategy JSONB NOT NULL DEFAULT '{}'; +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +ALTER TABLE ocr2_oracle_specs + DROP COLUMN onchain_signing_strategy; +-- +goose StatementEnd \ No newline at end of file From 7967744ef9ac240cc903d144a3e5ffc09bd06327 Mon Sep 17 00:00:00 2001 From: Sam Date: Thu, 25 Apr 2024 14:29:28 -0400 Subject: [PATCH 36/77] Force mercury poll time to 1s (#12771) --- core/services/ocr2/delegate.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index 2e623ab5467..dbde65efe40 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -768,6 +768,11 @@ func (d *Delegate) newServicesMercury( return nil, errors.New("could not coerce PluginProvider to MercuryProvider") } + // HACK: We need fast config switchovers because they create downtime. This + // won't be properly resolved until we implement blue-green deploys: + // https://smartcontract-it.atlassian.net/browse/MERC-3386 + lc.ContractConfigTrackerPollInterval = 1 * time.Second // Mercury requires a fast poll interval, this is the fastest that libocr supports. See: https://github.com/smartcontractkit/offchain-reporting/pull/520 + oracleArgsNoPlugin := libocr2.MercuryOracleArgs{ BinaryNetworkEndpointFactory: d.peerWrapper.Peer2, V2Bootstrappers: bootstrapPeers, From 167782c680b92b1e99ae3e9d1a8b87fd595dd644 Mon Sep 17 00:00:00 2001 From: Lei Date: Thu, 25 Apr 2024 11:57:35 -0700 Subject: [PATCH 37/77] minor improvements on contracts (#12944) --- .changeset/tricky-bats-exist.md | 5 + contracts/.changeset/new-guests-accept.md | 5 + .../dev/v2_3/AutomationRegistrar2_3.sol | 14 +- .../dev/v2_3/AutomationRegistry2_3.sol | 18 +- .../dev/v2_3/AutomationRegistryBase2_3.sol | 52 ++--- .../dev/v2_3/AutomationRegistryLogicA2_3.sol | 1 + .../dev/v2_3/AutomationRegistryLogicC2_3.sol | 7 +- .../automation/AutomationRegistrar2_3.test.ts | 182 ++++++++---------- .../automation_registrar_wrapper2_3.go | 18 +- ...automation_registry_logic_a_wrapper_2_3.go | 2 +- .../automation_registry_wrapper_2_3.go | 2 +- ...rapper-dependency-versions-do-not-edit.txt | 6 +- 12 files changed, 151 insertions(+), 161 deletions(-) create mode 100644 .changeset/tricky-bats-exist.md create mode 100644 contracts/.changeset/new-guests-accept.md diff --git a/.changeset/tricky-bats-exist.md b/.changeset/tricky-bats-exist.md new file mode 100644 index 00000000000..3c748353859 --- /dev/null +++ b/.changeset/tricky-bats-exist.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +minor fixes #bugfix diff --git a/contracts/.changeset/new-guests-accept.md b/contracts/.changeset/new-guests-accept.md new file mode 100644 index 00000000000..080fe17b2bc --- /dev/null +++ b/contracts/.changeset/new-guests-accept.md @@ -0,0 +1,5 @@ +--- +"@chainlink/contracts": patch +--- + +minor fixes #bugfix diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistrar2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistrar2_3.sol index 4284ba62f9d..8d4bf17ce91 100644 --- a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistrar2_3.sol +++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistrar2_3.sol @@ -81,7 +81,7 @@ contract AutomationRegistrar2_3 is TypeAndVersionInterface, ConfirmedOwner, IERC } /** * @member upkeepContract address to perform upkeep on - * @member amount quantity of LINK upkeep is funded with (specified in wei) + * @member amount quantity of billing token upkeep is funded with (specified in the billing token's decimals) * @member adminAddress address to cancel upkeep and withdraw remaining funds * @member gasLimit amount of gas to provide the target contract when performing upkeep * @member triggerType the type of trigger for the upkeep @@ -204,19 +204,17 @@ contract AutomationRegistrar2_3 is TypeAndVersionInterface, ConfirmedOwner, IERC /** * @dev register upkeep on AutomationRegistry contract and emit RegistrationApproved event * @param requestParams struct of all possible registration parameters - * @param hash the committment of the registration request */ - function approve(RegistrationParams calldata requestParams, bytes32 hash) external onlyOwner { + function approve(RegistrationParams calldata requestParams) external onlyOwner { + bytes32 hash = keccak256(abi.encode(requestParams)); + PendingRequest memory request = s_pendingRequests[hash]; if (request.admin == address(0)) { revert RequestNotFound(); } - bytes32 expectedHash = keccak256(abi.encode(requestParams)); - if (hash != expectedHash) { - revert HashMismatch(); - } + delete s_pendingRequests[hash]; - _approve(requestParams, expectedHash); + _approve(requestParams, hash); } /** diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistry2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistry2_3.sol index 93d3376a4f6..318b382ab32 100644 --- a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistry2_3.sol +++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistry2_3.sol @@ -207,13 +207,13 @@ contract AutomationRegistry2_3 is AutomationRegistryBase2_3, OCR2Abstract, Chain report.upkeepIds[i], upkeepTransmitInfo[i].upkeep ); - transmitVars.totalPremium += receipt.premiumJuels; - transmitVars.totalReimbursement += receipt.gasReimbursementJuels; + transmitVars.totalPremium += receipt.premiumInJuels; + transmitVars.totalReimbursement += receipt.gasReimbursementInJuels; emit UpkeepPerformed( report.upkeepIds[i], upkeepTransmitInfo[i].performSuccess, - receipt.gasReimbursementJuels + receipt.premiumJuels, // TODO - this is currently the LINK amount, but may change to billing token + receipt.gasReimbursementInJuels + receipt.premiumInJuels, // TODO - this is currently the LINK amount, but may change to billing token upkeepTransmitInfo[i].gasUsed, gasOverhead, report.triggers[i] @@ -320,6 +320,10 @@ contract AutomationRegistry2_3 is AutomationRegistryBase2_3, OCR2Abstract, Chain chainModule: onchainConfig.chainModule }); + uint32 previousConfigBlockNumber = s_storage.latestConfigBlockNumber; + uint32 newLatestConfigBlockNumber = uint32(onchainConfig.chainModule.blockNumber()); + uint32 newConfigCount = s_storage.configCount + 1; + s_storage = Storage({ checkGasLimit: onchainConfig.checkGasLimit, maxPerformGas: onchainConfig.maxPerformGas, @@ -330,17 +334,13 @@ contract AutomationRegistry2_3 is AutomationRegistryBase2_3, OCR2Abstract, Chain upkeepPrivilegeManager: onchainConfig.upkeepPrivilegeManager, financeAdmin: onchainConfig.financeAdmin, nonce: s_storage.nonce, - configCount: s_storage.configCount, - latestConfigBlockNumber: s_storage.latestConfigBlockNumber + configCount: newConfigCount, + latestConfigBlockNumber: newLatestConfigBlockNumber }); s_fallbackGasPrice = onchainConfig.fallbackGasPrice; s_fallbackLinkPrice = onchainConfig.fallbackLinkPrice; s_fallbackNativePrice = onchainConfig.fallbackNativePrice; - uint32 previousConfigBlockNumber = s_storage.latestConfigBlockNumber; - s_storage.latestConfigBlockNumber = uint32(onchainConfig.chainModule.blockNumber()); - s_storage.configCount += 1; - bytes memory onchainConfigBytes = abi.encode(onchainConfig); s_latestConfigDigest = _configDigestFromConfigData( diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol index 62c72adffc4..cb90bddf1f9 100644 --- a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol +++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryBase2_3.sol @@ -41,7 +41,7 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner { uint8 internal constant UPKEEP_VERSION_BASE = 4; // Next block of constants are only used in maxPayment estimation during checkUpkeep simulation - // These values are calibrated using hardhat tests which simulates various cases and verifies that + // These values are calibrated using hardhat tests which simulate various cases and verify that // the variables result in accurate estimation uint256 internal constant REGISTRY_CONDITIONAL_OVERHEAD = 93_000; // Fixed gas overhead for conditional upkeeps uint256 internal constant REGISTRY_LOG_OVERHEAD = 118_000; // Fixed gas overhead for log upkeeps @@ -433,16 +433,16 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner { /** * @notice struct containing receipt information about a payment or cost estimation - * @member gasCharge the amount to charge a user for gas spent using the billing token's native decimals - * @member premium the premium charged to the user, shared between all nodes, using the billing token's native decimals - * @member gasReimbursementJuels the amount to reimburse a node for gas spent - * @member premiumJuels the premium paid to NOPs, shared between all nodes + * @member gasChargeInBillingToken the amount to charge a user for gas spent using the billing token's native decimals + * @member premiumInBillingToken the premium charged to the user, shared between all nodes, using the billing token's native decimals + * @member gasReimbursementInJuels the amount to reimburse a node for gas spent + * @member premiumInJuels the premium paid to NOPs, shared between all nodes */ struct PaymentReceipt { - uint96 gasCharge; - uint96 premium; - uint96 gasReimbursementJuels; - uint96 premiumJuels; + uint96 gasChargeInBillingToken; + uint96 premiumInBillingToken; + uint96 gasReimbursementInJuels; + uint96 premiumInJuels; } event AdminPrivilegeConfigSet(address indexed admin, bytes privilegeConfig); @@ -683,12 +683,12 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner { uint256 gasPaymentHexaicosaUSD = (gasWei * (paymentParams.gasLimit + paymentParams.gasOverhead) + paymentParams.l1CostWei) * paymentParams.nativeUSD; // gasPaymentHexaicosaUSD has an extra 8 zeros because of decimals on nativeUSD feed - // gasCharge is scaled by the billing token's decimals - receipt.gasCharge = SafeCast.toUint96( + // gasChargeInBillingToken is scaled by the billing token's decimals + receipt.gasChargeInBillingToken = SafeCast.toUint96( (gasPaymentHexaicosaUSD * numeratorScalingFactor) / (paymentParams.billingTokenParams.priceUSD * denominatorScalingFactor) ); - receipt.gasReimbursementJuels = SafeCast.toUint96(gasPaymentHexaicosaUSD / paymentParams.linkUSD); + receipt.gasReimbursementInJuels = SafeCast.toUint96(gasPaymentHexaicosaUSD / paymentParams.linkUSD); // premium calculation uint256 flatFeeHexaicosaUSD = uint256(paymentParams.billingTokenParams.flatFeeMilliCents) * 1e21; // 1e13 for milliCents to attoUSD and 1e8 for attoUSD to hexaicosaUSD @@ -696,11 +696,11 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner { paymentParams.billingTokenParams.gasFeePPB * paymentParams.nativeUSD) / 1e9) + flatFeeHexaicosaUSD; // premium is scaled by the billing token's decimals - receipt.premium = SafeCast.toUint96( + receipt.premiumInBillingToken = SafeCast.toUint96( (premiumHexaicosaUSD * numeratorScalingFactor) / (paymentParams.billingTokenParams.priceUSD * denominatorScalingFactor) ); - receipt.premiumJuels = SafeCast.toUint96(premiumHexaicosaUSD / paymentParams.linkUSD); + receipt.premiumInJuels = SafeCast.toUint96(premiumHexaicosaUSD / paymentParams.linkUSD); return receipt; } @@ -764,7 +764,7 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner { }) ); - return receipt.gasCharge + receipt.premium; + return receipt.gasChargeInBillingToken + receipt.premiumInBillingToken; } /** @@ -1002,22 +1002,23 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner { // balance is in the token's native decimals uint96 balance = upkeep.balance; // payment is in the token's native decimals - uint96 payment = receipt.gasCharge + receipt.premium; + uint96 payment = receipt.gasChargeInBillingToken + receipt.premiumInBillingToken; // this shouldn't happen, but in rare edge cases, we charge the full balance in case the user // can't cover the amount owed - if (balance < receipt.gasCharge) { + if (balance < receipt.gasChargeInBillingToken) { // if the user can't cover the gas fee, then direct all of the payment to the transmitter and distribute no premium to the DON payment = balance; - receipt.gasReimbursementJuels = SafeCast.toUint96( + receipt.gasReimbursementInJuels = SafeCast.toUint96( (balance * paymentParams.billingTokenParams.priceUSD) / paymentParams.linkUSD ); - receipt.premiumJuels = 0; + receipt.premiumInJuels = 0; } else if (balance < payment) { // if the user can cover the gas fee, but not the premium, then reduce the premium payment = balance; - receipt.premiumJuels = SafeCast.toUint96( - ((balance * paymentParams.billingTokenParams.priceUSD) / paymentParams.linkUSD) - receipt.gasReimbursementJuels + receipt.premiumInJuels = SafeCast.toUint96( + ((balance * paymentParams.billingTokenParams.priceUSD) / paymentParams.linkUSD) - + receipt.gasReimbursementInJuels ); } @@ -1120,13 +1121,12 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner { * @notice updates the signers and transmitters lists */ function _updateTransmitters(address[] memory signers, address[] memory transmitters) internal { + uint96 transmittersListLength = uint96(s_transmittersList.length); + uint96 totalPremium = s_hotVars.totalPremium; + // move all pooled payments out of the pool to each transmitter's balance for (uint256 i = 0; i < s_transmittersList.length; i++) { - _updateTransmitterBalanceFromPool( - s_transmittersList[i], - s_hotVars.totalPremium, - uint96(s_transmittersList.length) - ); + _updateTransmitterBalanceFromPool(s_transmittersList[i], totalPremium, transmittersListLength); } // remove any old signer/transmitter addresses diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicA2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicA2_3.sol index 99fc97ce5ce..70ac2c6a38c 100644 --- a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicA2_3.sol +++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicA2_3.sol @@ -198,6 +198,7 @@ contract AutomationRegistryLogicA2_3 is AutomationRegistryBase2_3, Chainable { delete s_upkeepOffchainConfig[id]; // nullify existing proposed admin change if an upkeep is being migrated delete s_proposedAdmin[id]; + delete s_upkeepAdmin[id]; s_upkeepIDs.remove(id); emit UpkeepMigrated(id, upkeep.balance, destination); } diff --git a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicC2_3.sol b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicC2_3.sol index 4048227f111..d4565615ad1 100644 --- a/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicC2_3.sol +++ b/contracts/src/v0.8/automation/dev/v2_3/AutomationRegistryLogicC2_3.sol @@ -161,6 +161,7 @@ contract AutomationRegistryLogicC2_3 is AutomationRegistryBase2_3 { _onlyFinanceAdminAllowed(); if (s_payoutMode == PayoutMode.ON_CHAIN) revert MustSettleOnchain(); + uint96 totalPremium = s_hotVars.totalPremium; uint256 activeTransmittersLength = s_transmittersList.length; uint256 deactivatedTransmittersLength = s_deactivatedTransmitters.length(); uint256 length = activeTransmittersLength + deactivatedTransmittersLength; @@ -171,7 +172,7 @@ contract AutomationRegistryLogicC2_3 is AutomationRegistryBase2_3 { address transmitterAddr = s_transmittersList[i]; uint96 balance = _updateTransmitterBalanceFromPool( transmitterAddr, - s_hotVars.totalPremium, + totalPremium, uint96(activeTransmittersLength) ); @@ -548,7 +549,7 @@ contract AutomationRegistryLogicC2_3 is AutomationRegistryBase2_3 { } /** - * @notice returns the upkeep privilege config + * @notice returns the admin's privilege config */ function getAdminPrivilegeConfig(address admin) external view returns (bytes memory) { return s_adminPrivilegeConfig[admin]; @@ -562,7 +563,7 @@ contract AutomationRegistryLogicC2_3 is AutomationRegistryBase2_3 { } /** - * @notice returns the upkeep's forwarder contract + * @notice returns if the dedupKey exists or not */ function hasDedupKey(bytes32 dedupKey) external view returns (bool) { return s_dedupKeys[dedupKey]; diff --git a/contracts/test/v0.8/automation/AutomationRegistrar2_3.test.ts b/contracts/test/v0.8/automation/AutomationRegistrar2_3.test.ts index 02191dab999..31712e1380b 100644 --- a/contracts/test/v0.8/automation/AutomationRegistrar2_3.test.ts +++ b/contracts/test/v0.8/automation/AutomationRegistrar2_3.test.ts @@ -802,7 +802,6 @@ describe('AutomationRegistrar2_3', () => { }) describe('#approve', () => { - let hash: string let params: RegistrationParams beforeEach(async () => { @@ -834,47 +833,40 @@ describe('AutomationRegistrar2_3', () => { const tx = await linkToken .connect(requestSender) .transferAndCall(registrar.address, amount, abiEncodedBytes) - const receipt = await tx.wait() - hash = receipt.logs[2].topics[1] + await tx.wait() }) it('reverts if not called by the owner', async () => { - const tx = registrar.connect(stranger).approve( - { - name: upkeepName, - encryptedEmail: emptyBytes, - upkeepContract: mock.address, - gasLimit: performGas, - adminAddress: await admin.getAddress(), - checkData: emptyBytes, - triggerType: Trigger.CONDITION, - triggerConfig: trigger, - offchainConfig: emptyBytes, - amount, - billingToken: linkToken.address, - }, - hash, - ) + const tx = registrar.connect(stranger).approve({ + name: upkeepName, + encryptedEmail: emptyBytes, + upkeepContract: mock.address, + gasLimit: performGas, + adminAddress: await admin.getAddress(), + checkData: emptyBytes, + triggerType: Trigger.CONDITION, + triggerConfig: trigger, + offchainConfig: emptyBytes, + amount, + billingToken: linkToken.address, + }) await evmRevert(tx, 'Only callable by owner') }) it('reverts if the hash does not exist', async () => { - const tx = registrar.connect(registrarOwner).approve( - { - name: upkeepName, - encryptedEmail: emptyBytes, - upkeepContract: mock.address, - gasLimit: performGas, - adminAddress: await admin.getAddress(), - checkData: emptyBytes, - triggerType: Trigger.CONDITION, - triggerConfig: trigger, - offchainConfig: emptyBytes, - amount, - billingToken: linkToken.address, - }, - '0x000000000000000000000000322813fd9a801c5507c9de605d63cea4f2ce6c44', - ) + const tx = registrar.connect(registrarOwner).approve({ + name: upkeepName, + encryptedEmail: emptyBytes, + upkeepContract: mock.address, + gasLimit: performGas, + adminAddress: await admin.getAddress(), + checkData: emptyBytes, + triggerType: Trigger.CONDITION, + triggerConfig: trigger, + offchainConfig: emptyBytes, + amount, + billingToken: linkToken.address, + }) await evmRevertCustomError(tx, registrar, errorMsgs.requestNotFound) }) @@ -917,67 +909,58 @@ describe('AutomationRegistrar2_3', () => { for (let i = 0; i < invalidFields.length; i++) { const field = invalidFields[i] const badParams = Object.assign({}, params, field) as RegistrationParams - const tx = registrar.connect(registrarOwner).approve(badParams, hash) + const tx = registrar.connect(registrarOwner).approve(badParams) await expect( tx, `expected ${JSON.stringify(field)} to cause failure, but succeeded`, - ).to.be.revertedWithCustomError(registrar, errorMsgs.hashPayload) + ).to.be.revertedWithCustomError(registrar, errorMsgs.requestNotFound) } }) it('approves an existing registration request', async () => { - const tx = await registrar.connect(registrarOwner).approve( - { - name: upkeepName, - encryptedEmail: emptyBytes, - upkeepContract: mock.address, - gasLimit: performGas, - adminAddress: await admin.getAddress(), - checkData: emptyBytes, - triggerType: Trigger.CONDITION, - triggerConfig: trigger, - offchainConfig, - amount, - billingToken: linkToken.address, - }, - hash, - ) + const tx = await registrar.connect(registrarOwner).approve({ + name: upkeepName, + encryptedEmail: emptyBytes, + upkeepContract: mock.address, + gasLimit: performGas, + adminAddress: await admin.getAddress(), + checkData: emptyBytes, + triggerType: Trigger.CONDITION, + triggerConfig: trigger, + offchainConfig, + amount, + billingToken: linkToken.address, + }) await expect(tx).to.emit(registrar, 'RegistrationApproved') }) it('deletes the request afterwards / reverts if the request DNE', async () => { - await registrar.connect(registrarOwner).approve( - { - name: upkeepName, - encryptedEmail: emptyBytes, - upkeepContract: mock.address, - gasLimit: performGas, - adminAddress: await admin.getAddress(), - checkData: emptyBytes, - triggerType: Trigger.CONDITION, - triggerConfig: trigger, - offchainConfig, - amount, - billingToken: linkToken.address, - }, - hash, - ) - const tx = registrar.connect(registrarOwner).approve( - { - name: upkeepName, - encryptedEmail: emptyBytes, - upkeepContract: mock.address, - gasLimit: performGas, - adminAddress: await admin.getAddress(), - checkData: emptyBytes, - triggerType: Trigger.CONDITION, - triggerConfig: trigger, - offchainConfig, - amount, - billingToken: linkToken.address, - }, - hash, - ) + await registrar.connect(registrarOwner).approve({ + name: upkeepName, + encryptedEmail: emptyBytes, + upkeepContract: mock.address, + gasLimit: performGas, + adminAddress: await admin.getAddress(), + checkData: emptyBytes, + triggerType: Trigger.CONDITION, + triggerConfig: trigger, + offchainConfig, + amount, + billingToken: linkToken.address, + }) + const tx = registrar.connect(registrarOwner).approve({ + name: upkeepName, + encryptedEmail: emptyBytes, + upkeepContract: mock.address, + gasLimit: performGas, + adminAddress: await admin.getAddress(), + checkData: emptyBytes, + triggerType: Trigger.CONDITION, + triggerConfig: trigger, + offchainConfig, + amount, + billingToken: linkToken.address, + }) await evmRevertCustomError(tx, registrar, errorMsgs.requestNotFound) }) }) @@ -1049,22 +1032,19 @@ describe('AutomationRegistrar2_3', () => { await registrar.connect(registrarOwner).cancel(hash) let tx = registrar.connect(registrarOwner).cancel(hash) await evmRevertCustomError(tx, registrar, errorMsgs.requestNotFound) - tx = registrar.connect(registrarOwner).approve( - { - name: upkeepName, - encryptedEmail: emptyBytes, - upkeepContract: mock.address, - gasLimit: performGas, - adminAddress: await admin.getAddress(), - checkData: emptyBytes, - triggerType: Trigger.CONDITION, - triggerConfig: trigger, - offchainConfig: emptyBytes, - amount, - billingToken: linkToken.address, - }, - hash, - ) + tx = registrar.connect(registrarOwner).approve({ + name: upkeepName, + encryptedEmail: emptyBytes, + upkeepContract: mock.address, + gasLimit: performGas, + adminAddress: await admin.getAddress(), + checkData: emptyBytes, + triggerType: Trigger.CONDITION, + triggerConfig: trigger, + offchainConfig: emptyBytes, + amount, + billingToken: linkToken.address, + }) await evmRevertCustomError(tx, registrar, errorMsgs.requestNotFound) }) }) diff --git a/core/gethwrappers/generated/automation_registrar_wrapper2_3/automation_registrar_wrapper2_3.go b/core/gethwrappers/generated/automation_registrar_wrapper2_3/automation_registrar_wrapper2_3.go index dd16a290b7c..6cb4ee30be6 100644 --- a/core/gethwrappers/generated/automation_registrar_wrapper2_3/automation_registrar_wrapper2_3.go +++ b/core/gethwrappers/generated/automation_registrar_wrapper2_3/automation_registrar_wrapper2_3.go @@ -57,8 +57,8 @@ type AutomationRegistrar23TriggerRegistrationStorage struct { } var AutomationRegistrarMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"LINKAddress\",\"type\":\"address\"},{\"internalType\":\"contractIAutomationRegistryMaster2_3\",\"name\":\"registry\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"}],\"internalType\":\"structAutomationRegistrar2_3.InitialTriggerConfig[]\",\"name\":\"triggerConfigs\",\"type\":\"tuple[]\"},{\"internalType\":\"contractIERC20Metadata[]\",\"name\":\"billingTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"minRegistrationFees\",\"type\":\"uint256[]\"},{\"internalType\":\"contractIWrappedNative\",\"name\":\"wrappedNativeToken\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HashMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientPayment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAdminAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidBillingToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RequestNotFound\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"AutoApproveAllowedSenderSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"displayName\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"RegistrationApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"RegistrationRejected\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"encryptedEmail\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"RegistrationRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"}],\"name\":\"TriggerConfigSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"contractIERC20Metadata\",\"name\":\"billingToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedEmail\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structAutomationRegistrar2_3.RegistrationParams\",\"name\":\"requestParams\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"cancel\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"}],\"name\":\"getAutoApproveAllowedSender\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20Metadata\",\"name\":\"billingToken\",\"type\":\"address\"}],\"name\":\"getMinimumRegistrationAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"getPendingRequest\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRegistry\",\"outputs\":[{\"internalType\":\"contractIAutomationRegistryMaster2_3\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"}],\"name\":\"getTriggerRegistrationDetails\",\"outputs\":[{\"components\":[{\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"approvedCount\",\"type\":\"uint32\"}],\"internalType\":\"structAutomationRegistrar2_3.TriggerRegistrationStorage\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_LINK\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_WRAPPED_NATIVE_TOKEN\",\"outputs\":[{\"internalType\":\"contractIWrappedNative\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"contractIERC20Metadata\",\"name\":\"billingToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedEmail\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structAutomationRegistrar2_3.RegistrationParams\",\"name\":\"requestParams\",\"type\":\"tuple\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"setAutoApproveAllowedSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIAutomationRegistryMaster2_3\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"contractIERC20Metadata[]\",\"name\":\"billingTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"minBalances\",\"type\":\"uint256[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"}],\"name\":\"setTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60c06040523480156200001157600080fd5b506040516200358d3803806200358d8339810160408190526200003491620005db565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be8162000183565b5050506001600160a01b03808716608052811660a052620000e18584846200022e565b60005b84518110156200017657620001618582815181106200010757620001076200076d565b6020026020010151600001518683815181106200012857620001286200076d565b6020026020010151602001518784815181106200014957620001496200076d565b6020026020010151604001516200032a60201b60201c565b806200016d8162000783565b915050620000e4565b5050505050505062000804565b336001600160a01b03821603620001dd5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b62000238620003d8565b80518251146200025b57604051630dfe930960e41b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b03851617905560005b8251811015620002fb578181815181106200029857620002986200076d565b602002602001015160046000858481518110620002b957620002b96200076d565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055508080620002f29062000783565b91505062000279565b506040517fb9b6902016bd1219d5fa6161243b61e7e9f7f959526dd94ef8fa3e403bf881c390600090a1505050565b62000334620003d8565b60ff83166000908152600660205260409020805483919060ff19166001836002811115620003665762000366620007ab565b021790555060ff831660009081526006602052604090819020805464ffffffff00191661010063ffffffff851602179055517f830a6d06a4e2caac67eba04323de22bdb04f032dd8b3d6a0c52b503d9a7036a390620003cb90859085908590620007c1565b60405180910390a1505050565b6000546001600160a01b03163314620004345760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b6001600160a01b03811681146200044c57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156200048a576200048a6200044f565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620004bb57620004bb6200044f565b604052919050565b60006001600160401b03821115620004df57620004df6200044f565b5060051b60200190565b600082601f830112620004fb57600080fd5b81516020620005146200050e83620004c3565b62000490565b82815260059290921b840181019181810190868411156200053457600080fd5b8286015b848110156200055c5780516200054e8162000436565b835291830191830162000538565b509695505050505050565b600082601f8301126200057957600080fd5b815160206200058c6200050e83620004c3565b82815260059290921b84018101918181019086841115620005ac57600080fd5b8286015b848110156200055c5780518352918301918301620005b0565b8051620005d68162000436565b919050565b60008060008060008060c08789031215620005f557600080fd5b8651620006028162000436565b80965050602080880151620006178162000436565b60408901519096506001600160401b03808211156200063557600080fd5b818a0191508a601f8301126200064a57600080fd5b81516200065b6200050e82620004c3565b81815260609091028301840190848101908d8311156200067a57600080fd5b938501935b8285101562000701576060858f0312156200069a5760008081fd5b620006a462000465565b855160ff81168114620006b75760008081fd5b81528587015160038110620006cc5760008081fd5b81880152604086015163ffffffff81168114620006e95760008081fd5b6040820152825260609490940193908501906200067f565b60608d015190995094505050808311156200071b57600080fd5b620007298b848c01620004e9565b955060808a01519250808311156200074057600080fd5b50506200075089828a0162000567565b9250506200076160a08801620005c9565b90509295509295509295565b634e487b7160e01b600052603260045260246000fd5b600060018201620007a457634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052602160045260246000fd5b60ff841681526060810160038410620007ea57634e487b7160e01b600052602160045260246000fd5b83602083015263ffffffff83166040830152949350505050565b60805160a051612d39620008546000396000818161027b015281816105a601526106390152600081816104b301528181610a0301528181610a6c0152818161168301526116dc0152612d396000f3fe6080604052600436106101295760003560e01c806388b12d55116100a5578063accb832311610074578063befdae4611610059578063befdae46146104a1578063c4d252f5146104d5578063f2fde38b146104f557600080fd5b8063accb832314610461578063b5ff5b411461048157600080fd5b806388b12d55146103085780638da5cb5b146103d3578063a2b1ff94146103fe578063a4c0ed361461044157600080fd5b80635ab1bd53116100fc5780636bf7d75f116100e15780636bf7d75f1461026957806379ba50971461029d5780637e776f7f146102b257600080fd5b80635ab1bd53146101fd57806366ab87f91461024957600080fd5b8063181f5a771461012e578063212d08841461018d5780632ce3a14a146101ba578063367b9b4f146101db575b600080fd5b34801561013a57600080fd5b506101776040518060400160405280601981526020017f4175746f6d6174696f6e52656769737472617220322e332e300000000000000081525081565b6040516101849190611f79565b60405180910390f35b34801561019957600080fd5b506101ad6101a8366004611fa9565b610515565b604051610184919061202e565b6101cd6101c8366004612345565b6105a2565b604051908152602001610184565b3480156101e757600080fd5b506101fb6101f6366004612388565b610710565b005b34801561020957600080fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610184565b34801561025557600080fd5b506101fb610264366004612450565b6107a2565b34801561027557600080fd5b506102247f000000000000000000000000000000000000000000000000000000000000000081565b3480156102a957600080fd5b506101fb6108e9565b3480156102be57600080fd5b506102f86102cd366004612526565b73ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205460ff1690565b6040519015158152602001610184565b34801561031457600080fd5b5061039a610323366004612543565b6000908152600560209081526040918290208251606081018452815473ffffffffffffffffffffffffffffffffffffffff808216808452740100000000000000000000000000000000000000009092046bffffffffffffffffffffffff169483018590526001909301549092169301929092529091565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526bffffffffffffffffffffffff909116602083015201610184565b3480156103df57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610224565b34801561040a57600080fd5b506101cd610419366004612526565b73ffffffffffffffffffffffffffffffffffffffff1660009081526004602052604090205490565b34801561044d57600080fd5b506101fb61045c36600461255c565b6109eb565b34801561046d57600080fd5b506101fb61047c3660046125e5565b610b19565b34801561048d57600080fd5b506101fb61049c366004612630565b610c84565b3480156104ad57600080fd5b506102247f000000000000000000000000000000000000000000000000000000000000000081565b3480156104e157600080fd5b506101fb6104f0366004612543565b610d63565b34801561050157600080fd5b506101fb610510366004612526565b610f2a565b60408051606080820183526000808352602080840182905283850182905260ff86811683526006909152908490208451928301909452835492939192839116600281111561056557610565611fc4565b600281111561057657610576611fc4565b8152905463ffffffff610100820481166020840152650100000000009091041660409091015292915050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168260a0015173ffffffffffffffffffffffffffffffffffffffff1614801561060257503415155b156106bd5761061034610f3e565b82602001906bffffffffffffffffffffffff1690816bffffffffffffffffffffffff16815250507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561069f57600080fd5b505af11580156106b3573d6000803e3d6000fd5b5050505050610700565b610700333084602001516bffffffffffffffffffffffff168560a0015173ffffffffffffffffffffffffffffffffffffffff16610fe0909392919063ffffffff16565b61070a82336110c2565b92915050565b610718611529565b73ffffffffffffffffffffffffffffffffffffffff821660008181526003602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915591519182527f20c6237dac83526a849285a9f79d08a483291bdd3a056a0ef9ae94ecee1ad356910160405180910390a25050565b6107aa611529565b80518251146107e5576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851617905560005b82518110156108ba5781818151811061084357610843612679565b60200260200101516004600085848151811061086157610861612679565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080806108b2906126d7565b915050610828565b506040517fb9b6902016bd1219d5fa6161243b61e7e9f7f959526dd94ef8fa3e403bf881c390600090a1505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461096f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610a5a576040517f018d10be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610a6882840184612345565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168160a0015173ffffffffffffffffffffffffffffffffffffffff1614610af3576040517f018d10be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6bffffffffffffffffffffffff84166020820152610b1181866110c2565b505050505050565b610b21611529565b6000818152600560209081526040918290208251606081018452815473ffffffffffffffffffffffffffffffffffffffff808216808452740100000000000000000000000000000000000000009092046bffffffffffffffffffffffff16948301949094526001909201549092169282019290925290610bcd576040517f4b13b31e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083604051602001610be091906127c3565b604051602081830303815290604052805190602001209050808314610c31576040517f3f4d605300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083815260056020526040812090815560010180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055610c7d610c778561297f565b826115ac565b5050505050565b610c8c611529565b60ff8316600090815260066020526040902080548391907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001836002811115610cd957610cd9611fc4565b021790555060ff83166000908152600660205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010063ffffffff851602179055517f830a6d06a4e2caac67eba04323de22bdb04f032dd8b3d6a0c52b503d9a7036a390610d569085908590859061298b565b60405180910390a1505050565b6000818152600560209081526040918290208251606081018452815473ffffffffffffffffffffffffffffffffffffffff808216808452740100000000000000000000000000000000000000009092046bffffffffffffffffffffffff16948301949094526001909201549092169282019290925290331480610dfd575060005473ffffffffffffffffffffffffffffffffffffffff1633145b610e33576040517f61685c2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805173ffffffffffffffffffffffffffffffffffffffff16610e81576040517f4b13b31e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600560209081526040808320928355600190920180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905582519083015191830151610efb9273ffffffffffffffffffffffffffffffffffffffff90911691906bffffffffffffffffffffffff16611917565b60405182907f3663fb28ebc87645eb972c9dad8521bf665c623f287e79f1c56f1eb374b82a2290600090a25050565b610f32611529565b610f3b81611972565b50565b60006bffffffffffffffffffffffff821115610fdc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610966565b5090565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526110bc9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611a67565b50505050565b60a082015173ffffffffffffffffffffffffffffffffffffffff166000908152600460209081526040822054908401516bffffffffffffffffffffffff161015611138576040517fcd1c886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604083015173ffffffffffffffffffffffffffffffffffffffff16611189576040517f05bb467c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025460a08401516040517fa538b2eb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063a538b2eb90602401602060405180830381865afa1580156111fd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122191906129b6565b611257576040517f1183afea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008360405160200161126a91906129d3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600590935291205490915073ffffffffffffffffffffffffffffffffffffffff16156112fd576040517f357d0cc400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836000015173ffffffffffffffffffffffffffffffffffffffff16817f7684390ebb103102f7f48c71439c2408713f8d437782a6fab2756acc0e42c1b78660c001518760e00151886060015189604001518a608001518b61012001518c61014001518d61010001518e6020015160405161137f99989796959493929190612b3f565b60405180910390a3608084015160ff908116600090815260066020526040808220815160608101909252805492936114029383911660028111156113c5576113c5611fc4565b60028111156113d6576113d6611fc4565b8152905463ffffffff610100820481166020840152650100000000009091041660409091015285611b73565b1561146a57608085015160ff166000908152600660205260409020805465010000000000900463ffffffff1690600561143a83612bfa565b91906101000a81548163ffffffff021916908363ffffffff1602179055505061146385836115ac565b9050611521565b604080516060810182528682015173ffffffffffffffffffffffffffffffffffffffff90811682526020808901516bffffffffffffffffffffffff90811682850190815260a08b01518416858701908152600089815260059094529590922093519151167401000000000000000000000000000000000000000002908216178255915160019091018054919092167fffffffffffffffffffffffff0000000000000000000000000000000000000000919091161790555b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146115aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610966565b565b60025482516060840151604080860151608087015160a08801516101008901516101208a01516101408b015195517fc62cf68400000000000000000000000000000000000000000000000000000000815260009973ffffffffffffffffffffffffffffffffffffffff16988a988a9863c62cf6849861163c98939792969095939492939092909190600401612c1d565b6020604051808303816000875af115801561165b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061167f9190612cab565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168560a0015173ffffffffffffffffffffffffffffffffffffffff16036117f65760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634000aea08488602001518560405160200161172f91815260200190565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161175c93929190612cc4565b6020604051808303816000875af115801561177b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061179f91906129b6565b9050806117f0576040517f39f1c8d900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610966565b506118d2565b6118378286602001516bffffffffffffffffffffffff168760a0015173ffffffffffffffffffffffffffffffffffffffff16611c189092919063ffffffff16565b60208501516040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018390526bffffffffffffffffffffffff909116602482015273ffffffffffffffffffffffffffffffffffffffff83169063948108f790604401600060405180830381600087803b1580156118b957600080fd5b505af11580156118cd573d6000803e3d6000fd5b505050505b80847fb9a292fb7e3edd920cd2d2829a3615a640c43fd7de0a0820aa0668feb4c37d4b8760c001516040516119079190611f79565b60405180910390a3949350505050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261196d9084907fa9059cbb000000000000000000000000000000000000000000000000000000009060640161103a565b505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036119f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610966565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611ac9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611d9a9092919063ffffffff16565b80519091501561196d5780806020019051810190611ae791906129b6565b61196d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610966565b60008083516002811115611b8957611b89611fc4565b03611b965750600061070a565b600183516002811115611bab57611bab611fc4565b148015611bde575073ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604090205460ff16155b15611beb5750600061070a565b826020015163ffffffff16836040015163ffffffff161015611c0f5750600161070a565b50600092915050565b801580611cb857506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e90604401602060405180830381865afa158015611c92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb69190612cab565b155b611d44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610966565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261196d9084907f095ea7b3000000000000000000000000000000000000000000000000000000009060640161103a565b60606115218484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051611dce9190612d10565b60006040518083038185875af1925050503d8060008114611e0b576040519150601f19603f3d011682016040523d82523d6000602084013e611e10565b606091505b5091509150611e2187838387611e2c565b979650505050505050565b60608315611ec2578251600003611ebb5773ffffffffffffffffffffffffffffffffffffffff85163b611ebb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610966565b5081611521565b6115218383815115611ed75781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109669190611f79565b60005b83811015611f26578181015183820152602001611f0e565b50506000910152565b60008151808452611f47816020860160208601611f0b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611f8c6020830184611f2f565b9392505050565b803560ff81168114611fa457600080fd5b919050565b600060208284031215611fbb57600080fd5b611f8c82611f93565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6003811061202a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b6000606082019050612041828451611ff3565b602083015163ffffffff8082166020850152806040860151166040850152505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff811182821017156120ba576120ba612067565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561210757612107612067565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f3b57600080fd5b8035611fa48161210f565b80356bffffffffffffffffffffffff81168114611fa457600080fd5b803563ffffffff81168114611fa457600080fd5b600082601f83011261217d57600080fd5b813567ffffffffffffffff81111561219757612197612067565b6121c860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016120c0565b8181528460208386010111156121dd57600080fd5b816020850160208301376000918101602001919091529392505050565b6000610160828403121561220d57600080fd5b612215612096565b905061222082612131565b815261222e6020830161213c565b602082015261223f60408301612131565b604082015261225060608301612158565b606082015261226160808301611f93565b608082015261227260a08301612131565b60a082015260c082013567ffffffffffffffff8082111561229257600080fd5b61229e8583860161216c565b60c084015260e08401359150808211156122b757600080fd5b6122c38583860161216c565b60e0840152610100915081840135818111156122de57600080fd5b6122ea8682870161216c565b83850152506101209150818401358181111561230557600080fd5b6123118682870161216c565b83850152506101409150818401358181111561232c57600080fd5b6123388682870161216c565b8385015250505092915050565b60006020828403121561235757600080fd5b813567ffffffffffffffff81111561236e57600080fd5b611521848285016121fa565b8015158114610f3b57600080fd5b6000806040838503121561239b57600080fd5b82356123a68161210f565b915060208301356123b68161237a565b809150509250929050565b600067ffffffffffffffff8211156123db576123db612067565b5060051b60200190565b600082601f8301126123f657600080fd5b8135602061240b612406836123c1565b6120c0565b82815260059290921b8401810191818101908684111561242a57600080fd5b8286015b84811015612445578035835291830191830161242e565b509695505050505050565b60008060006060848603121561246557600080fd5b83356124708161210f565b925060208481013567ffffffffffffffff8082111561248e57600080fd5b818701915087601f8301126124a257600080fd5b81356124b0612406826123c1565b81815260059190911b8301840190848101908a8311156124cf57600080fd5b938501935b828510156124f65784356124e78161210f565b825293850193908501906124d4565b96505050604087013592508083111561250e57600080fd5b505061251c868287016123e5565b9150509250925092565b60006020828403121561253857600080fd5b8135611f8c8161210f565b60006020828403121561255557600080fd5b5035919050565b6000806000806060858703121561257257600080fd5b843561257d8161210f565b935060208501359250604085013567ffffffffffffffff808211156125a157600080fd5b818701915087601f8301126125b557600080fd5b8135818111156125c457600080fd5b8860208285010111156125d657600080fd5b95989497505060200194505050565b600080604083850312156125f857600080fd5b823567ffffffffffffffff81111561260f57600080fd5b8301610160818603121561262257600080fd5b946020939093013593505050565b60008060006060848603121561264557600080fd5b61264e84611f93565b925060208401356003811061266257600080fd5b915061267060408501612158565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612708576127086126a8565b5060010190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261274457600080fd5b830160208101925035905067ffffffffffffffff81111561276457600080fd5b80360382131561277357600080fd5b9250929050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526127f1602082016127d784612131565b73ffffffffffffffffffffffffffffffffffffffff169052565b60006127ff6020840161213c565b6bffffffffffffffffffffffff811660408401525061282060408401612131565b73ffffffffffffffffffffffffffffffffffffffff811660608401525061284960608401612158565b63ffffffff811660808401525061286260808401611f93565b60ff811660a08401525061287860a08401612131565b73ffffffffffffffffffffffffffffffffffffffff811660c0840152506128a260c084018461270f565b6101608060e08601526128ba6101808601838561277a565b92506128c960e087018761270f565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe061010081888703018189015261290386868561277a565b9550612911818a018a61270f565b955092505061012081888703018189015261292d86868561277a565b955061293b818a018a61270f565b955092505061014081888703018189015261295786868561277a565b9550612965818a018a61270f565b955092505080878603018388015250611e2184848361277a565b600061070a36836121fa565b60ff84168152606081016129a26020830185611ff3565b63ffffffff83166040830152949350505050565b6000602082840312156129c857600080fd5b8151611f8c8161237a565b602081526129fa60208201835173ffffffffffffffffffffffffffffffffffffffff169052565b60006020830151612a1b60408401826bffffffffffffffffffffffff169052565b50604083015173ffffffffffffffffffffffffffffffffffffffff8116606084015250606083015163ffffffff8116608084015250608083015160ff811660a08401525060a083015173ffffffffffffffffffffffffffffffffffffffff811660c08401525060c08301516101608060e0850152612a9d610180850183611f2f565b915060e08501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0610100818786030181880152612adb8584611f2f565b945080880151925050610120818786030181880152612afa8584611f2f565b945080880151925050610140818786030181880152612b198584611f2f565b908801518782039092018488015293509050612b358382611f2f565b9695505050505050565b6000610120808352612b538184018d611f2f565b90508281036020840152612b67818c611f2f565b905063ffffffff8a16604084015273ffffffffffffffffffffffffffffffffffffffff8916606084015260ff8816608084015282810360a0840152612bac8188611f2f565b905082810360c0840152612bc08187611f2f565b905082810360e0840152612bd48186611f2f565b9150506bffffffffffffffffffffffff83166101008301529a9950505050505050505050565b600063ffffffff808316818103612c1357612c136126a8565b6001019392505050565b600061010073ffffffffffffffffffffffffffffffffffffffff808c16845263ffffffff8b166020850152808a16604085015260ff891660608501528088166080850152508060a0840152612c7481840187611f2f565b905082810360c0840152612c888186611f2f565b905082810360e0840152612c9c8185611f2f565b9b9a5050505050505050505050565b600060208284031215612cbd57600080fd5b5051919050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff83166020820152606060408201526000612d076060830184611f2f565b95945050505050565b60008251612d22818460208701611f0b565b919091019291505056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"LINKAddress\",\"type\":\"address\"},{\"internalType\":\"contractIAutomationRegistryMaster2_3\",\"name\":\"registry\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"}],\"internalType\":\"structAutomationRegistrar2_3.InitialTriggerConfig[]\",\"name\":\"triggerConfigs\",\"type\":\"tuple[]\"},{\"internalType\":\"contractIERC20Metadata[]\",\"name\":\"billingTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"minRegistrationFees\",\"type\":\"uint256[]\"},{\"internalType\":\"contractIWrappedNative\",\"name\":\"wrappedNativeToken\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HashMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientPayment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAdminAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidBillingToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RequestNotFound\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"AutoApproveAllowedSenderSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"displayName\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"RegistrationApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"RegistrationRejected\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"encryptedEmail\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"RegistrationRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"}],\"name\":\"TriggerConfigSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"contractIERC20Metadata\",\"name\":\"billingToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedEmail\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structAutomationRegistrar2_3.RegistrationParams\",\"name\":\"requestParams\",\"type\":\"tuple\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"cancel\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"}],\"name\":\"getAutoApproveAllowedSender\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20Metadata\",\"name\":\"billingToken\",\"type\":\"address\"}],\"name\":\"getMinimumRegistrationAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"getPendingRequest\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRegistry\",\"outputs\":[{\"internalType\":\"contractIAutomationRegistryMaster2_3\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"}],\"name\":\"getTriggerRegistrationDetails\",\"outputs\":[{\"components\":[{\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"approvedCount\",\"type\":\"uint32\"}],\"internalType\":\"structAutomationRegistrar2_3.TriggerRegistrationStorage\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_LINK\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_WRAPPED_NATIVE_TOKEN\",\"outputs\":[{\"internalType\":\"contractIWrappedNative\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"upkeepContract\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"contractIERC20Metadata\",\"name\":\"billingToken\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedEmail\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structAutomationRegistrar2_3.RegistrationParams\",\"name\":\"requestParams\",\"type\":\"tuple\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"setAutoApproveAllowedSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIAutomationRegistryMaster2_3\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"contractIERC20Metadata[]\",\"name\":\"billingTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"minBalances\",\"type\":\"uint256[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"enumAutomationRegistrar2_3.AutoApproveType\",\"name\":\"autoApproveType\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"autoApproveMaxAllowed\",\"type\":\"uint32\"}],\"name\":\"setTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60c06040523480156200001157600080fd5b5060405162003556380380620035568339810160408190526200003491620005db565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be8162000183565b5050506001600160a01b03808716608052811660a052620000e18584846200022e565b60005b84518110156200017657620001618582815181106200010757620001076200076d565b6020026020010151600001518683815181106200012857620001286200076d565b6020026020010151602001518784815181106200014957620001496200076d565b6020026020010151604001516200032a60201b60201c565b806200016d8162000783565b915050620000e4565b5050505050505062000804565b336001600160a01b03821603620001dd5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b62000238620003d8565b80518251146200025b57604051630dfe930960e41b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b03851617905560005b8251811015620002fb578181815181106200029857620002986200076d565b602002602001015160046000858481518110620002b957620002b96200076d565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055508080620002f29062000783565b91505062000279565b506040517fb9b6902016bd1219d5fa6161243b61e7e9f7f959526dd94ef8fa3e403bf881c390600090a1505050565b62000334620003d8565b60ff83166000908152600660205260409020805483919060ff19166001836002811115620003665762000366620007ab565b021790555060ff831660009081526006602052604090819020805464ffffffff00191661010063ffffffff851602179055517f830a6d06a4e2caac67eba04323de22bdb04f032dd8b3d6a0c52b503d9a7036a390620003cb90859085908590620007c1565b60405180910390a1505050565b6000546001600160a01b03163314620004345760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b6001600160a01b03811681146200044c57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156200048a576200048a6200044f565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620004bb57620004bb6200044f565b604052919050565b60006001600160401b03821115620004df57620004df6200044f565b5060051b60200190565b600082601f830112620004fb57600080fd5b81516020620005146200050e83620004c3565b62000490565b82815260059290921b840181019181810190868411156200053457600080fd5b8286015b848110156200055c5780516200054e8162000436565b835291830191830162000538565b509695505050505050565b600082601f8301126200057957600080fd5b815160206200058c6200050e83620004c3565b82815260059290921b84018101918181019086841115620005ac57600080fd5b8286015b848110156200055c5780518352918301918301620005b0565b8051620005d68162000436565b919050565b60008060008060008060c08789031215620005f557600080fd5b8651620006028162000436565b80965050602080880151620006178162000436565b60408901519096506001600160401b03808211156200063557600080fd5b818a0191508a601f8301126200064a57600080fd5b81516200065b6200050e82620004c3565b81815260609091028301840190848101908d8311156200067a57600080fd5b938501935b8285101562000701576060858f0312156200069a5760008081fd5b620006a462000465565b855160ff81168114620006b75760008081fd5b81528587015160038110620006cc5760008081fd5b81880152604086015163ffffffff81168114620006e95760008081fd5b6040820152825260609490940193908501906200067f565b60608d015190995094505050808311156200071b57600080fd5b620007298b848c01620004e9565b955060808a01519250808311156200074057600080fd5b50506200075089828a0162000567565b9250506200076160a08801620005c9565b90509295509295509295565b634e487b7160e01b600052603260045260246000fd5b600060018201620007a457634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052602160045260246000fd5b60ff841681526060810160038410620007ea57634e487b7160e01b600052602160045260246000fd5b83602083015263ffffffff83166040830152949350505050565b60805160a051612d02620008546000396000818161029b015281816105a601526106390152600081816104b301528181610b4c01528181610bb50152818161165b01526116b40152612d026000f3fe6080604052600436106101295760003560e01c80637e776f7f116100a5578063a4c0ed3611610074578063befdae4611610059578063befdae46146104a1578063c4d252f5146104d5578063f2fde38b146104f557600080fd5b8063a4c0ed3614610461578063b5ff5b411461048157600080fd5b80637e776f7f146102d257806388b12d55146103285780638da5cb5b146103f3578063a2b1ff941461041e57600080fd5b8063367b9b4f116100fc57806366ab87f9116100e157806366ab87f9146102695780636bf7d75f1461028957806379ba5097146102bd57600080fd5b8063367b9b4f146101fd5780635ab1bd531461021d57600080fd5b8063181f5a771461012e578063212d08841461018d5780632ce3a14a146101ba5780633188a2ce146101db575b600080fd5b34801561013a57600080fd5b506101776040518060400160405280601981526020017f4175746f6d6174696f6e52656769737472617220322e332e300000000000000081525081565b6040516101849190611f51565b60405180910390f35b34801561019957600080fd5b506101ad6101a8366004611f81565b610515565b6040516101849190612006565b6101cd6101c836600461231d565b6105a2565b604051908152602001610184565b3480156101e757600080fd5b506101fb6101f6366004612352565b610710565b005b34801561020957600080fd5b506101fb61021836600461239c565b610859565b34801561022957600080fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610184565b34801561027557600080fd5b506101fb610284366004612464565b6108eb565b34801561029557600080fd5b506102447f000000000000000000000000000000000000000000000000000000000000000081565b3480156102c957600080fd5b506101fb610a32565b3480156102de57600080fd5b506103186102ed36600461253a565b73ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205460ff1690565b6040519015158152602001610184565b34801561033457600080fd5b506103ba610343366004612557565b6000908152600560209081526040918290208251606081018452815473ffffffffffffffffffffffffffffffffffffffff808216808452740100000000000000000000000000000000000000009092046bffffffffffffffffffffffff169483018590526001909301549092169301929092529091565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526bffffffffffffffffffffffff909116602083015201610184565b3480156103ff57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610244565b34801561042a57600080fd5b506101cd61043936600461253a565b73ffffffffffffffffffffffffffffffffffffffff1660009081526004602052604090205490565b34801561046d57600080fd5b506101fb61047c366004612570565b610b34565b34801561048d57600080fd5b506101fb61049c3660046125f9565b610c62565b3480156104ad57600080fd5b506102447f000000000000000000000000000000000000000000000000000000000000000081565b3480156104e157600080fd5b506101fb6104f0366004612557565b610d41565b34801561050157600080fd5b506101fb61051036600461253a565b610f08565b60408051606080820183526000808352602080840182905283850182905260ff86811683526006909152908490208451928301909452835492939192839116600281111561056557610565611f9c565b600281111561057657610576611f9c565b8152905463ffffffff610100820481166020840152650100000000009091041660409091015292915050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168260a0015173ffffffffffffffffffffffffffffffffffffffff1614801561060257503415155b156106bd5761061034610f1c565b82602001906bffffffffffffffffffffffff1690816bffffffffffffffffffffffff16815250507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561069f57600080fd5b505af11580156106b3573d6000803e3d6000fd5b5050505050610700565b610700333084602001516bffffffffffffffffffffffff168560a0015173ffffffffffffffffffffffffffffffffffffffff16610fbe909392919063ffffffff16565b61070a823361109a565b92915050565b610718611501565b60008160405160200161072b91906126f6565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181528282528051602091820120600081815260058352839020606085018452805473ffffffffffffffffffffffffffffffffffffffff808216808852740100000000000000000000000000000000000000009092046bffffffffffffffffffffffff169487019490945260019091015490921692840192909252909250610807576040517f4b13b31e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260056020526040812090815560010180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905561085361084d846128b2565b83611584565b50505050565b610861611501565b73ffffffffffffffffffffffffffffffffffffffff821660008181526003602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915591519182527f20c6237dac83526a849285a9f79d08a483291bdd3a056a0ef9ae94ecee1ad356910160405180910390a25050565b6108f3611501565b805182511461092e576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851617905560005b8251811015610a035781818151811061098c5761098c6128be565b6020026020010151600460008584815181106109aa576109aa6128be565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080806109fb9061291c565b915050610971565b506040517fb9b6902016bd1219d5fa6161243b61e7e9f7f959526dd94ef8fa3e403bf881c390600090a1505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610ab8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610ba3576040517f018d10be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610bb18284018461231d565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168160a0015173ffffffffffffffffffffffffffffffffffffffff1614610c3c576040517f018d10be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6bffffffffffffffffffffffff84166020820152610c5a818661109a565b505050505050565b610c6a611501565b60ff8316600090815260066020526040902080548391907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001836002811115610cb757610cb7611f9c565b021790555060ff83166000908152600660205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010063ffffffff851602179055517f830a6d06a4e2caac67eba04323de22bdb04f032dd8b3d6a0c52b503d9a7036a390610d3490859085908590612954565b60405180910390a1505050565b6000818152600560209081526040918290208251606081018452815473ffffffffffffffffffffffffffffffffffffffff808216808452740100000000000000000000000000000000000000009092046bffffffffffffffffffffffff16948301949094526001909201549092169282019290925290331480610ddb575060005473ffffffffffffffffffffffffffffffffffffffff1633145b610e11576040517f61685c2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805173ffffffffffffffffffffffffffffffffffffffff16610e5f576040517f4b13b31e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600560209081526040808320928355600190920180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905582519083015191830151610ed99273ffffffffffffffffffffffffffffffffffffffff90911691906bffffffffffffffffffffffff166118ef565b60405182907f3663fb28ebc87645eb972c9dad8521bf665c623f287e79f1c56f1eb374b82a2290600090a25050565b610f10611501565b610f198161194a565b50565b60006bffffffffffffffffffffffff821115610fba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610aaf565b5090565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526108539085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611a3f565b60a082015173ffffffffffffffffffffffffffffffffffffffff166000908152600460209081526040822054908401516bffffffffffffffffffffffff161015611110576040517fcd1c886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604083015173ffffffffffffffffffffffffffffffffffffffff16611161576040517f05bb467c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025460a08401516040517fa538b2eb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063a538b2eb90602401602060405180830381865afa1580156111d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111f9919061297f565b61122f576040517f1183afea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083604051602001611242919061299c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600590935291205490915073ffffffffffffffffffffffffffffffffffffffff16156112d5576040517f357d0cc400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836000015173ffffffffffffffffffffffffffffffffffffffff16817f7684390ebb103102f7f48c71439c2408713f8d437782a6fab2756acc0e42c1b78660c001518760e00151886060015189604001518a608001518b61012001518c61014001518d61010001518e6020015160405161135799989796959493929190612b08565b60405180910390a3608084015160ff908116600090815260066020526040808220815160608101909252805492936113da93839116600281111561139d5761139d611f9c565b60028111156113ae576113ae611f9c565b8152905463ffffffff610100820481166020840152650100000000009091041660409091015285611b4b565b1561144257608085015160ff166000908152600660205260409020805465010000000000900463ffffffff1690600561141283612bc3565b91906101000a81548163ffffffff021916908363ffffffff1602179055505061143b8583611584565b90506114f9565b604080516060810182528682015173ffffffffffffffffffffffffffffffffffffffff90811682526020808901516bffffffffffffffffffffffff90811682850190815260a08b01518416858701908152600089815260059094529590922093519151167401000000000000000000000000000000000000000002908216178255915160019091018054919092167fffffffffffffffffffffffff0000000000000000000000000000000000000000919091161790555b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610aaf565b565b60025482516060840151604080860151608087015160a08801516101008901516101208a01516101408b015195517fc62cf68400000000000000000000000000000000000000000000000000000000815260009973ffffffffffffffffffffffffffffffffffffffff16988a988a9863c62cf6849861161498939792969095939492939092909190600401612be6565b6020604051808303816000875af1158015611633573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116579190612c74565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168560a0015173ffffffffffffffffffffffffffffffffffffffff16036117ce5760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634000aea08488602001518560405160200161170791815260200190565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161173493929190612c8d565b6020604051808303816000875af1158015611753573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611777919061297f565b9050806117c8576040517f39f1c8d900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610aaf565b506118aa565b61180f8286602001516bffffffffffffffffffffffff168760a0015173ffffffffffffffffffffffffffffffffffffffff16611bf09092919063ffffffff16565b60208501516040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018390526bffffffffffffffffffffffff909116602482015273ffffffffffffffffffffffffffffffffffffffff83169063948108f790604401600060405180830381600087803b15801561189157600080fd5b505af11580156118a5573d6000803e3d6000fd5b505050505b80847fb9a292fb7e3edd920cd2d2829a3615a640c43fd7de0a0820aa0668feb4c37d4b8760c001516040516118df9190611f51565b60405180910390a3949350505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526119459084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401611018565b505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036119c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610aaf565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611aa1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611d729092919063ffffffff16565b8051909150156119455780806020019051810190611abf919061297f565b611945576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610aaf565b60008083516002811115611b6157611b61611f9c565b03611b6e5750600061070a565b600183516002811115611b8357611b83611f9c565b148015611bb6575073ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604090205460ff16155b15611bc35750600061070a565b826020015163ffffffff16836040015163ffffffff161015611be75750600161070a565b50600092915050565b801580611c9057506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e90604401602060405180830381865afa158015611c6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c8e9190612c74565b155b611d1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610aaf565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526119459084907f095ea7b30000000000000000000000000000000000000000000000000000000090606401611018565b60606114f98484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051611da69190612cd9565b60006040518083038185875af1925050503d8060008114611de3576040519150601f19603f3d011682016040523d82523d6000602084013e611de8565b606091505b5091509150611df987838387611e04565b979650505050505050565b60608315611e9a578251600003611e935773ffffffffffffffffffffffffffffffffffffffff85163b611e93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aaf565b50816114f9565b6114f98383815115611eaf5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aaf9190611f51565b60005b83811015611efe578181015183820152602001611ee6565b50506000910152565b60008151808452611f1f816020860160208601611ee3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611f646020830184611f07565b9392505050565b803560ff81168114611f7c57600080fd5b919050565b600060208284031215611f9357600080fd5b611f6482611f6b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612002577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b6000606082019050612019828451611fcb565b602083015163ffffffff8082166020850152806040860151166040850152505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff811182821017156120925761209261203f565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156120df576120df61203f565b604052919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f1957600080fd5b8035611f7c816120e7565b80356bffffffffffffffffffffffff81168114611f7c57600080fd5b803563ffffffff81168114611f7c57600080fd5b600082601f83011261215557600080fd5b813567ffffffffffffffff81111561216f5761216f61203f565b6121a060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612098565b8181528460208386010111156121b557600080fd5b816020850160208301376000918101602001919091529392505050565b600061016082840312156121e557600080fd5b6121ed61206e565b90506121f882612109565b815261220660208301612114565b602082015261221760408301612109565b604082015261222860608301612130565b606082015261223960808301611f6b565b608082015261224a60a08301612109565b60a082015260c082013567ffffffffffffffff8082111561226a57600080fd5b61227685838601612144565b60c084015260e084013591508082111561228f57600080fd5b61229b85838601612144565b60e0840152610100915081840135818111156122b657600080fd5b6122c286828701612144565b8385015250610120915081840135818111156122dd57600080fd5b6122e986828701612144565b83850152506101409150818401358181111561230457600080fd5b61231086828701612144565b8385015250505092915050565b60006020828403121561232f57600080fd5b813567ffffffffffffffff81111561234657600080fd5b6114f9848285016121d2565b60006020828403121561236457600080fd5b813567ffffffffffffffff81111561237b57600080fd5b82016101608185031215611f6457600080fd5b8015158114610f1957600080fd5b600080604083850312156123af57600080fd5b82356123ba816120e7565b915060208301356123ca8161238e565b809150509250929050565b600067ffffffffffffffff8211156123ef576123ef61203f565b5060051b60200190565b600082601f83011261240a57600080fd5b8135602061241f61241a836123d5565b612098565b82815260059290921b8401810191818101908684111561243e57600080fd5b8286015b848110156124595780358352918301918301612442565b509695505050505050565b60008060006060848603121561247957600080fd5b8335612484816120e7565b925060208481013567ffffffffffffffff808211156124a257600080fd5b818701915087601f8301126124b657600080fd5b81356124c461241a826123d5565b81815260059190911b8301840190848101908a8311156124e357600080fd5b938501935b8285101561250a5784356124fb816120e7565b825293850193908501906124e8565b96505050604087013592508083111561252257600080fd5b5050612530868287016123f9565b9150509250925092565b60006020828403121561254c57600080fd5b8135611f64816120e7565b60006020828403121561256957600080fd5b5035919050565b6000806000806060858703121561258657600080fd5b8435612591816120e7565b935060208501359250604085013567ffffffffffffffff808211156125b557600080fd5b818701915087601f8301126125c957600080fd5b8135818111156125d857600080fd5b8860208285010111156125ea57600080fd5b95989497505060200194505050565b60008060006060848603121561260e57600080fd5b61261784611f6b565b925060208401356003811061262b57600080fd5b915061263960408501612130565b90509250925092565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261267757600080fd5b830160208101925035905067ffffffffffffffff81111561269757600080fd5b8036038213156126a657600080fd5b9250929050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526127246020820161270a84612109565b73ffffffffffffffffffffffffffffffffffffffff169052565b600061273260208401612114565b6bffffffffffffffffffffffff811660408401525061275360408401612109565b73ffffffffffffffffffffffffffffffffffffffff811660608401525061277c60608401612130565b63ffffffff811660808401525061279560808401611f6b565b60ff811660a0840152506127ab60a08401612109565b73ffffffffffffffffffffffffffffffffffffffff811660c0840152506127d560c0840184612642565b6101608060e08601526127ed610180860183856126ad565b92506127fc60e0870187612642565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06101008188870301818901526128368686856126ad565b9550612844818a018a612642565b95509250506101208188870301818901526128608686856126ad565b955061286e818a018a612642565b955092505061014081888703018189015261288a8686856126ad565b9550612898818a018a612642565b955092505080878603018388015250611df98484836126ad565b600061070a36836121d2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361294d5761294d6128ed565b5060010190565b60ff841681526060810161296b6020830185611fcb565b63ffffffff83166040830152949350505050565b60006020828403121561299157600080fd5b8151611f648161238e565b602081526129c360208201835173ffffffffffffffffffffffffffffffffffffffff169052565b600060208301516129e460408401826bffffffffffffffffffffffff169052565b50604083015173ffffffffffffffffffffffffffffffffffffffff8116606084015250606083015163ffffffff8116608084015250608083015160ff811660a08401525060a083015173ffffffffffffffffffffffffffffffffffffffff811660c08401525060c08301516101608060e0850152612a66610180850183611f07565b915060e08501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0610100818786030181880152612aa48584611f07565b945080880151925050610120818786030181880152612ac38584611f07565b945080880151925050610140818786030181880152612ae28584611f07565b908801518782039092018488015293509050612afe8382611f07565b9695505050505050565b6000610120808352612b1c8184018d611f07565b90508281036020840152612b30818c611f07565b905063ffffffff8a16604084015273ffffffffffffffffffffffffffffffffffffffff8916606084015260ff8816608084015282810360a0840152612b758188611f07565b905082810360c0840152612b898187611f07565b905082810360e0840152612b9d8186611f07565b9150506bffffffffffffffffffffffff83166101008301529a9950505050505050505050565b600063ffffffff808316818103612bdc57612bdc6128ed565b6001019392505050565b600061010073ffffffffffffffffffffffffffffffffffffffff808c16845263ffffffff8b166020850152808a16604085015260ff891660608501528088166080850152508060a0840152612c3d81840187611f07565b905082810360c0840152612c518186611f07565b905082810360e0840152612c658185611f07565b9b9a5050505050505050505050565b600060208284031215612c8657600080fd5b5051919050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff83166020820152606060408201526000612cd06060830184611f07565b95945050505050565b60008251612ceb818460208701611ee3565b919091019291505056fea164736f6c6343000813000a", } var AutomationRegistrarABI = AutomationRegistrarMetaData.ABI @@ -408,16 +408,16 @@ func (_AutomationRegistrar *AutomationRegistrarTransactorSession) AcceptOwnershi return _AutomationRegistrar.Contract.AcceptOwnership(&_AutomationRegistrar.TransactOpts) } -func (_AutomationRegistrar *AutomationRegistrarTransactor) Approve(opts *bind.TransactOpts, requestParams AutomationRegistrar23RegistrationParams, hash [32]byte) (*types.Transaction, error) { - return _AutomationRegistrar.contract.Transact(opts, "approve", requestParams, hash) +func (_AutomationRegistrar *AutomationRegistrarTransactor) Approve(opts *bind.TransactOpts, requestParams AutomationRegistrar23RegistrationParams) (*types.Transaction, error) { + return _AutomationRegistrar.contract.Transact(opts, "approve", requestParams) } -func (_AutomationRegistrar *AutomationRegistrarSession) Approve(requestParams AutomationRegistrar23RegistrationParams, hash [32]byte) (*types.Transaction, error) { - return _AutomationRegistrar.Contract.Approve(&_AutomationRegistrar.TransactOpts, requestParams, hash) +func (_AutomationRegistrar *AutomationRegistrarSession) Approve(requestParams AutomationRegistrar23RegistrationParams) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.Approve(&_AutomationRegistrar.TransactOpts, requestParams) } -func (_AutomationRegistrar *AutomationRegistrarTransactorSession) Approve(requestParams AutomationRegistrar23RegistrationParams, hash [32]byte) (*types.Transaction, error) { - return _AutomationRegistrar.Contract.Approve(&_AutomationRegistrar.TransactOpts, requestParams, hash) +func (_AutomationRegistrar *AutomationRegistrarTransactorSession) Approve(requestParams AutomationRegistrar23RegistrationParams) (*types.Transaction, error) { + return _AutomationRegistrar.Contract.Approve(&_AutomationRegistrar.TransactOpts, requestParams) } func (_AutomationRegistrar *AutomationRegistrarTransactor) Cancel(opts *bind.TransactOpts, hash [32]byte) (*types.Transaction, error) { @@ -1633,7 +1633,7 @@ type AutomationRegistrarInterface interface { AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) - Approve(opts *bind.TransactOpts, requestParams AutomationRegistrar23RegistrationParams, hash [32]byte) (*types.Transaction, error) + Approve(opts *bind.TransactOpts, requestParams AutomationRegistrar23RegistrationParams) (*types.Transaction, error) Cancel(opts *bind.TransactOpts, hash [32]byte) (*types.Transaction, error) diff --git a/core/gethwrappers/generated/automation_registry_logic_a_wrapper_2_3/automation_registry_logic_a_wrapper_2_3.go b/core/gethwrappers/generated/automation_registry_logic_a_wrapper_2_3/automation_registry_logic_a_wrapper_2_3.go index 891415c7d3a..d08825fa1f4 100644 --- a/core/gethwrappers/generated/automation_registry_logic_a_wrapper_2_3/automation_registry_logic_a_wrapper_2_3.go +++ b/core/gethwrappers/generated/automation_registry_logic_a_wrapper_2_3/automation_registry_logic_a_wrapper_2_3.go @@ -46,7 +46,7 @@ type AutomationRegistryBase23BillingOverrides struct { var AutomationRegistryLogicAMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicB2_3\",\"name\":\"logicB\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLinkLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFeed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOffchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOnchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyFinanceAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"overrides\",\"type\":\"tuple\"}],\"name\":\"BillingConfigOverridden\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"BillingConfigOverrideRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contractIERC20Metadata\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"BillingConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeesWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"payments\",\"type\":\"uint256[]\"}],\"name\":\"NOPsSettledOffchain\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"migrateUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedUpkeeps\",\"type\":\"bytes\"}],\"name\":\"receiveUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"enumAutomationRegistryBase2_3.Trigger\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"contractIERC20Metadata\",\"name\":\"billingToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"registerUpkeep\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101806040523480156200001257600080fd5b506040516200477c3803806200477c83398101604081905262000035916200062f565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b91906200062f565b826001600160a01b031663226cf83c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200010091906200062f565b836001600160a01b031663614486af6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016591906200062f565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca91906200062f565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f91906200062f565b866001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029491906200062f565b876001600160a01b031663c5b964e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f9919062000656565b886001600160a01b031663ac4dc59a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000338573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200035e91906200062f565b3380600081620003b55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620003e857620003e8816200056b565b5050506001600160a01b0380891660805287811660a05286811660c05285811660e052848116610100528316610120526025805483919060ff19166001838181111562000439576200043962000679565b0217905550806001600160a01b0316610140816001600160a01b03168152505060c0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200049a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004c091906200068f565b60ff1660a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200052a91906200068f565b60ff16146200054c576040516301f86e1760e41b815260040160405180910390fd5b5050506001600160a01b039095166101605250620006b4945050505050565b336001600160a01b03821603620005c55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620003ac565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200062c57600080fd5b50565b6000602082840312156200064257600080fd5b81516200064f8162000616565b9392505050565b6000602082840312156200066957600080fd5b8151600281106200064f57600080fd5b634e487b7160e01b600052602160045260246000fd5b600060208284031215620006a257600080fd5b815160ff811681146200064f57600080fd5b60805160a05160c05160e0516101005161012051610140516101605161406862000714600039600081816088015260de01526000505060005050600081816111bd01526114d60152600050506000505060005050600050506140686000f3fe608060405260043610620000865760003560e01c80638e86139b11620000555780638e86139b1462000192578063c62cf68414620001b7578063c804802214620001eb578063f2fde38b14620002105762000086565b8063349e8cca14620000ce57806379ba5097146200012857806385c1b0ba14620001405780638da5cb5b1462000165575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015620000c7573d6000f35b3d6000fd5b005b348015620000db57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156200013557600080fd5b50620000cc62000235565b3480156200014d57600080fd5b50620000cc6200015f36600462002cac565b62000338565b3480156200017257600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16620000fe565b3480156200019f57600080fd5b50620000cc620001b136600462002d85565b62001080565b348015620001c457600080fd5b50620001dc620001d636600462002f43565b62001408565b6040519081526020016200011f565b348015620001f857600080fd5b50620000cc6200020a36600462003038565b620017b5565b3480156200021d57600080fd5b50620000cc6200022f36600462003052565b62001c8d565b60015473ffffffffffffffffffffffffffffffffffffffff163314620002bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600173ffffffffffffffffffffffffffffffffffffffff82166000908152601c602052604090205460ff16600381111562000377576200037762003079565b14158015620003c35750600373ffffffffffffffffffffffffffffffffffffffff82166000908152601c602052604090205460ff166003811115620003c057620003c062003079565b14155b15620003fb576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60165473ffffffffffffffffffffffffffffffffffffffff166200044b576040517fd12d7d8d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082900362000487576040517f2c2fc94100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290528190819060008667ffffffffffffffff811115620004f157620004f162002df0565b6040519080825280602002602001820160405280156200051b578160200160208202803683370190505b50905060008767ffffffffffffffff8111156200053c576200053c62002df0565b604051908082528060200260200182016040528015620005d357816020015b604080516101208101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e0820181905261010082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816200055b5790505b50905060008867ffffffffffffffff811115620005f457620005f462002df0565b6040519080825280602002602001820160405280156200062957816020015b6060815260200190600190039081620006135790505b50905060008967ffffffffffffffff8111156200064a576200064a62002df0565b6040519080825280602002602001820160405280156200067f57816020015b6060815260200190600190039081620006695790505b50905060008a67ffffffffffffffff811115620006a057620006a062002df0565b604051908082528060200260200182016040528015620006d557816020015b6060815260200190600190039081620006bf5790505b50905060005b8b81101562000def578c8c82818110620006f957620006f9620030a8565b602090810292909201356000818152600484526040808220815161012081018352815460ff8082161515835261010080830490911615159883019890985263ffffffff620100008204811694830194909452660100000000000081048416606083015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009091048116608083015260018301546fffffffffffffffffffffffffffffffff811660a08401526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08401527c0100000000000000000000000000000000000000000000000000000000900490931660e082015260029091015490911694810194909452909a5091985050819003620008305786610100015199508660c001516bffffffffffffffffffffffff1698505b8973ffffffffffffffffffffffffffffffffffffffff1687610100015173ffffffffffffffffffffffffffffffffffffffff1614620008f55773ffffffffffffffffffffffffffffffffffffffff8a166000908152602160205260409020546200089c908a9062003106565b73ffffffffffffffffffffffffffffffffffffffff8b16600081815260216020526040902091909155620008d2908c8b62001ca5565b86610100015199508660c001516bffffffffffffffffffffffff1698506200091e565b80156200091e5760c08701516200091b906bffffffffffffffffffffffff168a6200311c565b98505b620009298862001d39565b60808701516040517f1a5da6c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d8116600483015290911690631a5da6c890602401600060405180830381600087803b1580156200099957600080fd5b505af1158015620009ae573d6000803e3d6000fd5b5050505086858281518110620009c857620009c8620030a8565b60200260200101819052506005600089815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1686828151811062000a1c5762000a1c620030a8565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091018201526000898152600790915260409020805462000a5b9062003132565b80601f016020809104026020016040519081016040528092919081815260200182805462000a899062003132565b801562000ada5780601f1062000aae5761010080835404028352916020019162000ada565b820191906000526020600020905b81548152906001019060200180831162000abc57829003601f168201915b505050505084828151811062000af45762000af4620030a8565b6020026020010181905250601d6000898152602001908152602001600020805462000b1f9062003132565b80601f016020809104026020016040519081016040528092919081815260200182805462000b4d9062003132565b801562000b9e5780601f1062000b725761010080835404028352916020019162000b9e565b820191906000526020600020905b81548152906001019060200180831162000b8057829003601f168201915b505050505083828151811062000bb85762000bb8620030a8565b6020026020010181905250601e6000898152602001908152602001600020805462000be39062003132565b80601f016020809104026020016040519081016040528092919081815260200182805462000c119062003132565b801562000c625780601f1062000c365761010080835404028352916020019162000c62565b820191906000526020600020905b81548152906001019060200180831162000c4457829003601f168201915b505050505082828151811062000c7c5762000c7c620030a8565b602090810291909101810191909152600089815260048252604080822080547fffff0000000000000000000000000000000000000000000000000000000000001681556001810183905560020180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055600790925290812062000d029162002c0f565b6000888152601d6020526040812062000d1b9162002c0f565b6000888152601e6020526040812062000d349162002c0f565b600088815260066020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016905562000d7560028962001df0565b5060c0870151604080516bffffffffffffffffffffffff909216825273ffffffffffffffffffffffffffffffffffffffff8d16602083015289917fb38647142fbb1ea4c000fc4569b37a4e9a9f6313317b84ee3e5326c1a6cd06ff910160405180910390a28062000de68162003187565b915050620006db565b5073ffffffffffffffffffffffffffffffffffffffff891660009081526021602052604090205462000e2390899062003106565b73ffffffffffffffffffffffffffffffffffffffff8a1660008181526021602052604090209190915562000e59908b8a62001ca5565b60008c8c868167ffffffffffffffff81111562000e7a5762000e7a62002df0565b60405190808252806020026020018201604052801562000ea4578160200160208202803683370190505b508988888860405160200162000ec2989796959493929190620033b9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282526016547faab9edd6000000000000000000000000000000000000000000000000000000008452915190935073ffffffffffffffffffffffffffffffffffffffff808f1693638e86139b939091169163c71249ab91600491869163aab9edd6918482019160209190819003860181865afa15801562000f72573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f98919062003498565b866040518463ffffffff1660e01b815260040162000fb993929190620034bd565b600060405180830381865afa15801562000fd7573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526200101f9190810190620034e4565b6040518263ffffffff1660e01b81526004016200103d91906200355b565b600060405180830381600087803b1580156200105857600080fd5b505af11580156200106d573d6000803e3d6000fd5b5050505050505050505050505050505050565b6002336000908152601c602052604090205460ff166003811115620010a957620010a962003079565b14158015620010df57506003336000908152601c602052604090205460ff166003811115620010dc57620010dc62003079565b14155b1562001117576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080808080806200112d888a018a62003882565b965096509650965096509650965060005b8751811015620013fc57600073ffffffffffffffffffffffffffffffffffffffff16878281518110620011755762001175620030a8565b60200260200101516080015173ffffffffffffffffffffffffffffffffffffffff16036200128957858181518110620011b257620011b2620030a8565b6020026020010151307f0000000000000000000000000000000000000000000000000000000000000000604051620011ea9062002c4e565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f08015801562001234573d6000803e3d6000fd5b508782815181106200124a576200124a620030a8565b60200260200101516080019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b62001341888281518110620012a257620012a2620030a8565b6020026020010151888381518110620012bf57620012bf620030a8565b6020026020010151878481518110620012dc57620012dc620030a8565b6020026020010151878581518110620012f957620012f9620030a8565b6020026020010151878681518110620013165762001316620030a8565b6020026020010151878781518110620013335762001333620030a8565b602002602001015162001e07565b878181518110620013565762001356620030a8565b60200260200101517f74931a144e43a50694897f241d973aecb5024c0e910f9bb80a163ea3c1cf5a71888381518110620013945762001394620030a8565b602002602001015160c0015133604051620013df9291906bffffffffffffffffffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a280620013f38162003187565b9150506200113e565b50505050505050505050565b6000805473ffffffffffffffffffffffffffffffffffffffff1633148015906200143c57506200143a60093362002324565b155b1562001474576040517fd48b678b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8a163b620014c3576040517f09ee12d500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b620014ce8762002354565b905060008a307f0000000000000000000000000000000000000000000000000000000000000000604051620015039062002c4e565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f0801580156200154d573d6000803e3d6000fd5b5090506200163e826040518061012001604052806000151581526020016000151581526020018d63ffffffff16815260200163ffffffff801681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200160006fffffffffffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff168152602001600063ffffffff1681526020018a73ffffffffffffffffffffffffffffffffffffffff168152508b89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92508a915062001e079050565b601680547c0100000000000000000000000000000000000000000000000000000000900463ffffffff1690601c6200167683620039b3565b91906101000a81548163ffffffff021916908363ffffffff16021790555050817fbae366358c023f887e791d7a62f2e4316f1026bd77f6fb49501a917b3bc5d0128b8b604051620016ef92919063ffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a2817fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d87876040516200172b929190620039d9565b60405180910390a2817f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d5664856040516200176591906200355b565b60405180910390a2817f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf4850846040516200179f91906200355b565b60405180910390a2509998505050505050505050565b6000818152600460209081526040808320815161012081018352815460ff8082161515835261010080830490911615159583019590955263ffffffff620100008204811694830194909452660100000000000081048416606083015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009091048116608083015260018301546fffffffffffffffffffffffffffffffff811660a08401526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08401527c0100000000000000000000000000000000000000000000000000000000900490931660e08201526002909101549091169181019190915290620018d960005473ffffffffffffffffffffffffffffffffffffffff1690565b61010083015173ffffffffffffffffffffffffffffffffffffffff90811660009081526022602090815260408083206002015460155482517f57e871e70000000000000000000000000000000000000000000000000000000081529251968616331497506bffffffffffffffffffffffff90911695939416926357e871e7926004808401939192918290030181865afa1580156200197b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620019a1919062003a26565b9050836060015163ffffffff16600003620019e8576040517ffbc0357800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606084015163ffffffff9081161462001a2d576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8215801562001a60575060008581526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b1562001a98576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8262001aae5762001aab6032826200311c565b90505b6000858152600460205260409020805463ffffffff8084166601000000000000027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff9092169190911790915562001b0b90600290879062001df016565b506000826bffffffffffffffffffffffff168560a001516fffffffffffffffffffffffffffffffff16101562001b7e5760a085015162001b4c908462003a40565b90508460c001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff16111562001b7e575060c08401515b808560c0015162001b90919062003a40565b600087815260046020908152604080832060010180547fffffffff000000000000000000000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000006bffffffffffffffffffffffff9687160217905561010089015173ffffffffffffffffffffffffffffffffffffffff168352602190915290205462001c229183169062003106565b61010086015173ffffffffffffffffffffffffffffffffffffffff1660009081526021602052604080822092909255905167ffffffffffffffff84169188917f91cb3bb75cfbd718bbfccc56b7f53d92d7048ef4ca39a3b7b7c6d4af1f7911819190a3505050505050565b62001c97620025f3565b62001ca28162002678565b50565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905262001d349084906200276f565b505050565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff16331462001d97576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600460205260409020546601000000000000900463ffffffff9081161462001ca2576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600062001dfe838362002882565b90505b92915050565b601454760100000000000000000000000000000000000000000000900460ff161562001e5f576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60175483517c010000000000000000000000000000000000000000000000000000000090910463ffffffff16101562001ec4576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108fc856040015163ffffffff16108062001f0a5750601654604086015163ffffffff780100000000000000000000000000000000000000000000000090920482169116115b1562001f42576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000868152600460205260409020546a0100000000000000000000900473ffffffffffffffffffffffffffffffffffffffff161562001fad576040517f6e3b930b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010085015173ffffffffffffffffffffffffffffffffffffffff9081166000908152602260205260409020546701000000000000009004166200201d576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846004600088815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff02191690831515021790555060408201518160000160026101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160066101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600a6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060a08201518160010160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160010160106101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050836005600088815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508260076000888152602001908152602001600020908162002262919062003aba565b5060c085015161010086015173ffffffffffffffffffffffffffffffffffffffff16600090815260216020526040902054620022ad916bffffffffffffffffffffffff16906200311c565b61010086015173ffffffffffffffffffffffffffffffffffffffff16600090815260216020908152604080832093909355888252601d905220620022f2838262003aba565b506000868152601e602052604090206200230d828262003aba565b506200231b6002876200298d565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151562001dfe565b601554604080517f57e871e70000000000000000000000000000000000000000000000000000000081529051600092839273ffffffffffffffffffffffffffffffffffffffff90911691839183916385df51fd9160019184916357e871e79160048083019260209291908290030181865afa158015620023d8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620023fe919062003a26565b6200240a919062003106565b6040518263ffffffff1660e01b81526004016200242991815260200190565b602060405180830381865afa15801562002447573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200246d919062003a26565b60165460408051602081019390935230908301527c0100000000000000000000000000000000000000000000000000000000900463ffffffff166060820152608001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083015201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060045b600f8110156200258157838282815181106200253d576200253d620030a8565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080620025788162003187565b9150506200251d565b5084600181111562002597576200259762003079565b60f81b81600f81518110620025b057620025b0620030a8565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350620025ea8162003be1565b95945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331462002676576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401620002b3565b565b3373ffffffffffffffffffffffffffffffffffffffff821603620026f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620002b3565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000620027d3826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166200299b9092919063ffffffff16565b80519091501562001d345780806020019051810190620027f4919062003c24565b62001d34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401620002b3565b600081815260018301602052604081205480156200297b576000620028a960018362003106565b8554909150600090620028bf9060019062003106565b90508181146200292b576000866000018281548110620028e357620028e3620030a8565b9060005260206000200154905080876000018481548110620029095762002909620030a8565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200293f576200293f62003c44565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062001e01565b600091505062001e01565b5092915050565b600062001dfe8383620029b4565b6060620029ac848460008562002a06565b949350505050565b6000818152600183016020526040812054620029fd5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562001e01565b50600062001e01565b60608247101562002a9a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401620002b3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405162002ac5919062003c73565b60006040518083038185875af1925050503d806000811462002b04576040519150601f19603f3d011682016040523d82523d6000602084013e62002b09565b606091505b509150915062002b1c8783838762002b27565b979650505050505050565b6060831562002bc257825160000362002bba5773ffffffffffffffffffffffffffffffffffffffff85163b62002bba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401620002b3565b5081620029ac565b620029ac838381511562002bd95781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002b391906200355b565b50805462002c1d9062003132565b6000825580601f1062002c2e575050565b601f01602090049060005260206000209081019062001ca2919062002c5c565b6103ca8062003c9283390190565b5b8082111562002c73576000815560010162002c5d565b5090565b73ffffffffffffffffffffffffffffffffffffffff8116811462001ca257600080fd5b803562002ca78162002c77565b919050565b60008060006040848603121562002cc257600080fd5b833567ffffffffffffffff8082111562002cdb57600080fd5b818601915086601f83011262002cf057600080fd5b81358181111562002d0057600080fd5b8760208260051b850101111562002d1657600080fd5b6020928301955093505084013562002d2e8162002c77565b809150509250925092565b60008083601f84011262002d4c57600080fd5b50813567ffffffffffffffff81111562002d6557600080fd5b60208301915083602082850101111562002d7e57600080fd5b9250929050565b6000806020838503121562002d9957600080fd5b823567ffffffffffffffff81111562002db157600080fd5b62002dbf8582860162002d39565b90969095509350505050565b803563ffffffff8116811462002ca757600080fd5b80356002811062002ca757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610120810167ffffffffffffffff8111828210171562002e465762002e4662002df0565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171562002e965762002e9662002df0565b604052919050565b600067ffffffffffffffff82111562002ebb5762002ebb62002df0565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011262002ef957600080fd5b813562002f1062002f0a8262002e9e565b62002e4c565b81815284602083860101111562002f2657600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060008060006101008a8c03121562002f6357600080fd5b62002f6e8a62002c9a565b985062002f7e60208b0162002dcb565b975062002f8e60408b0162002c9a565b965062002f9e60608b0162002de0565b955062002fae60808b0162002c9a565b945060a08a013567ffffffffffffffff8082111562002fcc57600080fd5b62002fda8d838e0162002d39565b909650945060c08c013591508082111562002ff457600080fd5b620030028d838e0162002ee7565b935060e08c01359150808211156200301957600080fd5b50620030288c828d0162002ee7565b9150509295985092959850929598565b6000602082840312156200304b57600080fd5b5035919050565b6000602082840312156200306557600080fd5b8135620030728162002c77565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111562001e015762001e01620030d7565b8082018082111562001e015762001e01620030d7565b600181811c908216806200314757607f821691505b60208210810362003181577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203620031bb57620031bb620030d7565b5060010190565b600081518084526020808501945080840160005b838110156200329b5781518051151588528381015115158489015260408082015163ffffffff908116918a01919091526060808301518216908a015260808083015173ffffffffffffffffffffffffffffffffffffffff908116918b019190915260a0808401516fffffffffffffffffffffffffffffffff16908b015260c0808401516bffffffffffffffffffffffff16908b015260e080840151909216918a01919091526101009182015116908801526101209096019590820190600101620031d6565b509495945050505050565b600081518084526020808501945080840160005b838110156200329b57815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101620032ba565b60005b838110156200330b578181015183820152602001620032f1565b50506000910152565b600081518084526200332e816020860160208601620032ee565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b85811015620033ac5782840389526200339984835162003314565b988501989350908401906001016200337e565b5091979650505050505050565b60e081528760e082015260006101007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8a1115620033f657600080fd5b8960051b808c838601378301838103820160208501526200341a8282018b620031c2565b9150508281036040840152620034318189620032a6565b90508281036060840152620034478188620032a6565b905082810360808401526200345d818762003360565b905082810360a084015262003473818662003360565b905082810360c084015262003489818562003360565b9b9a5050505050505050505050565b600060208284031215620034ab57600080fd5b815160ff811681146200307257600080fd5b60ff8416815260ff83166020820152606060408201526000620025ea606083018462003314565b600060208284031215620034f757600080fd5b815167ffffffffffffffff8111156200350f57600080fd5b8201601f810184136200352157600080fd5b80516200353262002f0a8262002e9e565b8181528560208385010111156200354857600080fd5b620025ea826020830160208601620032ee565b60208152600062001dfe602083018462003314565b600067ffffffffffffffff8211156200358d576200358d62002df0565b5060051b60200190565b600082601f830112620035a957600080fd5b81356020620035bc62002f0a8362003570565b82815260059290921b84018101918181019086841115620035dc57600080fd5b8286015b84811015620035f95780358352918301918301620035e0565b509695505050505050565b801515811462001ca257600080fd5b803562002ca78162003604565b80356fffffffffffffffffffffffffffffffff8116811462002ca757600080fd5b80356bffffffffffffffffffffffff8116811462002ca757600080fd5b600082601f8301126200367057600080fd5b813560206200368362002f0a8362003570565b8281526101209283028501820192828201919087851115620036a457600080fd5b8387015b858110156200377e5781818a031215620036c25760008081fd5b620036cc62002e1f565b620036d78262003613565b8152620036e686830162003613565b868201526040620036f981840162002dcb565b9082015260606200370c83820162002dcb565b9082015260806200371f83820162002c9a565b9082015260a06200373283820162003620565b9082015260c06200374583820162003641565b9082015260e06200375883820162002dcb565b908201526101006200376c83820162002c9a565b908201528452928401928101620036a8565b5090979650505050505050565b600082601f8301126200379d57600080fd5b81356020620037b062002f0a8362003570565b82815260059290921b84018101918181019086841115620037d057600080fd5b8286015b84811015620035f9578035620037ea8162002c77565b8352918301918301620037d4565b600082601f8301126200380a57600080fd5b813560206200381d62002f0a8362003570565b82815260059290921b840181019181810190868411156200383d57600080fd5b8286015b84811015620035f957803567ffffffffffffffff811115620038635760008081fd5b620038738986838b010162002ee7565b84525091830191830162003841565b600080600080600080600060e0888a0312156200389e57600080fd5b873567ffffffffffffffff80821115620038b757600080fd5b620038c58b838c0162003597565b985060208a0135915080821115620038dc57600080fd5b620038ea8b838c016200365e565b975060408a01359150808211156200390157600080fd5b6200390f8b838c016200378b565b965060608a01359150808211156200392657600080fd5b620039348b838c016200378b565b955060808a01359150808211156200394b57600080fd5b620039598b838c01620037f8565b945060a08a01359150808211156200397057600080fd5b6200397e8b838c01620037f8565b935060c08a01359150808211156200399557600080fd5b50620039a48a828b01620037f8565b91505092959891949750929550565b600063ffffffff808316818103620039cf57620039cf620030d7565b6001019392505050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b60006020828403121562003a3957600080fd5b5051919050565b6bffffffffffffffffffffffff828116828216039080821115620029865762002986620030d7565b601f82111562001d3457600081815260208120601f850160051c8101602086101562003a915750805b601f850160051c820191505b8181101562003ab25782815560010162003a9d565b505050505050565b815167ffffffffffffffff81111562003ad75762003ad762002df0565b62003aef8162003ae8845462003132565b8462003a68565b602080601f83116001811462003b45576000841562003b0e5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855562003ab2565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101562003b945788860151825594840194600190910190840162003b73565b508582101562003bd157878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b8051602080830151919081101562003181577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b60006020828403121562003c3757600080fd5b8151620030728162003604565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000825162003c87818460208701620032ee565b919091019291505056fe60c060405234801561001057600080fd5b506040516103ca3803806103ca83398101604081905261002f91610076565b600080546001600160a01b0319166001600160a01b039384161790559181166080521660a0526100b9565b80516001600160a01b038116811461007157600080fd5b919050565b60008060006060848603121561008b57600080fd5b6100948461005a565b92506100a26020850161005a565b91506100b06040850161005a565b90509250925092565b60805160a0516102e76100e36000396000603801526000818160c4015261011701526102e76000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806379188d161461007b578063f00e6a2a146100aa575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610076573d6000f35b3d6000fd5b61008e6100893660046101c1565b6100ee565b6040805192151583526020830191909152015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526020016100a1565b60008054819073ffffffffffffffffffffffffffffffffffffffff16331461011557600080fd5b7f00000000000000000000000000000000000000000000000000000000000000005a91505a61138881101561014957600080fd5b61138881039050856040820482031161016157600080fd5b50803b61016d57600080fd5b6000808551602087016000858af192505a610188908361029a565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080604083850312156101d457600080fd5b82359150602083013567ffffffffffffffff808211156101f357600080fd5b818501915085601f83011261020757600080fd5b81358181111561021957610219610192565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561025f5761025f610192565b8160405282815288602084870101111561027857600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b818103818111156102d4577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9291505056fea164736f6c6343000813000aa164736f6c6343000813000a", + Bin: "0x6101806040523480156200001257600080fd5b50604051620047913803806200479183398101604081905262000035916200062f565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b91906200062f565b826001600160a01b031663226cf83c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200010091906200062f565b836001600160a01b031663614486af6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016591906200062f565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca91906200062f565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f91906200062f565b866001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029491906200062f565b876001600160a01b031663c5b964e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f9919062000656565b886001600160a01b031663ac4dc59a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000338573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200035e91906200062f565b3380600081620003b55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620003e857620003e8816200056b565b5050506001600160a01b0380891660805287811660a05286811660c05285811660e052848116610100528316610120526025805483919060ff19166001838181111562000439576200043962000679565b0217905550806001600160a01b0316610140816001600160a01b03168152505060c0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200049a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004c091906200068f565b60ff1660a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200052a91906200068f565b60ff16146200054c576040516301f86e1760e41b815260040160405180910390fd5b5050506001600160a01b039095166101605250620006b4945050505050565b336001600160a01b03821603620005c55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620003ac565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200062c57600080fd5b50565b6000602082840312156200064257600080fd5b81516200064f8162000616565b9392505050565b6000602082840312156200066957600080fd5b8151600281106200064f57600080fd5b634e487b7160e01b600052602160045260246000fd5b600060208284031215620006a257600080fd5b815160ff811681146200064f57600080fd5b60805160a05160c05160e0516101005161012051610140516101605161407d62000714600039600081816088015260de01526000505060005050600081816111d201526114eb01526000505060005050600050506000505061407d6000f3fe608060405260043610620000865760003560e01c80638e86139b11620000555780638e86139b1462000192578063c62cf68414620001b7578063c804802214620001eb578063f2fde38b14620002105762000086565b8063349e8cca14620000ce57806379ba5097146200012857806385c1b0ba14620001405780638da5cb5b1462000165575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015620000c7573d6000f35b3d6000fd5b005b348015620000db57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156200013557600080fd5b50620000cc62000235565b3480156200014d57600080fd5b50620000cc6200015f36600462002cc1565b62000338565b3480156200017257600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16620000fe565b3480156200019f57600080fd5b50620000cc620001b136600462002d9a565b62001095565b348015620001c457600080fd5b50620001dc620001d636600462002f58565b6200141d565b6040519081526020016200011f565b348015620001f857600080fd5b50620000cc6200020a3660046200304d565b620017ca565b3480156200021d57600080fd5b50620000cc6200022f36600462003067565b62001ca2565b60015473ffffffffffffffffffffffffffffffffffffffff163314620002bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600173ffffffffffffffffffffffffffffffffffffffff82166000908152601c602052604090205460ff1660038111156200037757620003776200308e565b14158015620003c35750600373ffffffffffffffffffffffffffffffffffffffff82166000908152601c602052604090205460ff166003811115620003c057620003c06200308e565b14155b15620003fb576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60165473ffffffffffffffffffffffffffffffffffffffff166200044b576040517fd12d7d8d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082900362000487576040517f2c2fc94100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290528190819060008667ffffffffffffffff811115620004f157620004f162002e05565b6040519080825280602002602001820160405280156200051b578160200160208202803683370190505b50905060008767ffffffffffffffff8111156200053c576200053c62002e05565b604051908082528060200260200182016040528015620005d357816020015b604080516101208101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e0820181905261010082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816200055b5790505b50905060008867ffffffffffffffff811115620005f457620005f462002e05565b6040519080825280602002602001820160405280156200062957816020015b6060815260200190600190039081620006135790505b50905060008967ffffffffffffffff8111156200064a576200064a62002e05565b6040519080825280602002602001820160405280156200067f57816020015b6060815260200190600190039081620006695790505b50905060008a67ffffffffffffffff811115620006a057620006a062002e05565b604051908082528060200260200182016040528015620006d557816020015b6060815260200190600190039081620006bf5790505b50905060005b8b81101562000e04578c8c82818110620006f957620006f9620030bd565b602090810292909201356000818152600484526040808220815161012081018352815460ff8082161515835261010080830490911615159883019890985263ffffffff620100008204811694830194909452660100000000000081048416606083015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009091048116608083015260018301546fffffffffffffffffffffffffffffffff811660a08401526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08401527c0100000000000000000000000000000000000000000000000000000000900490931660e082015260029091015490911694810194909452909a5091985050819003620008305786610100015199508660c001516bffffffffffffffffffffffff1698505b8973ffffffffffffffffffffffffffffffffffffffff1687610100015173ffffffffffffffffffffffffffffffffffffffff1614620008f55773ffffffffffffffffffffffffffffffffffffffff8a166000908152602160205260409020546200089c908a906200311b565b73ffffffffffffffffffffffffffffffffffffffff8b16600081815260216020526040902091909155620008d2908c8b62001cba565b86610100015199508660c001516bffffffffffffffffffffffff1698506200091e565b80156200091e5760c08701516200091b906bffffffffffffffffffffffff168a62003131565b98505b620009298862001d4e565b60808701516040517f1a5da6c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d8116600483015290911690631a5da6c890602401600060405180830381600087803b1580156200099957600080fd5b505af1158015620009ae573d6000803e3d6000fd5b5050505086858281518110620009c857620009c8620030bd565b60200260200101819052506005600089815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1686828151811062000a1c5762000a1c620030bd565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091018201526000898152600790915260409020805462000a5b9062003147565b80601f016020809104026020016040519081016040528092919081815260200182805462000a899062003147565b801562000ada5780601f1062000aae5761010080835404028352916020019162000ada565b820191906000526020600020905b81548152906001019060200180831162000abc57829003601f168201915b505050505084828151811062000af45762000af4620030bd565b6020026020010181905250601d6000898152602001908152602001600020805462000b1f9062003147565b80601f016020809104026020016040519081016040528092919081815260200182805462000b4d9062003147565b801562000b9e5780601f1062000b725761010080835404028352916020019162000b9e565b820191906000526020600020905b81548152906001019060200180831162000b8057829003601f168201915b505050505083828151811062000bb85762000bb8620030bd565b6020026020010181905250601e6000898152602001908152602001600020805462000be39062003147565b80601f016020809104026020016040519081016040528092919081815260200182805462000c119062003147565b801562000c625780601f1062000c365761010080835404028352916020019162000c62565b820191906000526020600020905b81548152906001019060200180831162000c4457829003601f168201915b505050505082828151811062000c7c5762000c7c620030bd565b602090810291909101810191909152600089815260048252604080822080547fffff0000000000000000000000000000000000000000000000000000000000001681556001810183905560020180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055600790925290812062000d029162002c24565b6000888152601d6020526040812062000d1b9162002c24565b6000888152601e6020526040812062000d349162002c24565b600088815260066020908152604080832080547fffffffffffffffffffffffff000000000000000000000000000000000000000090811690915560059092529091208054909116905562000d8a60028962001e05565b5060c0870151604080516bffffffffffffffffffffffff909216825273ffffffffffffffffffffffffffffffffffffffff8d16602083015289917fb38647142fbb1ea4c000fc4569b37a4e9a9f6313317b84ee3e5326c1a6cd06ff910160405180910390a28062000dfb816200319c565b915050620006db565b5073ffffffffffffffffffffffffffffffffffffffff891660009081526021602052604090205462000e389089906200311b565b73ffffffffffffffffffffffffffffffffffffffff8a1660008181526021602052604090209190915562000e6e908b8a62001cba565b60008c8c868167ffffffffffffffff81111562000e8f5762000e8f62002e05565b60405190808252806020026020018201604052801562000eb9578160200160208202803683370190505b508988888860405160200162000ed7989796959493929190620033ce565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282526016547faab9edd6000000000000000000000000000000000000000000000000000000008452915190935073ffffffffffffffffffffffffffffffffffffffff808f1693638e86139b939091169163c71249ab91600491869163aab9edd6918482019160209190819003860181865afa15801562000f87573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000fad9190620034ad565b866040518463ffffffff1660e01b815260040162000fce93929190620034d2565b600060405180830381865afa15801562000fec573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052620010349190810190620034f9565b6040518263ffffffff1660e01b815260040162001052919062003570565b600060405180830381600087803b1580156200106d57600080fd5b505af115801562001082573d6000803e3d6000fd5b5050505050505050505050505050505050565b6002336000908152601c602052604090205460ff166003811115620010be57620010be6200308e565b14158015620010f457506003336000908152601c602052604090205460ff166003811115620010f157620010f16200308e565b14155b156200112c576040517f0ebeec3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080808080808062001142888a018a62003897565b965096509650965096509650965060005b87518110156200141157600073ffffffffffffffffffffffffffffffffffffffff168782815181106200118a576200118a620030bd565b60200260200101516080015173ffffffffffffffffffffffffffffffffffffffff16036200129e57858181518110620011c757620011c7620030bd565b6020026020010151307f0000000000000000000000000000000000000000000000000000000000000000604051620011ff9062002c63565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f08015801562001249573d6000803e3d6000fd5b508782815181106200125f576200125f620030bd565b60200260200101516080019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b62001356888281518110620012b757620012b7620030bd565b6020026020010151888381518110620012d457620012d4620030bd565b6020026020010151878481518110620012f157620012f1620030bd565b60200260200101518785815181106200130e576200130e620030bd565b60200260200101518786815181106200132b576200132b620030bd565b6020026020010151878781518110620013485762001348620030bd565b602002602001015162001e1c565b8781815181106200136b576200136b620030bd565b60200260200101517f74931a144e43a50694897f241d973aecb5024c0e910f9bb80a163ea3c1cf5a71888381518110620013a957620013a9620030bd565b602002602001015160c0015133604051620013f49291906bffffffffffffffffffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a28062001408816200319c565b91505062001153565b50505050505050505050565b6000805473ffffffffffffffffffffffffffffffffffffffff1633148015906200145157506200144f60093362002339565b155b1562001489576040517fd48b678b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8a163b620014d8576040517f09ee12d500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b620014e38762002369565b905060008a307f0000000000000000000000000000000000000000000000000000000000000000604051620015189062002c63565b73ffffffffffffffffffffffffffffffffffffffff938416815291831660208301529091166040820152606001604051809103906000f08015801562001562573d6000803e3d6000fd5b50905062001653826040518061012001604052806000151581526020016000151581526020018d63ffffffff16815260200163ffffffff801681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200160006fffffffffffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff168152602001600063ffffffff1681526020018a73ffffffffffffffffffffffffffffffffffffffff168152508b89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92508a915062001e1c9050565b601680547c0100000000000000000000000000000000000000000000000000000000900463ffffffff1690601c6200168b83620039c8565b91906101000a81548163ffffffff021916908363ffffffff16021790555050817fbae366358c023f887e791d7a62f2e4316f1026bd77f6fb49501a917b3bc5d0128b8b6040516200170492919063ffffffff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60405180910390a2817fcba2d5723b2ee59e53a8e8a82a4a7caf4fdfe70e9f7c582950bf7e7a5c24e83d878760405162001740929190620039ee565b60405180910390a2817f2b72ac786c97e68dbab71023ed6f2bdbfc80ad9bb7808941929229d71b7d5664856040516200177a919062003570565b60405180910390a2817f3e8740446213c8a77d40e08f79136ce3f347d13ed270a6ebdf57159e0faf485084604051620017b4919062003570565b60405180910390a2509998505050505050505050565b6000818152600460209081526040808320815161012081018352815460ff8082161515835261010080830490911615159583019590955263ffffffff620100008204811694830194909452660100000000000081048416606083015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009091048116608083015260018301546fffffffffffffffffffffffffffffffff811660a08401526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08401527c0100000000000000000000000000000000000000000000000000000000900490931660e08201526002909101549091169181019190915290620018ee60005473ffffffffffffffffffffffffffffffffffffffff1690565b61010083015173ffffffffffffffffffffffffffffffffffffffff90811660009081526022602090815260408083206002015460155482517f57e871e70000000000000000000000000000000000000000000000000000000081529251968616331497506bffffffffffffffffffffffff90911695939416926357e871e7926004808401939192918290030181865afa15801562001990573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620019b6919062003a3b565b9050836060015163ffffffff16600003620019fd576040517ffbc0357800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606084015163ffffffff9081161462001a42576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8215801562001a75575060008581526005602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b1562001aad576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8262001ac35762001ac060328262003131565b90505b6000858152600460205260409020805463ffffffff8084166601000000000000027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff9092169190911790915562001b2090600290879062001e0516565b506000826bffffffffffffffffffffffff168560a001516fffffffffffffffffffffffffffffffff16101562001b935760a085015162001b61908462003a55565b90508460c001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff16111562001b93575060c08401515b808560c0015162001ba5919062003a55565b600087815260046020908152604080832060010180547fffffffff000000000000000000000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000006bffffffffffffffffffffffff9687160217905561010089015173ffffffffffffffffffffffffffffffffffffffff168352602190915290205462001c37918316906200311b565b61010086015173ffffffffffffffffffffffffffffffffffffffff1660009081526021602052604080822092909255905167ffffffffffffffff84169188917f91cb3bb75cfbd718bbfccc56b7f53d92d7048ef4ca39a3b7b7c6d4af1f7911819190a3505050505050565b62001cac62002608565b62001cb7816200268d565b50565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905262001d4990849062002784565b505050565b60008181526005602052604090205473ffffffffffffffffffffffffffffffffffffffff16331462001dac576040517fa47c170600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600460205260409020546601000000000000900463ffffffff9081161462001cb7576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600062001e13838362002897565b90505b92915050565b601454760100000000000000000000000000000000000000000000900460ff161562001e74576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60175483517c010000000000000000000000000000000000000000000000000000000090910463ffffffff16101562001ed9576040517fae7235df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108fc856040015163ffffffff16108062001f1f5750601654604086015163ffffffff780100000000000000000000000000000000000000000000000090920482169116115b1562001f57576040517f14c237fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000868152600460205260409020546a0100000000000000000000900473ffffffffffffffffffffffffffffffffffffffff161562001fc2576040517f6e3b930b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010085015173ffffffffffffffffffffffffffffffffffffffff90811660009081526022602052604090205467010000000000000090041662002032576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846004600088815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff02191690831515021790555060408201518160000160026101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160066101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600a6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060a08201518160010160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060c08201518160010160106101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050836005600088815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508260076000888152602001908152602001600020908162002277919062003acf565b5060c085015161010086015173ffffffffffffffffffffffffffffffffffffffff16600090815260216020526040902054620022c2916bffffffffffffffffffffffff169062003131565b61010086015173ffffffffffffffffffffffffffffffffffffffff16600090815260216020908152604080832093909355888252601d90522062002307838262003acf565b506000868152601e6020526040902062002322828262003acf565b5062002330600287620029a2565b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151562001e13565b601554604080517f57e871e70000000000000000000000000000000000000000000000000000000081529051600092839273ffffffffffffffffffffffffffffffffffffffff90911691839183916385df51fd9160019184916357e871e79160048083019260209291908290030181865afa158015620023ed573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002413919062003a3b565b6200241f91906200311b565b6040518263ffffffff1660e01b81526004016200243e91815260200190565b602060405180830381865afa1580156200245c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002482919062003a3b565b60165460408051602081019390935230908301527c0100000000000000000000000000000000000000000000000000000000900463ffffffff166060820152608001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083015201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060045b600f811015620025965783828281518110620025525762002552620030bd565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350806200258d816200319c565b91505062002532565b50846001811115620025ac57620025ac6200308e565b60f81b81600f81518110620025c557620025c5620030bd565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350620025ff8162003bf6565b95945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146200268b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401620002b3565b565b3373ffffffffffffffffffffffffffffffffffffffff8216036200270e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620002b3565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000620027e8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16620029b09092919063ffffffff16565b80519091501562001d49578080602001905181019062002809919062003c39565b62001d49576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401620002b3565b6000818152600183016020526040812054801562002990576000620028be6001836200311b565b8554909150600090620028d4906001906200311b565b905081811462002940576000866000018281548110620028f857620028f8620030bd565b90600052602060002001549050808760000184815481106200291e576200291e620030bd565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062002954576200295462003c59565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062001e16565b600091505062001e16565b5092915050565b600062001e138383620029c9565b6060620029c1848460008562002a1b565b949350505050565b600081815260018301602052604081205462002a125750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562001e16565b50600062001e16565b60608247101562002aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401620002b3565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405162002ada919062003c88565b60006040518083038185875af1925050503d806000811462002b19576040519150601f19603f3d011682016040523d82523d6000602084013e62002b1e565b606091505b509150915062002b318783838762002b3c565b979650505050505050565b6060831562002bd757825160000362002bcf5773ffffffffffffffffffffffffffffffffffffffff85163b62002bcf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401620002b3565b5081620029c1565b620029c1838381511562002bee5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002b3919062003570565b50805462002c329062003147565b6000825580601f1062002c43575050565b601f01602090049060005260206000209081019062001cb7919062002c71565b6103ca8062003ca783390190565b5b8082111562002c88576000815560010162002c72565b5090565b73ffffffffffffffffffffffffffffffffffffffff8116811462001cb757600080fd5b803562002cbc8162002c8c565b919050565b60008060006040848603121562002cd757600080fd5b833567ffffffffffffffff8082111562002cf057600080fd5b818601915086601f83011262002d0557600080fd5b81358181111562002d1557600080fd5b8760208260051b850101111562002d2b57600080fd5b6020928301955093505084013562002d438162002c8c565b809150509250925092565b60008083601f84011262002d6157600080fd5b50813567ffffffffffffffff81111562002d7a57600080fd5b60208301915083602082850101111562002d9357600080fd5b9250929050565b6000806020838503121562002dae57600080fd5b823567ffffffffffffffff81111562002dc657600080fd5b62002dd48582860162002d4e565b90969095509350505050565b803563ffffffff8116811462002cbc57600080fd5b80356002811062002cbc57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610120810167ffffffffffffffff8111828210171562002e5b5762002e5b62002e05565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171562002eab5762002eab62002e05565b604052919050565b600067ffffffffffffffff82111562002ed05762002ed062002e05565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011262002f0e57600080fd5b813562002f2562002f1f8262002eb3565b62002e61565b81815284602083860101111562002f3b57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060008060006101008a8c03121562002f7857600080fd5b62002f838a62002caf565b985062002f9360208b0162002de0565b975062002fa360408b0162002caf565b965062002fb360608b0162002df5565b955062002fc360808b0162002caf565b945060a08a013567ffffffffffffffff8082111562002fe157600080fd5b62002fef8d838e0162002d4e565b909650945060c08c01359150808211156200300957600080fd5b620030178d838e0162002efc565b935060e08c01359150808211156200302e57600080fd5b506200303d8c828d0162002efc565b9150509295985092959850929598565b6000602082840312156200306057600080fd5b5035919050565b6000602082840312156200307a57600080fd5b8135620030878162002c8c565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111562001e165762001e16620030ec565b8082018082111562001e165762001e16620030ec565b600181811c908216806200315c57607f821691505b60208210810362003196577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203620031d057620031d0620030ec565b5060010190565b600081518084526020808501945080840160005b83811015620032b05781518051151588528381015115158489015260408082015163ffffffff908116918a01919091526060808301518216908a015260808083015173ffffffffffffffffffffffffffffffffffffffff908116918b019190915260a0808401516fffffffffffffffffffffffffffffffff16908b015260c0808401516bffffffffffffffffffffffff16908b015260e080840151909216918a01919091526101009182015116908801526101209096019590820190600101620031eb565b509495945050505050565b600081518084526020808501945080840160005b83811015620032b057815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101620032cf565b60005b838110156200332057818101518382015260200162003306565b50506000910152565b600081518084526200334381602086016020860162003303565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b85811015620033c1578284038952620033ae84835162003329565b9885019893509084019060010162003393565b5091979650505050505050565b60e081528760e082015260006101007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8a11156200340b57600080fd5b8960051b808c838601378301838103820160208501526200342f8282018b620031d7565b9150508281036040840152620034468189620032bb565b905082810360608401526200345c8188620032bb565b9050828103608084015262003472818762003375565b905082810360a084015262003488818662003375565b905082810360c08401526200349e818562003375565b9b9a5050505050505050505050565b600060208284031215620034c057600080fd5b815160ff811681146200308757600080fd5b60ff8416815260ff83166020820152606060408201526000620025ff606083018462003329565b6000602082840312156200350c57600080fd5b815167ffffffffffffffff8111156200352457600080fd5b8201601f810184136200353657600080fd5b80516200354762002f1f8262002eb3565b8181528560208385010111156200355d57600080fd5b620025ff82602083016020860162003303565b60208152600062001e13602083018462003329565b600067ffffffffffffffff821115620035a257620035a262002e05565b5060051b60200190565b600082601f830112620035be57600080fd5b81356020620035d162002f1f8362003585565b82815260059290921b84018101918181019086841115620035f157600080fd5b8286015b848110156200360e5780358352918301918301620035f5565b509695505050505050565b801515811462001cb757600080fd5b803562002cbc8162003619565b80356fffffffffffffffffffffffffffffffff8116811462002cbc57600080fd5b80356bffffffffffffffffffffffff8116811462002cbc57600080fd5b600082601f8301126200368557600080fd5b813560206200369862002f1f8362003585565b8281526101209283028501820192828201919087851115620036b957600080fd5b8387015b85811015620037935781818a031215620036d75760008081fd5b620036e162002e34565b620036ec8262003628565b8152620036fb86830162003628565b8682015260406200370e81840162002de0565b9082015260606200372183820162002de0565b9082015260806200373483820162002caf565b9082015260a06200374783820162003635565b9082015260c06200375a83820162003656565b9082015260e06200376d83820162002de0565b908201526101006200378183820162002caf565b908201528452928401928101620036bd565b5090979650505050505050565b600082601f830112620037b257600080fd5b81356020620037c562002f1f8362003585565b82815260059290921b84018101918181019086841115620037e557600080fd5b8286015b848110156200360e578035620037ff8162002c8c565b8352918301918301620037e9565b600082601f8301126200381f57600080fd5b813560206200383262002f1f8362003585565b82815260059290921b840181019181810190868411156200385257600080fd5b8286015b848110156200360e57803567ffffffffffffffff811115620038785760008081fd5b620038888986838b010162002efc565b84525091830191830162003856565b600080600080600080600060e0888a031215620038b357600080fd5b873567ffffffffffffffff80821115620038cc57600080fd5b620038da8b838c01620035ac565b985060208a0135915080821115620038f157600080fd5b620038ff8b838c0162003673565b975060408a01359150808211156200391657600080fd5b620039248b838c01620037a0565b965060608a01359150808211156200393b57600080fd5b620039498b838c01620037a0565b955060808a01359150808211156200396057600080fd5b6200396e8b838c016200380d565b945060a08a01359150808211156200398557600080fd5b620039938b838c016200380d565b935060c08a0135915080821115620039aa57600080fd5b50620039b98a828b016200380d565b91505092959891949750929550565b600063ffffffff808316818103620039e457620039e4620030ec565b6001019392505050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b60006020828403121562003a4e57600080fd5b5051919050565b6bffffffffffffffffffffffff8281168282160390808211156200299b576200299b620030ec565b601f82111562001d4957600081815260208120601f850160051c8101602086101562003aa65750805b601f850160051c820191505b8181101562003ac75782815560010162003ab2565b505050505050565b815167ffffffffffffffff81111562003aec5762003aec62002e05565b62003b048162003afd845462003147565b8462003a7d565b602080601f83116001811462003b5a576000841562003b235750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855562003ac7565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101562003ba95788860151825594840194600190910190840162003b88565b508582101562003be657878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b8051602080830151919081101562003196577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b60006020828403121562003c4c57600080fd5b8151620030878162003619565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000825162003c9c81846020870162003303565b919091019291505056fe60c060405234801561001057600080fd5b506040516103ca3803806103ca83398101604081905261002f91610076565b600080546001600160a01b0319166001600160a01b039384161790559181166080521660a0526100b9565b80516001600160a01b038116811461007157600080fd5b919050565b60008060006060848603121561008b57600080fd5b6100948461005a565b92506100a26020850161005a565b91506100b06040850161005a565b90509250925092565b60805160a0516102e76100e36000396000603801526000818160c4015261011701526102e76000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806379188d161461007b578063f00e6a2a146100aa575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610076573d6000f35b3d6000fd5b61008e6100893660046101c1565b6100ee565b6040805192151583526020830191909152015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001681526020016100a1565b60008054819073ffffffffffffffffffffffffffffffffffffffff16331461011557600080fd5b7f00000000000000000000000000000000000000000000000000000000000000005a91505a61138881101561014957600080fd5b61138881039050856040820482031161016157600080fd5b50803b61016d57600080fd5b6000808551602087016000858af192505a610188908361029a565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080604083850312156101d457600080fd5b82359150602083013567ffffffffffffffff808211156101f357600080fd5b818501915085601f83011261020757600080fd5b81358181111561021957610219610192565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561025f5761025f610192565b8160405282815288602084870101111561027857600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b818103818111156102d4577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9291505056fea164736f6c6343000813000aa164736f6c6343000813000a", } var AutomationRegistryLogicAABI = AutomationRegistryLogicAMetaData.ABI diff --git a/core/gethwrappers/generated/automation_registry_wrapper_2_3/automation_registry_wrapper_2_3.go b/core/gethwrappers/generated/automation_registry_wrapper_2_3/automation_registry_wrapper_2_3.go index 1edcb07dc6f..29bfe3155f5 100644 --- a/core/gethwrappers/generated/automation_registry_wrapper_2_3/automation_registry_wrapper_2_3.go +++ b/core/gethwrappers/generated/automation_registry_wrapper_2_3/automation_registry_wrapper_2_3.go @@ -65,7 +65,7 @@ type AutomationRegistryBase23OnchainConfig struct { var AutomationRegistryMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistryLogicA2_3\",\"name\":\"logicA\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLinkLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFeed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOffchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustSettleOnchain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyFinanceAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingOverrides\",\"name\":\"overrides\",\"type\":\"tuple\"}],\"name\":\"BillingConfigOverridden\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"BillingConfigOverrideRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contractIERC20Metadata\",\"name\":\"token\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"BillingConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newModule\",\"type\":\"address\"}],\"name\":\"ChainSpecificModuleUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeesWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"payments\",\"type\":\"uint256[]\"}],\"name\":\"NOPsSettledOffchain\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfigBytes\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"reorgProtectionEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"financeAdmin\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackNativePrice\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"contractIChainModule\",\"name\":\"chainModule\",\"type\":\"address\"}],\"internalType\":\"structAutomationRegistryBase2_3.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"contractIERC20Metadata[]\",\"name\":\"billingTokens\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"gasFeePPB\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"flatFeeMilliCents\",\"type\":\"uint24\"},{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"priceFeed\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"fallbackPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"minSpend\",\"type\":\"uint96\"}],\"internalType\":\"structAutomationRegistryBase2_3.BillingConfig[]\",\"name\":\"billingConfigs\",\"type\":\"tuple[]\"}],\"name\":\"setConfigTypeSafe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101806040523480156200001257600080fd5b506040516200668a3803806200668a83398101604081905262000035916200062f565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b91906200062f565b826001600160a01b031663226cf83c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200010091906200062f565b836001600160a01b031663614486af6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016591906200062f565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca91906200062f565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f91906200062f565b866001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029491906200062f565b876001600160a01b031663c5b964e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f9919062000656565b886001600160a01b031663ac4dc59a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000338573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200035e91906200062f565b3380600081620003b55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620003e857620003e8816200056b565b5050506001600160a01b0380891660805287811660a05286811660c05285811660e052848116610100528316610120526025805483919060ff19166001838181111562000439576200043962000679565b0217905550806001600160a01b0316610140816001600160a01b03168152505060c0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200049a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004c091906200068f565b60ff1660a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200052a91906200068f565b60ff16146200054c576040516301f86e1760e41b815260040160405180910390fd5b5050506001600160a01b039095166101605250620006b4945050505050565b336001600160a01b03821603620005c55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620003ac565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200062c57600080fd5b50565b6000602082840312156200064257600080fd5b81516200064f8162000616565b9392505050565b6000602082840312156200066957600080fd5b8151600281106200064f57600080fd5b634e487b7160e01b600052602160045260246000fd5b600060208284031215620006a257600080fd5b815160ff811681146200064f57600080fd5b60805160a05160c05160e05161010051610120516101405161016051615f56620007346000396000818160be01526101910152600050506000505060005050600050506000613b1701526000505060008181610de701528181610ef5015281816110200152818161106a015281816116ec01526131400152615f566000f3fe6080604052600436106100bc5760003560e01c80638da5cb5b11610074578063b1dc65a41161004e578063b1dc65a4146102f6578063e3d0e71214610316578063f2fde38b14610336576100bc565b80638da5cb5b14610265578063a4c0ed3614610290578063afcb95d7146102b0576100bc565b8063349e8cca116100a5578063349e8cca1461018257806379ba5097146101d657806381ff7048146101eb576100bc565b80630870d3a114610103578063181f5a7714610123575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e8080156100fc573d6000f35b3d6000fd5b005b34801561010f57600080fd5b5061010161011e366004614c9d565b610356565b34801561012f57600080fd5b5061016c6040518060400160405280601881526020017f4175746f6d6174696f6e526567697374727920322e332e30000000000000000081525081565b6040516101799190614e19565b60405180910390f35b34801561018e57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610179565b3480156101e257600080fd5b50610101610ccd565b3480156101f757600080fd5b5061024260175460135463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610179565b34801561027157600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166101b1565b34801561029c57600080fd5b506101016102ab366004614e75565b610dcf565b3480156102bc57600080fd5b50601354601454604080516000815260208101939093526c0100000000000000000000000090910463ffffffff1690820152606001610179565b34801561030257600080fd5b50610101610311366004614f16565b6110eb565b34801561032257600080fd5b50610101610331366004614fcd565b6113cc565b34801561034257600080fd5b5061010161035136600461509a565b611406565b61035e61141a565b601f8851111561039a576040517f25d0209c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560ff166000036103d7576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b865188511415806103f657506103ee8660036150e6565b60ff16885111155b1561042d576040517f1d2d1c5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051825114610468576040517fcf54c06a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610472828261149d565b61047c8888611ad5565b604051806101200160405280601460000160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff168152602001600063ffffffff1681526020018660a0015162ffffff16815260200186610120015161ffff1681526020018760ff168152602001601460000160169054906101000a900460ff1615158152602001601460000160179054906101000a900460ff1615158152602001866080015115158152602001866101e0015173ffffffffffffffffffffffffffffffffffffffff16815250601460008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160106101000a81548162ffffff021916908362ffffff16021790555060608201518160000160136101000a81548161ffff021916908361ffff16021790555060808201518160000160156101000a81548160ff021916908360ff16021790555060a08201518160000160166101000a81548160ff02191690831515021790555060c08201518160000160176101000a81548160ff02191690831515021790555060e08201518160000160186101000a81548160ff0219169083151502179055506101008201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050604051806101600160405280866060015173ffffffffffffffffffffffffffffffffffffffff168152602001866000015163ffffffff168152602001866020015163ffffffff1681526020016016600001601c9054906101000a900463ffffffff1663ffffffff16815260200186610100015173ffffffffffffffffffffffffffffffffffffffff168152602001601660010160149054906101000a900463ffffffff1663ffffffff168152602001601660010160189054906101000a900463ffffffff1663ffffffff168152602001866040015163ffffffff16815260200186610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018660c0015163ffffffff1681526020018660e0015163ffffffff16815250601660008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160186101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060a08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101208201518160020160146101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160186101000a81548163ffffffff021916908363ffffffff160217905550905050846101600151601981905550846101800151601a81905550846101a00151601b819055506000601660010160189054906101000a900463ffffffff169050856101e0015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa69190615102565b601780547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000063ffffffff9384160217808255600192601491610b1d9185917401000000000000000000000000000000000000000090041661511b565b92506101000a81548163ffffffff021916908363ffffffff160217905550600086604051602001610b4e9190615189565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018152919052601754909150610bb3904690309074010000000000000000000000000000000000000000900463ffffffff168d8d8d878d8d612196565b6013556000610bc26009612240565b90505b8015610bff57610bec610be4610bdc60018461530f565b600990612250565b600990612263565b5080610bf781615322565b915050610bc5565b5060005b876101c0015151811015610c5657610c43886101c001518281518110610c2b57610c2b615357565b6020026020010151600961228590919063ffffffff16565b5080610c4e81615386565b915050610c03565b506013546017546040517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0592610cb99286927401000000000000000000000000000000000000000090910463ffffffff16908f908f908f9089908f908f906153be565b60405180910390a150505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d53576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610e3e576040517fc8bad78d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208114610e78576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610e8682840184615454565b6000818152600460205260409020549091506601000000000000900463ffffffff90811614610ee1576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600460205260409020600201547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614610f65576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260046020526040902060010154610fa490859070010000000000000000000000000000000090046bffffffffffffffffffffffff1661546d565b600082815260046020908152604080832060010180546bffffffffffffffffffffffff95909516700100000000000000000000000000000000027fffffffff000000000000000000000000ffffffffffffffffffffffffffffffff9095169490941790935573ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168252602190522054611053908590615492565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660009081526021602090815260409182902093909355516bffffffffffffffffffffffff871681529087169183917fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa734891506203910160405180910390a35050505050565b60005a60408051610120810182526014546bffffffffffffffffffffffff8116825263ffffffff6c01000000000000000000000000820416602083015262ffffff7001000000000000000000000000000000008204169282019290925261ffff730100000000000000000000000000000000000000830416606082015260ff75010000000000000000000000000000000000000000008304811660808301527601000000000000000000000000000000000000000000008304811615801560a08401527701000000000000000000000000000000000000000000000084048216151560c0840152780100000000000000000000000000000000000000000000000090930416151560e082015260155473ffffffffffffffffffffffffffffffffffffffff1661010082015291925061124f576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604090205460ff16611298576040517f1099ed7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6013548a35146112d4576040517fdfdcf8e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60808101516112e49060016154a5565b60ff16861415806112f55750858414155b1561132c576040517f0244f71a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61133c8a8a8a8a8a8a8a8a6122a7565b60006113488a8a612510565b905060208b0135600881901c63ffffffff166113658484876125c9565b836020015163ffffffff168163ffffffff1611156113bd57601480547fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c0100000000000000000000000063ffffffff8416021790555b50505050505050505050505050565b6000806000858060200190518101906113e5919061568f565b9250925092506113fb8989898689898888610356565b505050505050505050565b61140e61141a565b611417816131b6565b50565b60005473ffffffffffffffffffffffffffffffffffffffff16331461149b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610d4a565b565b60005b60245481101561155b5760226000602483815481106114c1576114c1615357565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffff00000000000000000000000000000000000000000000000000000000168155600181019190915560020180547fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001690558061155381615386565b9150506114a0565b50611568602460006146f1565b60255460ff1660005b8351811015611acf57600084828151811061158e5761158e615357565b6020026020010151905060008483815181106115ac576115ac615357565b602002602001015190508173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611601573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611625919061583a565b60ff16816060015160ff161415806116b35750806040015173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611687573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ab919061583a565b60ff16600814155b156116ea576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161480156117565750600184600181111561175457611754615857565b145b1561178d576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821615806117c85750604081015173ffffffffffffffffffffffffffffffffffffffff16155b156117ff576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82811660009081526022602052604090205467010000000000000090041615611869576040517f357d0cc400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6024805460018181019092557f7cd332d19b93bcabe3cce7ca0c18a052f57e5fd03b4758a09f30f5ddc4b22ec401805473ffffffffffffffffffffffffffffffffffffffff8086167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216821790925560008181526022602090815260409182902086518154928801518489015160608a015160ff167b01000000000000000000000000000000000000000000000000000000027fffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffff9190981667010000000000000002167fffffffff000000000000000000000000000000000000000000ffffffffffffff62ffffff909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000090951663ffffffff9093169290921793909317929092169190911793909317835560808501519383019390935560a0840151600290920180546bffffffffffffffffffffffff9093167fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009093169290921790915590517fca93cbe727c73163ec538f71be6c0a64877d7f1f6dd35d5ca7cbaef3a3e34ba390611ab2908490600060c08201905063ffffffff835116825262ffffff602084015116602083015273ffffffffffffffffffffffffffffffffffffffff604084015116604083015260ff6060840151166060830152608083015160808301526bffffffffffffffffffffffff60a08401511660a083015292915050565b60405180910390a250508080611ac790615386565b915050611571565b50505050565b60005b600e54811015611b4c57611b39600e8281548110611af857611af8615357565b600091825260209091200154601454600e5473ffffffffffffffffffffffffffffffffffffffff909216916bffffffffffffffffffffffff909116906132ab565b5080611b4481615386565b915050611ad8565b5060255460009060ff16815b600e54811015611cbd57600e8181548110611b7557611b75615357565b6000918252602082200154600d805473ffffffffffffffffffffffffffffffffffffffff9092169550600c929184908110611bb257611bb2615357565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff9081168452838201949094526040928301822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690559286168152600b909252902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556001826001811115611c5457611c54615857565b148015611c99575073ffffffffffffffffffffffffffffffffffffffff83166000908152600b60205260409020546201000090046bffffffffffffffffffffffff1615155b15611cab57611ca9600f84612285565b505b80611cb581615386565b915050611b58565b50611cca600d60006146f1565b611cd6600e60006146f1565b6040805160808101825260008082526020820181905291810182905260608101829052905b855181101561216657600c6000878381518110611d1a57611d1a615357565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff1615611d85576040517f77cea0fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16868281518110611daf57611daf615357565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611e04576040517f815e1d6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806001151581526020018260ff16815250600c6000888481518110611e3557611e35615357565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909316929092171790558451859082908110611edd57611edd615357565b60200260200101519350600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611f4d576040517f58a70a0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152600b60209081526040918290208251608081018452905460ff80821615801584526101008304909116938301939093526bffffffffffffffffffffffff6201000082048116948301949094526e01000000000000000000000000000090049092166060830152909250612008576040517f6a7281ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180835260ff80831660208086019182526014546bffffffffffffffffffffffff9081166060880190815273ffffffffffffffffffffffffffffffffffffffff8a166000908152600b909352604092839020885181549551948a0151925184166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff939094166201000002929092167fffffffffffff000000000000000000000000000000000000000000000000ffff94909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009095169490941717919091169290921791909117905583600181111561214257612142615857565b0361215457612152600f85612263565b505b8061215e81615386565b915050611cfb565b50845161217a90600d90602088019061470f565b50835161218e90600e90602087019061470f565b505050505050565b6000808a8a8a8a8a8a8a8a8a6040516020016121ba99989796959493929190615886565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179b9a5050505050505050505050565b600061224a825490565b92915050565b600061225c83836134b3565b9392505050565b600061225c8373ffffffffffffffffffffffffffffffffffffffff84166134dd565b600061225c8373ffffffffffffffffffffffffffffffffffffffff84166135d7565b600087876040516122b992919061591b565b6040519081900381206122d0918b9060200161592b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201208383019092526000808452908301819052909250906000805b888110156124a75760018587836020811061233c5761233c615357565b61234991901a601b6154a5565b8c8c8581811061235b5761235b615357565b905060200201358b8b8681811061237457612374615357565b90506020020135604051600081526020016040526040516123b1949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156123d3573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff81166000908152600c602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290955093509050612481576040517f0f4c073700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015160080260ff166001901b84019350808061249f90615386565b91505061231f565b50827e01010101010101010101010101010101010101010101010101010101010101841614612502576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050565b6125496040518060c001604052806000815260200160008152602001606081526020016060815260200160608152602001606081525090565b600061255783850185615a1c565b604081015151606082015151919250908114158061257a57508082608001515114155b8061258a5750808260a001515114155b156125c1576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b509392505050565b600082604001515167ffffffffffffffff8111156125e9576125e96147a6565b6040519080825280602002602001820160405280156126b557816020015b6040805161020081018252600060e08201818152610100830182905261012083018290526101408301829052610160830182905261018083018290526101a083018290526101c083018290526101e0830182905282526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816126075790505b50905060006040518060800160405280600061ffff16815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff16815260200160008152509050600085610100015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612753573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127779190615102565b9050600086610100015173ffffffffffffffffffffffffffffffffffffffff166318b8f6136040518163ffffffff1660e01b8152600401602060405180830381865afa1580156127cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ef9190615102565b905060005b866040015151811015612c7f57600460008860400151838151811061281b5761281b615357565b6020908102919091018101518252818101929092526040908101600020815161012081018352815460ff8082161515835261010080830490911615159583019590955263ffffffff620100008204811694830194909452660100000000000081048416606083015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009091048116608083015260018301546fffffffffffffffffffffffffffffffff811660a08401526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08401527c0100000000000000000000000000000000000000000000000000000000900490931660e082015260029091015490911691810191909152855186908390811061293e5761293e615357565b6020026020010151600001819052506129738760400151828151811061296657612966615357565b6020026020010151613626565b85828151811061298557612985615357565b60200260200101516060019060018111156129a2576129a2615857565b908160018111156129b5576129b5615857565b81525050612a19876040015182815181106129d2576129d2615357565b602002602001015184896080015184815181106129f1576129f1615357565b6020026020010151888581518110612a0b57612a0b615357565b60200260200101518c6136d1565b868381518110612a2b57612a2b615357565b6020026020010151602001878481518110612a4857612a48615357565b602002602001015160c0018281525082151515158152505050848181518110612a7357612a73615357565b60200260200101516020015115612aa357600184600001818151612a979190615b09565b61ffff16905250612aa8565b612c6d565b612b0e858281518110612abd57612abd615357565b6020026020010151600001516080015188606001518381518110612ae357612ae3615357565b60200260200101518960a001518481518110612b0157612b01615357565b60200260200101516137f0565b868381518110612b2057612b20615357565b6020026020010151604001878481518110612b3d57612b3d615357565b6020026020010151608001828152508215151515815250505087608001516001612b6791906154a5565b612b759060ff166040615b24565b6103a48860a001518381518110612b8e57612b8e615357565b602002602001015151612ba19190615492565b612bab9190615492565b858281518110612bbd57612bbd615357565b602002602001015160a0018181525050848181518110612bdf57612bdf615357565b602002602001015160a0015184606001818151612bfc9190615492565b9052508451859082908110612c1357612c13615357565b60200260200101516080015186612c2a919061530f565b9550612c6d87604001518281518110612c4557612c45615357565b602002602001015184878481518110612c6057612c60615357565b6020026020010151613a0b565b80612c7781615386565b9150506127f4565b50825161ffff16600003612c965750505050505050565b61c800612ca4366010615b24565b5a612caf908861530f565b612cb99190615492565b612cc39190615492565b83519095506123f090612cda9061ffff1687615b6a565b612ce49190615492565b6040805160808101825260008082526020820181905291810182905260608101829052919650612d1389613b10565b905060005b88604001515181101561304f57868181518110612d3757612d37615357565b6020026020010151602001511561303d57801580612dcf575086612d5c60018361530f565b81518110612d6c57612d6c615357565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff16878281518110612da557612da5615357565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff1614155b15612e0357612e008a888381518110612dea57612dea615357565b6020026020010151600001516101000151613bfa565b92505b6000612f218b6040518061012001604052808b8681518110612e2757612e27615357565b60200260200101516080015181526020018c81526020018a606001518c8781518110612e5557612e55615357565b602002602001015160a001518a612e6c9190615b24565b612e769190615b6a565b81526020018d6000015181526020018d6020015181526020018681526020018b8681518110612ea757612ea7615357565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff168152602001878152602001600115158152508c604001518581518110612ef657612ef6615357565b60200260200101518b8681518110612f1057612f10615357565b602002602001015160000151613d76565b9050806060015187604001818151612f39919061546d565b6bffffffffffffffffffffffff169052506040810151602088018051612f6090839061546d565b6bffffffffffffffffffffffff169052508751889083908110612f8557612f85615357565b60200260200101516040015115158a604001518381518110612fa957612fa9615357565b60200260200101517fad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b83606001518460400151612fe6919061546d565b8b8681518110612ff857612ff8615357565b6020026020010151608001518d8f60800151888151811061301b5761301b615357565b60200260200101516040516130339493929190615b7e565b60405180910390a3505b8061304781615386565b915050612d18565b505050602083810151336000908152600b9092526040909120805460029061308c9084906201000090046bffffffffffffffffffffffff1661546d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508260400151601460000160008282829054906101000a90046bffffffffffffffffffffffff166130ea919061546d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508260400151836020015161312c919061546d565b6bffffffffffffffffffffffff16602160007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546131a89190615492565b909155505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603613235576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610d4a565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e01000000000000000000000000000090049091166060820152906134a75760008160600151856133439190615bbb565b905060006133518583615be0565b90508083604001818151613365919061546d565b6bffffffffffffffffffffffff169052506133808582615c0b565b83606001818151613391919061546d565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b60008260000182815481106134ca576134ca615357565b9060005260206000200154905092915050565b600081815260018301602052604081205480156135c657600061350160018361530f565b85549091506000906135159060019061530f565b905081811461357a57600086600001828154811061353557613535615357565b906000526020600020015490508087600001848154811061355857613558615357565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061358b5761358b615c3b565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061224a565b600091505061224a565b5092915050565b600081815260018301602052604081205461361e5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561224a565b50600061224a565b6000818160045b600f8110156136b3577fff00000000000000000000000000000000000000000000000000000000000000821683826020811061366b5761366b615357565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146136a157506000949350505050565b806136ab81615386565b91505061362d565b5081600f1a60018111156136c9576136c9615857565b949350505050565b6000808080856060015160018111156136ec576136ec615857565b03613712576136fe8888888888614072565b61370d576000925090506137e6565b61378a565b60018560600151600181111561372a5761372a615857565b0361375857600061373d898989886141fc565b925090508061375257506000925090506137e6565b5061378a565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516060015163ffffffff1687106137df57877fc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636876040516137cc9190614e19565b60405180910390a26000925090506137e6565b6001925090505b9550959350505050565b601454600090819077010000000000000000000000000000000000000000000000900460ff161561384d576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16770100000000000000000000000000000000000000000000001790556040517f4585e33b00000000000000000000000000000000000000000000000000000000906138c2908590602401614e19565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d16906139959087908790600401615c6a565b60408051808303816000875af11580156139b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139d79190615c83565b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16905590969095509350505050565b600081606001516001811115613a2357613a23615857565b03613a8757600083815260046020526040902060010180547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff851602179055505050565b600181606001516001811115613a9f57613a9f615857565b03613b0b5760c08101805160009081526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055915191517fa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f29190a25b505050565b60008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613b80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ba49190615ccb565b50935050925050600082131580613bba57508042105b80613bea57506000846040015162ffffff16118015613bea5750613bde814261530f565b846040015162ffffff16105b156135d0575050601b5492915050565b60408051608081018252600080825260208083018281528385018381526060850184905273ffffffffffffffffffffffffffffffffffffffff878116855260229093528584208054640100000000810462ffffff1690925263ffffffff82169092527b01000000000000000000000000000000000000000000000000000000810460ff16855285517ffeaf968c00000000000000000000000000000000000000000000000000000000815295519495919484936701000000000000009092049091169163feaf968c9160048083019260a09291908290030181865afa158015613ce7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d0b9190615ccb565b50935050925050600082131580613d2157508042105b80613d5157506000866040015162ffffff16118015613d515750613d45814261530f565b866040015162ffffff16105b15613d655760018301546060850152613d6d565b606084018290525b50505092915050565b604080516080810182526000808252602080830182905292820181905260608201529082015115613def5760008381526023602090815260409182902082518084018452905463ffffffff811680835262ffffff640100000000909204821692840192835260e089018051909401529051915191169101525b6000613dfb8686614409565b60c0840151602082015182519293509091600091613e189161546d565b905082600001516bffffffffffffffffffffffff16826bffffffffffffffffffffffff161015613e9d57819050613e7e87608001518860e0015160600151846bffffffffffffffffffffffff16613e6f9190615b24565b613e799190615b6a565b61464f565b6bffffffffffffffffffffffff16604084015260006060840152613f29565b806bffffffffffffffffffffffff16826bffffffffffffffffffffffff161015613f2957819050613f1583604001516bffffffffffffffffffffffff1688608001518960e0015160600151856bffffffffffffffffffffffff16613f019190615b24565b613f0b9190615b6a565b613e79919061530f565b6bffffffffffffffffffffffff1660608401525b60008681526004602052604090206001018054829190601090613f6f90849070010000000000000000000000000000000090046bffffffffffffffffffffffff16615bbb565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008881526004602052604081206001018054928516935091613fca9084906fffffffffffffffffffffffffffffffff16615d1b565b92506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550806bffffffffffffffffffffffff16602160008960c0015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254614061919061530f565b909155509298975050505050505050565b600080848060200190518101906140899190615d44565b845160e00151815191925063ffffffff908116911610156140e657867f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8866040516140d49190614e19565b60405180910390a260009150506141f3565b8260e0015180156141a657506020810151158015906141a65750602081015161010084015182516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa15801561417f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141a39190615102565b14155b806141b85750805163ffffffff168611155b156141ed57867f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301866040516140d49190614e19565b60019150505b95945050505050565b6000806000848060200190518101906142159190615d9c565b905060008782600001518360200151846040015160405160200161427794939291909384526020840192909252604083015260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016606082015260640190565b6040516020818303038152906040528051906020012090508460e00151801561435257506080820151158015906143525750608082015161010086015160608401516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa15801561432b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061434f9190615102565b14155b80614367575086826060015163ffffffff1610155b156143b157877f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc3018760405161439c9190614e19565b60405180910390a26000935091506144009050565b60008181526008602052604090205460ff16156143f857877f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e88760405161439c9190614e19565b600193509150505b94509492505050565b60408051608081018252600080825260208201819052918101829052606081019190915260008260e001516000015160ff1690506000846060015161ffff1684606001516144579190615b24565b9050836101000151801561446a5750803a105b1561447257503a5b600060128311614483576001614499565b61448e60128461530f565b61449990600a615f3d565b90506000601284106144ac5760016144c2565b6144b784601261530f565b6144c290600a615f3d565b905060008660a001518760400151886020015189600001516144e49190615492565b6144ee9087615b24565b6144f89190615492565b6145029190615b24565b9050614525828860e001516060015161451b9190615b24565b613e6f8584615b24565b6bffffffffffffffffffffffff168652608087015161454890613e799083615b6a565b6bffffffffffffffffffffffff1660408088019190915260e088015101516000906145819062ffffff16683635c9adc5dea00000615b24565b9050600081633b9aca008a60a001518b60e001516020015163ffffffff168c604001518d600001518b6145b49190615b24565b6145be9190615492565b6145c89190615b24565b6145d29190615b24565b6145dc9190615b6a565b6145e69190615492565b9050614609848a60e00151606001516145ff9190615b24565b613e6f8784615b24565b6bffffffffffffffffffffffff166020890152608089015161462f90613e799083615b6a565b6bffffffffffffffffffffffff1660608901525050505050505092915050565b60006bffffffffffffffffffffffff8211156146ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610d4a565b5090565b50805460008255906000526020600020908101906114179190614791565b828054828255906000526020600020908101928215614789579160200282015b8281111561478957825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90911617825560209092019160019091019061472f565b506146ed9291505b5b808211156146ed5760008155600101614792565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610200810167ffffffffffffffff811182821017156147f9576147f96147a6565b60405290565b60405160c0810167ffffffffffffffff811182821017156147f9576147f96147a6565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614869576148696147a6565b604052919050565b600067ffffffffffffffff82111561488b5761488b6147a6565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff8116811461141757600080fd5b80356148c281614895565b919050565b600082601f8301126148d857600080fd5b813560206148ed6148e883614871565b614822565b82815260059290921b8401810191818101908684111561490c57600080fd5b8286015b8481101561493057803561492381614895565b8352918301918301614910565b509695505050505050565b60ff8116811461141757600080fd5b80356148c28161493b565b63ffffffff8116811461141757600080fd5b80356148c281614955565b801515811461141757600080fd5b80356148c281614972565b62ffffff8116811461141757600080fd5b80356148c28161498b565b61ffff8116811461141757600080fd5b80356148c2816149a7565b600061020082840312156149d557600080fd5b6149dd6147d5565b90506149e882614967565b81526149f660208301614967565b6020820152614a0760408301614967565b6040820152614a18606083016148b7565b6060820152614a2960808301614980565b6080820152614a3a60a0830161499c565b60a0820152614a4b60c08301614967565b60c0820152614a5c60e08301614967565b60e0820152610100614a6f8184016148b7565b90820152610120614a818382016149b7565b90820152610140614a938382016148b7565b90820152610160828101359082015261018080830135908201526101a080830135908201526101c08083013567ffffffffffffffff811115614ad457600080fd5b614ae0858286016148c7565b8284015250506101e0614af48184016148b7565b9082015292915050565b803567ffffffffffffffff811681146148c257600080fd5b600082601f830112614b2757600080fd5b813567ffffffffffffffff811115614b4157614b416147a6565b614b7260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614822565b818152846020838601011115614b8757600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff8116811461141757600080fd5b600082601f830112614bcf57600080fd5b81356020614bdf6148e883614871565b82815260c09283028501820192828201919087851115614bfe57600080fd5b8387015b85811015614c905781818a031215614c1a5760008081fd5b614c226147ff565b8135614c2d81614955565b815281860135614c3c8161498b565b81870152604082810135614c4f81614895565b90820152606082810135614c628161493b565b908201526080828101359082015260a080830135614c7f81614ba4565b908201528452928401928101614c02565b5090979650505050505050565b600080600080600080600080610100898b031215614cba57600080fd5b883567ffffffffffffffff80821115614cd257600080fd5b614cde8c838d016148c7565b995060208b0135915080821115614cf457600080fd5b614d008c838d016148c7565b9850614d0e60408c0161494a565b975060608b0135915080821115614d2457600080fd5b614d308c838d016149c2565b9650614d3e60808c01614afe565b955060a08b0135915080821115614d5457600080fd5b614d608c838d01614b16565b945060c08b0135915080821115614d7657600080fd5b614d828c838d016148c7565b935060e08b0135915080821115614d9857600080fd5b50614da58b828c01614bbe565b9150509295985092959890939650565b6000815180845260005b81811015614ddb57602081850181015186830182015201614dbf565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061225c6020830184614db5565b60008083601f840112614e3e57600080fd5b50813567ffffffffffffffff811115614e5657600080fd5b602083019150836020828501011115614e6e57600080fd5b9250929050565b60008060008060608587031215614e8b57600080fd5b8435614e9681614895565b935060208501359250604085013567ffffffffffffffff811115614eb957600080fd5b614ec587828801614e2c565b95989497509550505050565b60008083601f840112614ee357600080fd5b50813567ffffffffffffffff811115614efb57600080fd5b6020830191508360208260051b8501011115614e6e57600080fd5b60008060008060008060008060e0898b031215614f3257600080fd5b606089018a811115614f4357600080fd5b8998503567ffffffffffffffff80821115614f5d57600080fd5b614f698c838d01614e2c565b909950975060808b0135915080821115614f8257600080fd5b614f8e8c838d01614ed1565b909750955060a08b0135915080821115614fa757600080fd5b50614fb48b828c01614ed1565b999c989b50969995989497949560c00135949350505050565b60008060008060008060c08789031215614fe657600080fd5b863567ffffffffffffffff80821115614ffe57600080fd5b61500a8a838b016148c7565b9750602089013591508082111561502057600080fd5b61502c8a838b016148c7565b965061503a60408a0161494a565b9550606089013591508082111561505057600080fd5b61505c8a838b01614b16565b945061506a60808a01614afe565b935060a089013591508082111561508057600080fd5b5061508d89828a01614b16565b9150509295509295509295565b6000602082840312156150ac57600080fd5b813561225c81614895565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff81811683821602908116908181146135d0576135d06150b7565b60006020828403121561511457600080fd5b5051919050565b63ffffffff8181168382160190808211156135d0576135d06150b7565b600081518084526020808501945080840160005b8381101561517e57815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010161514c565b509495945050505050565b602081526151a060208201835163ffffffff169052565b600060208301516151b9604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015180151560a08401525060a083015162ffffff811660c08401525060c083015163ffffffff811660e08401525060e08301516101006152388185018363ffffffff169052565b84015190506101206152618482018373ffffffffffffffffffffffffffffffffffffffff169052565b84015190506101406152788482018361ffff169052565b84015190506101606152a18482018373ffffffffffffffffffffffffffffffffffffffff169052565b840151610180848101919091528401516101a0808501919091528401516101c0808501919091528401516102006101e0808601829052919250906152e9610220860184615138565b95015173ffffffffffffffffffffffffffffffffffffffff169301929092525090919050565b8181038181111561224a5761224a6150b7565b600081615331576153316150b7565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036153b7576153b76150b7565b5060010190565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526153ee8184018a615138565b905082810360808401526154028189615138565b905060ff871660a084015282810360c084015261541f8187614db5565b905067ffffffffffffffff851660e08401528281036101008401526154448185614db5565b9c9b505050505050505050505050565b60006020828403121561546657600080fd5b5035919050565b6bffffffffffffffffffffffff8181168382160190808211156135d0576135d06150b7565b8082018082111561224a5761224a6150b7565b60ff818116838216019081111561224a5761224a6150b7565b80516148c281614955565b80516148c281614895565b80516148c281614972565b80516148c28161498b565b80516148c2816149a7565b600082601f83011261550657600080fd5b815160206155166148e883614871565b82815260059290921b8401810191818101908684111561553557600080fd5b8286015b8481101561493057805161554c81614895565b8352918301918301615539565b600082601f83011261556a57600080fd5b8151602061557a6148e883614871565b82815260059290921b8401810191818101908684111561559957600080fd5b8286015b848110156149305780516155b081614895565b835291830191830161559d565b600082601f8301126155ce57600080fd5b815160206155de6148e883614871565b82815260c092830285018201928282019190878511156155fd57600080fd5b8387015b85811015614c905781818a0312156156195760008081fd5b6156216147ff565b815161562c81614955565b81528186015161563b8161498b565b8187015260408281015161564e81614895565b908201526060828101516156618161493b565b908201526080828101519082015260a08083015161567e81614ba4565b908201528452928401928101615601565b6000806000606084860312156156a457600080fd5b835167ffffffffffffffff808211156156bc57600080fd5b9085019061020082880312156156d157600080fd5b6156d96147d5565b6156e2836154be565b81526156f0602084016154be565b6020820152615701604084016154be565b6040820152615712606084016154c9565b6060820152615723608084016154d4565b608082015261573460a084016154df565b60a082015261574560c084016154be565b60c082015261575660e084016154be565b60e08201526101006157698185016154c9565b9082015261012061577b8482016154ea565b9082015261014061578d8482016154c9565b90820152610160838101519082015261018080840151908201526101a080840151908201526101c080840151838111156157c657600080fd5b6157d28a8287016154f5565b8284015250506101e06157e68185016154c9565b90820152602087015190955091508082111561580157600080fd5b61580d87838801615559565b9350604086015191508082111561582357600080fd5b50615830868287016155bd565b9150509250925092565b60006020828403121561584c57600080fd5b815161225c8161493b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526158cd8285018b615138565b915083820360808501526158e1828a615138565b915060ff881660a085015283820360c08501526158fe8288614db5565b90861660e085015283810361010085015290506154448185614db5565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b600082601f83011261595257600080fd5b813560206159626148e883614871565b82815260059290921b8401810191818101908684111561598157600080fd5b8286015b848110156149305780358352918301918301615985565b600082601f8301126159ad57600080fd5b813560206159bd6148e883614871565b82815260059290921b840181019181810190868411156159dc57600080fd5b8286015b8481101561493057803567ffffffffffffffff811115615a005760008081fd5b615a0e8986838b0101614b16565b8452509183019183016159e0565b600060208284031215615a2e57600080fd5b813567ffffffffffffffff80821115615a4657600080fd5b9083019060c08286031215615a5a57600080fd5b615a626147ff565b8235815260208301356020820152604083013582811115615a8257600080fd5b615a8e87828601615941565b604083015250606083013582811115615aa657600080fd5b615ab287828601615941565b606083015250608083013582811115615aca57600080fd5b615ad68782860161599c565b60808301525060a083013582811115615aee57600080fd5b615afa8782860161599c565b60a08301525095945050505050565b61ffff8181168382160190808211156135d0576135d06150b7565b808202811582820484141761224a5761224a6150b7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615b7957615b79615b3b565b500490565b6bffffffffffffffffffffffff85168152836020820152826040820152608060608201526000615bb16080830184614db5565b9695505050505050565b6bffffffffffffffffffffffff8281168282160390808211156135d0576135d06150b7565b60006bffffffffffffffffffffffff80841680615bff57615bff615b3b565b92169190910492915050565b6bffffffffffffffffffffffff818116838216028082169190828114615c3357615c336150b7565b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8281526040602082015260006136c96040830184614db5565b60008060408385031215615c9657600080fd5b8251615ca181614972565b6020939093015192949293505050565b805169ffffffffffffffffffff811681146148c257600080fd5b600080600080600060a08688031215615ce357600080fd5b615cec86615cb1565b9450602086015193506040860151925060608601519150615d0f60808701615cb1565b90509295509295909350565b6fffffffffffffffffffffffffffffffff8181168382160190808211156135d0576135d06150b7565b600060408284031215615d5657600080fd5b6040516040810181811067ffffffffffffffff82111715615d7957615d796147a6565b6040528251615d8781614955565b81526020928301519281019290925250919050565b600060a08284031215615dae57600080fd5b60405160a0810181811067ffffffffffffffff82111715615dd157615dd16147a6565b806040525082518152602083015160208201526040830151615df281614955565b60408201526060830151615e0581614955565b60608201526080928301519281019290925250919050565b600181815b80851115615e7657817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615e5c57615e5c6150b7565b80851615615e6957918102915b93841c9390800290615e22565b509250929050565b600082615e8d5750600161224a565b81615e9a5750600061224a565b8160018114615eb05760028114615eba57615ed6565b600191505061224a565b60ff841115615ecb57615ecb6150b7565b50506001821b61224a565b5060208310610133831016604e8410600b8410161715615ef9575081810a61224a565b615f038383615e1d565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615f3557615f356150b7565b029392505050565b600061225c8383615e7e56fea164736f6c6343000813000a", + Bin: "0x6101806040523480156200001257600080fd5b50604051620065f5380380620065f583398101604081905262000035916200062f565b80816001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b91906200062f565b826001600160a01b031663226cf83c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200010091906200062f565b836001600160a01b031663614486af6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016591906200062f565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca91906200062f565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f91906200062f565b866001600160a01b031663a08714c06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200026e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029491906200062f565b876001600160a01b031663c5b964e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002d3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f9919062000656565b886001600160a01b031663ac4dc59a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000338573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200035e91906200062f565b3380600081620003b55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620003e857620003e8816200056b565b5050506001600160a01b0380891660805287811660a05286811660c05285811660e052848116610100528316610120526025805483919060ff19166001838181111562000439576200043962000679565b0217905550806001600160a01b0316610140816001600160a01b03168152505060c0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200049a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004c091906200068f565b60ff1660a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200052a91906200068f565b60ff16146200054c576040516301f86e1760e41b815260040160405180910390fd5b5050506001600160a01b039095166101605250620006b4945050505050565b336001600160a01b03821603620005c55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620003ac565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200062c57600080fd5b50565b6000602082840312156200064257600080fd5b81516200064f8162000616565b9392505050565b6000602082840312156200066957600080fd5b8151600281106200064f57600080fd5b634e487b7160e01b600052602160045260246000fd5b600060208284031215620006a257600080fd5b815160ff811681146200064f57600080fd5b60805160a05160c05160e05161010051610120516101405161016051615ec1620007346000396000818160be01526101910152600050506000505060005050600050506000613a8201526000505060008181610d5401528181610e6201528181610f8d01528181610fd70152818161165901526130ab0152615ec16000f3fe6080604052600436106100bc5760003560e01c80638da5cb5b11610074578063b1dc65a41161004e578063b1dc65a4146102f6578063e3d0e71214610316578063f2fde38b14610336576100bc565b80638da5cb5b14610265578063a4c0ed3614610290578063afcb95d7146102b0576100bc565b8063349e8cca116100a5578063349e8cca1461018257806379ba5097146101d657806381ff7048146101eb576100bc565b80630870d3a114610103578063181f5a7714610123575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e8080156100fc573d6000f35b3d6000fd5b005b34801561010f57600080fd5b5061010161011e366004614c08565b610356565b34801561012f57600080fd5b5061016c6040518060400160405280601881526020017f4175746f6d6174696f6e526567697374727920322e332e30000000000000000081525081565b6040516101799190614d84565b60405180910390f35b34801561018e57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610179565b3480156101e257600080fd5b50610101610c3a565b3480156101f757600080fd5b5061024260175460135463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610179565b34801561027157600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166101b1565b34801561029c57600080fd5b506101016102ab366004614de0565b610d3c565b3480156102bc57600080fd5b50601354601454604080516000815260208101939093526c0100000000000000000000000090910463ffffffff1690820152606001610179565b34801561030257600080fd5b50610101610311366004614e81565b611058565b34801561032257600080fd5b50610101610331366004614f38565b611339565b34801561034257600080fd5b50610101610351366004615005565b611373565b61035e611387565b601f8851111561039a576040517f25d0209c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560ff166000036103d7576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b865188511415806103f657506103ee866003615051565b60ff16885111155b1561042d576040517f1d2d1c5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051825114610468576040517fcf54c06a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610472828261140a565b61047c8888611a42565b604051806101200160405280601460000160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff168152602001600063ffffffff1681526020018660a0015162ffffff16815260200186610120015161ffff1681526020018760ff168152602001601460000160169054906101000a900460ff1615158152602001601460000160179054906101000a900460ff1615158152602001866080015115158152602001866101e0015173ffffffffffffffffffffffffffffffffffffffff16815250601460008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160106101000a81548162ffffff021916908362ffffff16021790555060608201518160000160136101000a81548161ffff021916908361ffff16021790555060808201518160000160156101000a81548160ff021916908360ff16021790555060a08201518160000160166101000a81548160ff02191690831515021790555060c08201518160000160176101000a81548160ff02191690831515021790555060e08201518160000160186101000a81548160ff0219169083151502179055506101008201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050506000601660010160189054906101000a900463ffffffff1690506000866101e0015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561072c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610750919061506d565b6017549091506000906107829074010000000000000000000000000000000000000000900463ffffffff166001615086565b9050604051806101600160405280896060015173ffffffffffffffffffffffffffffffffffffffff168152602001896000015163ffffffff168152602001896020015163ffffffff1681526020016016600001601c9054906101000a900463ffffffff1663ffffffff16815260200189610100015173ffffffffffffffffffffffffffffffffffffffff1681526020018263ffffffff1681526020018363ffffffff168152602001896040015163ffffffff16815260200189610140015173ffffffffffffffffffffffffffffffffffffffff1681526020018960c0015163ffffffff1681526020018960e0015163ffffffff16815250601660008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160186101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060a08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101208201518160020160146101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160186101000a81548163ffffffff021916908363ffffffff160217905550905050876101600151601981905550876101800151601a81905550876101a00151601b81905550600088604051602001610ac591906150f4565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018152919052601754909150610b2a904690309074010000000000000000000000000000000000000000900463ffffffff168f8f8f878f8f612101565b6013556000610b3960096121ab565b90505b8015610b7657610b63610b5b610b5360018461527a565b6009906121bb565b6009906121ce565b5080610b6e8161528d565b915050610b3c565b5060005b896101c0015151811015610bcd57610bba8a6101c001518281518110610ba257610ba26152c2565b602002602001015160096121f090919063ffffffff16565b5080610bc5816152f1565b915050610b7a565b507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0584601354601660010160149054906101000a900463ffffffff168f8f8f878f8f604051610c2499989796959493929190615329565b60405180910390a1505050505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610cc0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610dab576040517fc8bad78d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208114610de5576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610df3828401846153bf565b6000818152600460205260409020549091506601000000000000900463ffffffff90811614610e4e576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600460205260409020600201547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614610ed2576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260046020526040902060010154610f1190859070010000000000000000000000000000000090046bffffffffffffffffffffffff166153d8565b600082815260046020908152604080832060010180546bffffffffffffffffffffffff95909516700100000000000000000000000000000000027fffffffff000000000000000000000000ffffffffffffffffffffffffffffffff9095169490941790935573ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168252602190522054610fc09085906153fd565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660009081526021602090815260409182902093909355516bffffffffffffffffffffffff871681529087169183917fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa734891506203910160405180910390a35050505050565b60005a60408051610120810182526014546bffffffffffffffffffffffff8116825263ffffffff6c01000000000000000000000000820416602083015262ffffff7001000000000000000000000000000000008204169282019290925261ffff730100000000000000000000000000000000000000830416606082015260ff75010000000000000000000000000000000000000000008304811660808301527601000000000000000000000000000000000000000000008304811615801560a08401527701000000000000000000000000000000000000000000000084048216151560c0840152780100000000000000000000000000000000000000000000000090930416151560e082015260155473ffffffffffffffffffffffffffffffffffffffff166101008201529192506111bc576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604090205460ff16611205576040517f1099ed7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6013548a3514611241576040517fdfdcf8e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6080810151611251906001615410565b60ff16861415806112625750858414155b15611299576040517f0244f71a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112a98a8a8a8a8a8a8a8a612212565b60006112b58a8a61247b565b905060208b0135600881901c63ffffffff166112d2848487612534565b836020015163ffffffff168163ffffffff16111561132a57601480547fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c0100000000000000000000000063ffffffff8416021790555b50505050505050505050505050565b60008060008580602001905181019061135291906155fa565b9250925092506113688989898689898888610356565b505050505050505050565b61137b611387565b61138481613121565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611408576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610cb7565b565b60005b6024548110156114c857602260006024838154811061142e5761142e6152c2565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffff00000000000000000000000000000000000000000000000000000000168155600181019190915560020180547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169055806114c0816152f1565b91505061140d565b506114d56024600061465c565b60255460ff1660005b8351811015611a3c5760008482815181106114fb576114fb6152c2565b602002602001015190506000848381518110611519576115196152c2565b602002602001015190508173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561156e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061159291906157a5565b60ff16816060015160ff161415806116205750806040015173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115f4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161891906157a5565b60ff16600814155b15611657576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161480156116c3575060018460018111156116c1576116c16157c2565b145b156116fa576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821615806117355750604081015173ffffffffffffffffffffffffffffffffffffffff16155b1561176c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff828116600090815260226020526040902054670100000000000000900416156117d6576040517f357d0cc400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6024805460018181019092557f7cd332d19b93bcabe3cce7ca0c18a052f57e5fd03b4758a09f30f5ddc4b22ec401805473ffffffffffffffffffffffffffffffffffffffff8086167fffffffffffffffffffffffff0000000000000000000000000000000000000000909216821790925560008181526022602090815260409182902086518154928801518489015160608a015160ff167b01000000000000000000000000000000000000000000000000000000027fffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffff9190981667010000000000000002167fffffffff000000000000000000000000000000000000000000ffffffffffffff62ffffff909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000090951663ffffffff9093169290921793909317929092169190911793909317835560808501519383019390935560a0840151600290920180546bffffffffffffffffffffffff9093167fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009093169290921790915590517fca93cbe727c73163ec538f71be6c0a64877d7f1f6dd35d5ca7cbaef3a3e34ba390611a1f908490600060c08201905063ffffffff835116825262ffffff602084015116602083015273ffffffffffffffffffffffffffffffffffffffff604084015116604083015260ff6060840151166060830152608083015160808301526bffffffffffffffffffffffff60a08401511660a083015292915050565b60405180910390a250508080611a34906152f1565b9150506114de565b50505050565b600e546014546bffffffffffffffffffffffff1660005b600e54811015611ab557611aa2600e8281548110611a7957611a796152c2565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff168385613216565b5080611aad816152f1565b915050611a59565b5060255460009060ff16815b600e54811015611c2657600e8181548110611ade57611ade6152c2565b6000918252602082200154600d805473ffffffffffffffffffffffffffffffffffffffff9092169550600c929184908110611b1b57611b1b6152c2565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff9081168452838201949094526040928301822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690559286168152600b909252902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556001826001811115611bbd57611bbd6157c2565b148015611c02575073ffffffffffffffffffffffffffffffffffffffff83166000908152600b60205260409020546201000090046bffffffffffffffffffffffff1615155b15611c1457611c12600f846121f0565b505b80611c1e816152f1565b915050611ac1565b50611c33600d600061465c565b611c3f600e600061465c565b6040805160808101825260008082526020820181905291810182905260608101829052905b87518110156120cf57600c6000898381518110611c8357611c836152c2565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff1615611cee576040517f77cea0fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16888281518110611d1857611d186152c2565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611d6d576040517f815e1d6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806001151581526020018260ff16815250600c60008a8481518110611d9e57611d9e6152c2565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909316929092171790558651879082908110611e4657611e466152c2565b60200260200101519350600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611eb6576040517f58a70a0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152600b60209081526040918290208251608081018452905460ff80821615801584526101008304909116938301939093526bffffffffffffffffffffffff6201000082048116948301949094526e01000000000000000000000000000090049092166060830152909250611f71576040517f6a7281ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180835260ff80831660208086019182526014546bffffffffffffffffffffffff9081166060880190815273ffffffffffffffffffffffffffffffffffffffff8a166000908152600b909352604092839020885181549551948a0151925184166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff939094166201000002929092167fffffffffffff000000000000000000000000000000000000000000000000ffff94909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909516949094171791909116929092179190911790558360018111156120ab576120ab6157c2565b036120bd576120bb600f856121ce565b505b806120c7816152f1565b915050611c64565b5086516120e390600d9060208a019061467a565b5085516120f790600e90602089019061467a565b5050505050505050565b6000808a8a8a8a8a8a8a8a8a604051602001612125999897969594939291906157f1565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179b9a5050505050505050505050565b60006121b5825490565b92915050565b60006121c7838361341e565b9392505050565b60006121c78373ffffffffffffffffffffffffffffffffffffffff8416613448565b60006121c78373ffffffffffffffffffffffffffffffffffffffff8416613542565b60008787604051612224929190615886565b60405190819003812061223b918b90602001615896565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201208383019092526000808452908301819052909250906000805b88811015612412576001858783602081106122a7576122a76152c2565b6122b491901a601b615410565b8c8c858181106122c6576122c66152c2565b905060200201358b8b868181106122df576122df6152c2565b905060200201356040516000815260200160405260405161231c949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa15801561233e573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff81166000908152600c602090815290849020838501909452925460ff80821615158085526101009092041693830193909352909550935090506123ec576040517f0f4c073700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015160080260ff166001901b84019350808061240a906152f1565b91505061228a565b50827e0101010101010101010101010101010101010101010101010101010101010184161461246d576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050565b6124b46040518060c001604052806000815260200160008152602001606081526020016060815260200160608152602001606081525090565b60006124c283850185615987565b60408101515160608201515191925090811415806124e557508082608001515114155b806124f55750808260a001515114155b1561252c576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b509392505050565b600082604001515167ffffffffffffffff81111561255457612554614711565b60405190808252806020026020018201604052801561262057816020015b6040805161020081018252600060e08201818152610100830182905261012083018290526101408301829052610160830182905261018083018290526101a083018290526101c083018290526101e0830182905282526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816125725790505b50905060006040518060800160405280600061ffff16815260200160006bffffffffffffffffffffffff16815260200160006bffffffffffffffffffffffff16815260200160008152509050600085610100015173ffffffffffffffffffffffffffffffffffffffff166357e871e76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156126be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126e2919061506d565b9050600086610100015173ffffffffffffffffffffffffffffffffffffffff166318b8f6136040518163ffffffff1660e01b8152600401602060405180830381865afa158015612736573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061275a919061506d565b905060005b866040015151811015612bea576004600088604001518381518110612786576127866152c2565b6020908102919091018101518252818101929092526040908101600020815161012081018352815460ff8082161515835261010080830490911615159583019590955263ffffffff620100008204811694830194909452660100000000000081048416606083015273ffffffffffffffffffffffffffffffffffffffff6a01000000000000000000009091048116608083015260018301546fffffffffffffffffffffffffffffffff811660a08401526bffffffffffffffffffffffff70010000000000000000000000000000000082041660c08401527c0100000000000000000000000000000000000000000000000000000000900490931660e08201526002909101549091169181019190915285518690839081106128a9576128a96152c2565b6020026020010151600001819052506128de876040015182815181106128d1576128d16152c2565b6020026020010151613591565b8582815181106128f0576128f06152c2565b602002602001015160600190600181111561290d5761290d6157c2565b90816001811115612920576129206157c2565b815250506129848760400151828151811061293d5761293d6152c2565b6020026020010151848960800151848151811061295c5761295c6152c2565b6020026020010151888581518110612976576129766152c2565b60200260200101518c61363c565b868381518110612996576129966152c2565b60200260200101516020018784815181106129b3576129b36152c2565b602002602001015160c00182815250821515151581525050508481815181106129de576129de6152c2565b60200260200101516020015115612a0e57600184600001818151612a029190615a74565b61ffff16905250612a13565b612bd8565b612a79858281518110612a2857612a286152c2565b6020026020010151600001516080015188606001518381518110612a4e57612a4e6152c2565b60200260200101518960a001518481518110612a6c57612a6c6152c2565b602002602001015161375b565b868381518110612a8b57612a8b6152c2565b6020026020010151604001878481518110612aa857612aa86152c2565b6020026020010151608001828152508215151515815250505087608001516001612ad29190615410565b612ae09060ff166040615a8f565b6103a48860a001518381518110612af957612af96152c2565b602002602001015151612b0c91906153fd565b612b1691906153fd565b858281518110612b2857612b286152c2565b602002602001015160a0018181525050848181518110612b4a57612b4a6152c2565b602002602001015160a0015184606001818151612b6791906153fd565b9052508451859082908110612b7e57612b7e6152c2565b60200260200101516080015186612b95919061527a565b9550612bd887604001518281518110612bb057612bb06152c2565b602002602001015184878481518110612bcb57612bcb6152c2565b6020026020010151613976565b80612be2816152f1565b91505061275f565b50825161ffff16600003612c015750505050505050565b61c800612c0f366010615a8f565b5a612c1a908861527a565b612c2491906153fd565b612c2e91906153fd565b83519095506123f090612c459061ffff1687615ad5565b612c4f91906153fd565b6040805160808101825260008082526020820181905291810182905260608101829052919650612c7e89613a7b565b905060005b886040015151811015612fba57868181518110612ca257612ca26152c2565b60200260200101516020015115612fa857801580612d3a575086612cc760018361527a565b81518110612cd757612cd76152c2565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff16878281518110612d1057612d106152c2565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff1614155b15612d6e57612d6b8a888381518110612d5557612d556152c2565b6020026020010151600001516101000151613b65565b92505b6000612e8c8b6040518061012001604052808b8681518110612d9257612d926152c2565b60200260200101516080015181526020018c81526020018a606001518c8781518110612dc057612dc06152c2565b602002602001015160a001518a612dd79190615a8f565b612de19190615ad5565b81526020018d6000015181526020018d6020015181526020018681526020018b8681518110612e1257612e126152c2565b602002602001015160000151610100015173ffffffffffffffffffffffffffffffffffffffff168152602001878152602001600115158152508c604001518581518110612e6157612e616152c2565b60200260200101518b8681518110612e7b57612e7b6152c2565b602002602001015160000151613ce1565b9050806060015187604001818151612ea491906153d8565b6bffffffffffffffffffffffff169052506040810151602088018051612ecb9083906153d8565b6bffffffffffffffffffffffff169052508751889083908110612ef057612ef06152c2565b60200260200101516040015115158a604001518381518110612f1457612f146152c2565b60200260200101517fad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b83606001518460400151612f5191906153d8565b8b8681518110612f6357612f636152c2565b6020026020010151608001518d8f608001518881518110612f8657612f866152c2565b6020026020010151604051612f9e9493929190615ae9565b60405180910390a3505b80612fb2816152f1565b915050612c83565b505050602083810151336000908152600b90925260409091208054600290612ff79084906201000090046bffffffffffffffffffffffff166153d8565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508260400151601460000160008282829054906101000a90046bffffffffffffffffffffffff1661305591906153d8565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508260400151836020015161309791906153d8565b6bffffffffffffffffffffffff16602160007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461311391906153fd565b909155505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036131a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610cb7565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e01000000000000000000000000000090049091166060820152906134125760008160600151856132ae9190615b26565b905060006132bc8583615b4b565b905080836040018181516132d091906153d8565b6bffffffffffffffffffffffff169052506132eb8582615b76565b836060018181516132fc91906153d8565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b60400151949350505050565b6000826000018281548110613435576134356152c2565b9060005260206000200154905092915050565b6000818152600183016020526040812054801561353157600061346c60018361527a565b85549091506000906134809060019061527a565b90508181146134e55760008660000182815481106134a0576134a06152c2565b90600052602060002001549050808760000184815481106134c3576134c36152c2565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806134f6576134f6615ba6565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506121b5565b60009150506121b5565b5092915050565b6000818152600183016020526040812054613589575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556121b5565b5060006121b5565b6000818160045b600f81101561361e577fff0000000000000000000000000000000000000000000000000000000000000082168382602081106135d6576135d66152c2565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461360c57506000949350505050565b80613616816152f1565b915050613598565b5081600f1a6001811115613634576136346157c2565b949350505050565b600080808085606001516001811115613657576136576157c2565b0361367d576136698888888888613fdd565b61367857600092509050613751565b6136f5565b600185606001516001811115613695576136956157c2565b036136c35760006136a889898988614167565b92509050806136bd5750600092509050613751565b506136f5565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84516060015163ffffffff16871061374a57877fc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636876040516137379190614d84565b60405180910390a2600092509050613751565b6001925090505b9550959350505050565b601454600090819077010000000000000000000000000000000000000000000000900460ff16156137b8576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16770100000000000000000000000000000000000000000000001790556040517f4585e33b000000000000000000000000000000000000000000000000000000009061382d908590602401614d84565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d16906139009087908790600401615bd5565b60408051808303816000875af115801561391e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139429190615bee565b601480547fffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff16905590969095509350505050565b60008160600151600181111561398e5761398e6157c2565b036139f257600083815260046020526040902060010180547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff851602179055505050565b600181606001516001811115613a0a57613a0a6157c2565b03613a765760c08101805160009081526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055915191517fa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f29190a25b505050565b60008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015613aeb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b0f9190615c36565b50935050925050600082131580613b2557508042105b80613b5557506000846040015162ffffff16118015613b555750613b49814261527a565b846040015162ffffff16105b1561353b575050601b5492915050565b60408051608081018252600080825260208083018281528385018381526060850184905273ffffffffffffffffffffffffffffffffffffffff878116855260229093528584208054640100000000810462ffffff1690925263ffffffff82169092527b01000000000000000000000000000000000000000000000000000000810460ff16855285517ffeaf968c00000000000000000000000000000000000000000000000000000000815295519495919484936701000000000000009092049091169163feaf968c9160048083019260a09291908290030181865afa158015613c52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c769190615c36565b50935050925050600082131580613c8c57508042105b80613cbc57506000866040015162ffffff16118015613cbc5750613cb0814261527a565b866040015162ffffff16105b15613cd05760018301546060850152613cd8565b606084018290525b50505092915050565b604080516080810182526000808252602080830182905292820181905260608201529082015115613d5a5760008381526023602090815260409182902082518084018452905463ffffffff811680835262ffffff640100000000909204821692840192835260e089018051909401529051915191169101525b6000613d668686614374565b60c0840151602082015182519293509091600091613d83916153d8565b905082600001516bffffffffffffffffffffffff16826bffffffffffffffffffffffff161015613e0857819050613de987608001518860e0015160600151846bffffffffffffffffffffffff16613dda9190615a8f565b613de49190615ad5565b6145ba565b6bffffffffffffffffffffffff16604084015260006060840152613e94565b806bffffffffffffffffffffffff16826bffffffffffffffffffffffff161015613e9457819050613e8083604001516bffffffffffffffffffffffff1688608001518960e0015160600151856bffffffffffffffffffffffff16613e6c9190615a8f565b613e769190615ad5565b613de4919061527a565b6bffffffffffffffffffffffff1660608401525b60008681526004602052604090206001018054829190601090613eda90849070010000000000000000000000000000000090046bffffffffffffffffffffffff16615b26565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008881526004602052604081206001018054928516935091613f359084906fffffffffffffffffffffffffffffffff16615c86565b92506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550806bffffffffffffffffffffffff16602160008960c0015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254613fcc919061527a565b909155509298975050505050505050565b60008084806020019051810190613ff49190615caf565b845160e00151815191925063ffffffff9081169116101561405157867f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e88660405161403f9190614d84565b60405180910390a2600091505061415e565b8260e00151801561411157506020810151158015906141115750602081015161010084015182516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa1580156140ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061410e919061506d565b14155b806141235750805163ffffffff168611155b1561415857867f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc3018660405161403f9190614d84565b60019150505b95945050505050565b6000806000848060200190518101906141809190615d07565b90506000878260000151836020015184604001516040516020016141e294939291909384526020840192909252604083015260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016606082015260640190565b6040516020818303038152906040528051906020012090508460e0015180156142bd57506080820151158015906142bd5750608082015161010086015160608401516040517f85df51fd00000000000000000000000000000000000000000000000000000000815263ffffffff909116600482015273ffffffffffffffffffffffffffffffffffffffff909116906385df51fd90602401602060405180830381865afa158015614296573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142ba919061506d565b14155b806142d2575086826060015163ffffffff1610155b1561431c57877f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301876040516143079190614d84565b60405180910390a260009350915061436b9050565b60008181526008602052604090205460ff161561436357877f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8876040516143079190614d84565b600193509150505b94509492505050565b60408051608081018252600080825260208201819052918101829052606081019190915260008260e001516000015160ff1690506000846060015161ffff1684606001516143c29190615a8f565b905083610100015180156143d55750803a105b156143dd57503a5b6000601283116143ee576001614404565b6143f960128461527a565b61440490600a615ea8565b905060006012841061441757600161442d565b61442284601261527a565b61442d90600a615ea8565b905060008660a0015187604001518860200151896000015161444f91906153fd565b6144599087615a8f565b61446391906153fd565b61446d9190615a8f565b9050614490828860e00151606001516144869190615a8f565b613dda8584615a8f565b6bffffffffffffffffffffffff16865260808701516144b390613de49083615ad5565b6bffffffffffffffffffffffff1660408088019190915260e088015101516000906144ec9062ffffff16683635c9adc5dea00000615a8f565b9050600081633b9aca008a60a001518b60e001516020015163ffffffff168c604001518d600001518b61451f9190615a8f565b61452991906153fd565b6145339190615a8f565b61453d9190615a8f565b6145479190615ad5565b61455191906153fd565b9050614574848a60e001516060015161456a9190615a8f565b613dda8784615a8f565b6bffffffffffffffffffffffff166020890152608089015161459a90613de49083615ad5565b6bffffffffffffffffffffffff1660608901525050505050505092915050565b60006bffffffffffffffffffffffff821115614658576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610cb7565b5090565b508054600082559060005260206000209081019061138491906146fc565b8280548282559060005260206000209081019282156146f4579160200282015b828111156146f457825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90911617825560209092019160019091019061469a565b506146589291505b5b8082111561465857600081556001016146fd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610200810167ffffffffffffffff8111828210171561476457614764614711565b60405290565b60405160c0810167ffffffffffffffff8111828210171561476457614764614711565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156147d4576147d4614711565b604052919050565b600067ffffffffffffffff8211156147f6576147f6614711565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff8116811461138457600080fd5b803561482d81614800565b919050565b600082601f83011261484357600080fd5b81356020614858614853836147dc565b61478d565b82815260059290921b8401810191818101908684111561487757600080fd5b8286015b8481101561489b57803561488e81614800565b835291830191830161487b565b509695505050505050565b60ff8116811461138457600080fd5b803561482d816148a6565b63ffffffff8116811461138457600080fd5b803561482d816148c0565b801515811461138457600080fd5b803561482d816148dd565b62ffffff8116811461138457600080fd5b803561482d816148f6565b61ffff8116811461138457600080fd5b803561482d81614912565b6000610200828403121561494057600080fd5b614948614740565b9050614953826148d2565b8152614961602083016148d2565b6020820152614972604083016148d2565b604082015261498360608301614822565b6060820152614994608083016148eb565b60808201526149a560a08301614907565b60a08201526149b660c083016148d2565b60c08201526149c760e083016148d2565b60e08201526101006149da818401614822565b908201526101206149ec838201614922565b908201526101406149fe838201614822565b90820152610160828101359082015261018080830135908201526101a080830135908201526101c08083013567ffffffffffffffff811115614a3f57600080fd5b614a4b85828601614832565b8284015250506101e0614a5f818401614822565b9082015292915050565b803567ffffffffffffffff8116811461482d57600080fd5b600082601f830112614a9257600080fd5b813567ffffffffffffffff811115614aac57614aac614711565b614add60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161478d565b818152846020838601011115614af257600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff8116811461138457600080fd5b600082601f830112614b3a57600080fd5b81356020614b4a614853836147dc565b82815260c09283028501820192828201919087851115614b6957600080fd5b8387015b85811015614bfb5781818a031215614b855760008081fd5b614b8d61476a565b8135614b98816148c0565b815281860135614ba7816148f6565b81870152604082810135614bba81614800565b90820152606082810135614bcd816148a6565b908201526080828101359082015260a080830135614bea81614b0f565b908201528452928401928101614b6d565b5090979650505050505050565b600080600080600080600080610100898b031215614c2557600080fd5b883567ffffffffffffffff80821115614c3d57600080fd5b614c498c838d01614832565b995060208b0135915080821115614c5f57600080fd5b614c6b8c838d01614832565b9850614c7960408c016148b5565b975060608b0135915080821115614c8f57600080fd5b614c9b8c838d0161492d565b9650614ca960808c01614a69565b955060a08b0135915080821115614cbf57600080fd5b614ccb8c838d01614a81565b945060c08b0135915080821115614ce157600080fd5b614ced8c838d01614832565b935060e08b0135915080821115614d0357600080fd5b50614d108b828c01614b29565b9150509295985092959890939650565b6000815180845260005b81811015614d4657602081850181015186830182015201614d2a565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006121c76020830184614d20565b60008083601f840112614da957600080fd5b50813567ffffffffffffffff811115614dc157600080fd5b602083019150836020828501011115614dd957600080fd5b9250929050565b60008060008060608587031215614df657600080fd5b8435614e0181614800565b935060208501359250604085013567ffffffffffffffff811115614e2457600080fd5b614e3087828801614d97565b95989497509550505050565b60008083601f840112614e4e57600080fd5b50813567ffffffffffffffff811115614e6657600080fd5b6020830191508360208260051b8501011115614dd957600080fd5b60008060008060008060008060e0898b031215614e9d57600080fd5b606089018a811115614eae57600080fd5b8998503567ffffffffffffffff80821115614ec857600080fd5b614ed48c838d01614d97565b909950975060808b0135915080821115614eed57600080fd5b614ef98c838d01614e3c565b909750955060a08b0135915080821115614f1257600080fd5b50614f1f8b828c01614e3c565b999c989b50969995989497949560c00135949350505050565b60008060008060008060c08789031215614f5157600080fd5b863567ffffffffffffffff80821115614f6957600080fd5b614f758a838b01614832565b97506020890135915080821115614f8b57600080fd5b614f978a838b01614832565b9650614fa560408a016148b5565b95506060890135915080821115614fbb57600080fd5b614fc78a838b01614a81565b9450614fd560808a01614a69565b935060a0890135915080821115614feb57600080fd5b50614ff889828a01614a81565b9150509295509295509295565b60006020828403121561501757600080fd5b81356121c781614800565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff818116838216029081169081811461353b5761353b615022565b60006020828403121561507f57600080fd5b5051919050565b63ffffffff81811683821601908082111561353b5761353b615022565b600081518084526020808501945080840160005b838110156150e957815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016150b7565b509495945050505050565b6020815261510b60208201835163ffffffff169052565b60006020830151615124604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015180151560a08401525060a083015162ffffff811660c08401525060c083015163ffffffff811660e08401525060e08301516101006151a38185018363ffffffff169052565b84015190506101206151cc8482018373ffffffffffffffffffffffffffffffffffffffff169052565b84015190506101406151e38482018361ffff169052565b840151905061016061520c8482018373ffffffffffffffffffffffffffffffffffffffff169052565b840151610180848101919091528401516101a0808501919091528401516101c0808501919091528401516102006101e0808601829052919250906152546102208601846150a3565b95015173ffffffffffffffffffffffffffffffffffffffff169301929092525090919050565b818103818111156121b5576121b5615022565b60008161529c5761529c615022565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361532257615322615022565b5060010190565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526153598184018a6150a3565b9050828103608084015261536d81896150a3565b905060ff871660a084015282810360c084015261538a8187614d20565b905067ffffffffffffffff851660e08401528281036101008401526153af8185614d20565b9c9b505050505050505050505050565b6000602082840312156153d157600080fd5b5035919050565b6bffffffffffffffffffffffff81811683821601908082111561353b5761353b615022565b808201808211156121b5576121b5615022565b60ff81811683821601908111156121b5576121b5615022565b805161482d816148c0565b805161482d81614800565b805161482d816148dd565b805161482d816148f6565b805161482d81614912565b600082601f83011261547157600080fd5b81516020615481614853836147dc565b82815260059290921b840181019181810190868411156154a057600080fd5b8286015b8481101561489b5780516154b781614800565b83529183019183016154a4565b600082601f8301126154d557600080fd5b815160206154e5614853836147dc565b82815260059290921b8401810191818101908684111561550457600080fd5b8286015b8481101561489b57805161551b81614800565b8352918301918301615508565b600082601f83011261553957600080fd5b81516020615549614853836147dc565b82815260c0928302850182019282820191908785111561556857600080fd5b8387015b85811015614bfb5781818a0312156155845760008081fd5b61558c61476a565b8151615597816148c0565b8152818601516155a6816148f6565b818701526040828101516155b981614800565b908201526060828101516155cc816148a6565b908201526080828101519082015260a0808301516155e981614b0f565b90820152845292840192810161556c565b60008060006060848603121561560f57600080fd5b835167ffffffffffffffff8082111561562757600080fd5b90850190610200828803121561563c57600080fd5b615644614740565b61564d83615429565b815261565b60208401615429565b602082015261566c60408401615429565b604082015261567d60608401615434565b606082015261568e6080840161543f565b608082015261569f60a0840161544a565b60a08201526156b060c08401615429565b60c08201526156c160e08401615429565b60e08201526101006156d4818501615434565b908201526101206156e6848201615455565b908201526101406156f8848201615434565b90820152610160838101519082015261018080840151908201526101a080840151908201526101c0808401518381111561573157600080fd5b61573d8a828701615460565b8284015250506101e0615751818501615434565b90820152602087015190955091508082111561576c57600080fd5b615778878388016154c4565b9350604086015191508082111561578e57600080fd5b5061579b86828701615528565b9150509250925092565b6000602082840312156157b757600080fd5b81516121c7816148a6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526158388285018b6150a3565b9150838203608085015261584c828a6150a3565b915060ff881660a085015283820360c08501526158698288614d20565b90861660e085015283810361010085015290506153af8185614d20565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b600082601f8301126158bd57600080fd5b813560206158cd614853836147dc565b82815260059290921b840181019181810190868411156158ec57600080fd5b8286015b8481101561489b57803583529183019183016158f0565b600082601f83011261591857600080fd5b81356020615928614853836147dc565b82815260059290921b8401810191818101908684111561594757600080fd5b8286015b8481101561489b57803567ffffffffffffffff81111561596b5760008081fd5b6159798986838b0101614a81565b84525091830191830161594b565b60006020828403121561599957600080fd5b813567ffffffffffffffff808211156159b157600080fd5b9083019060c082860312156159c557600080fd5b6159cd61476a565b82358152602083013560208201526040830135828111156159ed57600080fd5b6159f9878286016158ac565b604083015250606083013582811115615a1157600080fd5b615a1d878286016158ac565b606083015250608083013582811115615a3557600080fd5b615a4187828601615907565b60808301525060a083013582811115615a5957600080fd5b615a6587828601615907565b60a08301525095945050505050565b61ffff81811683821601908082111561353b5761353b615022565b80820281158282048414176121b5576121b5615022565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615ae457615ae4615aa6565b500490565b6bffffffffffffffffffffffff85168152836020820152826040820152608060608201526000615b1c6080830184614d20565b9695505050505050565b6bffffffffffffffffffffffff82811682821603908082111561353b5761353b615022565b60006bffffffffffffffffffffffff80841680615b6a57615b6a615aa6565b92169190910492915050565b6bffffffffffffffffffffffff818116838216028082169190828114615b9e57615b9e615022565b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8281526040602082015260006136346040830184614d20565b60008060408385031215615c0157600080fd5b8251615c0c816148dd565b6020939093015192949293505050565b805169ffffffffffffffffffff8116811461482d57600080fd5b600080600080600060a08688031215615c4e57600080fd5b615c5786615c1c565b9450602086015193506040860151925060608601519150615c7a60808701615c1c565b90509295509295909350565b6fffffffffffffffffffffffffffffffff81811683821601908082111561353b5761353b615022565b600060408284031215615cc157600080fd5b6040516040810181811067ffffffffffffffff82111715615ce457615ce4614711565b6040528251615cf2816148c0565b81526020928301519281019290925250919050565b600060a08284031215615d1957600080fd5b60405160a0810181811067ffffffffffffffff82111715615d3c57615d3c614711565b806040525082518152602083015160208201526040830151615d5d816148c0565b60408201526060830151615d70816148c0565b60608201526080928301519281019290925250919050565b600181815b80851115615de157817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615dc757615dc7615022565b80851615615dd457918102915b93841c9390800290615d8d565b509250929050565b600082615df8575060016121b5565b81615e05575060006121b5565b8160018114615e1b5760028114615e2557615e41565b60019150506121b5565b60ff841115615e3657615e36615022565b50506001821b6121b5565b5060208310610133831016604e8410600b8410161715615e64575081810a6121b5565b615e6e8383615d88565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115615ea057615ea0615022565b029392505050565b60006121c78383615de956fea164736f6c6343000813000a", } var AutomationRegistryABI = AutomationRegistryMetaData.ABI diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index a8dae2092cb..d5a931321ab 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -8,13 +8,13 @@ automation_compatible_utils: ../../contracts/solc/v0.8.19/AutomationCompatibleUt automation_consumer_benchmark: ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark/AutomationConsumerBenchmark.abi ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark/AutomationConsumerBenchmark.bin f52c76f1aaed4be541d82d97189d70f5aa027fc9838037dd7a7d21910c8c488e automation_forwarder_logic: ../../contracts/solc/v0.8.16/AutomationForwarderLogic/AutomationForwarderLogic.abi ../../contracts/solc/v0.8.16/AutomationForwarderLogic/AutomationForwarderLogic.bin 15ae0c367297955fdab4b552dbb10e1f2be80a8fde0efec4a4d398693e9d72b5 automation_registrar_wrapper2_1: ../../contracts/solc/v0.8.16/AutomationRegistrar2_1/AutomationRegistrar2_1.abi ../../contracts/solc/v0.8.16/AutomationRegistrar2_1/AutomationRegistrar2_1.bin eb06d853aab39d3196c593b03e555851cbe8386e0fe54a74c2479f62d14b3c42 -automation_registrar_wrapper2_3: ../../contracts/solc/v0.8.19/AutomationRegistrar2_3/AutomationRegistrar2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistrar2_3/AutomationRegistrar2_3.bin 4d8c1fae4c8bf59ad996a1ac00f2131158ac1d96c3039c2e7deaa502f0317719 +automation_registrar_wrapper2_3: ../../contracts/solc/v0.8.19/AutomationRegistrar2_3/AutomationRegistrar2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistrar2_3/AutomationRegistrar2_3.bin 05dfc1601a6e8a43d98c982b5cb1ad1060b49948dc0c8ccd829ca2c9f6d9430e automation_registry_logic_a_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.bin 2f267fb8467a15c587ce4586ac56069f7229344ad3936430d7c7624c0528a171 -automation_registry_logic_a_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.bin 1163ecd34c575cb17ffbc2f88fa175816f36982e91992d940ed435d306b3418c +automation_registry_logic_a_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.bin e8ae5a25765092049f79eb8344db8e572bacb43c6c6e284b3d00f82667c248f7 automation_registry_logic_b_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.bin a6d33dfbbfb0ff253eb59a51f4f6d6d4c22ea5ec95aae52d25d49a312b37a22f automation_registry_logic_b_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_3/AutomationRegistryLogicB2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_3/AutomationRegistryLogicB2_3.bin 2d0f45d2087f6f3c8bfa0a16b26a1c8c1d5c64b89859478c609201535c96eeed automation_registry_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.bin de60f69878e9b32a291a001c91fc8636544c2cfbd9b507c8c1a4873b602bfb62 -automation_registry_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.bin 68acf720890c89512a43c3468712f5da6c1c9613bc7c462b51599293f0cce9f4 +automation_registry_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.bin fa9159b9dd36e37209d9805d0fde82f1cba7d0e2674ecc5a7595d48eb40203c4 automation_utils_2_1: ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.abi ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.bin 815b17b63f15d26a0274b962eefad98cdee4ec897ead58688bbb8e2470e585f5 automation_utils_2_2: ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.abi ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.bin 8743f6231aaefa3f2a0b2d484258070d506e2d0860690e66890dccc3949edb2e automation_utils_2_3: ../../contracts/solc/v0.8.19/AutomationUtils2_3/AutomationUtils2_3.abi ../../contracts/solc/v0.8.19/AutomationUtils2_3/AutomationUtils2_3.bin 11e2b481dc9a4d936e3443345d45d2cc571164459d214917b42a8054b295393b From 9c948c7d30b748ce0d881e88b492237db03ebe9d Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Thu, 25 Apr 2024 12:42:50 -0700 Subject: [PATCH 38/77] fix: disable gh releases for contracts (#12980) --- .github/workflows/solidity.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/solidity.yml b/.github/workflows/solidity.yml index 5940313fc65..b2dc3d4153c 100644 --- a/.github/workflows/solidity.yml +++ b/.github/workflows/solidity.yml @@ -258,10 +258,7 @@ jobs: uses: smartcontractkit/.github/actions/ci-publish-npm@4b0ab756abcb1760cb82e1e87b94ff431905bffc # ci-publish-npm@0.4.0 with: npm-token: ${{ secrets.NPM_TOKEN }} - github-token: ${{ secrets.GITHUB_TOKEN }} - github-release-tag-name: ${{ github.ref_name }} - github-release-changelog-path: "contracts/CHANGELOG.md" - create-github-release: true + create-github-release: false publish-command: "pnpm publish-prod --no-git-checks" package-json-directory: contracts From aab15199469180a6e193931d2a70f0c52442ebc2 Mon Sep 17 00:00:00 2001 From: Cedric Date: Thu, 25 Apr 2024 21:21:06 +0100 Subject: [PATCH 39/77] [KS-137] Add support for execution strategies (#12841) * [KS-137] Add support for execution strategies * [KS-137] Add support for execution strategies --- core/capabilities/remote/target.go | 9 +- core/capabilities/remote/target_test.go | 4 +- core/capabilities/remote/trigger_publisher.go | 6 +- .../remote/trigger_publisher_test.go | 6 +- .../capabilities/remote/trigger_subscriber.go | 8 +- .../remote/trigger_subscriber_test.go | 4 +- core/capabilities/syncer.go | 10 +- core/services/chainlink/application.go | 28 ++- core/services/workflows/delegate.go | 52 ++++- core/services/workflows/engine.go | 187 ++++++++++++------ core/services/workflows/engine_test.go | 10 + core/services/workflows/execution_strategy.go | 171 ++++++++++++++++ .../workflows/execution_strategy_test.go | 170 ++++++++++++++++ core/services/workflows/models.go | 10 +- core/services/workflows/models_yaml.go | 18 +- .../marshalling/workflow_2_spec.json | 2 +- 16 files changed, 601 insertions(+), 94 deletions(-) create mode 100644 core/services/workflows/execution_strategy.go create mode 100644 core/services/workflows/execution_strategy_test.go diff --git a/core/capabilities/remote/target.go b/core/capabilities/remote/target.go index 92b0724512a..655f4f84abb 100644 --- a/core/capabilities/remote/target.go +++ b/core/capabilities/remote/target.go @@ -4,6 +4,7 @@ import ( "context" "errors" + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -12,7 +13,7 @@ import ( // remoteTargetCaller/Receiver are shims translating between capability API calls and network messages type remoteTargetCaller struct { capInfo commoncap.CapabilityInfo - donInfo *types.DON + donInfo *capabilities.DON dispatcher types.Dispatcher lggr logger.Logger } @@ -22,14 +23,14 @@ var _ types.Receiver = &remoteTargetCaller{} type remoteTargetReceiver struct { capInfo commoncap.CapabilityInfo - donInfo *types.DON + donInfo *capabilities.DON dispatcher types.Dispatcher lggr logger.Logger } var _ types.Receiver = &remoteTargetReceiver{} -func NewRemoteTargetCaller(capInfo commoncap.CapabilityInfo, donInfo *types.DON, dispatcher types.Dispatcher, lggr logger.Logger) *remoteTargetCaller { +func NewRemoteTargetCaller(capInfo commoncap.CapabilityInfo, donInfo *capabilities.DON, dispatcher types.Dispatcher, lggr logger.Logger) *remoteTargetCaller { return &remoteTargetCaller{ capInfo: capInfo, donInfo: donInfo, @@ -72,7 +73,7 @@ func (c *remoteTargetCaller) Receive(msg *types.MessageBody) { c.lggr.Debugw("not implemented - received message", "capabilityId", c.capInfo.ID, "payload", msg.Payload) } -func NewRemoteTargetReceiver(capInfo commoncap.CapabilityInfo, donInfo *types.DON, dispatcher types.Dispatcher, lggr logger.Logger) *remoteTargetReceiver { +func NewRemoteTargetReceiver(capInfo commoncap.CapabilityInfo, donInfo *capabilities.DON, dispatcher types.Dispatcher, lggr logger.Logger) *remoteTargetReceiver { return &remoteTargetReceiver{ capInfo: capInfo, donInfo: donInfo, diff --git a/core/capabilities/remote/target_test.go b/core/capabilities/remote/target_test.go index a9e72d778df..0f9bad51f67 100644 --- a/core/capabilities/remote/target_test.go +++ b/core/capabilities/remote/target_test.go @@ -6,9 +6,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote" - "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" remoteMocks "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -18,7 +18,7 @@ import ( func TestTarget_Placeholder(t *testing.T) { lggr := logger.TestLogger(t) ctx := testutils.Context(t) - donInfo := &types.DON{ + donInfo := &capabilities.DON{ Members: []p2ptypes.PeerID{{}}, } dispatcher := remoteMocks.NewDispatcher(t) diff --git a/core/capabilities/remote/trigger_publisher.go b/core/capabilities/remote/trigger_publisher.go index d06254657c7..12d539a2dc0 100644 --- a/core/capabilities/remote/trigger_publisher.go +++ b/core/capabilities/remote/trigger_publisher.go @@ -24,8 +24,8 @@ type triggerPublisher struct { config types.RemoteTriggerConfig underlying commoncap.TriggerCapability capInfo commoncap.CapabilityInfo - capDonInfo types.DON - workflowDONs map[string]types.DON + capDonInfo commoncap.DON + workflowDONs map[string]commoncap.DON dispatcher types.Dispatcher messageCache *messageCache[registrationKey, p2ptypes.PeerID] registrations map[registrationKey]*pubRegState @@ -48,7 +48,7 @@ type pubRegState struct { var _ types.Receiver = &triggerPublisher{} var _ services.Service = &triggerPublisher{} -func NewTriggerPublisher(config types.RemoteTriggerConfig, underlying commoncap.TriggerCapability, capInfo commoncap.CapabilityInfo, capDonInfo types.DON, workflowDONs map[string]types.DON, dispatcher types.Dispatcher, lggr logger.Logger) *triggerPublisher { +func NewTriggerPublisher(config types.RemoteTriggerConfig, underlying commoncap.TriggerCapability, capInfo commoncap.CapabilityInfo, capDonInfo commoncap.DON, workflowDONs map[string]commoncap.DON, dispatcher types.Dispatcher, lggr logger.Logger) *triggerPublisher { config.ApplyDefaults() return &triggerPublisher{ config: config, diff --git a/core/capabilities/remote/trigger_publisher_test.go b/core/capabilities/remote/trigger_publisher_test.go index dd107e12e61..71a5174c07f 100644 --- a/core/capabilities/remote/trigger_publisher_test.go +++ b/core/capabilities/remote/trigger_publisher_test.go @@ -29,12 +29,12 @@ func TestTriggerPublisher_Register(t *testing.T) { require.NoError(t, p1.UnmarshalText([]byte(peerID1))) p2 := p2ptypes.PeerID{} require.NoError(t, p2.UnmarshalText([]byte(peerID2))) - capDonInfo := remotetypes.DON{ + capDonInfo := commoncap.DON{ ID: "capability-don", Members: []p2ptypes.PeerID{p1}, F: 0, } - workflowDonInfo := remotetypes.DON{ + workflowDonInfo := commoncap.DON{ ID: "workflow-don", Members: []p2ptypes.PeerID{p2}, F: 0, @@ -47,7 +47,7 @@ func TestTriggerPublisher_Register(t *testing.T) { MinResponsesToAggregate: 1, MessageExpiryMs: 100_000, } - workflowDONs := map[string]remotetypes.DON{ + workflowDONs := map[string]commoncap.DON{ workflowDonInfo.ID: workflowDonInfo, } underlying := &testTrigger{ diff --git a/core/capabilities/remote/trigger_subscriber.go b/core/capabilities/remote/trigger_subscriber.go index a7cb58c008b..e9704bf1865 100644 --- a/core/capabilities/remote/trigger_subscriber.go +++ b/core/capabilities/remote/trigger_subscriber.go @@ -6,6 +6,7 @@ import ( sync "sync" "time" + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb" "github.com/smartcontractkit/chainlink-common/pkg/services" @@ -24,9 +25,9 @@ import ( type triggerSubscriber struct { config types.RemoteTriggerConfig capInfo commoncap.CapabilityInfo - capDonInfo types.DON + capDonInfo capabilities.DON capDonMembers map[p2ptypes.PeerID]struct{} - localDonInfo types.DON + localDonInfo capabilities.DON dispatcher types.Dispatcher aggregator types.Aggregator messageCache *messageCache[triggerEventKey, p2ptypes.PeerID] @@ -54,8 +55,7 @@ var _ services.Service = &triggerSubscriber{} // TODO makes this configurable with a default const defaultSendChannelBufferSize = 1000 -func NewTriggerSubscriber(config types.RemoteTriggerConfig, capInfo commoncap.CapabilityInfo, capDonInfo types.DON, localDonInfo types.DON, - dispatcher types.Dispatcher, aggregator types.Aggregator, lggr logger.Logger) *triggerSubscriber { +func NewTriggerSubscriber(config types.RemoteTriggerConfig, capInfo commoncap.CapabilityInfo, capDonInfo capabilities.DON, localDonInfo capabilities.DON, dispatcher types.Dispatcher, aggregator types.Aggregator, lggr logger.Logger) *triggerSubscriber { if aggregator == nil { lggr.Warnw("no aggregator provided, using default MODE aggregator", "capabilityId", capInfo.ID) aggregator = NewDefaultModeAggregator(uint32(capDonInfo.F + 1)) diff --git a/core/capabilities/remote/trigger_subscriber_test.go b/core/capabilities/remote/trigger_subscriber_test.go index df04306e2b0..4d251d49dc8 100644 --- a/core/capabilities/remote/trigger_subscriber_test.go +++ b/core/capabilities/remote/trigger_subscriber_test.go @@ -38,12 +38,12 @@ func TestTriggerSubscriber_RegisterAndReceive(t *testing.T) { require.NoError(t, p1.UnmarshalText([]byte(peerID1))) p2 := p2ptypes.PeerID{} require.NoError(t, p2.UnmarshalText([]byte(peerID2))) - capDonInfo := remotetypes.DON{ + capDonInfo := commoncap.DON{ ID: "capability-don", Members: []p2ptypes.PeerID{p1}, F: 0, } - workflowDonInfo := remotetypes.DON{ + workflowDonInfo := commoncap.DON{ ID: "workflow-don", Members: []p2ptypes.PeerID{p2}, F: 0, diff --git a/core/capabilities/syncer.go b/core/capabilities/syncer.go index dc9126dba36..67d388a8221 100644 --- a/core/capabilities/syncer.go +++ b/core/capabilities/syncer.go @@ -6,6 +6,7 @@ import ( "sync" "time" + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/capabilities/mercury" "github.com/smartcontractkit/chainlink-common/pkg/capabilities/triggers" @@ -70,7 +71,7 @@ func (s *registrySyncer) Start(ctx context.Context) error { "12D3KooWN2hztiXNNS1jMQTTvvPRYcarK1C7T3Mdqk4x4gwyo5WS", } allPeers := make(map[ragetypes.PeerID]p2ptypes.StreamConfig) - addPeersToDONInfo := func(peers []string, donInfo *remotetypes.DON) error { + addPeersToDONInfo := func(peers []string, donInfo *capabilities.DON) error { for _, peerID := range peers { var p ragetypes.PeerID err := p.UnmarshalText([]byte(peerID)) @@ -82,11 +83,11 @@ func (s *registrySyncer) Start(ctx context.Context) error { } return nil } - workflowDonInfo := remotetypes.DON{ID: "workflowDon1", F: 1} + workflowDonInfo := capabilities.DON{ID: "workflowDon1", F: 1} if err := addPeersToDONInfo(workflowDONPeers, &workflowDonInfo); err != nil { return err } - triggerCapabilityDonInfo := remotetypes.DON{ID: "capabilityDon1", F: 1} + triggerCapabilityDonInfo := capabilities.DON{ID: "capabilityDon1", F: 1} if err := addPeersToDONInfo(triggerDONPeers, &triggerCapabilityDonInfo); err != nil { return err } @@ -101,6 +102,7 @@ func (s *registrySyncer) Start(ctx context.Context) error { CapabilityType: commoncap.CapabilityTypeTrigger, Description: "Remote Trigger", Version: "0.0.1", + DON: &triggerCapabilityDonInfo, } myId := s.peerWrapper.GetPeer().ID().String() config := remotetypes.RemoteTriggerConfig{ @@ -125,7 +127,7 @@ func (s *registrySyncer) Start(ctx context.Context) error { } if slices.Contains(triggerDONPeers, myId) { s.lggr.Info("member of a capability DON - starting remote publishers") - workflowDONs := map[string]remotetypes.DON{ + workflowDONs := map[string]capabilities.DON{ workflowDonInfo.ID: workflowDonInfo, } underlying := triggers.NewMercuryTriggerService(1000, s.lggr) diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 0ac6555aecc..2aebef3f8f7 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -49,6 +49,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2" "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" + p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" externalp2p "github.com/smartcontractkit/chainlink/v2/core/services/p2p/wrapper" "github.com/smartcontractkit/chainlink/v2/core/services/periodicbackup" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" @@ -189,9 +190,12 @@ func NewApplication(opts ApplicationOpts) (Application, error) { unrestrictedHTTPClient := opts.UnrestrictedHTTPClient registry := capabilities.NewRegistry(globalLogger) + var externalPeerWrapper p2ptypes.PeerWrapper if cfg.Capabilities().Peering().Enabled() { - externalPeerWrapper := externalp2p.NewExternalPeerWrapper(keyStore.P2P(), cfg.Capabilities().Peering(), globalLogger) - signer := externalPeerWrapper + externalPeer := externalp2p.NewExternalPeerWrapper(keyStore.P2P(), cfg.Capabilities().Peering(), globalLogger) + signer := externalPeer + externalPeerWrapper = externalPeer + srvcs = append(srvcs, externalPeerWrapper) // NOTE: RegistrySyncer will depend on a Relayer when fully implemented @@ -367,16 +371,26 @@ func NewApplication(opts ApplicationOpts) (Application, error) { globalLogger, streamRegistry, pipelineRunner, - cfg.JobPipeline()), - job.Workflow: workflows.NewDelegate( - globalLogger, - registry, - legacyEVMChains, + cfg.JobPipeline(), ), } webhookJobRunner = delegates[job.Webhook].(*webhook.Delegate).WebhookJobRunner() ) + delegates[job.Workflow] = workflows.NewDelegate( + globalLogger, + registry, + legacyEVMChains, + func() *p2ptypes.PeerID { + if externalPeerWrapper == nil { + return nil + } + + peerID := externalPeerWrapper.GetPeer().ID() + return &peerID + }, + ) + // Flux monitor requires ethereum just to boot, silence errors with a null delegate if !cfg.EVMRPCEnabled() { delegates[job.FluxMonitor] = &job.NullDelegate{Type: job.FluxMonitor} diff --git a/core/services/workflows/delegate.go b/core/services/workflows/delegate.go index e22a78212d2..8dc440da477 100644 --- a/core/services/workflows/delegate.go +++ b/core/services/workflows/delegate.go @@ -2,22 +2,26 @@ package workflows import ( "context" + "encoding/hex" "fmt" "github.com/google/uuid" "github.com/pelletier/go-toml" + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/types/core" "github.com/smartcontractkit/chainlink/v2/core/capabilities/targets" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" + p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" ) type Delegate struct { registry core.CapabilitiesRegistry logger logger.Logger legacyEVMChains legacyevm.LegacyChainContainer + peerID func() *p2ptypes.PeerID } var _ job.Delegate = (*Delegate)(nil) @@ -42,11 +46,18 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) ([]job.Ser d.logger.Errorw("could not initialize writes", err) } + dinfo, err := initializeDONInfo(d.logger) + if err != nil { + d.logger.Errorw("could not add initialize don info", err) + } + cfg := Config{ Lggr: d.logger, Spec: spec.WorkflowSpec.Workflow, WorkflowID: spec.WorkflowSpec.WorkflowID, Registry: d.registry, + DONInfo: dinfo, + PeerID: d.peerID, } engine, err := NewEngine(cfg) if err != nil { @@ -55,8 +66,45 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) ([]job.Ser return []job.ServiceCtx{engine}, nil } -func NewDelegate(logger logger.Logger, registry core.CapabilitiesRegistry, legacyEVMChains legacyevm.LegacyChainContainer) *Delegate { - return &Delegate{logger: logger, registry: registry, legacyEVMChains: legacyEVMChains} +func initializeDONInfo(lggr logger.Logger) (*capabilities.DON, error) { + var key [16]byte + + // TODO: fetch the key and DONInfo from the registry + keyString := "44fb5c1ee8ee48846c808a383da3aba3" + k, err := hex.DecodeString(keyString) + if err != nil { + lggr.Errorf("could not decode key %s: %w", keyString, err) + } + key = [16]byte(k) + + p2pStrings := []string{ + "12D3KooWBCF1XT5Wi8FzfgNCqRL76Swv8TRU3TiD4QiJm8NMNX7N", + "12D3KooWG1AyvwmCpZ93J8pBQUE1SuzrjDXnT4BeouncHR3jWLCG", + "12D3KooWGeUKZBRMbx27FUTgBwZa9Ap9Ym92mywwpuqkEtz8XWyv", + "12D3KooW9zYWQv3STmDeNDidyzxsJSTxoCTLicafgfeEz9nhwhC4", + } + + p2pIDs := []p2ptypes.PeerID{} + for _, p := range p2pStrings { + pid := p2ptypes.PeerID{} + err := pid.UnmarshalText([]byte(p)) + if err != nil { + return nil, err + } + + p2pIDs = append(p2pIDs, pid) + } + + return &capabilities.DON{ + Members: p2pIDs, + Config: capabilities.DONConfig{ + SharedSecret: key, + }, + }, nil +} + +func NewDelegate(logger logger.Logger, registry core.CapabilitiesRegistry, legacyEVMChains legacyevm.LegacyChainContainer, peerID func() *p2ptypes.PeerID) *Delegate { + return &Delegate{logger: logger, registry: registry, legacyEVMChains: legacyEVMChains, peerID: peerID} } func ValidatedWorkflowSpec(tomlString string) (job.Job, error) { diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go index 052c2c86647..0ecc311acac 100644 --- a/core/services/workflows/engine.go +++ b/core/services/workflows/engine.go @@ -13,6 +13,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/types/core" "github.com/smartcontractkit/chainlink-common/pkg/values" "github.com/smartcontractkit/chainlink/v2/core/logger" + p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" ) const ( @@ -21,12 +22,18 @@ const ( mockedWorkflowID = "15c631d295ef5e32deb99a10ee6804bc4af1385568f9b3363f6552ac6dbb2cef" ) +type donInfo struct { + *capabilities.DON + PeerID func() *p2ptypes.PeerID +} + // Engine handles the lifecycle of a single workflow and its executions. type Engine struct { services.StateMachine logger logger.Logger registry core.CapabilitiesRegistry workflow *workflow + donInfo donInfo executionStates *inMemoryStore pendingStepRequests chan stepRequest triggerEvents chan capabilities.CapabilityResponse @@ -88,7 +95,11 @@ LOOP: continue } - // Walk the graph and register each step's capability to this workflow + // Walk the graph and initialize each step. + // This means: + // - fetching the capability + // - register the capability to this workflow + // - initializing the step's executionStrategy err := e.workflow.walkDo(keywordTrigger, func(s *step) error { // The graph contains a dummy step for triggers, but // we handle triggers separately since there might be more than one. @@ -96,45 +107,12 @@ LOOP: return nil } - // If the capability already exists, that means we've already registered it - if s.capability != nil { - return nil - } - - cp, innerErr := e.registry.Get(ctx, s.Type) - if innerErr != nil { - return fmt.Errorf("failed to get capability with ref %s: %s, retrying in %d seconds", s.Type, innerErr, retrySec) - } - - // We only need to configure actions, consensus and targets here, and - // they all satisfy the `CallbackExecutable` interface - cc, ok := cp.(capabilities.CallbackExecutable) - if !ok { - return fmt.Errorf("could not coerce capability %s to CallbackExecutable", s.Type) - } - - if s.config == nil { - configMap, ierr := values.NewMap(s.Config) - if ierr != nil { - return fmt.Errorf("failed to convert config to values.Map: %s", ierr) - } - s.config = configMap - } - - reg := capabilities.RegisterToWorkflowRequest{ - Metadata: capabilities.RegistrationMetadata{ - WorkflowID: e.workflow.id, - }, - Config: s.config, - } - - innerErr = cc.RegisterToWorkflow(ctx, reg) - if innerErr != nil { - return fmt.Errorf("failed to register to workflow (%+v): %w", reg, innerErr) + err := e.initializeCapability(ctx, s, retrySec) + if err != nil { + return err } - s.capability = cc - return nil + return e.initializeExecutionStrategy(s) }) if err != nil { initSuccessful = false @@ -158,6 +136,101 @@ LOOP: e.logger.Info("engine initialized") } +func (e *Engine) initializeCapability(ctx context.Context, s *step, retrySec int) error { + // If the capability already exists, that means we've already registered it + if s.capability != nil { + return nil + } + + cp, innerErr := e.registry.Get(ctx, s.Type) + if innerErr != nil { + return fmt.Errorf("failed to get capability with ref %s: %s, retrying in %d seconds", s.Type, innerErr, retrySec) + } + + // We only need to configure actions, consensus and targets here, and + // they all satisfy the `CallbackCapability` interface + cc, ok := cp.(capabilities.CallbackCapability) + if !ok { + return fmt.Errorf("could not coerce capability %s to CallbackCapability", s.Type) + } + + if s.config == nil { + configMap, ierr := values.NewMap(s.Config) + if ierr != nil { + return fmt.Errorf("failed to convert config to values.Map: %s", ierr) + } + s.config = configMap + } + + reg := capabilities.RegisterToWorkflowRequest{ + Metadata: capabilities.RegistrationMetadata{ + WorkflowID: e.workflow.id, + }, + Config: s.config, + } + + innerErr = cc.RegisterToWorkflow(ctx, reg) + if innerErr != nil { + return fmt.Errorf("failed to register to workflow (%+v): %w", reg, innerErr) + } + + s.capability = cc + return nil +} + +// initializeExecutionStrategy for `step`. +// Broadly speaking, we'll use `immediateExecution` for non-target steps +// and `scheduledExecution` for targets. If we don't have the necessary +// config to initialize a scheduledExecution for a target, we'll fallback to +// using `immediateExecution`. +func (e *Engine) initializeExecutionStrategy(step *step) error { + if step.executionStrategy != nil { + return nil + } + + // If donInfo has no peerID, then the peer wrapper hasn't been initialized. + // Let's error and try again next time around. + if e.donInfo.PeerID() == nil { + return fmt.Errorf("failed to initialize execution strategy: peer ID %s has not been initialized", e.donInfo.PeerID()) + } + + ie := immediateExecution{} + if step.CapabilityType != capabilities.CapabilityTypeTarget { + e.logger.Debugf("initializing step %+v with immediate execution strategy: not a target", step) + step.executionStrategy = ie + return nil + } + + dinfo := e.donInfo + if dinfo.DON == nil { + e.logger.Debugf("initializing target step with immediate execution strategy: donInfo %+v", e.donInfo) + step.executionStrategy = ie + return nil + } + + var position *int + for i, w := range dinfo.Members { + if w == *dinfo.PeerID() { + idx := i + position = &idx + } + } + + if position == nil { + e.logger.Debugf("initializing step %+v with immediate execution strategy: position not found in donInfo %+v", step, e.donInfo) + step.executionStrategy = ie + return nil + } + + step.executionStrategy = scheduledExecution{ + DON: e.donInfo.DON, + Position: *position, + PeerID: e.donInfo.PeerID(), + } + e.logger.Debugf("initializing step %+v with scheduled execution strategy", step) + return nil +} + // registerTrigger is used during the initialization phase to bind a trigger to this workflow func (e *Engine) registerTrigger(ctx context.Context, t *triggerCapability) error { triggerInputs, err := values.NewMap( @@ -436,20 +509,24 @@ func (e *Engine) workerForStepRequest(ctx context.Context, msg stepRequest) { defer func() { e.newWorkerCh <- struct{}{} }() defer e.wg.Done() - e.logger.Debugw("executing on a step event", "stepRef", msg.stepRef, "executionID", msg.state.executionID) + // Instantiate a child logger; in addition to the WorkflowID field the workflow + // logger will already have, this adds the `stepRef` and `executionID` + l := e.logger.With("stepRef", msg.stepRef, "executionID", msg.state.executionID) + + l.Debugw("executing on a step event") stepState := &stepState{ outputs: &stepOutput{}, executionID: msg.state.executionID, ref: msg.stepRef, } - inputs, outputs, err := e.executeStep(ctx, msg) + inputs, outputs, err := e.executeStep(ctx, l, msg) if err != nil { - e.logger.Errorf("error executing step request: %s", err, "executionID", msg.state.executionID, "stepRef", msg.stepRef) + l.Errorf("error executing step request: %s", err) stepState.outputs.err = err stepState.status = statusErrored } else { - e.logger.Infow("step executed successfully", "executionID", msg.state.executionID, "stepRef", msg.stepRef, "outputs", outputs) + l.Infow("step executed successfully", "outputs", outputs) stepState.outputs.value = outputs stepState.status = statusCompleted } @@ -464,13 +541,13 @@ func (e *Engine) workerForStepRequest(ctx context.Context, msg stepRequest) { // like this one will get picked up again and will be reprocessed. select { case <-ctx.Done(): - e.logger.Errorf("context canceled before step update could be issued", err, "executionID", msg.state.executionID, "stepRef", msg.stepRef) + l.Errorf("context canceled before step update could be issued", err) case e.stepUpdateCh <- *stepState: } } // executeStep executes the referenced capability within a step and returns the result. -func (e *Engine) executeStep(ctx context.Context, msg stepRequest) (*values.Map, values.Value, error) { +func (e *Engine) executeStep(ctx context.Context, l logger.Logger, msg stepRequest) (*values.Map, values.Value, error) { step, err := e.workflow.Vertex(msg.stepRef) if err != nil { return nil, nil, err @@ -495,18 +572,12 @@ func (e *Engine) executeStep(ctx context.Context, msg stepRequest) (*values.Map, }, } - resp, err := capabilities.ExecuteSync(ctx, step.capability, tr) + output, err := step.executionStrategy.Apply(ctx, l, step.capability, tr) if err != nil { return inputs, nil, err } - // `ExecuteSync` returns a `values.List` even if there was - // just one return value. If that is the case, let's unwrap the - // single value to make it easier to use in -- for example -- variable interpolation. - if len(resp.Underlying) > 1 { - return inputs, resp, err - } - return inputs, resp.Underlying[0], err + return inputs, output, err } func (e *Engine) deregisterTrigger(ctx context.Context, t *triggerCapability) error { @@ -595,6 +666,8 @@ type Config struct { MaxWorkerLimit int QueueSize int NewWorkerTimeout time.Duration + DONInfo *capabilities.DON + PeerID func() *p2ptypes.PeerID } const ( @@ -638,9 +711,13 @@ func NewEngine(cfg Config) (engine *Engine, err error) { } engine = &Engine{ - logger: cfg.Lggr.Named("WorkflowEngine"), - registry: cfg.Registry, - workflow: workflow, + logger: cfg.Lggr.Named("WorkflowEngine").With("workflowID", cfg.WorkflowID), + registry: cfg.Registry, + workflow: workflow, + donInfo: donInfo{ + DON: cfg.DONInfo, + PeerID: cfg.PeerID, + }, executionStates: newInMemoryStore(), pendingStepRequests: make(chan stepRequest, cfg.QueueSize), newWorkerCh: newWorkerCh, diff --git a/core/services/workflows/engine_test.go b/core/services/workflows/engine_test.go index 448ff13ec79..d82c9d4b7d2 100644 --- a/core/services/workflows/engine_test.go +++ b/core/services/workflows/engine_test.go @@ -14,6 +14,7 @@ import ( coreCap "github.com/smartcontractkit/chainlink/v2/core/capabilities" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" + p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" ) const hardcodedWorkflow = ` @@ -148,10 +149,13 @@ func TestEngineWithHardcodedWorkflow(t *testing.T) { require.NoError(t, reg.Add(ctx, target2)) lggr := logger.TestLogger(t) + peerID := p2ptypes.PeerID{} cfg := Config{ Lggr: lggr, Registry: reg, Spec: hardcodedWorkflow, + DONInfo: nil, + PeerID: func() *p2ptypes.PeerID { return &peerID }, } eng, err := NewEngine(cfg) require.NoError(t, err) @@ -308,10 +312,13 @@ func TestEngine_ErrorsTheWorkflowIfAStepErrors(t *testing.T) { require.NoError(t, reg.Add(ctx, mockFailingConsensus())) require.NoError(t, reg.Add(ctx, mockTarget())) + peerID := p2ptypes.PeerID{} cfg := Config{ Lggr: logger.TestLogger(t), Registry: reg, Spec: simpleWorkflow, + DONInfo: nil, + PeerID: func() *p2ptypes.PeerID { return &peerID }, } eng, err := NewEngine(cfg) require.NoError(t, err) @@ -413,10 +420,13 @@ func TestEngine_MultiStepDependencies(t *testing.T) { action, out := mockAction() require.NoError(t, reg.Add(ctx, action)) + peerID := p2ptypes.PeerID{} cfg := Config{ Lggr: logger.TestLogger(t), Registry: reg, Spec: multiStepWorkflow, + DONInfo: nil, + PeerID: func() *p2ptypes.PeerID { return &peerID }, } eng, err := NewEngine(cfg) require.NoError(t, err) diff --git a/core/services/workflows/execution_strategy.go b/core/services/workflows/execution_strategy.go new file mode 100644 index 00000000000..f5da8bca4be --- /dev/null +++ b/core/services/workflows/execution_strategy.go @@ -0,0 +1,171 @@ +package workflows + +import ( + "context" + "fmt" + "time" + + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" + "github.com/smartcontractkit/chainlink-common/pkg/values" + "github.com/smartcontractkit/chainlink/v2/core/logger" + p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" + + "github.com/smartcontractkit/libocr/permutation" + + "golang.org/x/crypto/sha3" +) + +type executionStrategy interface { + Apply(ctx context.Context, l logger.Logger, cap capabilities.CallbackCapability, req capabilities.CapabilityRequest) (values.Value, error) +} + +var _ executionStrategy = immediateExecution{} + +type immediateExecution struct{} + +func (i immediateExecution) Apply(ctx context.Context, lggr logger.Logger, cap capabilities.CallbackCapability, req capabilities.CapabilityRequest) (values.Value, error) { + l, err := capabilities.ExecuteSync(ctx, cap, req) + if err != nil { + return nil, err + } + + // `ExecuteSync` returns a `values.List` even if there was + // just one return value. If that is the case, let's unwrap the + // single value to make it easier to use in -- for example -- variable interpolation. + if len(l.Underlying) > 1 { + return l, nil + } + + return l.Underlying[0], nil +} + +var _ executionStrategy = scheduledExecution{} + +type scheduledExecution struct { + DON *capabilities.DON + PeerID *p2ptypes.PeerID + Position int +} + +var ( + // S = [N] + Schedule_AllAtOnce = "allAtOnce" + // S = [1 * N] + Schedule_OneAtATime = "oneAtATime" +) + +// scheduledExecution generates a pseudo-random transmission schedule, +// and delays execution until a node is required to transmit. +func (d scheduledExecution) Apply(ctx context.Context, lggr logger.Logger, cap capabilities.CallbackCapability, req capabilities.CapabilityRequest) (values.Value, error) { + tc, err := d.transmissionConfig(req.Config) + if err != nil { + return nil, err + } + + info, err := cap.Info(ctx) + if err != nil { + return nil, err + } + + switch { + // Case 1: Local DON + case info.DON == nil: + n := len(d.DON.Members) + key := d.key(d.DON.Config.SharedSecret, req.Metadata.WorkflowID, req.Metadata.WorkflowExecutionID) + sched, err := schedule(tc.Schedule, n) + if err != nil { + return nil, err + } + + picked := permutation.Permutation(n, key) + delay := d.delayFor(d.Position, sched, picked, tc.DeltaStage) + if delay == nil { + lggr.Debugw("skipping transmission: node is not included in schedule") + return nil, nil + } + + lggr.Debugf("execution delayed by %+v", *delay) + select { + case <-ctx.Done(): + return nil, ctx.Err() + case <-time.After(*delay): + lggr.Debugw("executing delayed execution") + return immediateExecution{}.Apply(ctx, lggr, cap, req) + } + // Case 2: Remote DON + default: + // TODO: fill in the remote DON case once consensus has been reach on what to do. + lggr.Debugw("remote DON transmission not implemented: using immediate execution") + return immediateExecution{}.Apply(ctx, lggr, cap, req) + } +} + +// `key` uses a shared secret, combined with a workflowID and a workflowExecutionID to generate +// a secret that can later be used to pseudo-randomly determine a schedule for a set of nodes in a DON. +// The addition of the workflowExecutionID -- which nodes don't know ahead of time -- additionally guarantees +// that a malicious coalition of nodes can't "game" the schedule. +// IMPORTANT: changing this function should happen carefully to maintain the guarantee that all nodes +// arrive at the same secret. +func (d scheduledExecution) key(sharedSecret [16]byte, workflowID, workflowExecutionID string) [16]byte { + hash := sha3.NewLegacyKeccak256() + hash.Write(sharedSecret[:]) + hash.Write([]byte(workflowID)) + hash.Write([]byte(workflowExecutionID)) + + var key [16]byte + copy(key[:], hash.Sum(nil)) + return key +} + +type transmissionConfig struct { + Schedule string + DeltaStage time.Duration +} + +func (d scheduledExecution) transmissionConfig(config *values.Map) (transmissionConfig, error) { + var tc struct { + DeltaStage string + Schedule string + } + err := config.UnwrapTo(&tc) + if err != nil { + return transmissionConfig{}, err + } + + duration, err := time.ParseDuration(tc.DeltaStage) + if err != nil { + return transmissionConfig{}, fmt.Errorf("failed to parse DeltaStage %s as duration: %w", tc.DeltaStage, err) + } + + return transmissionConfig{ + Schedule: tc.Schedule, + DeltaStage: duration, + }, nil +} + +func (d scheduledExecution) delayFor(position int, schedule []int, permutation []int, deltaStage time.Duration) *time.Duration { + sum := 0 + for i, s := range schedule { + sum += s + if permutation[position] < sum { + result := time.Duration(i) * deltaStage + return &result + } + } + + return nil +} + +func schedule(sched string, N int) ([]int, error) { + switch sched { + case Schedule_AllAtOnce: + return []int{N}, nil + case Schedule_OneAtATime: + sch := []int{} + for i := 0; i < N; i++ { + sch = append(sch, 1) + } + return sch, nil + } + return nil, fmt.Errorf("unknown schedule %s", sched) +} diff --git a/core/services/workflows/execution_strategy_test.go b/core/services/workflows/execution_strategy_test.go new file mode 100644 index 00000000000..bdf782c87b9 --- /dev/null +++ b/core/services/workflows/execution_strategy_test.go @@ -0,0 +1,170 @@ +package workflows + +import ( + "crypto/rand" + "encoding/hex" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + "github.com/smartcontractkit/chainlink-common/pkg/values" + "github.com/smartcontractkit/chainlink/v2/core/logger" + p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" +) + +func assertBetween(t *testing.T, got time.Duration, low time.Duration, high time.Duration) { + assert.GreaterOrEqual(t, got, low) + assert.LessOrEqual(t, got, high) +} + +func TestScheduledExecutionStrategy_LocalDON(t *testing.T) { + var gotTime time.Time + var called bool + + // Our capability has DONInfo == nil, so we'll treat it as a local + // capability and use the local DON Info to determine the transmission + // schedule. + mt := newMockCapability( + capabilities.MustNewCapabilityInfo( + "write_polygon-testnet-mumbai", + capabilities.CapabilityTypeTarget, + "a write capability targeting polygon mumbai testnet", + "v1.0.0", + nil, + ), + func(req capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) { + gotTime = time.Now() + called = true + return capabilities.CapabilityResponse{}, nil + }, + ) + + l := logger.TestLogger(t) + + // The combination of this key and the metadata above + // will yield the permutation [3, 2, 0, 1] + key, err := hex.DecodeString("fb13ca015a9ec60089c7141e9522de79") + require.NoError(t, err) + + testCases := []struct { + name string + position int + schedule string + low time.Duration + high time.Duration + }{ + { + name: "position 0; oneAtATime", + position: 0, + schedule: "oneAtATime", + low: 300 * time.Millisecond, + high: 400 * time.Millisecond, + }, + { + name: "position 1; oneAtATime", + position: 1, + schedule: "oneAtATime", + low: 200 * time.Millisecond, + high: 300 * time.Millisecond, + }, + { + name: "position 2; oneAtATime", + position: 2, + schedule: "oneAtATime", + low: 0 * time.Millisecond, + high: 100 * time.Millisecond, + }, + { + name: "position 3; oneAtATime", + position: 3, + schedule: "oneAtATime", + low: 100 * time.Millisecond, + high: 200 * time.Millisecond, + }, + { + name: "position 0; allAtOnce", + position: 0, + schedule: "allAtOnce", + low: 0 * time.Millisecond, + high: 100 * time.Millisecond, + }, + { + name: "position 1; allAtOnce", + position: 1, + schedule: "allAtOnce", + low: 0 * time.Millisecond, + high: 100 * time.Millisecond, + }, + { + name: "position 2; allAtOnce", + position: 2, + schedule: "allAtOnce", + low: 0 * time.Millisecond, + high: 100 * time.Millisecond, + }, + { + name: "position 3; allAtOnce", + position: 3, + schedule: "allAtOnce", + low: 0 * time.Millisecond, + high: 100 * time.Millisecond, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + startTime := time.Now() + + m, err := values.NewMap(map[string]any{ + "schedule": tc.schedule, + "deltaStage": "100ms", + }) + require.NoError(t, err) + + req := capabilities.CapabilityRequest{ + Config: m, + Metadata: capabilities.RequestMetadata{ + WorkflowID: "mock-workflow-id", + WorkflowExecutionID: "mock-execution-id", + }, + } + + ids := []p2ptypes.PeerID{ + randKey(), + randKey(), + randKey(), + randKey(), + } + don := &capabilities.DON{ + Members: ids, + Config: capabilities.DONConfig{ + SharedSecret: [16]byte(key), + }, + } + peerID := ids[tc.position] + de := scheduledExecution{ + DON: don, + PeerID: &peerID, + Position: tc.position, + } + _, err = de.Apply(tests.Context(t), l, mt, req) + require.NoError(t, err) + require.True(t, called) + + assertBetween(t, gotTime.Sub(startTime), tc.low, tc.high) + }) + } +} + +func randKey() [32]byte { + key := make([]byte, 32) + _, err := rand.Read(key) + if err != nil { + panic(err) + } + return [32]byte(key) +} diff --git a/core/services/workflows/models.go b/core/services/workflows/models.go index e6c92a641e4..92abf36d2c0 100644 --- a/core/services/workflows/models.go +++ b/core/services/workflows/models.go @@ -19,10 +19,13 @@ type stepRequest struct { // // Within the workflow spec, they are called "Capability Properties". type stepDefinition struct { + // TODO: Rename this, type here refers to the capability ID, not its type. Type string `json:"type" jsonschema:"required"` Ref string `json:"ref,omitempty" jsonschema:"pattern=^[a-z0-9_]+$"` Inputs map[string]any `json:"inputs,omitempty"` Config map[string]any `json:"config" jsonschema:"required"` + + CapabilityType capabilities.CapabilityType `json:"-"` } // workflowSpec is the parsed representation of a workflow. @@ -106,9 +109,10 @@ func (w *workflow) dependents(start string) ([]*step, error) { // step wraps a stepDefinition with additional context for dependencies and execution type step struct { stepDefinition - dependencies []string - capability capabilities.CallbackExecutable - config *values.Map + dependencies []string + capability capabilities.CallbackCapability + config *values.Map + executionStrategy executionStrategy } type triggerCapability struct { diff --git a/core/services/workflows/models_yaml.go b/core/services/workflows/models_yaml.go index 396811c3729..3d65e24a814 100644 --- a/core/services/workflows/models_yaml.go +++ b/core/services/workflows/models_yaml.go @@ -10,6 +10,8 @@ import ( "github.com/invopop/jsonschema" "github.com/shopspring/decimal" "sigs.k8s.io/yaml" + + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" ) func GenerateJsonSchema() ([]byte, error) { @@ -47,22 +49,30 @@ type workflowSpecYaml struct { func (w workflowSpecYaml) toWorkflowSpec() workflowSpec { triggers := make([]stepDefinition, 0, len(w.Triggers)) for _, t := range w.Triggers { - triggers = append(triggers, t.toStepDefinition()) + sd := t.toStepDefinition() + sd.CapabilityType = capabilities.CapabilityTypeTrigger + triggers = append(triggers, sd) } actions := make([]stepDefinition, 0, len(w.Actions)) for _, a := range w.Actions { - actions = append(actions, a.toStepDefinition()) + sd := a.toStepDefinition() + sd.CapabilityType = capabilities.CapabilityTypeAction + actions = append(actions, sd) } consensus := make([]stepDefinition, 0, len(w.Consensus)) for _, c := range w.Consensus { - consensus = append(consensus, c.toStepDefinition()) + sd := c.toStepDefinition() + sd.CapabilityType = capabilities.CapabilityTypeConsensus + consensus = append(consensus, sd) } targets := make([]stepDefinition, 0, len(w.Targets)) for _, t := range w.Targets { - targets = append(targets, t.toStepDefinition()) + sd := t.toStepDefinition() + sd.CapabilityType = capabilities.CapabilityTypeTarget + targets = append(targets, sd) } return workflowSpec{ diff --git a/core/services/workflows/testdata/fixtures/workflows/marshalling/workflow_2_spec.json b/core/services/workflows/testdata/fixtures/workflows/marshalling/workflow_2_spec.json index dfa13449a48..f4024e24267 100644 --- a/core/services/workflows/testdata/fixtures/workflows/marshalling/workflow_2_spec.json +++ b/core/services/workflows/testdata/fixtures/workflows/marshalling/workflow_2_spec.json @@ -28,4 +28,4 @@ "config": {} } ] -} \ No newline at end of file +} From 1d9dd466e2933b7558949554b882f29f63d90b9f Mon Sep 17 00:00:00 2001 From: Domino Valdano Date: Thu, 25 Apr 2024 18:39:18 -0700 Subject: [PATCH 40/77] Make LogPoller more robust against local finality violations (#12605) * Reduce unnecessary code duplication getCurrentBlockMaybeHandleReorg is called just before the for loop over unfinalized blocks begins, and at the end of each iteration. Simplifying by moving them both to the beginning of the for loop * Fix bugs in TestLogPoller_BackupPollAndSaveLogsSkippingLogsThatAreTooOld This fixes 2 bugs on develop branch in this test, and removes some unused commented code. First Bug ========= The first bug was causing a false positive PASS on develop branch, which was obscuring a (very minor) bug in BackupPoller that's been fixed in this PR. The comment here about what the test was intended to test is still correct: // Only the 2nd batch + 1 log from a previous batch should be backfilled, because we perform backfill starting // from one block behind the latest finalized block Contrary to the comment, the code was returning 2 logs from the 1st batch (Data=9 & Data=10), plus 9 of 10 logs from the 2nd batch. This was incorrect behavior, but the test was also checking for the same incorrect behavior (looking for 11 logs with first one being Data=9) instead of what's described in the comment. The bug in the production code was that it starts the Backup Poller at Finalized - 1 instead of Finalized. This is a harmless "bug", just unnecessarily starting a block too early, since there's no reason for backup logpoller to re-request the same finalized logs that's already been processed. Now, the code returns the last log from the 1st batch + all but one logs from the 2nd batch, which is correct. (It can't return the last log because that goes beyond the last safe block.) So the test checks that there are 10 logs with first one being Data=10 (last log from the first batch.) Second Bug ========== The second bug was passing firstBatchBlock and secondBatchBlock directly to markBlockAsFinalized() instead of passing firstBatchBlock - 1 and secondBatchBlock - 1. This was only working because of a bug in the version of geth we're currently using: when you request the pending block from simulated geth, it gives you back the current block (1 block prior) instead of the current block. (For example, in the first case, even though we wanted block 11, the latest current block, we request block 12 and get back block 11.) This has been fixed in the latest version of geth... so presumably if we don't fix this here the test would have started failing as soon as we upgrade to the latest version of geth. It doesn't change any behavior of the test for the present version of geth, just makes it more clear that we want block 11 not 12. * Check that all results from batchFetchBlocks() are finalized aside from "latest" batchFetchBlocks() will now fetch the "finalized" block along with the rest of each batch, and validate that all of the block numbers (aside from the special when "lateest" is requested) are <= the finalized block number returned. Also, change backfill() to always save the last block of each batch of logs requested, rather than the last block of the logs returned. This only makes a difference if the last block requested has no logs matching the filter, but this change is essential for being able to safely change lastSafeBlockNumber from latestFinalizedBlock - 1 to latestFinalizedBlock * Update logpoller tests * fix merge conflict * reduce cognitive complexity * Add validationReqType type definition * Fix comments * Add Test_FetchBlocks --- .changeset/fresh-moles-explode.md | 5 + core/chains/evm/logpoller/log_poller.go | 189 +++++++++++++----- .../evm/logpoller/log_poller_internal_test.go | 136 ++++++++++++- core/chains/evm/logpoller/log_poller_test.go | 49 ++--- 4 files changed, 290 insertions(+), 89 deletions(-) create mode 100644 .changeset/fresh-moles-explode.md diff --git a/.changeset/fresh-moles-explode.md b/.changeset/fresh-moles-explode.md new file mode 100644 index 00000000000..205002b40a0 --- /dev/null +++ b/.changeset/fresh-moles-explode.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +core/chains/evm/logpoller: Stricter finality checks in LogPoller, to be more robust during rpc failover events #updated diff --git a/core/chains/evm/logpoller/log_poller.go b/core/chains/evm/logpoller/log_poller.go index de2a182bbce..7592ec104c4 100644 --- a/core/chains/evm/logpoller/log_poller.go +++ b/core/chains/evm/logpoller/log_poller.go @@ -699,8 +699,8 @@ func (lp *logPoller) BackupPollAndSaveLogs(ctx context.Context) { } return } - // If this is our first run, start from block min(lastProcessed.FinalizedBlockNumber-1, lastProcessed.BlockNumber-backupPollerBlockDelay) - backupStartBlock := mathutil.Min(lastProcessed.FinalizedBlockNumber-1, lastProcessed.BlockNumber-lp.backupPollerBlockDelay) + // If this is our first run, start from block min(lastProcessed.FinalizedBlockNumber, lastProcessed.BlockNumber-backupPollerBlockDelay) + backupStartBlock := mathutil.Min(lastProcessed.FinalizedBlockNumber, lastProcessed.BlockNumber-lp.backupPollerBlockDelay) // (or at block 0 if whole blockchain is too short) lp.backupPollerNextBlock = mathutil.Max(backupStartBlock, 0) } @@ -771,11 +771,16 @@ func convertTopics(topics []common.Hash) [][]byte { return topicsForDB } -func (lp *logPoller) blocksFromLogs(ctx context.Context, logs []types.Log) (blocks []LogPollerBlock, err error) { +// blocksFromLogs fetches all of the blocks associated with a given list of logs. It will also unconditionally fetch endBlockNumber, +// whether or not there are any logs in the list from that block +func (lp *logPoller) blocksFromLogs(ctx context.Context, logs []types.Log, endBlockNumber uint64) (blocks []LogPollerBlock, err error) { var numbers []uint64 for _, log := range logs { numbers = append(numbers, log.BlockNumber) } + if numbers[len(numbers)-1] != endBlockNumber { + numbers = append(numbers, endBlockNumber) + } return lp.GetBlocksRange(ctx, numbers) } @@ -789,6 +794,7 @@ func (lp *logPoller) backfill(ctx context.Context, start, end int64) error { batchSize := lp.backfillBatchSize for from := start; from <= end; from += batchSize { to := mathutil.Min(from+batchSize-1, end) + gethLogs, err := lp.ec.FilterLogs(ctx, lp.Filter(big.NewInt(from), big.NewInt(to), nil)) if err != nil { var rpcErr client.JsonError @@ -810,13 +816,19 @@ func (lp *logPoller) backfill(ctx context.Context, start, end int64) error { if len(gethLogs) == 0 { continue } - blocks, err := lp.blocksFromLogs(ctx, gethLogs) + blocks, err := lp.blocksFromLogs(ctx, gethLogs, uint64(to)) if err != nil { return err } + endblock := blocks[len(blocks)-1] + if gethLogs[len(gethLogs)-1].BlockNumber != uint64(to) { + // Pop endblock if there were no logs for it, so that length of blocks & gethLogs are the same to pass to convertLogs + blocks = blocks[:len(blocks)-1] + } + lp.lggr.Debugw("Backfill found logs", "from", from, "to", to, "logs", len(gethLogs), "blocks", blocks) - err = lp.orm.InsertLogsWithBlock(ctx, convertLogs(gethLogs, blocks, lp.lggr, lp.ec.ConfiguredChainID()), blocks[len(blocks)-1]) + err = lp.orm.InsertLogsWithBlock(ctx, convertLogs(gethLogs, blocks, lp.lggr, lp.ec.ConfiguredChainID()), endblock) if err != nil { lp.lggr.Warnw("Unable to insert logs, retrying", "err", err, "from", from, "to", to) return err @@ -955,19 +967,18 @@ func (lp *logPoller) PollAndSaveLogs(ctx context.Context, currentBlockNumber int currentBlockNumber = lastSafeBackfillBlock + 1 } - if currentBlockNumber > currentBlock.Number { - // If we successfully backfilled we have logs up to and including lastSafeBackfillBlock, - // now load the first unfinalized block. - currentBlock, err = lp.getCurrentBlockMaybeHandleReorg(ctx, currentBlockNumber, nil) - if err != nil { - // If there's an error handling the reorg, we can't be sure what state the db was left in. - // Resume from the latest block saved. - lp.lggr.Errorw("Unable to get current block", "err", err) - return + for { + if currentBlockNumber > currentBlock.Number { + currentBlock, err = lp.getCurrentBlockMaybeHandleReorg(ctx, currentBlockNumber, nil) + if err != nil { + // If there's an error handling the reorg, we can't be sure what state the db was left in. + // Resume from the latest block saved. + lp.lggr.Errorw("Unable to get current block", "err", err) + return + } + currentBlockNumber = currentBlock.Number } - } - for { h := currentBlock.Hash var logs []types.Log logs, err = lp.ec.FilterLogs(ctx, lp.Filter(nil, nil, &h)) @@ -992,14 +1003,6 @@ func (lp *logPoller) PollAndSaveLogs(ctx context.Context, currentBlockNumber int if currentBlockNumber > latestBlockNumber { break } - currentBlock, err = lp.getCurrentBlockMaybeHandleReorg(ctx, currentBlockNumber, nil) - if err != nil { - // If there's an error handling the reorg, we can't be sure what state the db was left in. - // Resume from the latest block saved. - lp.lggr.Errorw("Unable to get current block", "err", err) - return - } - currentBlockNumber = currentBlock.Number } } @@ -1252,12 +1255,16 @@ func (lp *logPoller) GetBlocksRange(ctx context.Context, numbers []uint64) ([]Lo return blocks, nil } +// fillRemainingBlocksFromRPC sends a batch request for each block in blocksRequested, and converts them from +// geth blocks into LogPollerBlock structs. This is only intended to be used for requesting finalized blocks, +// if any of the blocks coming back are not finalized, an error will be returned func (lp *logPoller) fillRemainingBlocksFromRPC( ctx context.Context, blocksRequested map[uint64]struct{}, blocksFound map[uint64]LogPollerBlock, ) (map[uint64]LogPollerBlock, error) { var remainingBlocks []string + for num := range blocksRequested { if _, ok := blocksFound[num]; !ok { remainingBlocks = append(remainingBlocks, hexutil.EncodeBig(new(big.Int).SetUint64(num))) @@ -1287,54 +1294,126 @@ func (lp *logPoller) fillRemainingBlocksFromRPC( return logPollerBlocks, nil } -func (lp *logPoller) batchFetchBlocks(ctx context.Context, blocksRequested []string, batchSize int64) ([]*evmtypes.Head, error) { - reqs := make([]rpc.BatchElem, 0, len(blocksRequested)) - for _, num := range blocksRequested { - req := rpc.BatchElem{ - Method: "eth_getBlockByNumber", - Args: []interface{}{num, false}, - Result: &evmtypes.Head{}, - } - reqs = append(reqs, req) +// newBlockReq constructs an eth_getBlockByNumber request for particular block number +func newBlockReq(num string) rpc.BatchElem { + return rpc.BatchElem{ + Method: "eth_getBlockByNumber", + Args: []interface{}{num, false}, + Result: &evmtypes.Head{}, } +} - for i := 0; i < len(reqs); i += int(batchSize) { - j := i + int(batchSize) - if j > len(reqs) { - j = len(reqs) - } +type blockValidationType string - err := lp.ec.BatchCallContext(ctx, reqs[i:j]) - if err != nil { - return nil, err +var ( + latestBlock blockValidationType = blockValidationType(rpc.LatestBlockNumber.String()) + finalizedBlock blockValidationType = blockValidationType(rpc.FinalizedBlockNumber.String()) +) + +// fetchBlocks fetches a list of blocks in a single batch. validationReq is the string to use for the +// additional validation request (either the "finalized" or "latest" string defined in rpc module), which +// will be used to validate the finality of the other blocks. +func (lp *logPoller) fetchBlocks(ctx context.Context, blocksRequested []string, validationReq blockValidationType) (blocks []*evmtypes.Head, err error) { + n := len(blocksRequested) + blocks = make([]*evmtypes.Head, 0, n+1) + reqs := make([]rpc.BatchElem, 0, n+1) + + validationBlockIndex := n + for k, num := range blocksRequested { + if num == string(validationReq) { + validationBlockIndex = k } + reqs = append(reqs, newBlockReq(num)) + } + + if validationBlockIndex == n { + // Add validation req if it wasn't in there already + reqs = append(reqs, newBlockReq(string(validationReq))) + } + + err = lp.ec.BatchCallContext(ctx, reqs) + if err != nil { + return nil, err } - var blocks = make([]*evmtypes.Head, 0, len(reqs)) - for _, r := range reqs { - if r.Error != nil { - return nil, r.Error + validationBlock, err := validateBlockResponse(reqs[validationBlockIndex]) + if err != nil { + return nil, err + } + latestFinalizedBlockNumber := validationBlock.Number + if validationReq == latestBlock { + // subtract finalityDepth from "latest" to get finalized, when useFinalityTags = false + latestFinalizedBlockNumber = mathutil.Max(latestFinalizedBlockNumber-lp.finalityDepth, 0) + } + if len(reqs) == n+1 { + reqs = reqs[:n] // ignore last req if we added it explicitly for validation + } + + for k, r := range reqs { + if k == validationBlockIndex { + // Already validated this one, just insert it in proper place + blocks = append(blocks, validationBlock) + continue } - block, is := r.Result.(*evmtypes.Head) - if !is { - return nil, pkgerrors.Errorf("expected result to be a %T, got %T", &evmtypes.Head{}, r.Result) + block, err2 := validateBlockResponse(r) + if err2 != nil { + return nil, err2 } - if block == nil { - return nil, pkgerrors.New("invariant violation: got nil block") + + blockRequested := r.Args[0].(string) + if blockRequested != string(latestBlock) && block.Number > latestFinalizedBlockNumber { + return nil, fmt.Errorf( + "Received unfinalized block %d while expecting finalized block (latestFinalizedBlockNumber = %d)", + block.Number, latestFinalizedBlockNumber) } - if block.Hash == (common.Hash{}) { - return nil, pkgerrors.Errorf("missing block hash for block number: %d", block.Number) + + blocks = append(blocks, block) + } + return blocks, nil +} + +func (lp *logPoller) batchFetchBlocks(ctx context.Context, blocksRequested []string, batchSize int64) ([]*evmtypes.Head, error) { + var blocks = make([]*evmtypes.Head, 0, len(blocksRequested)+1) + + validationReq := finalizedBlock + if !lp.useFinalityTag { + validationReq = latestBlock + } + + for i := 0; i < len(blocksRequested); i += int(batchSize) { + j := i + int(batchSize) + if j > len(blocksRequested) { + j = len(blocksRequested) } - if block.Number < 0 { - return nil, pkgerrors.Errorf("expected block number to be >= to 0, got %d", block.Number) + moreBlocks, err := lp.fetchBlocks(ctx, blocksRequested[i:j], validationReq) + if err != nil { + return nil, err } - blocks = append(blocks, block) + blocks = append(blocks, moreBlocks...) } return blocks, nil } +func validateBlockResponse(r rpc.BatchElem) (*evmtypes.Head, error) { + block, is := r.Result.(*evmtypes.Head) + + if !is { + return nil, pkgerrors.Errorf("expected result to be a %T, got %T", &evmtypes.Head{}, r.Result) + } + if block == nil { + return nil, pkgerrors.New("invariant violation: got nil block") + } + if block.Hash == (common.Hash{}) { + return nil, pkgerrors.Errorf("missing block hash for block number: %d", block.Number) + } + if block.Number < 0 { + return nil, pkgerrors.Errorf("expected block number to be >= to 0, got %d", block.Number) + } + return block, nil +} + // IndexedLogsWithSigsExcluding returns the set difference(A-B) of logs with signature sigA and sigB, matching is done on the topics index // // For example, query to retrieve unfulfilled requests by querying request log events without matching fulfillment log events. diff --git a/core/chains/evm/logpoller/log_poller_internal_test.go b/core/chains/evm/logpoller/log_poller_internal_test.go index b6af0f7de5c..4236f0b8ef1 100644 --- a/core/chains/evm/logpoller/log_poller_internal_test.go +++ b/core/chains/evm/logpoller/log_poller_internal_test.go @@ -2,6 +2,7 @@ package logpoller import ( "context" + "errors" "fmt" "math/big" "reflect" @@ -12,6 +13,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rpc" pkgerrors "github.com/pkg/errors" @@ -205,13 +207,14 @@ func TestLogPoller_BackupPollerStartup(t *testing.T) { chainID := testutils.FixtureChainID db := pgtest.NewSqlxDB(t) orm := NewORM(chainID, db, lggr) + latestBlock := int64(4) - head := evmtypes.Head{Number: 3} + head := evmtypes.Head{Number: latestBlock} events := []common.Hash{EmitterABI.Events["Log1"].ID} log1 := types.Log{ Index: 0, BlockHash: common.Hash{}, - BlockNumber: uint64(3), + BlockNumber: uint64(latestBlock), Topics: events, Address: addr, TxHash: common.HexToHash("0x1234"), @@ -230,20 +233,44 @@ func TestLogPoller_BackupPollerStartup(t *testing.T) { BackfillBatchSize: 3, RpcBatchSize: 2, KeepFinalizedBlocksDepth: 1000, + BackupPollerBlockDelay: 0, } lp := NewLogPoller(orm, ec, lggr, lpOpts) lp.BackupPollAndSaveLogs(ctx) assert.Equal(t, int64(0), lp.backupPollerNextBlock) assert.Equal(t, 1, observedLogs.FilterMessageSnippet("ran before first successful log poller run").Len()) - lp.PollAndSaveLogs(ctx, 3) + lp.PollAndSaveLogs(ctx, latestBlock) lastProcessed, err := lp.orm.SelectLatestBlock(ctx) require.NoError(t, err) - require.Equal(t, int64(3), lastProcessed.BlockNumber) + require.Equal(t, latestBlock, lastProcessed.BlockNumber) lp.BackupPollAndSaveLogs(ctx) - assert.Equal(t, int64(1), lp.backupPollerNextBlock) // Ensure non-negative! + assert.Equal(t, int64(2), lp.backupPollerNextBlock) +} + +func mockBatchCallContext(t *testing.T, ec *evmclimocks.Client) { + ec.On("BatchCallContext", mock.Anything, mock.Anything).Return(nil).Run(func(args mock.Arguments) { + elems := args.Get(1).([]rpc.BatchElem) + for _, e := range elems { + var num int64 + block := e.Args[0].(string) + switch block { + case "latest": + num = 8 + case "finalized": + num = 5 + default: + n, err := hexutil.DecodeUint64(block) + require.NoError(t, err) + num = int64(n) + } + result := e.Result.(*evmtypes.Head) + *result = evmtypes.Head{Number: num, Hash: utils.NewHash()} + + } + }) } func TestLogPoller_Replay(t *testing.T) { @@ -269,16 +296,20 @@ func TestLogPoller_Replay(t *testing.T) { } ec := evmclimocks.NewClient(t) - ec.On("HeadByNumber", mock.Anything, mock.Anything).Return(&head, nil) - ec.On("FilterLogs", mock.Anything, mock.Anything).Return([]types.Log{log1}, nil).Twice() + ec.On("HeadByNumber", mock.Anything, mock.Anything).Return(func(context.Context, *big.Int) (*evmtypes.Head, error) { + headCopy := head + return &headCopy, nil + }) + ec.On("FilterLogs", mock.Anything, mock.Anything).Return([]types.Log{log1}, nil).Once() ec.On("ConfiguredChainID").Return(chainID, nil) + lpOpts := Opts{ - PollPeriod: time.Hour, + PollPeriod: time.Second, FinalityDepth: 3, BackfillBatchSize: 3, RpcBatchSize: 3, KeepFinalizedBlocksDepth: 20, - BackupPollerBlockDelay: 100, + BackupPollerBlockDelay: 0, } lp := NewLogPoller(orm, ec, lggr, lpOpts) @@ -308,6 +339,8 @@ func TestLogPoller_Replay(t *testing.T) { // Replay() should return error code received from replayComplete t.Run("returns error code on replay complete", func(t *testing.T) { + ec.On("FilterLogs", mock.Anything, mock.Anything).Return([]types.Log{log1}, nil).Once() + mockBatchCallContext(t, ec) anyErr := pkgerrors.New("any error") done := make(chan struct{}) go func() { @@ -345,6 +378,7 @@ func TestLogPoller_Replay(t *testing.T) { var wg sync.WaitGroup defer func() { wg.Wait() }() ec.On("FilterLogs", mock.Anything, mock.Anything).Once().Return([]types.Log{log1}, nil).Run(func(args mock.Arguments) { + head = evmtypes.Head{Number: 4} wg.Add(1) go func() { defer wg.Done() @@ -371,6 +405,7 @@ func TestLogPoller_Replay(t *testing.T) { ec.On("FilterLogs", mock.Anything, mock.Anything).Return([]types.Log{log1}, nil).Maybe() // in case task gets delayed by >= 100ms + head = evmtypes.Head{Number: 5} t.Cleanup(lp.reset) servicetest.Run(t, lp) @@ -395,6 +430,8 @@ func TestLogPoller_Replay(t *testing.T) { ec.On("FilterLogs", mock.Anything, mock.Anything).Once().Return([]types.Log{log1}, nil).Run(func(args mock.Arguments) { go func() { defer close(done) + + head = evmtypes.Head{Number: 4} // Restore latest block to 4, so this matches the fromBlock requested select { case lp.replayStart <- 4: case <-ctx.Done(): @@ -405,9 +442,10 @@ func TestLogPoller_Replay(t *testing.T) { lp.cancel() close(pass) }) - ec.On("FilterLogs", mock.Anything, mock.Anything).Return([]types.Log{log1}, nil).Maybe() // in case task gets delayed by >= 100ms + ec.On("FilterLogs", mock.Anything, mock.Anything).Return([]types.Log{log1}, nil) t.Cleanup(lp.reset) + head = evmtypes.Head{Number: 5} // Latest block must be > lastProcessed in order for SaveAndPollLogs() to call FilterLogs() servicetest.Run(t, lp) select { @@ -420,6 +458,9 @@ func TestLogPoller_Replay(t *testing.T) { // ReplayAsync should return as soon as replayStart is received t.Run("ReplayAsync success", func(t *testing.T) { t.Cleanup(lp.reset) + head = evmtypes.Head{Number: 5} + ec.On("FilterLogs", mock.Anything, mock.Anything).Return([]types.Log{log1}, nil) + mockBatchCallContext(t, ec) servicetest.Run(t, lp) lp.ReplayAsync(1) @@ -430,6 +471,7 @@ func TestLogPoller_Replay(t *testing.T) { t.Run("ReplayAsync error", func(t *testing.T) { t.Cleanup(lp.reset) servicetest.Run(t, lp) + head = evmtypes.Head{Number: 4} anyErr := pkgerrors.New("async error") observedLogs.TakeAll() @@ -462,6 +504,9 @@ func TestLogPoller_Replay(t *testing.T) { err = lp.orm.InsertBlock(ctx, head.Hash, head.Number, head.Timestamp, head.Number) require.NoError(t, err) + ec.On("FilterLogs", mock.Anything, mock.Anything).Return([]types.Log{log1}, nil) + mockBatchCallContext(t, ec) + err = lp.Replay(ctx, 1) require.NoError(t, err) }) @@ -554,6 +599,77 @@ func Test_latestBlockAndFinalityDepth(t *testing.T) { }) } +func Test_FetchBlocks(t *testing.T) { + lggr := logger.Test(t) + chainID := testutils.FixtureChainID + db := pgtest.NewSqlxDB(t) + orm := NewORM(chainID, db, lggr) + ctx := testutils.Context(t) + + lpOpts := Opts{ + PollPeriod: time.Hour, + BackfillBatchSize: 2, + RpcBatchSize: 2, + KeepFinalizedBlocksDepth: 50, + FinalityDepth: 3, + } + + ec := evmclimocks.NewClient(t) + mockBatchCallContext(t, ec) // This will return 5 for "finalized" and 8 for "latest" + + cases := []struct { + name string + blocksRequested []string + expectedErr error + }{{ + "successful validation including finalized and latest", + []string{"0x3", "latest", "0x5", "finalized", "0x1"}, + nil, + }, { + "successful validation with all block numbers", + []string{"0x2", "0x5", "0x3", "0x4"}, + nil, + }, { + "finality violation including finalized and latest", + []string{"0x8", "0x2", "latest", "finalized"}, + errors.New("Received unfinalized block 8 while expecting finalized block (latestFinalizedBlockNumber = 5)"), + }, { + "finality violation with all block numbers", + []string{"0x9", "0x2", "finalized", "latest"}, + errors.New("Received unfinalized block 9 while expecting finalized block (latestFinalizedBlockNumber = 5)"), + }} + + lp := NewLogPoller(orm, ec, lggr, lpOpts) + for _, tc := range cases { + for _, lp.useFinalityTag = range []bool{false, true} { + blockValidationReq := latestBlock + if lp.useFinalityTag { + blockValidationReq = finalizedBlock + } + t.Run(fmt.Sprintf("%s where useFinalityTag=%t", tc.name, lp.useFinalityTag), func(t *testing.T) { + blocks, err := lp.fetchBlocks(ctx, tc.blocksRequested, blockValidationReq) + if tc.expectedErr != nil { + require.Equal(t, err.Error(), tc.expectedErr.Error()) + return // PASS + } + require.NoError(t, err) + for i, blockRequested := range tc.blocksRequested { + switch blockRequested { + case string(latestBlock): + assert.Equal(t, int64(8), blocks[i].Number) + case string(finalizedBlock): + assert.Equal(t, int64(5), blocks[i].Number) + default: + blockNum, err2 := hexutil.DecodeUint64(blockRequested) + require.NoError(t, err2) + assert.Equal(t, int64(blockNum), blocks[i].Number) + } + } + }) + } + } +} + func benchmarkFilter(b *testing.B, nFilters, nAddresses, nEvents int) { lggr := logger.Test(b) lpOpts := Opts{ diff --git a/core/chains/evm/logpoller/log_poller_test.go b/core/chains/evm/logpoller/log_poller_test.go index 2096ccf3cf4..74ec41fa85a 100644 --- a/core/chains/evm/logpoller/log_poller_test.go +++ b/core/chains/evm/logpoller/log_poller_test.go @@ -545,8 +545,6 @@ func TestLogPoller_BackupPollAndSaveLogsSkippingLogsThatAreTooOld(t *testing.T) BackupPollerBlockDelay: 1, } th := SetupTH(t, lpOpts) - //header, err := th.Client.HeaderByNumber(ctx, nil) - //require.NoError(t, err) // Emit some logs in blocks for i := 1; i <= logsBatch; i++ { @@ -559,7 +557,7 @@ func TestLogPoller_BackupPollAndSaveLogsSkippingLogsThatAreTooOld(t *testing.T) // 1 -> 2 -> ... -> firstBatchBlock firstBatchBlock := th.PollAndSaveLogs(ctx, 1) // Mark current tip of the chain as finalized (after emitting 10 logs) - markBlockAsFinalized(t, th, firstBatchBlock) + markBlockAsFinalized(t, th, firstBatchBlock-1) // Emit 2nd batch of block for i := 1; i <= logsBatch; i++ { @@ -571,7 +569,7 @@ func TestLogPoller_BackupPollAndSaveLogsSkippingLogsThatAreTooOld(t *testing.T) // 1 -> 2 -> ... -> firstBatchBlock (finalized) -> .. -> firstBatchBlock + emitted logs secondBatchBlock := th.PollAndSaveLogs(ctx, firstBatchBlock) // Mark current tip of the block as finalized (after emitting 20 logs) - markBlockAsFinalized(t, th, secondBatchBlock) + markBlockAsFinalized(t, th, secondBatchBlock-1) // Register filter err := th.LogPoller.RegisterFilter(ctx, logpoller.Filter{ @@ -595,8 +593,8 @@ func TestLogPoller_BackupPollAndSaveLogsSkippingLogsThatAreTooOld(t *testing.T) th.EmitterAddress1, ) require.NoError(t, err) - require.Len(t, logs, logsBatch+1) - require.Equal(t, hexutil.MustDecode(`0x0000000000000000000000000000000000000000000000000000000000000009`), logs[0].Data) + require.Len(t, logs, logsBatch) + require.Equal(t, hexutil.MustDecode(`0x000000000000000000000000000000000000000000000000000000000000000a`), logs[0].Data) } func TestLogPoller_BlockTimestamps(t *testing.T) { @@ -676,6 +674,7 @@ func TestLogPoller_BlockTimestamps(t *testing.T) { require.NoError(t, err) // Logs should have correct timestamps + require.NotZero(t, len(lg1)) b, _ := th.Client.BlockByHash(ctx, lg1[0].BlockHash) t.Log(len(lg1), lg1[0].BlockTimestamp) assert.Equal(t, int64(b.Time()), lg1[0].BlockTimestamp.UTC().Unix(), time1) @@ -1181,6 +1180,7 @@ func TestLogPoller_PollAndSaveLogsDeepReorg(t *testing.T) { // Check that L1_1 has a proper data payload lgs, err := th.ORM.SelectLogsByBlockRange(testutils.Context(t), 2, 2) require.NoError(t, err) + require.NotZero(t, len(lgs)) assert.Equal(t, hexutil.MustDecode(`0x0000000000000000000000000000000000000000000000000000000000000001`), lgs[0].Data) // Single block reorg and log poller not working for a while, mine blocks and progress with finalization @@ -1208,6 +1208,7 @@ func TestLogPoller_PollAndSaveLogsDeepReorg(t *testing.T) { // Expect L1_2 to be properly updated lgs, err = th.ORM.SelectLogsByBlockRange(testutils.Context(t), 2, 2) require.NoError(t, err) + require.NotZero(t, len(lgs)) assert.Equal(t, hexutil.MustDecode(`0x0000000000000000000000000000000000000000000000000000000000000002`), lgs[0].Data) th.assertHaveCanonical(t, 1, 1) th.assertDontHave(t, 2, 3) // These blocks are backfilled @@ -1301,6 +1302,7 @@ func TestLogPoller_LoadFilters(t *testing.T) { func TestLogPoller_GetBlocks_Range(t *testing.T) { t.Parallel() + lpOpts := logpoller.Opts{ UseFinalityTag: false, FinalityDepth: 2, @@ -1310,7 +1312,15 @@ func TestLogPoller_GetBlocks_Range(t *testing.T) { } th := SetupTH(t, lpOpts) - err := th.LogPoller.RegisterFilter(testutils.Context(t), logpoller.Filter{ + _, err := th.Emitter1.EmitLog1(th.Owner, []*big.Int{big.NewInt(1)}) + require.NoError(t, err) + th.Client.Commit() // Commit block #2 with log in it + + _, err = th.Emitter1.EmitLog1(th.Owner, []*big.Int{big.NewInt(2)}) + require.NoError(t, err) + th.Client.Commit() // Commit block #3 with a different log + + err = th.LogPoller.RegisterFilter(testutils.Context(t), logpoller.Filter{ Name: "GetBlocks Test", EventSigs: []common.Hash{EmitterABI.Events["Log1"].ID, EmitterABI.Events["Log2"].ID}, Addresses: []common.Address{th.EmitterAddress1, th.EmitterAddress2}, @@ -1330,16 +1340,13 @@ func TestLogPoller_GetBlocks_Range(t *testing.T) { assert.Equal(t, 1, len(blocks)) assert.Equal(t, 1, int(blocks[0].BlockNumber)) - // LP fails to retrieve block 2 because it's neither in DB nor returned by RPC + // LP fails to return block 2 because it hasn't been finalized yet blockNums = []uint64{2} _, err = th.LogPoller.GetBlocksRange(testutils.Context(t), blockNums) require.Error(t, err) - assert.Equal(t, "blocks were not found in db or RPC call: [2]", err.Error()) + assert.Equal(t, "Received unfinalized block 2 while expecting finalized block (latestFinalizedBlockNumber = 1)", err.Error()) - // Emit a log and mine block #2 - _, err = th.Emitter1.EmitLog1(th.Owner, []*big.Int{big.NewInt(1)}) - require.NoError(t, err) - th.Client.Commit() + th.Client.Commit() // Commit block #4, so that block #2 is finalized // Assert block 2 is not yet in DB _, err = th.ORM.SelectBlockByNumber(testutils.Context(t), 2) @@ -1351,10 +1358,7 @@ func TestLogPoller_GetBlocks_Range(t *testing.T) { assert.Equal(t, 1, len(rpcBlocks)) assert.Equal(t, 2, int(rpcBlocks[0].BlockNumber)) - // Emit a log and mine block #3 - _, err = th.Emitter1.EmitLog1(th.Owner, []*big.Int{big.NewInt(2)}) - require.NoError(t, err) - th.Client.Commit() + th.Client.Commit() // commit block #5 so that #3 becomes finalized // Assert block 3 is not yet in DB _, err = th.ORM.SelectBlockByNumber(testutils.Context(t), 3) @@ -1368,12 +1372,9 @@ func TestLogPoller_GetBlocks_Range(t *testing.T) { assert.Equal(t, 1, int(rpcBlocks2[0].BlockNumber)) assert.Equal(t, 3, int(rpcBlocks2[1].BlockNumber)) - // after calling PollAndSaveLogs, block 2 & 3 are persisted in DB + // after calling PollAndSaveLogs, block 3 (latest finalized block) is persisted in DB th.LogPoller.PollAndSaveLogs(testutils.Context(t), 1) - block, err := th.ORM.SelectBlockByNumber(testutils.Context(t), 2) - require.NoError(t, err) - assert.Equal(t, 2, int(block.BlockNumber)) - block, err = th.ORM.SelectBlockByNumber(testutils.Context(t), 3) + block, err := th.ORM.SelectBlockByNumber(testutils.Context(t), 3) require.NoError(t, err) assert.Equal(t, 3, int(block.BlockNumber)) @@ -1507,9 +1508,9 @@ func TestLogPoller_DBErrorHandling(t *testing.T) { time.Sleep(100 * time.Millisecond) require.NoError(t, lp.Start(ctx)) - require.Eventually(t, func() bool { + testutils.AssertEventually(t, func() bool { return observedLogs.Len() >= 1 - }, 2*time.Second, 20*time.Millisecond) + }) err = lp.Close() require.NoError(t, err) From 0c4c24ad8c95e505cd2a29be711cc40e612658b0 Mon Sep 17 00:00:00 2001 From: Christopher Dimitri Sastropranoto Date: Fri, 26 Apr 2024 12:44:17 +0700 Subject: [PATCH 41/77] Add function to remove operators in Capability Registry (#12979) * update remove operators function * address PR feedback --- .changeset/smooth-comics-love.md | 5 + contracts/.changeset/hot-weeks-agree.md | 5 + .../src/v0.8/keystone/CapabilityRegistry.sol | 14 ++ ...lityRegistry_RemoveNodeOperatorsTest.t.sol | 46 ++++++ .../keystone_capability_registry.go | 147 +++++++++++++++++- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 6 files changed, 216 insertions(+), 3 deletions(-) create mode 100644 .changeset/smooth-comics-love.md create mode 100644 contracts/.changeset/hot-weeks-agree.md create mode 100644 contracts/src/v0.8/keystone/test/CapabilityRegistry_RemoveNodeOperatorsTest.t.sol diff --git a/.changeset/smooth-comics-love.md b/.changeset/smooth-comics-love.md new file mode 100644 index 00000000000..6d41284978d --- /dev/null +++ b/.changeset/smooth-comics-love.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +update keystone gethwrapper with remove operator function #internal diff --git a/contracts/.changeset/hot-weeks-agree.md b/contracts/.changeset/hot-weeks-agree.md new file mode 100644 index 00000000000..5bd77e9ebe5 --- /dev/null +++ b/contracts/.changeset/hot-weeks-agree.md @@ -0,0 +1,5 @@ +--- +"@chainlink/contracts": patch +--- + +add function to remove node operators from capability registry diff --git a/contracts/src/v0.8/keystone/CapabilityRegistry.sol b/contracts/src/v0.8/keystone/CapabilityRegistry.sol index ad452f1606b..faedd858bef 100644 --- a/contracts/src/v0.8/keystone/CapabilityRegistry.sol +++ b/contracts/src/v0.8/keystone/CapabilityRegistry.sol @@ -34,6 +34,10 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { /// @param name The human readable name of the node operator event NodeOperatorAdded(uint256 nodeOperatorId, address indexed admin, string name); + /// @notice This event is emitted when a node operator is removed + /// @param nodeOperatorId The ID of the node operator that was removed + event NodeOperatorRemoved(uint256 nodeOperatorId); + /// @notice This event is emitted when a new capability is added /// @param capabilityId The ID of the newly added capability event CapabilityAdded(bytes32 indexed capabilityId); @@ -64,6 +68,16 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { } } + /// @notice Removes a node operator + /// @param nodeOperatorIds The IDs of the node operators to remove + function removeNodeOperators(uint256[] calldata nodeOperatorIds) external onlyOwner { + for (uint256 i; i < nodeOperatorIds.length; ++i) { + uint256 nodeOperatorId = nodeOperatorIds[i]; + delete s_nodeOperators[nodeOperatorId]; + emit NodeOperatorRemoved(nodeOperatorId); + } + } + /// @notice Gets a node operator's data /// @param nodeOperatorId The ID of the node operator to query for /// @return NodeOperator The node operator data diff --git a/contracts/src/v0.8/keystone/test/CapabilityRegistry_RemoveNodeOperatorsTest.t.sol b/contracts/src/v0.8/keystone/test/CapabilityRegistry_RemoveNodeOperatorsTest.t.sol new file mode 100644 index 00000000000..31b043fab3e --- /dev/null +++ b/contracts/src/v0.8/keystone/test/CapabilityRegistry_RemoveNodeOperatorsTest.t.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {BaseTest} from "./BaseTest.t.sol"; +import {CapabilityRegistry} from "../CapabilityRegistry.sol"; + +contract CapabilityRegistry_RemoveNodeOperatorsTest is BaseTest { + event NodeOperatorRemoved(uint256 nodeOperatorId); + + uint256 private constant TEST_NODE_OPERATOR_ONE_ID = 0; + uint256 private constant TEST_NODE_OPERATOR_TWO_ID = 1; + + function setUp() public override { + BaseTest.setUp(); + changePrank(ADMIN); + s_capabilityRegistry.addNodeOperators(_getNodeOperators()); + } + + function test_RevertWhen_CalledByNonOwner() public { + changePrank(STRANGER); + vm.expectRevert("Only callable by owner"); + uint256[] memory nodeOperatorsToRemove = new uint256[](2); + nodeOperatorsToRemove[1] = 1; + s_capabilityRegistry.removeNodeOperators(nodeOperatorsToRemove); + } + + function test_RemovesNodeOperator() public { + changePrank(ADMIN); + + vm.expectEmit(true, true, true, true, address(s_capabilityRegistry)); + emit NodeOperatorRemoved(TEST_NODE_OPERATOR_ONE_ID); + vm.expectEmit(true, true, true, true, address(s_capabilityRegistry)); + emit NodeOperatorRemoved(TEST_NODE_OPERATOR_TWO_ID); + uint256[] memory nodeOperatorsToRemove = new uint256[](2); + nodeOperatorsToRemove[1] = 1; + s_capabilityRegistry.removeNodeOperators(nodeOperatorsToRemove); + + CapabilityRegistry.NodeOperator memory nodeOperatorOne = s_capabilityRegistry.getNodeOperator(0); + assertEq(nodeOperatorOne.admin, address(0)); + assertEq(nodeOperatorOne.name, ""); + + CapabilityRegistry.NodeOperator memory nodeOperatorTwo = s_capabilityRegistry.getNodeOperator(1); + assertEq(nodeOperatorTwo.admin, address(0)); + assertEq(nodeOperatorTwo.name, ""); + } +} diff --git a/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go b/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go index ef8b252b924..47c65d5276b 100644 --- a/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go +++ b/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go @@ -41,8 +41,8 @@ type CapabilityRegistryNodeOperator struct { } var CapabilityRegistryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"InvalidNodeOperatorAdmin\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"capability\",\"type\":\"tuple\"}],\"name\":\"addCapability\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"addNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityID\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"name\":\"getCapabilityID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"getNodeOperator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b610d9e806101576000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80636e5f2869116100765780638da5cb5b1161005b5780638da5cb5b146101885780639cb7c5f4146101b0578063f2fde38b1461021757600080fd5b80636e5f28691461016d57806379ba50971461018057600080fd5b8063181f5a77146100a8578063229111f5146100f0578063398f37731461013857806365c14dc71461014d575b600080fd5b604080518082018252601881527f4361706162696c697479526567697374727920312e302e300000000000000000602082015290516100e7919061081d565b60405180910390f35b61012a6100fe366004610837565b604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b6040519081526020016100e7565b61014b610146366004610859565b61022a565b005b61016061015b3660046108ce565b6103c8565b6040516100e791906108e7565b61014b61017b36600461092a565b6104ae565b61014b61052b565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e7565b6101fc6101be3660046108ce565b604080518082019091526000808252602082015250600090815260026020908152604091829020825180840190935280548352600101549082015290565b604080518251815260209283015192810192909252016100e7565b61014b61022536600461096b565b61062d565b610232610641565b60005b818110156103c357600083838381811061025157610251610986565b905060200281019061026391906109b5565b61026c90610a9a565b805190915073ffffffffffffffffffffffffffffffffffffffff166102bd576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600454604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815260008681526003909252939020825181547fffffffffffffffffffffffff0000000000000000000000000000000000000000169216919091178155915190919060018201906103409082610bff565b5090505060046000815461035390610d19565b909155508151602083015160405173ffffffffffffffffffffffffffffffffffffffff909216917fda6697b182650034bd205cdc2dbfabb06bdb3a0a83a2b45bfefa3c4881284e0b916103a891859190610d78565b60405180910390a25050806103bc90610d19565b9050610235565b505050565b6040805180820190915260008152606060208201526000828152600360209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff168352600181018054919284019161042590610b64565b80601f016020809104026020016040519081016040528092919081815260200182805461045190610b64565b801561049e5780601f106104735761010080835404028352916020019161049e565b820191906000526020600020905b81548152906001019060200180831161048157829003601f168201915b5050505050815250509050919050565b6104b6610641565b60408051823560208083018290528085013583850181905284518085038601815260609094018086528451948301949094206000818152600290935294822092835560019092019190915582917f65610e5677eedff94555572640e442f89848a109ef8593fa927ac30b2565ff069190a25050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610635610641565b61063e816106c4565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016105a8565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610743576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016105a8565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000815180845260005b818110156107df576020818501810151868301820152016107c3565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061083060208301846107b9565b9392505050565b6000806040838503121561084a57600080fd5b50508035926020909101359150565b6000806020838503121561086c57600080fd5b823567ffffffffffffffff8082111561088457600080fd5b818501915085601f83011261089857600080fd5b8135818111156108a757600080fd5b8660208260051b85010111156108bc57600080fd5b60209290920196919550909350505050565b6000602082840312156108e057600080fd5b5035919050565b6020815273ffffffffffffffffffffffffffffffffffffffff82511660208201526000602083015160408084015261092260608401826107b9565b949350505050565b60006040828403121561093c57600080fd5b50919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461096657600080fd5b919050565b60006020828403121561097d57600080fd5b61083082610942565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126109e957600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610a4557610a456109f3565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610a9257610a926109f3565b604052919050565b600060408236031215610aac57600080fd5b610ab4610a22565b610abd83610942565b815260208084013567ffffffffffffffff80821115610adb57600080fd5b9085019036601f830112610aee57600080fd5b813581811115610b0057610b006109f3565b610b30847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610a4b565b91508082523684828501011115610b4657600080fd5b80848401858401376000908201840152918301919091525092915050565b600181811c90821680610b7857607f821691505b60208210810361093c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b601f8211156103c357600081815260208120601f850160051c81016020861015610bd85750805b601f850160051c820191505b81811015610bf757828155600101610be4565b505050505050565b815167ffffffffffffffff811115610c1957610c196109f3565b610c2d81610c278454610b64565b84610bb1565b602080601f831160018114610c805760008415610c4a5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610bf7565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015610ccd57888601518255948401946001909101908401610cae565b5085821015610d0957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610d71577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b82815260406020820152600061092260408301846107b956fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[],\"name\":\"InvalidNodeOperatorAdmin\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"NodeOperatorRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"capability\",\"type\":\"tuple\"}],\"name\":\"addCapability\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"addNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityID\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"name\":\"getCapabilityID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"getNodeOperator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint256[]\"}],\"name\":\"removeNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b610ef1806101576000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c80636e5f2869116100765780638da5cb5b1161005b5780638da5cb5b146101b65780639cb7c5f4146101de578063f2fde38b1461024557600080fd5b80636e5f28691461019b57806379ba5097146101ae57600080fd5b8063229111f5116100a7578063229111f514610120578063398f37731461016857806365c14dc71461017b57600080fd5b8063181f5a77146100c35780631cdf63431461010b575b600080fd5b604080518082018252601881527f4361706162696c697479526567697374727920312e302e300000000000000000602082015290516101029190610957565b60405180910390f35b61011e6101193660046109bd565b610258565b005b61015a61012e3660046109ff565b604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b604051908152602001610102565b61011e6101763660046109bd565b61031b565b61018e610189366004610a21565b6104b4565b6040516101029190610a3a565b61011e6101a9366004610a7d565b61059a565b61011e610617565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610102565b61022a6101ec366004610a21565b604080518082019091526000808252602082015250600090815260026020908152604091829020825180840190935280548352600101549082015290565b60408051825181526020928301519281019290925201610102565b61011e610253366004610abe565b610719565b61026061072d565b60005b8181101561031657600083838381811061027f5761027f610ad9565b60209081029290920135600081815260039093526040832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001681559093509190506102d060018301826108a5565b50506040518181527f1e5877d7b3001d1569bf733b76c7eceda58bd6c031e5b8d0b7042308ba2e9d4f9060200160405180910390a15061030f81610b08565b9050610263565b505050565b61032361072d565b60005b8181101561031657600083838381811061034257610342610ad9565b90506020028101906103549190610b67565b61035d90610c4c565b805190915073ffffffffffffffffffffffffffffffffffffffff166103ae576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600454604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815260008681526003909252939020825181547fffffffffffffffffffffffff0000000000000000000000000000000000000000169216919091178155915190919060018201906104319082610db1565b5090505060046000815461044490610b08565b909155508151602083015160405173ffffffffffffffffffffffffffffffffffffffff909216917fda6697b182650034bd205cdc2dbfabb06bdb3a0a83a2b45bfefa3c4881284e0b9161049991859190610ecb565b60405180910390a25050806104ad90610b08565b9050610326565b6040805180820190915260008152606060208201526000828152600360209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff168352600181018054919284019161051190610d16565b80601f016020809104026020016040519081016040528092919081815260200182805461053d90610d16565b801561058a5780601f1061055f5761010080835404028352916020019161058a565b820191906000526020600020905b81548152906001019060200180831161056d57829003601f168201915b5050505050815250509050919050565b6105a261072d565b60408051823560208083018290528085013583850181905284518085038601815260609094018086528451948301949094206000818152600290935294822092835560019092019190915582917f65610e5677eedff94555572640e442f89848a109ef8593fa927ac30b2565ff069190a25050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461069d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61072161072d565b61072a816107b0565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610694565b565b3373ffffffffffffffffffffffffffffffffffffffff82160361082f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610694565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b5080546108b190610d16565b6000825580601f106108c1575050565b601f01602090049060005260206000209081019061072a91905b808211156108ef57600081556001016108db565b5090565b6000815180845260005b81811015610919576020818501810151868301820152016108fd565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061096a60208301846108f3565b9392505050565b60008083601f84011261098357600080fd5b50813567ffffffffffffffff81111561099b57600080fd5b6020830191508360208260051b85010111156109b657600080fd5b9250929050565b600080602083850312156109d057600080fd5b823567ffffffffffffffff8111156109e757600080fd5b6109f385828601610971565b90969095509350505050565b60008060408385031215610a1257600080fd5b50508035926020909101359150565b600060208284031215610a3357600080fd5b5035919050565b6020815273ffffffffffffffffffffffffffffffffffffffff825116602082015260006020830151604080840152610a7560608401826108f3565b949350505050565b600060408284031215610a8f57600080fd5b50919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610ab957600080fd5b919050565b600060208284031215610ad057600080fd5b61096a82610a95565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610b60577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610b9b57600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610bf757610bf7610ba5565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610c4457610c44610ba5565b604052919050565b600060408236031215610c5e57600080fd5b610c66610bd4565b610c6f83610a95565b815260208084013567ffffffffffffffff80821115610c8d57600080fd5b9085019036601f830112610ca057600080fd5b813581811115610cb257610cb2610ba5565b610ce2847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610bfd565b91508082523684828501011115610cf857600080fd5b80848401858401376000908201840152918301919091525092915050565b600181811c90821680610d2a57607f821691505b602082108103610a8f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b601f82111561031657600081815260208120601f850160051c81016020861015610d8a5750805b601f850160051c820191505b81811015610da957828155600101610d96565b505050505050565b815167ffffffffffffffff811115610dcb57610dcb610ba5565b610ddf81610dd98454610d16565b84610d63565b602080601f831160018114610e325760008415610dfc5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610da9565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015610e7f57888601518255948401946001909101908401610e60565b5085821015610ebb57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b828152604060208201526000610a7560408301846108f356fea164736f6c6343000813000a", } var CapabilityRegistryABI = CapabilityRegistryMetaData.ABI @@ -327,6 +327,18 @@ func (_CapabilityRegistry *CapabilityRegistryTransactorSession) AddNodeOperators return _CapabilityRegistry.Contract.AddNodeOperators(&_CapabilityRegistry.TransactOpts, nodeOperators) } +func (_CapabilityRegistry *CapabilityRegistryTransactor) RemoveNodeOperators(opts *bind.TransactOpts, nodeOperatorIds []*big.Int) (*types.Transaction, error) { + return _CapabilityRegistry.contract.Transact(opts, "removeNodeOperators", nodeOperatorIds) +} + +func (_CapabilityRegistry *CapabilityRegistrySession) RemoveNodeOperators(nodeOperatorIds []*big.Int) (*types.Transaction, error) { + return _CapabilityRegistry.Contract.RemoveNodeOperators(&_CapabilityRegistry.TransactOpts, nodeOperatorIds) +} + +func (_CapabilityRegistry *CapabilityRegistryTransactorSession) RemoveNodeOperators(nodeOperatorIds []*big.Int) (*types.Transaction, error) { + return _CapabilityRegistry.Contract.RemoveNodeOperators(&_CapabilityRegistry.TransactOpts, nodeOperatorIds) +} + func (_CapabilityRegistry *CapabilityRegistryTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { return _CapabilityRegistry.contract.Transact(opts, "transferOwnership", to) } @@ -595,6 +607,123 @@ func (_CapabilityRegistry *CapabilityRegistryFilterer) ParseNodeOperatorAdded(lo return event, nil } +type CapabilityRegistryNodeOperatorRemovedIterator struct { + Event *CapabilityRegistryNodeOperatorRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CapabilityRegistryNodeOperatorRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CapabilityRegistryNodeOperatorRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CapabilityRegistryNodeOperatorRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CapabilityRegistryNodeOperatorRemovedIterator) Error() error { + return it.fail +} + +func (it *CapabilityRegistryNodeOperatorRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CapabilityRegistryNodeOperatorRemoved struct { + NodeOperatorId *big.Int + Raw types.Log +} + +func (_CapabilityRegistry *CapabilityRegistryFilterer) FilterNodeOperatorRemoved(opts *bind.FilterOpts) (*CapabilityRegistryNodeOperatorRemovedIterator, error) { + + logs, sub, err := _CapabilityRegistry.contract.FilterLogs(opts, "NodeOperatorRemoved") + if err != nil { + return nil, err + } + return &CapabilityRegistryNodeOperatorRemovedIterator{contract: _CapabilityRegistry.contract, event: "NodeOperatorRemoved", logs: logs, sub: sub}, nil +} + +func (_CapabilityRegistry *CapabilityRegistryFilterer) WatchNodeOperatorRemoved(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryNodeOperatorRemoved) (event.Subscription, error) { + + logs, sub, err := _CapabilityRegistry.contract.WatchLogs(opts, "NodeOperatorRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CapabilityRegistryNodeOperatorRemoved) + if err := _CapabilityRegistry.contract.UnpackLog(event, "NodeOperatorRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CapabilityRegistry *CapabilityRegistryFilterer) ParseNodeOperatorRemoved(log types.Log) (*CapabilityRegistryNodeOperatorRemoved, error) { + event := new(CapabilityRegistryNodeOperatorRemoved) + if err := _CapabilityRegistry.contract.UnpackLog(event, "NodeOperatorRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type CapabilityRegistryOwnershipTransferRequestedIterator struct { Event *CapabilityRegistryOwnershipTransferRequested @@ -873,6 +1002,8 @@ func (_CapabilityRegistry *CapabilityRegistry) ParseLog(log types.Log) (generate return _CapabilityRegistry.ParseCapabilityAdded(log) case _CapabilityRegistry.abi.Events["NodeOperatorAdded"].ID: return _CapabilityRegistry.ParseNodeOperatorAdded(log) + case _CapabilityRegistry.abi.Events["NodeOperatorRemoved"].ID: + return _CapabilityRegistry.ParseNodeOperatorRemoved(log) case _CapabilityRegistry.abi.Events["OwnershipTransferRequested"].ID: return _CapabilityRegistry.ParseOwnershipTransferRequested(log) case _CapabilityRegistry.abi.Events["OwnershipTransferred"].ID: @@ -891,6 +1022,10 @@ func (CapabilityRegistryNodeOperatorAdded) Topic() common.Hash { return common.HexToHash("0xda6697b182650034bd205cdc2dbfabb06bdb3a0a83a2b45bfefa3c4881284e0b") } +func (CapabilityRegistryNodeOperatorRemoved) Topic() common.Hash { + return common.HexToHash("0x1e5877d7b3001d1569bf733b76c7eceda58bd6c031e5b8d0b7042308ba2e9d4f") +} + func (CapabilityRegistryOwnershipTransferRequested) Topic() common.Hash { return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") } @@ -920,6 +1055,8 @@ type CapabilityRegistryInterface interface { AddNodeOperators(opts *bind.TransactOpts, nodeOperators []CapabilityRegistryNodeOperator) (*types.Transaction, error) + RemoveNodeOperators(opts *bind.TransactOpts, nodeOperatorIds []*big.Int) (*types.Transaction, error) + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) FilterCapabilityAdded(opts *bind.FilterOpts, capabilityId [][32]byte) (*CapabilityRegistryCapabilityAddedIterator, error) @@ -934,6 +1071,12 @@ type CapabilityRegistryInterface interface { ParseNodeOperatorAdded(log types.Log) (*CapabilityRegistryNodeOperatorAdded, error) + FilterNodeOperatorRemoved(opts *bind.FilterOpts) (*CapabilityRegistryNodeOperatorRemovedIterator, error) + + WatchNodeOperatorRemoved(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryNodeOperatorRemoved) (event.Subscription, error) + + ParseNodeOperatorRemoved(log types.Log) (*CapabilityRegistryNodeOperatorRemoved, error) + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CapabilityRegistryOwnershipTransferRequestedIterator, error) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) diff --git a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 836eb3e68b7..62a75a8a644 100644 --- a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,4 +1,4 @@ GETH_VERSION: 1.13.8 forwarder: ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.bin b4c900aae9e022f01abbac7993d41f93912247613ac6270b0c4da4ef6f2016e3 -keystone_capability_registry: ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.abi ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.bin 579334dfcb59da4221823735dc815116745b488ddde327199367e04457aac808 +keystone_capability_registry: ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.abi ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.bin 9eaa36e45c1b33c1fa72b7e25d6d1ca351413225611abb84ae053270b569cca4 ocr3_capability: ../../../contracts/solc/v0.8.19/OCR3Capability/OCR3Capability.abi ../../../contracts/solc/v0.8.19/OCR3Capability/OCR3Capability.bin 9dcbdf55bd5729ba266148da3f17733eb592c871c2108ccca546618628fd9ad2 From 8c8994e24284236645509b4c49152e6270ce0e35 Mon Sep 17 00:00:00 2001 From: george-dorin <120329946+george-dorin@users.noreply.github.com> Date: Fri, 26 Apr 2024 15:55:40 +0300 Subject: [PATCH 42/77] Validate config on NewApplication (#12997) * validate config on new application spawn * Add changeset * Check config only in the rebroadcast-transactions command --- .changeset/pink-schools-provide.md | 5 +++++ core/cmd/shell_local.go | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 .changeset/pink-schools-provide.md diff --git a/.changeset/pink-schools-provide.md b/.changeset/pink-schools-provide.md new file mode 100644 index 00000000000..6b2aa5ea0c4 --- /dev/null +++ b/.changeset/pink-schools-provide.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#bugfix Fixed an issue where the `rebroadcast-transactions` commands did not execute config validation. diff --git a/core/cmd/shell_local.go b/core/cmd/shell_local.go index 6dbffbe404a..24cb43e2090 100644 --- a/core/cmd/shell_local.go +++ b/core/cmd/shell_local.go @@ -580,6 +580,11 @@ func (s *Shell) RebroadcastTransactions(c *cli.Context) (err error) { } } + err = s.Config.Validate() + if err != nil { + return err + } + lggr := logger.Sugared(s.Logger.Named("RebroadcastTransactions")) db, err := pg.OpenUnlockedDB(s.Config.AppID(), s.Config.Database()) if err != nil { From f55d8be495a83c97ac5439672563400e12ec2ee7 Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 26 Apr 2024 10:10:40 -0400 Subject: [PATCH 43/77] Configurable Mercury transmitter parameters (#12680) * Configurable Mercury transmitter parameters * Changeset * Remove commented code * add tag * Rename --- .changeset/sour-jars-cross.md | 13 ++++++ core/cmd/shell.go | 5 ++- core/config/docs/core.toml | 14 +++++++ core/config/mercury_config.go | 7 ++++ core/config/toml/types.go | 20 ++++++++- core/internal/cltest/cltest.go | 3 +- core/services/chainlink/config_mercury.go | 21 ++++++++++ core/services/chainlink/config_test.go | 8 ++++ core/services/chainlink/relayer_factory.go | 9 ++-- .../testdata/config-empty-effective.toml | 4 ++ .../chainlink/testdata/config-full.toml | 4 ++ .../config-multi-chain-effective.toml | 4 ++ core/services/ocr2/delegate.go | 1 + core/services/relay/evm/evm.go | 25 ++++++----- .../services/relay/evm/mercury/transmitter.go | 27 +++++++----- .../relay/evm/mercury/transmitter_test.go | 42 ++++++++++++------- .../evm/mercury/wsrpc/pb/mercury_wsrpc.pb.go | 1 + .../testdata/config-empty-effective.toml | 4 ++ core/web/resolver/testdata/config-full.toml | 4 ++ .../config-multi-chain-effective.toml | 4 ++ docs/CONFIG.md | 27 ++++++++++++ testdata/scripts/node/validate/default.txtar | 4 ++ .../disk-based-logging-disabled.txtar | 4 ++ .../validate/disk-based-logging-no-dir.txtar | 4 ++ .../node/validate/disk-based-logging.txtar | 4 ++ .../node/validate/invalid-ocr-p2p.txtar | 4 ++ testdata/scripts/node/validate/invalid.txtar | 4 ++ testdata/scripts/node/validate/valid.txtar | 4 ++ testdata/scripts/node/validate/warnings.txtar | 4 ++ 29 files changed, 234 insertions(+), 45 deletions(-) create mode 100644 .changeset/sour-jars-cross.md diff --git a/.changeset/sour-jars-cross.md b/.changeset/sour-jars-cross.md new file mode 100644 index 00000000000..b904e8e3dd0 --- /dev/null +++ b/.changeset/sour-jars-cross.md @@ -0,0 +1,13 @@ +--- +"chainlink": patch +--- + +#added + +Add configurability to mercury transmitter + +```toml +[Mercury.Transmitter] +TransmitQueueMaxSize = 10_000 # Default +TransmitTimeout = "5s" # Default +``` diff --git a/core/cmd/shell.go b/core/cmd/shell.go index 0372148e742..adbb66ce63f 100644 --- a/core/cmd/shell.go +++ b/core/cmd/shell.go @@ -174,8 +174,9 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G } evmFactoryCfg := chainlink.EVMFactoryConfig{ - CSAETHKeystore: keyStore, - ChainOpts: legacyevm.ChainOpts{AppConfig: cfg, MailMon: mailMon, DS: ds}, + CSAETHKeystore: keyStore, + ChainOpts: legacyevm.ChainOpts{AppConfig: cfg, MailMon: mailMon, DS: ds}, + MercuryTransmitter: cfg.Mercury().Transmitter(), } // evm always enabled for backward compatibility // TODO BCF-2510 this needs to change in order to clear the path for EVM extraction diff --git a/core/config/docs/core.toml b/core/config/docs/core.toml index 605f6ced0bc..92d75430daf 100644 --- a/core/config/docs/core.toml +++ b/core/config/docs/core.toml @@ -622,3 +622,17 @@ LatestReportDeadline = "5s" # Default [Mercury.TLS] # CertFile is the path to a PEM file of trusted root certificate authority certificates CertFile = "/path/to/client/certs.pem" # Example + +# Mercury.Transmitter controls settings for the mercury transmitter +[Mercury.Transmitter] +# TransmitQueueMaxSize controls the size of the transmit queue. This is scoped +# per OCR instance. If the queue is full, the transmitter will start dropping +# the oldest messages in order to make space. +# +# This is useful if mercury server goes offline and the nop needs to buffer +# transmissions. +TransmitQueueMaxSize = 10_000 # Default +# TransmitTimeout controls how long the transmitter will wait for a response +# when sending a message to the mercury server, before aborting and considering +# the transmission to be failed. +TransmitTimeout = "5s" # Default diff --git a/core/config/mercury_config.go b/core/config/mercury_config.go index 1210fd282ef..f16fc4661a5 100644 --- a/core/config/mercury_config.go +++ b/core/config/mercury_config.go @@ -3,6 +3,7 @@ package config import ( "time" + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/types" ) @@ -16,8 +17,14 @@ type MercuryTLS interface { CertFile() string } +type MercuryTransmitter interface { + TransmitQueueMaxSize() uint32 + TransmitTimeout() commonconfig.Duration +} + type Mercury interface { Credentials(credName string) *types.MercuryCredentials Cache() MercuryCache TLS() MercuryTLS + Transmitter() MercuryTransmitter } diff --git a/core/config/toml/types.go b/core/config/toml/types.go index ed52c21e34e..ba74528b3b6 100644 --- a/core/config/toml/types.go +++ b/core/config/toml/types.go @@ -1312,14 +1312,30 @@ func (m *MercuryTLS) ValidateConfig() (err error) { return } +type MercuryTransmitter struct { + TransmitQueueMaxSize *uint32 + TransmitTimeout *commonconfig.Duration +} + +func (m *MercuryTransmitter) setFrom(f *MercuryTransmitter) { + if v := f.TransmitQueueMaxSize; v != nil { + m.TransmitQueueMaxSize = v + } + if v := f.TransmitTimeout; v != nil { + m.TransmitTimeout = v + } +} + type Mercury struct { - Cache MercuryCache `toml:",omitempty"` - TLS MercuryTLS `toml:",omitempty"` + Cache MercuryCache `toml:",omitempty"` + TLS MercuryTLS `toml:",omitempty"` + Transmitter MercuryTransmitter `toml:",omitempty"` } func (m *Mercury) setFrom(f *Mercury) { m.Cache.setFrom(&f.Cache) m.TLS.setFrom(&f.TLS) + m.Transmitter.setFrom(&f.Transmitter) } func (m *Mercury) ValidateConfig() (err error) { diff --git a/core/internal/cltest/cltest.go b/core/internal/cltest/cltest.go index dc7079e44d9..58cedbb96e1 100644 --- a/core/internal/cltest/cltest.go +++ b/core/internal/cltest/cltest.go @@ -369,7 +369,8 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn MailMon: mailMon, DS: ds, }, - CSAETHKeystore: keyStore, + CSAETHKeystore: keyStore, + MercuryTransmitter: cfg.Mercury().Transmitter(), } if cfg.EVMEnabled() { diff --git a/core/services/chainlink/config_mercury.go b/core/services/chainlink/config_mercury.go index 27303a68899..1b64e0bde45 100644 --- a/core/services/chainlink/config_mercury.go +++ b/core/services/chainlink/config_mercury.go @@ -3,6 +3,7 @@ package chainlink import ( "time" + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/config" @@ -25,6 +26,8 @@ func (m *mercuryCacheConfig) LatestReportDeadline() time.Duration { return m.c.LatestReportDeadline.Duration() } +var _ config.MercuryTLS = (*mercuryTLSConfig)(nil) + type mercuryTLSConfig struct { c toml.MercuryTLS } @@ -33,6 +36,20 @@ func (m *mercuryTLSConfig) CertFile() string { return *m.c.CertFile } +var _ config.MercuryTransmitter = (*mercuryTransmitterConfig)(nil) + +type mercuryTransmitterConfig struct { + c toml.MercuryTransmitter +} + +func (m *mercuryTransmitterConfig) TransmitQueueMaxSize() uint32 { + return *m.c.TransmitQueueMaxSize +} + +func (m *mercuryTransmitterConfig) TransmitTimeout() commonconfig.Duration { + return *m.c.TransmitTimeout +} + type mercuryConfig struct { c toml.Mercury s toml.MercurySecrets @@ -60,3 +77,7 @@ func (m *mercuryConfig) Cache() config.MercuryCache { func (m *mercuryConfig) TLS() config.MercuryTLS { return &mercuryTLSConfig{c: m.c.TLS} } + +func (m *mercuryConfig) Transmitter() config.MercuryTransmitter { + return &mercuryTransmitterConfig{c: m.c.Transmitter} +} diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index d02948fd07b..0d40697345d 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -710,6 +710,10 @@ func TestConfig_Marshal(t *testing.T) { TLS: toml.MercuryTLS{ CertFile: ptr("/path/to/cert.pem"), }, + Transmitter: toml.MercuryTransmitter{ + TransmitQueueMaxSize: ptr(uint32(123)), + TransmitTimeout: commoncfg.MustNewDuration(234 * time.Second), + }, } for _, tt := range []struct { @@ -1165,6 +1169,10 @@ LatestReportDeadline = '1m42s' [Mercury.TLS] CertFile = '/path/to/cert.pem' + +[Mercury.Transmitter] +TransmitQueueMaxSize = 123 +TransmitTimeout = '3m54s' `}, {"full", full, fullTOML}, {"multi-chain", multiChain, multiChainTOML}, diff --git a/core/services/chainlink/relayer_factory.go b/core/services/chainlink/relayer_factory.go index 00db81cce37..31645b7c54d 100644 --- a/core/services/chainlink/relayer_factory.go +++ b/core/services/chainlink/relayer_factory.go @@ -19,6 +19,7 @@ import ( "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/config" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" + coreconfig "github.com/smartcontractkit/chainlink/v2/core/config" "github.com/smartcontractkit/chainlink/v2/core/config/env" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" @@ -38,6 +39,7 @@ type RelayerFactory struct { type EVMFactoryConfig struct { legacyevm.ChainOpts evmrelay.CSAETHKeystore + coreconfig.MercuryTransmitter } func (r *RelayerFactory) NewEVM(ctx context.Context, config EVMFactoryConfig) (map[types.RelayID]evmrelay.LoopRelayAdapter, error) { @@ -67,9 +69,10 @@ func (r *RelayerFactory) NewEVM(ctx context.Context, config EVMFactoryConfig) (m } relayerOpts := evmrelay.RelayerOpts{ - DS: ccOpts.DS, - CSAETHKeystore: config.CSAETHKeystore, - MercuryPool: r.MercuryPool, + DS: ccOpts.DS, + CSAETHKeystore: config.CSAETHKeystore, + MercuryPool: r.MercuryPool, + TransmitterConfig: config.MercuryTransmitter, } relayer, err2 := evmrelay.NewRelayer(lggr.Named(relayID.ChainID), chain, relayerOpts) if err2 != nil { diff --git a/core/services/chainlink/testdata/config-empty-effective.toml b/core/services/chainlink/testdata/config-empty-effective.toml index 759a380d15c..38c3ed62017 100644 --- a/core/services/chainlink/testdata/config-empty-effective.toml +++ b/core/services/chainlink/testdata/config-empty-effective.toml @@ -230,6 +230,10 @@ LatestReportDeadline = '5s' [Mercury.TLS] CertFile = '' +[Mercury.Transmitter] +TransmitQueueMaxSize = 10000 +TransmitTimeout = '5s' + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml index 8a016149e59..b199ae530f5 100644 --- a/core/services/chainlink/testdata/config-full.toml +++ b/core/services/chainlink/testdata/config-full.toml @@ -240,6 +240,10 @@ LatestReportDeadline = '1m42s' [Mercury.TLS] CertFile = '/path/to/cert.pem' +[Mercury.Transmitter] +TransmitQueueMaxSize = 123 +TransmitTimeout = '3m54s' + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 13 diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml index a6cba2aaac3..7aa3bb50b35 100644 --- a/core/services/chainlink/testdata/config-multi-chain-effective.toml +++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml @@ -230,6 +230,10 @@ LatestReportDeadline = '5s' [Mercury.TLS] CertFile = '' +[Mercury.Transmitter] +TransmitQueueMaxSize = 10000 +TransmitTimeout = '5s' + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index dbde65efe40..4e1eb0cc623 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -198,6 +198,7 @@ type mercuryConfig interface { Credentials(credName string) *types.MercuryCredentials Cache() coreconfig.MercuryCache TLS() coreconfig.MercuryTLS + Transmitter() coreconfig.MercuryTransmitter } type thresholdConfig interface { diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index 9097c217590..737a8e7561e 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -78,7 +78,8 @@ type Relayer struct { codec commontypes.Codec // Mercury - mercuryORM mercury.ORM + mercuryORM mercury.ORM + transmitterCfg mercury.TransmitterConfig // LLO/data streams cdcFactory llo.ChannelDefinitionCacheFactory @@ -93,7 +94,8 @@ type CSAETHKeystore interface { type RelayerOpts struct { DS sqlutil.DataSource CSAETHKeystore - MercuryPool wsrpc.Pool + MercuryPool wsrpc.Pool + TransmitterConfig mercury.TransmitterConfig } func (c RelayerOpts) Validate() error { @@ -122,14 +124,15 @@ func NewRelayer(lggr logger.Logger, chain legacyevm.Chain, opts RelayerOpts) (*R lloORM := llo.NewORM(opts.DS, chain.ID()) cdcFactory := llo.NewChannelDefinitionCacheFactory(lggr, lloORM, chain.LogPoller()) return &Relayer{ - ds: opts.DS, - chain: chain, - lggr: lggr, - ks: opts.CSAETHKeystore, - mercuryPool: opts.MercuryPool, - cdcFactory: cdcFactory, - lloORM: lloORM, - mercuryORM: mercuryORM, + ds: opts.DS, + chain: chain, + lggr: lggr, + ks: opts.CSAETHKeystore, + mercuryPool: opts.MercuryPool, + cdcFactory: cdcFactory, + lloORM: lloORM, + mercuryORM: mercuryORM, + transmitterCfg: opts.TransmitterConfig, }, nil } @@ -246,7 +249,7 @@ func (r *Relayer) NewMercuryProvider(rargs commontypes.RelayArgs, pargs commonty default: return nil, fmt.Errorf("invalid feed version %d", feedID.Version()) } - transmitter := mercury.NewTransmitter(lggr, clients, privKey.PublicKey, rargs.JobID, *relayConfig.FeedID, r.mercuryORM, transmitterCodec) + transmitter := mercury.NewTransmitter(lggr, r.transmitterCfg, clients, privKey.PublicKey, rargs.JobID, *relayConfig.FeedID, r.mercuryORM, transmitterCodec) return NewMercuryProvider(cp, r.chainReader, r.codec, NewMercuryChainReader(r.chain.HeadTracker()), transmitter, reportCodecV1, reportCodecV2, reportCodecV3, lggr), nil } diff --git a/core/services/relay/evm/mercury/transmitter.go b/core/services/relay/evm/mercury/transmitter.go index 6f49ca91bfc..82a76450e5f 100644 --- a/core/services/relay/evm/mercury/transmitter.go +++ b/core/services/relay/evm/mercury/transmitter.go @@ -23,6 +23,7 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/types/mercury" @@ -33,12 +34,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/utils" ) -var ( - maxTransmitQueueSize = 10_000 - maxDeleteQueueSize = 10_000 - transmitTimeout = 5 * time.Second -) - const ( // Mercury server error codes DuplicateReport = 2 @@ -104,9 +99,15 @@ type TransmitterReportDecoder interface { var _ Transmitter = (*mercuryTransmitter)(nil) +type TransmitterConfig interface { + TransmitQueueMaxSize() uint32 + TransmitTimeout() commonconfig.Duration +} + type mercuryTransmitter struct { services.StateMachine lggr logger.Logger + cfg TransmitterConfig servers map[string]*server @@ -142,6 +143,8 @@ func getPayloadTypes() abi.Arguments { type server struct { lggr logger.Logger + transmitTimeout time.Duration + c wsrpc.Client pm *PersistenceManager q *TransmitQueue @@ -221,7 +224,7 @@ func (s *server) runQueueLoop(stopCh services.StopChan, wg *sync.WaitGroup, feed // queue was closed return } - ctx, cancel := context.WithTimeout(runloopCtx, utils.WithJitter(transmitTimeout)) + ctx, cancel := context.WithTimeout(runloopCtx, utils.WithJitter(s.transmitTimeout)) res, err := s.c.Transmit(ctx, t.Req) cancel() if runloopCtx.Err() != nil { @@ -272,18 +275,19 @@ func (s *server) runQueueLoop(stopCh services.StopChan, wg *sync.WaitGroup, feed } } -func NewTransmitter(lggr logger.Logger, clients map[string]wsrpc.Client, fromAccount ed25519.PublicKey, jobID int32, feedID [32]byte, orm ORM, codec TransmitterReportDecoder) *mercuryTransmitter { +func NewTransmitter(lggr logger.Logger, cfg TransmitterConfig, clients map[string]wsrpc.Client, fromAccount ed25519.PublicKey, jobID int32, feedID [32]byte, orm ORM, codec TransmitterReportDecoder) *mercuryTransmitter { feedIDHex := fmt.Sprintf("0x%x", feedID[:]) servers := make(map[string]*server, len(clients)) for serverURL, client := range clients { cLggr := lggr.Named(serverURL).With("serverURL", serverURL) - pm := NewPersistenceManager(cLggr, serverURL, orm, jobID, maxTransmitQueueSize, flushDeletesFrequency, pruneFrequency) + pm := NewPersistenceManager(cLggr, serverURL, orm, jobID, int(cfg.TransmitQueueMaxSize()), flushDeletesFrequency, pruneFrequency) servers[serverURL] = &server{ cLggr, + cfg.TransmitTimeout().Duration(), client, pm, - NewTransmitQueue(cLggr, serverURL, feedIDHex, maxTransmitQueueSize, pm), - make(chan *pb.TransmitRequest, maxDeleteQueueSize), + NewTransmitQueue(cLggr, serverURL, feedIDHex, int(cfg.TransmitQueueMaxSize()), pm), + make(chan *pb.TransmitRequest, int(cfg.TransmitQueueMaxSize())), transmitSuccessCount.WithLabelValues(feedIDHex, serverURL), transmitDuplicateCount.WithLabelValues(feedIDHex, serverURL), transmitConnectionErrorCount.WithLabelValues(feedIDHex, serverURL), @@ -295,6 +299,7 @@ func NewTransmitter(lggr logger.Logger, clients map[string]wsrpc.Client, fromAcc return &mercuryTransmitter{ services.StateMachine{}, lggr.Named("MercuryTransmitter").With("feedID", feedIDHex), + cfg, servers, codec, feedID, diff --git a/core/services/relay/evm/mercury/transmitter_test.go b/core/services/relay/evm/mercury/transmitter_test.go index 46bf116ed3a..b0da9bea635 100644 --- a/core/services/relay/evm/mercury/transmitter_test.go +++ b/core/services/relay/evm/mercury/transmitter_test.go @@ -4,6 +4,7 @@ import ( "context" "math/big" "testing" + "time" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/pkg/errors" @@ -12,6 +13,7 @@ import ( ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -21,6 +23,16 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" ) +type mockCfg struct{} + +func (m mockCfg) TransmitQueueMaxSize() uint32 { + return 10_000 +} + +func (m mockCfg) TransmitTimeout() commonconfig.Duration { + return *commonconfig.MustNewDuration(1 * time.Hour) +} + func Test_MercuryTransmitter_Transmit(t *testing.T) { lggr := logger.TestLogger(t) db := pgtest.NewSqlxDB(t) @@ -36,7 +48,7 @@ func Test_MercuryTransmitter_Transmit(t *testing.T) { report := sampleV1Report c := &mocks.MockWSRPCClient{} clients[sURL] = c - mt := NewTransmitter(lggr, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) + mt := NewTransmitter(lggr, mockCfg{}, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) // init the queue since we skipped starting transmitter mt.servers[sURL].q.Init([]*Transmission{}) err := mt.Transmit(testutils.Context(t), sampleReportContext, report, sampleSigs) @@ -50,7 +62,7 @@ func Test_MercuryTransmitter_Transmit(t *testing.T) { report := sampleV2Report c := &mocks.MockWSRPCClient{} clients[sURL] = c - mt := NewTransmitter(lggr, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) + mt := NewTransmitter(lggr, mockCfg{}, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) // init the queue since we skipped starting transmitter mt.servers[sURL].q.Init([]*Transmission{}) err := mt.Transmit(testutils.Context(t), sampleReportContext, report, sampleSigs) @@ -64,7 +76,7 @@ func Test_MercuryTransmitter_Transmit(t *testing.T) { report := sampleV3Report c := &mocks.MockWSRPCClient{} clients[sURL] = c - mt := NewTransmitter(lggr, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) + mt := NewTransmitter(lggr, mockCfg{}, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) // init the queue since we skipped starting transmitter mt.servers[sURL].q.Init([]*Transmission{}) err := mt.Transmit(testutils.Context(t), sampleReportContext, report, sampleSigs) @@ -83,7 +95,7 @@ func Test_MercuryTransmitter_Transmit(t *testing.T) { clients[sURL2] = c clients[sURL3] = c - mt := NewTransmitter(lggr, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) + mt := NewTransmitter(lggr, mockCfg{}, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) // init the queue since we skipped starting transmitter mt.servers[sURL].q.Init([]*Transmission{}) mt.servers[sURL2].q.Init([]*Transmission{}) @@ -125,7 +137,7 @@ func Test_MercuryTransmitter_LatestTimestamp(t *testing.T) { }, } clients[sURL] = c - mt := NewTransmitter(lggr, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) + mt := NewTransmitter(lggr, mockCfg{}, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) ts, err := mt.LatestTimestamp(testutils.Context(t)) require.NoError(t, err) @@ -141,7 +153,7 @@ func Test_MercuryTransmitter_LatestTimestamp(t *testing.T) { }, } clients[sURL] = c - mt := NewTransmitter(lggr, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) + mt := NewTransmitter(lggr, mockCfg{}, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) ts, err := mt.LatestTimestamp(testutils.Context(t)) require.NoError(t, err) @@ -155,7 +167,7 @@ func Test_MercuryTransmitter_LatestTimestamp(t *testing.T) { }, } clients[sURL] = c - mt := NewTransmitter(lggr, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) + mt := NewTransmitter(lggr, mockCfg{}, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) _, err := mt.LatestTimestamp(testutils.Context(t)) require.Error(t, err) assert.Contains(t, err.Error(), "something exploded") @@ -185,7 +197,7 @@ func Test_MercuryTransmitter_LatestTimestamp(t *testing.T) { return out, nil }, } - mt := NewTransmitter(lggr, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) + mt := NewTransmitter(lggr, mockCfg{}, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) ts, err := mt.LatestTimestamp(testutils.Context(t)) require.NoError(t, err) @@ -228,7 +240,7 @@ func Test_MercuryTransmitter_LatestPrice(t *testing.T) { }, } clients[sURL] = c - mt := NewTransmitter(lggr, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) + mt := NewTransmitter(lggr, mockCfg{}, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) t.Run("BenchmarkPriceFromReport succeeds", func(t *testing.T) { codec.val = originalPrice @@ -259,7 +271,7 @@ func Test_MercuryTransmitter_LatestPrice(t *testing.T) { }, } clients[sURL] = c - mt := NewTransmitter(lggr, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) + mt := NewTransmitter(lggr, mockCfg{}, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) price, err := mt.LatestPrice(testutils.Context(t), sampleFeedID) require.NoError(t, err) @@ -273,7 +285,7 @@ func Test_MercuryTransmitter_LatestPrice(t *testing.T) { }, } clients[sURL] = c - mt := NewTransmitter(lggr, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) + mt := NewTransmitter(lggr, mockCfg{}, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) _, err := mt.LatestPrice(testutils.Context(t), sampleFeedID) require.Error(t, err) assert.Contains(t, err.Error(), "something exploded") @@ -303,7 +315,7 @@ func Test_MercuryTransmitter_FetchInitialMaxFinalizedBlockNumber(t *testing.T) { }, } clients[sURL] = c - mt := NewTransmitter(lggr, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) + mt := NewTransmitter(lggr, mockCfg{}, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) bn, err := mt.FetchInitialMaxFinalizedBlockNumber(testutils.Context(t)) require.NoError(t, err) @@ -319,7 +331,7 @@ func Test_MercuryTransmitter_FetchInitialMaxFinalizedBlockNumber(t *testing.T) { }, } clients[sURL] = c - mt := NewTransmitter(lggr, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) + mt := NewTransmitter(lggr, mockCfg{}, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) bn, err := mt.FetchInitialMaxFinalizedBlockNumber(testutils.Context(t)) require.NoError(t, err) @@ -332,7 +344,7 @@ func Test_MercuryTransmitter_FetchInitialMaxFinalizedBlockNumber(t *testing.T) { }, } clients[sURL] = c - mt := NewTransmitter(lggr, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) + mt := NewTransmitter(lggr, mockCfg{}, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) _, err := mt.FetchInitialMaxFinalizedBlockNumber(testutils.Context(t)) require.Error(t, err) assert.Contains(t, err.Error(), "something exploded") @@ -350,7 +362,7 @@ func Test_MercuryTransmitter_FetchInitialMaxFinalizedBlockNumber(t *testing.T) { }, } clients[sURL] = c - mt := NewTransmitter(lggr, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) + mt := NewTransmitter(lggr, mockCfg{}, clients, sampleClientPubKey, jobID, sampleFeedID, orm, codec) _, err := mt.FetchInitialMaxFinalizedBlockNumber(testutils.Context(t)) require.Error(t, err) assert.Contains(t, err.Error(), "latestReport failed; mismatched feed IDs, expected: 0x1c916b4aa7e57ca7b68ae1bf45653f56b656fd3aa335ef7fae696b663f1b8472, got: 0x") diff --git a/core/services/relay/evm/mercury/wsrpc/pb/mercury_wsrpc.pb.go b/core/services/relay/evm/mercury/wsrpc/pb/mercury_wsrpc.pb.go index 4d05db4380f..0c31a1d7ac9 100644 --- a/core/services/relay/evm/mercury/wsrpc/pb/mercury_wsrpc.pb.go +++ b/core/services/relay/evm/mercury/wsrpc/pb/mercury_wsrpc.pb.go @@ -11,6 +11,7 @@ import ( ) // MercuryClient is the client API for Mercury service. +// type MercuryClient interface { Transmit(ctx context.Context, in *TransmitRequest) (*TransmitResponse, error) LatestReport(ctx context.Context, in *LatestReportRequest) (*LatestReportResponse, error) diff --git a/core/web/resolver/testdata/config-empty-effective.toml b/core/web/resolver/testdata/config-empty-effective.toml index 759a380d15c..38c3ed62017 100644 --- a/core/web/resolver/testdata/config-empty-effective.toml +++ b/core/web/resolver/testdata/config-empty-effective.toml @@ -230,6 +230,10 @@ LatestReportDeadline = '5s' [Mercury.TLS] CertFile = '' +[Mercury.Transmitter] +TransmitQueueMaxSize = 10000 +TransmitTimeout = '5s' + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml index 69d56974130..75fad4d2fc9 100644 --- a/core/web/resolver/testdata/config-full.toml +++ b/core/web/resolver/testdata/config-full.toml @@ -240,6 +240,10 @@ LatestReportDeadline = '1m42s' [Mercury.TLS] CertFile = '' +[Mercury.Transmitter] +TransmitQueueMaxSize = 123 +TransmitTimeout = '3m54s' + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 13 diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml index a6cba2aaac3..7aa3bb50b35 100644 --- a/core/web/resolver/testdata/config-multi-chain-effective.toml +++ b/core/web/resolver/testdata/config-multi-chain-effective.toml @@ -230,6 +230,10 @@ LatestReportDeadline = '5s' [Mercury.TLS] CertFile = '' +[Mercury.Transmitter] +TransmitQueueMaxSize = 10000 +TransmitTimeout = '5s' + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 0596fcdd84d..f93d990413f 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -1698,6 +1698,33 @@ CertFile = "/path/to/client/certs.pem" # Example ``` CertFile is the path to a PEM file of trusted root certificate authority certificates +## Mercury.Transmitter +```toml +[Mercury.Transmitter] +TransmitQueueMaxSize = 10_000 # Default +TransmitTimeout = "5s" # Default +``` +Mercury.Transmitter controls settings for the mercury transmitter + +### TransmitQueueMaxSize +```toml +TransmitQueueMaxSize = 10_000 # Default +``` +TransmitQueueMaxSize controls the size of the transmit queue. This is scoped +per OCR instance. If the queue is full, the transmitter will start dropping +the oldest messages in order to make space. + +This is useful if mercury server goes offline and the nop needs to buffer +transmissions. + +### TransmitTimeout +```toml +TransmitTimeout = "5s" # Default +``` +TransmitTimeout controls how long the transmitter will wait for a response +when sending a message to the mercury server, before aborting and considering +the transmission to be failed. + ## EVM EVM defaults depend on ChainID: diff --git a/testdata/scripts/node/validate/default.txtar b/testdata/scripts/node/validate/default.txtar index dd3af5f91b6..a8e8e41750d 100644 --- a/testdata/scripts/node/validate/default.txtar +++ b/testdata/scripts/node/validate/default.txtar @@ -242,6 +242,10 @@ LatestReportDeadline = '5s' [Mercury.TLS] CertFile = '' +[Mercury.Transmitter] +TransmitQueueMaxSize = 10000 +TransmitTimeout = '5s' + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar index 15a476460da..feaf546f022 100644 --- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar @@ -286,6 +286,10 @@ LatestReportDeadline = '5s' [Mercury.TLS] CertFile = '' +[Mercury.Transmitter] +TransmitQueueMaxSize = 10000 +TransmitTimeout = '5s' + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar index cc8b4577bfb..b37fed41150 100644 --- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar +++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar @@ -286,6 +286,10 @@ LatestReportDeadline = '5s' [Mercury.TLS] CertFile = '' +[Mercury.Transmitter] +TransmitQueueMaxSize = 10000 +TransmitTimeout = '5s' + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar index c578d200923..6ae02ab38f4 100644 --- a/testdata/scripts/node/validate/disk-based-logging.txtar +++ b/testdata/scripts/node/validate/disk-based-logging.txtar @@ -286,6 +286,10 @@ LatestReportDeadline = '5s' [Mercury.TLS] CertFile = '' +[Mercury.Transmitter] +TransmitQueueMaxSize = 10000 +TransmitTimeout = '5s' + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar index 91ae520532d..45c97477bd5 100644 --- a/testdata/scripts/node/validate/invalid-ocr-p2p.txtar +++ b/testdata/scripts/node/validate/invalid-ocr-p2p.txtar @@ -271,6 +271,10 @@ LatestReportDeadline = '5s' [Mercury.TLS] CertFile = '' +[Mercury.Transmitter] +TransmitQueueMaxSize = 10000 +TransmitTimeout = '5s' + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar index a5e4b766b6e..df0118bbbbf 100644 --- a/testdata/scripts/node/validate/invalid.txtar +++ b/testdata/scripts/node/validate/invalid.txtar @@ -276,6 +276,10 @@ LatestReportDeadline = '5s' [Mercury.TLS] CertFile = '' +[Mercury.Transmitter] +TransmitQueueMaxSize = 10000 +TransmitTimeout = '5s' + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar index c220d7f2e5f..edb07fd5e4f 100644 --- a/testdata/scripts/node/validate/valid.txtar +++ b/testdata/scripts/node/validate/valid.txtar @@ -283,6 +283,10 @@ LatestReportDeadline = '5s' [Mercury.TLS] CertFile = '' +[Mercury.Transmitter] +TransmitQueueMaxSize = 10000 +TransmitTimeout = '5s' + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 diff --git a/testdata/scripts/node/validate/warnings.txtar b/testdata/scripts/node/validate/warnings.txtar index 018aaf95f4c..cf121e959e1 100644 --- a/testdata/scripts/node/validate/warnings.txtar +++ b/testdata/scripts/node/validate/warnings.txtar @@ -265,6 +265,10 @@ LatestReportDeadline = '5s' [Mercury.TLS] CertFile = '' +[Mercury.Transmitter] +TransmitQueueMaxSize = 10000 +TransmitTimeout = '5s' + [Capabilities] [Capabilities.Peering] IncomingMessageBufferSize = 10 From 27d941328655e0cde608c1eff47de736c11e2e58 Mon Sep 17 00:00:00 2001 From: Dmytro Haidashenko <34754799+dhaidashenko@users.noreply.github.com> Date: Fri, 26 Apr 2024 16:28:55 +0200 Subject: [PATCH 44/77] LogPoller CLI command to resolve reorg greater than finality depth (#12867) * find lca and remove block after CLI * fix sort.Find typo * make RemoveBlocks local cmd * tests * added changeset * added tags to the changeset * fixed tests * make cmds, vars cases consistent --- .changeset/brave-dots-breathe.md | 7 ++ core/chains/evm/logpoller/disabled.go | 8 ++ core/chains/evm/logpoller/log_poller.go | 99 +++++++++++++++ core/chains/evm/logpoller/log_poller_test.go | 116 ++++++++++++++++++ core/chains/evm/logpoller/mocks/log_poller.go | 48 ++++++++ core/chains/evm/logpoller/observability.go | 6 + core/chains/evm/logpoller/orm.go | 9 ++ core/chains/evm/logpoller/orm_test.go | 30 +++++ core/cmd/blocks_commands.go | 58 +++++++++ core/cmd/blocks_commands_test.go | 25 ++++ core/cmd/shell_local.go | 79 ++++++++++++ core/cmd/shell_local_test.go | 56 +++++++++ core/internal/mocks/application.go | 50 ++++++++ core/services/chainlink/application.go | 43 +++++++ core/web/api.go | 2 +- core/web/lca_controller.go | 74 +++++++++++ core/web/lca_controller_test.go | 29 +++++ core/web/router.go | 2 + testdata/scripts/blocks/help.txtar | 3 +- testdata/scripts/help-all/help-all.txtar | 2 + testdata/scripts/node/help.txtar | 1 + 21 files changed, 745 insertions(+), 2 deletions(-) create mode 100644 .changeset/brave-dots-breathe.md create mode 100644 core/web/lca_controller.go create mode 100644 core/web/lca_controller_test.go diff --git a/.changeset/brave-dots-breathe.md b/.changeset/brave-dots-breathe.md new file mode 100644 index 00000000000..f1ae4f4d21e --- /dev/null +++ b/.changeset/brave-dots-breathe.md @@ -0,0 +1,7 @@ +--- +"chainlink": minor +--- + +Added a new CLI command, `blocks find-lca,` which finds the latest block that is available in both the database and on the chain for the specified chain. +Added a new CLI command, `node remove-blocks,` which removes all blocks and logs greater than or equal to the specified block number. +#nops #added diff --git a/core/chains/evm/logpoller/disabled.go b/core/chains/evm/logpoller/disabled.go index f3e64378384..6f95b9c55da 100644 --- a/core/chains/evm/logpoller/disabled.go +++ b/core/chains/evm/logpoller/disabled.go @@ -114,3 +114,11 @@ func (d disabled) LatestBlockByEventSigsAddrsWithConfs(ctx context.Context, from func (d disabled) LogsDataWordBetween(ctx context.Context, eventSig common.Hash, address common.Address, wordIndexMin, wordIndexMax int, wordValue common.Hash, confs Confirmations) ([]Log, error) { return nil, ErrDisabled } + +func (d disabled) FindLCA(ctx context.Context) (*LogPollerBlock, error) { + return nil, ErrDisabled +} + +func (d disabled) DeleteLogsAndBlocksAfter(ctx context.Context, start int64) error { + return ErrDisabled +} diff --git a/core/chains/evm/logpoller/log_poller.go b/core/chains/evm/logpoller/log_poller.go index 7592ec104c4..cd26889627f 100644 --- a/core/chains/evm/logpoller/log_poller.go +++ b/core/chains/evm/logpoller/log_poller.go @@ -44,6 +44,8 @@ type LogPoller interface { GetFilters() map[string]Filter LatestBlock(ctx context.Context) (LogPollerBlock, error) GetBlocksRange(ctx context.Context, numbers []uint64) ([]LogPollerBlock, error) + FindLCA(ctx context.Context) (*LogPollerBlock, error) + DeleteLogsAndBlocksAfter(ctx context.Context, start int64) error // General querying Logs(ctx context.Context, start, end int64, eventSig common.Hash, address common.Address) ([]Log, error) @@ -1422,6 +1424,103 @@ func (lp *logPoller) IndexedLogsWithSigsExcluding(ctx context.Context, address c return lp.orm.SelectIndexedLogsWithSigsExcluding(ctx, eventSigA, eventSigB, topicIndex, address, fromBlock, toBlock, confs) } +// DeleteLogsAndBlocksAfter - removes blocks and logs starting from the specified block +func (lp *logPoller) DeleteLogsAndBlocksAfter(ctx context.Context, start int64) error { + return lp.orm.DeleteLogsAndBlocksAfter(ctx, start) +} + +func (lp *logPoller) FindLCA(ctx context.Context) (*LogPollerBlock, error) { + latest, err := lp.orm.SelectLatestBlock(ctx) + if err != nil { + return nil, fmt.Errorf("failed to select the latest block: %w", err) + } + + oldest, err := lp.orm.SelectOldestBlock(ctx, 0) + if err != nil { + return nil, fmt.Errorf("failed to select the oldest block: %w", err) + } + + if latest == nil || oldest == nil { + return nil, fmt.Errorf("expected at least one block to be present in DB") + } + + lp.lggr.Debugf("Received request to find LCA. Searching in range [%d, %d]", oldest.BlockNumber, latest.BlockNumber) + + // Find the largest block number for which block hash stored in the DB matches one that we get from the RPC. + // `sort.Find` expects slice of following format s = [1, 0, -1] and returns smallest index i for which s[i] = 0. + // To utilise `sort.Find` we represent range of blocks as slice [latestBlock, latestBlock-1, ..., olderBlock+1, oldestBlock] + // and return 1 if DB block was reorged or 0 if it's still present on chain. + lcaI, found := sort.Find(int(latest.BlockNumber-oldest.BlockNumber)+1, func(i int) int { + const notFound = 1 + const found = 0 + // if there is an error - stop the search + if err != nil { + return notFound + } + + // canceled search + if ctx.Err() != nil { + err = fmt.Errorf("aborted, FindLCA request cancelled: %w", ctx.Err()) + return notFound + } + iBlockNumber := latest.BlockNumber - int64(i) + var dbBlock *LogPollerBlock + // Block with specified block number might not exist in the database, to address that we check closest child + // of the iBlockNumber. If the child is present on chain, it's safe to assume that iBlockNumber is present too + dbBlock, err = lp.orm.SelectOldestBlock(ctx, iBlockNumber) + if err != nil { + err = fmt.Errorf("failed to select block %d by number: %w", iBlockNumber, err) + return notFound + } + + if dbBlock == nil { + err = fmt.Errorf("expected block to exist with blockNumber >= %d as observed block with number %d", iBlockNumber, latest.BlockNumber) + return notFound + } + + lp.lggr.Debugf("Looking for matching block on chain blockNumber: %d blockHash: %s", + dbBlock.BlockNumber, dbBlock.BlockHash) + var chainBlock *evmtypes.Head + chainBlock, err = lp.ec.HeadByHash(ctx, dbBlock.BlockHash) + // our block in DB does not exist on chain + if (chainBlock == nil && err == nil) || errors.Is(err, ethereum.NotFound) { + err = nil + return notFound + } + if err != nil { + err = fmt.Errorf("failed to get block %s from RPC: %w", dbBlock.BlockHash, err) + return notFound + } + + if chainBlock.BlockNumber() != dbBlock.BlockNumber { + err = fmt.Errorf("expected block numbers to match (db: %d, chain: %d), if block hashes match "+ + "(db: %s, chain: %s)", dbBlock.BlockNumber, chainBlock.BlockNumber(), dbBlock.BlockHash, chainBlock.Hash) + return notFound + } + + return found + }) + if err != nil { + return nil, fmt.Errorf("failed to find: %w", err) + } + + if !found { + return nil, fmt.Errorf("failed to find LCA, this means that whole database LogPoller state was reorged out of chain or RPC/Core node is misconfigured") + } + + lcaBlockNumber := latest.BlockNumber - int64(lcaI) + lca, err := lp.orm.SelectBlockByNumber(ctx, lcaBlockNumber) + if err != nil { + return nil, fmt.Errorf("failed to select lca from db: %w", err) + } + + if lca == nil { + return nil, fmt.Errorf("expected lca (blockNum: %d) to exist in DB", lcaBlockNumber) + } + + return lca, nil +} + func EvmWord(i uint64) common.Hash { var b = make([]byte, 8) binary.BigEndian.PutUint64(b, i) diff --git a/core/chains/evm/logpoller/log_poller_test.go b/core/chains/evm/logpoller/log_poller_test.go index 74ec41fa85a..cb211043a4c 100644 --- a/core/chains/evm/logpoller/log_poller_test.go +++ b/core/chains/evm/logpoller/log_poller_test.go @@ -1921,3 +1921,119 @@ func markBlockAsFinalizedByHash(t *testing.T, th TestHarness, blockHash common.H require.NoError(t, err) th.Client.Blockchain().SetFinalized(b.Header()) } + +func TestFindLCA(t *testing.T) { + ctx := testutils.Context(t) + ec := evmtest.NewEthClientMockWithDefaultChain(t) + lggr := logger.Test(t) + chainID := testutils.NewRandomEVMChainID() + db := pgtest.NewSqlxDB(t) + + orm := logpoller.NewORM(chainID, db, lggr) + + lpOpts := logpoller.Opts{ + PollPeriod: time.Hour, + FinalityDepth: 2, + BackfillBatchSize: 20, + RpcBatchSize: 10, + KeepFinalizedBlocksDepth: 1000, + } + + lp := logpoller.NewLogPoller(orm, ec, lggr, lpOpts) + t.Run("Fails, if failed to select oldest block", func(t *testing.T) { + _, err := lp.FindLCA(ctx) + require.ErrorContains(t, err, "failed to select the latest block") + }) + // oldest + require.NoError(t, orm.InsertBlock(ctx, common.HexToHash("0x123"), 10, time.Now(), 0)) + // latest + latestBlockHash := common.HexToHash("0x124") + require.NoError(t, orm.InsertBlock(ctx, latestBlockHash, 16, time.Now(), 0)) + t.Run("Fails, if caller's context canceled", func(t *testing.T) { + lCtx, cancel := context.WithCancel(ctx) + ec.On("HeadByHash", mock.Anything, latestBlockHash).Return(nil, nil).Run(func(_ mock.Arguments) { + cancel() + }).Once() + _, err := lp.FindLCA(lCtx) + require.ErrorContains(t, err, "aborted, FindLCA request cancelled") + + }) + t.Run("Fails, if RPC returns an error", func(t *testing.T) { + expectedError := fmt.Errorf("failed to call RPC") + ec.On("HeadByHash", mock.Anything, latestBlockHash).Return(nil, expectedError).Once() + _, err := lp.FindLCA(ctx) + require.ErrorContains(t, err, expectedError.Error()) + }) + t.Run("Fails, if block numbers do not match", func(t *testing.T) { + ec.On("HeadByHash", mock.Anything, latestBlockHash).Return(&evmtypes.Head{ + Number: 123, + }, nil).Once() + _, err := lp.FindLCA(ctx) + require.ErrorContains(t, err, "expected block numbers to match") + }) + t.Run("Fails, if none of the blocks in db matches on chain", func(t *testing.T) { + ec.On("HeadByHash", mock.Anything, mock.Anything).Return(nil, nil).Times(3) + _, err := lp.FindLCA(ctx) + require.ErrorContains(t, err, "failed to find LCA, this means that whole database LogPoller state was reorged out of chain or RPC/Core node is misconfigured") + }) + + type block struct { + BN int + Exists bool + } + testCases := []struct { + Name string + Blocks []block + ExpectedBlockNumber int + ExpectedError error + }{ + { + Name: "All of the blocks are present on chain - returns the latest", + Blocks: []block{{BN: 1, Exists: true}, {BN: 2, Exists: true}, {BN: 3, Exists: true}, {BN: 4, Exists: true}}, + ExpectedBlockNumber: 4, + }, + { + Name: "None of the blocks exists on chain - returns an erro", + Blocks: []block{{BN: 1, Exists: false}, {BN: 2, Exists: false}, {BN: 3, Exists: false}, {BN: 4, Exists: false}}, + ExpectedBlockNumber: 0, + ExpectedError: fmt.Errorf("failed to find LCA, this means that whole database LogPoller state was reorged out of chain or RPC/Core node is misconfigured"), + }, + { + Name: "Only latest block does not exist", + Blocks: []block{{BN: 1, Exists: true}, {BN: 2, Exists: true}, {BN: 3, Exists: true}, {BN: 4, Exists: false}}, + ExpectedBlockNumber: 3, + }, + { + Name: "Only oldest block exists on chain", + Blocks: []block{{BN: 1, Exists: true}, {BN: 2, Exists: false}, {BN: 3, Exists: false}, {BN: 4, Exists: false}}, + ExpectedBlockNumber: 1, + }, + } + + blockHashI := int64(0) + for _, tc := range testCases { + t.Run(tc.Name, func(t *testing.T) { + // reset the database + require.NoError(t, orm.DeleteLogsAndBlocksAfter(ctx, 0)) + for _, b := range tc.Blocks { + blockHashI++ + hash := common.BigToHash(big.NewInt(blockHashI)) + require.NoError(t, orm.InsertBlock(ctx, hash, int64(b.BN), time.Now(), 0)) + // Hashes are unique for all test cases + var onChainBlock *evmtypes.Head + if b.Exists { + onChainBlock = &evmtypes.Head{Number: int64(b.BN)} + } + ec.On("HeadByHash", mock.Anything, hash).Return(onChainBlock, nil).Maybe() + } + + result, err := lp.FindLCA(ctx) + if tc.ExpectedError != nil { + require.ErrorContains(t, err, tc.ExpectedError.Error()) + } else { + require.NotNil(t, result) + require.Equal(t, result.BlockNumber, int64(tc.ExpectedBlockNumber), "expected block numbers to match") + } + }) + } +} diff --git a/core/chains/evm/logpoller/mocks/log_poller.go b/core/chains/evm/logpoller/mocks/log_poller.go index 548e9ca3b90..ef3f4dbd428 100644 --- a/core/chains/evm/logpoller/mocks/log_poller.go +++ b/core/chains/evm/logpoller/mocks/log_poller.go @@ -37,6 +37,54 @@ func (_m *LogPoller) Close() error { return r0 } +// DeleteLogsAndBlocksAfter provides a mock function with given fields: ctx, start +func (_m *LogPoller) DeleteLogsAndBlocksAfter(ctx context.Context, start int64) error { + ret := _m.Called(ctx, start) + + if len(ret) == 0 { + panic("no return value specified for DeleteLogsAndBlocksAfter") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok { + r0 = rf(ctx, start) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// FindLCA provides a mock function with given fields: ctx +func (_m *LogPoller) FindLCA(ctx context.Context) (*logpoller.LogPollerBlock, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for FindLCA") + } + + var r0 *logpoller.LogPollerBlock + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*logpoller.LogPollerBlock, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *logpoller.LogPollerBlock); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*logpoller.LogPollerBlock) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // GetBlocksRange provides a mock function with given fields: ctx, numbers func (_m *LogPoller) GetBlocksRange(ctx context.Context, numbers []uint64) ([]logpoller.LogPollerBlock, error) { ret := _m.Called(ctx, numbers) diff --git a/core/chains/evm/logpoller/observability.go b/core/chains/evm/logpoller/observability.go index 14dec5274ad..8f3cdfe185e 100644 --- a/core/chains/evm/logpoller/observability.go +++ b/core/chains/evm/logpoller/observability.go @@ -151,6 +151,12 @@ func (o *ObservedORM) SelectLatestBlock(ctx context.Context) (*LogPollerBlock, e }) } +func (o *ObservedORM) SelectOldestBlock(ctx context.Context, minAllowedBlockNumber int64) (*LogPollerBlock, error) { + return withObservedQuery(o, "SelectOldestBlock", func() (*LogPollerBlock, error) { + return o.ORM.SelectOldestBlock(ctx, minAllowedBlockNumber) + }) +} + func (o *ObservedORM) SelectLatestLogByEventSigWithConfs(ctx context.Context, eventSig common.Hash, address common.Address, confs Confirmations) (*Log, error) { return withObservedQuery(o, "SelectLatestLogByEventSigWithConfs", func() (*Log, error) { return o.ORM.SelectLatestLogByEventSigWithConfs(ctx, eventSig, address, confs) diff --git a/core/chains/evm/logpoller/orm.go b/core/chains/evm/logpoller/orm.go index 838a38c8ebb..5e0a74a9183 100644 --- a/core/chains/evm/logpoller/orm.go +++ b/core/chains/evm/logpoller/orm.go @@ -38,6 +38,7 @@ type ORM interface { SelectBlockByNumber(ctx context.Context, blockNumber int64) (*LogPollerBlock, error) SelectBlockByHash(ctx context.Context, hash common.Hash) (*LogPollerBlock, error) SelectLatestBlock(ctx context.Context) (*LogPollerBlock, error) + SelectOldestBlock(ctx context.Context, minAllowedBlockNumber int64) (*LogPollerBlock, error) SelectLogs(ctx context.Context, start, end int64, address common.Address, eventSig common.Hash) ([]Log, error) SelectLogsWithSigs(ctx context.Context, start, end int64, address common.Address, eventSigs []common.Hash) ([]Log, error) @@ -202,6 +203,14 @@ func (o *DSORM) SelectLatestBlock(ctx context.Context) (*LogPollerBlock, error) return &b, nil } +func (o *DSORM) SelectOldestBlock(ctx context.Context, minAllowedBlockNumber int64) (*LogPollerBlock, error) { + var b LogPollerBlock + if err := o.ds.GetContext(ctx, &b, `SELECT * FROM evm.log_poller_blocks WHERE evm_chain_id = $1 AND block_number >= $2 ORDER BY block_number ASC LIMIT 1`, ubig.New(o.chainID), minAllowedBlockNumber); err != nil { + return nil, err + } + return &b, nil +} + func (o *DSORM) SelectLatestLogByEventSigWithConfs(ctx context.Context, eventSig common.Hash, address common.Address, confs Confirmations) (*Log, error) { args, err := newQueryArgsForEvent(o.chainID, address, eventSig). withConfs(confs). diff --git a/core/chains/evm/logpoller/orm_test.go b/core/chains/evm/logpoller/orm_test.go index 8a45ff2f1c5..2a1be62dd5b 100644 --- a/core/chains/evm/logpoller/orm_test.go +++ b/core/chains/evm/logpoller/orm_test.go @@ -1759,3 +1759,33 @@ func Benchmark_DeleteExpiredLogs(b *testing.B) { assert.NoError(b, err1) } } + +func TestSelectOldestBlock(t *testing.T) { + th := SetupTH(t, lpOpts) + o1 := th.ORM + o2 := th.ORM2 + ctx := testutils.Context(t) + t.Run("Selects oldest within given chain", func(t *testing.T) { + // insert blocks + require.NoError(t, o2.InsertBlock(ctx, common.HexToHash("0x1231"), 11, time.Now(), 0)) + require.NoError(t, o2.InsertBlock(ctx, common.HexToHash("0x1232"), 12, time.Now(), 0)) + // insert newer block from different chain + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x1233"), 13, time.Now(), 0)) + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x1231"), 14, time.Now(), 0)) + block, err := o1.SelectOldestBlock(ctx, 0) + require.NoError(t, err) + require.NotNil(t, block) + require.Equal(t, block.BlockNumber, int64(13)) + require.Equal(t, block.BlockHash, common.HexToHash("0x1233")) + }) + t.Run("Does not select blocks older than specified limit", func(t *testing.T) { + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x1232"), 11, time.Now(), 0)) + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x1233"), 13, time.Now(), 0)) + require.NoError(t, o1.InsertBlock(ctx, common.HexToHash("0x1234"), 15, time.Now(), 0)) + block, err := o1.SelectOldestBlock(ctx, 12) + require.NoError(t, err) + require.NotNil(t, block) + require.Equal(t, block.BlockNumber, int64(13)) + require.Equal(t, block.BlockHash, common.HexToHash("0x1233")) + }) +} diff --git a/core/cmd/blocks_commands.go b/core/cmd/blocks_commands.go index 72b0523e18d..158caf253ab 100644 --- a/core/cmd/blocks_commands.go +++ b/core/cmd/blocks_commands.go @@ -9,6 +9,8 @@ import ( "github.com/pkg/errors" "github.com/urfave/cli" "go.uber.org/multierr" + + "github.com/smartcontractkit/chainlink/v2/core/web" ) func initBlocksSubCmds(s *Shell) []cli.Command { @@ -34,6 +36,18 @@ func initBlocksSubCmds(s *Shell) []cli.Command { }, }, }, + { + Name: "find-lca", + Usage: "Find latest common block stored in DB and on chain", + Action: s.FindLCA, + Flags: []cli.Flag{ + cli.Int64Flag{ + Name: "evm-chain-id", + Usage: "Chain ID of the EVM-based blockchain", + Required: true, + }, + }, + }, } } @@ -75,3 +89,47 @@ func (s *Shell) ReplayFromBlock(c *cli.Context) (err error) { fmt.Println("Replay started") return nil } + +// LCAPresenter implements TableRenderer for an LCAResponse. +type LCAPresenter struct { + web.LCAResponse +} + +// ToRow presents the EVMChainResource as a slice of strings. +func (p *LCAPresenter) ToRow() []string { + return []string{p.EVMChainID.String(), p.Hash, strconv.FormatInt(p.BlockNumber, 10)} +} + +// RenderTable implements TableRenderer +// Just renders a single row +func (p LCAPresenter) RenderTable(rt RendererTable) error { + renderList([]string{"ChainID", "Block Hash", "Block Number"}, [][]string{p.ToRow()}, rt.Writer) + + return nil +} + +// FindLCA finds last common block stored in DB and on chain. +func (s *Shell) FindLCA(c *cli.Context) (err error) { + v := url.Values{} + + if c.IsSet("evm-chain-id") { + v.Add("evmChainID", fmt.Sprintf("%d", c.Int64("evm-chain-id"))) + } + + resp, err := s.HTTP.Get(s.ctx(), + fmt.Sprintf( + "/v2/find_lca?%s", + v.Encode(), + )) + if err != nil { + return s.errorOut(err) + } + + defer func() { + if cerr := resp.Body.Close(); cerr != nil { + err = multierr.Append(err, cerr) + } + }() + + return s.renderAPIResponse(resp, &LCAPresenter{}, "Last Common Ancestor") +} diff --git a/core/cmd/blocks_commands_test.go b/core/cmd/blocks_commands_test.go index 30540748cb1..f7656b94ae1 100644 --- a/core/cmd/blocks_commands_test.go +++ b/core/cmd/blocks_commands_test.go @@ -41,3 +41,28 @@ func Test_ReplayFromBlock(t *testing.T) { c = cli.NewContext(nil, set, nil) require.NoError(t, client.ReplayFromBlock(c)) } + +func Test_FindLCA(t *testing.T) { + t.Parallel() + + //ethClient.On("BalanceAt", mock.Anything, mock.Anything, mock.Anything).Return(big.NewInt(42), nil) + app := startNewApplicationV2(t, func(c *chainlink.Config, s *chainlink.Secrets) { + c.EVM[0].ChainID = (*ubig.Big)(big.NewInt(5)) + c.EVM[0].Enabled = ptr(true) + }) + + client, _ := app.NewShellAndRenderer() + + set := flag.NewFlagSet("test", 0) + flagSetApplyFromAction(client.FindLCA, set, "") + + //Incorrect chain ID + require.NoError(t, set.Set("evm-chain-id", "1")) + c := cli.NewContext(nil, set, nil) + require.ErrorContains(t, client.FindLCA(c), "does not match any local chains") + + //Correct chain ID + require.NoError(t, set.Set("evm-chain-id", "5")) + c = cli.NewContext(nil, set, nil) + require.ErrorContains(t, client.FindLCA(c), "FindLCA is only available if LogPoller is enabled") +} diff --git a/core/cmd/shell_local.go b/core/cmd/shell_local.go index 24cb43e2090..7c9c025d4be 100644 --- a/core/cmd/shell_local.go +++ b/core/cmd/shell_local.go @@ -34,6 +34,7 @@ import ( "github.com/jmoiron/sqlx" cutils "github.com/smartcontractkit/chainlink-common/pkg/utils" + "github.com/smartcontractkit/chainlink/v2/core/build" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" @@ -253,6 +254,23 @@ func initLocalSubCmds(s *Shell, safe bool) []cli.Command { }, }, }, + { + Name: "remove-blocks", + Usage: "Deletes block range and all associated data", + Action: s.RemoveBlocks, + Flags: []cli.Flag{ + cli.IntFlag{ + Name: "start", + Usage: "Beginning of block range to be deleted", + Required: true, + }, + cli.Int64Flag{ + Name: "evm-chain-id", + Usage: "Chain ID of the EVM-based blockchain", + Required: true, + }, + }, + }, } } @@ -1180,3 +1198,64 @@ func insertFixtures(dbURL url.URL, pathToFixtures string) (err error) { _, err = db.Exec(string(fixturesSQL)) return err } + +// RemoveBlocks - removes blocks after the specified blocks number +func (s *Shell) RemoveBlocks(c *cli.Context) error { + start := c.Int64("start") + if start <= 0 { + return s.errorOut(errors.New("Must pass a positive value in '--start' parameter")) + } + + chainID := big.NewInt(0) + if c.IsSet("evm-chain-id") { + err := chainID.UnmarshalText([]byte(c.String("evm-chain-id"))) + if err != nil { + return s.errorOut(err) + } + } + + cfg := s.Config + err := cfg.Validate() + if err != nil { + return s.errorOut(fmt.Errorf("error validating configuration: %+v", err)) + } + + lggr := logger.Sugared(s.Logger.Named("RemoveBlocks")) + ldb := pg.NewLockedDB(cfg.AppID(), cfg.Database(), cfg.Database().Lock(), lggr) + ctx, cancel := context.WithCancel(context.Background()) + go shutdown.HandleShutdown(func(sig string) { + cancel() + lggr.Info("received signal to stop - closing the database and releasing lock") + + if cErr := ldb.Close(); cErr != nil { + lggr.Criticalf("Failed to close LockedDB: %v", cErr) + } + + if cErr := s.CloseLogger(); cErr != nil { + log.Printf("Failed to close Logger: %v", cErr) + } + }) + + if err = ldb.Open(ctx); err != nil { + // If not successful, we know neither locks nor connection remains opened + return s.errorOut(errors.Wrap(err, "opening db")) + } + defer lggr.ErrorIfFn(ldb.Close, "Error closing db") + + // From now on, DB locks and DB connection will be released on every return. + // Keep watching on logger.Fatal* calls and os.Exit(), because defer will not be executed. + + app, err := s.AppFactory.NewApplication(ctx, s.Config, s.Logger, ldb.DB()) + if err != nil { + return s.errorOut(errors.Wrap(err, "fatal error instantiating application")) + } + + err = app.DeleteLogPollerDataAfter(ctx, chainID, start) + if err != nil { + return s.errorOut(err) + } + + lggr.Infof("RemoveBlocks: successfully removed blocks") + + return nil +} diff --git a/core/cmd/shell_local_test.go b/core/cmd/shell_local_test.go index 7427e6caedb..e7322e513ae 100644 --- a/core/cmd/shell_local_test.go +++ b/core/cmd/shell_local_test.go @@ -2,6 +2,7 @@ package cmd_test import ( "flag" + "fmt" "math/big" "os" "strconv" @@ -514,3 +515,58 @@ func TestShell_CleanupChainTables(t *testing.T) { c := cli.NewContext(nil, set, nil) require.NoError(t, client.CleanupChainTables(c)) } + +func TestShell_RemoveBlocks(t *testing.T) { + db := pgtest.NewSqlxDB(t) + cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { + s.Password.Keystore = models.NewSecret("dummy") + c.EVM[0].Nodes[0].Name = ptr("fake") + c.EVM[0].Nodes[0].HTTPURL = commonconfig.MustParseURL("http://fake.com") + c.EVM[0].Nodes[0].WSURL = commonconfig.MustParseURL("WSS://fake.com/ws") + // seems to be needed for config validate + c.Insecure.OCRDevelopmentMode = nil + }) + + lggr := logger.TestLogger(t) + + app := mocks.NewApplication(t) + app.On("GetSqlxDB").Maybe().Return(db) + shell := cmd.Shell{ + Config: cfg, + AppFactory: cltest.InstanceAppFactory{App: app}, + FallbackAPIInitializer: cltest.NewMockAPIInitializer(t), + Runner: cltest.EmptyRunner{}, + Logger: lggr, + } + + t.Run("Returns error, if --start is not positive", func(t *testing.T) { + set := flag.NewFlagSet("test", 0) + flagSetApplyFromAction(shell.RemoveBlocks, set, "") + require.NoError(t, set.Set("start", "0")) + require.NoError(t, set.Set("evm-chain-id", "12")) + c := cli.NewContext(nil, set, nil) + err := shell.RemoveBlocks(c) + require.ErrorContains(t, err, "Must pass a positive value in '--start' parameter") + }) + t.Run("Returns error, if removal fails", func(t *testing.T) { + set := flag.NewFlagSet("test", 0) + flagSetApplyFromAction(shell.RemoveBlocks, set, "") + require.NoError(t, set.Set("start", "10000")) + require.NoError(t, set.Set("evm-chain-id", "12")) + expectedError := fmt.Errorf("failed to delete log poller's data") + app.On("DeleteLogPollerDataAfter", mock.Anything, big.NewInt(12), int64(10000)).Return(expectedError).Once() + c := cli.NewContext(nil, set, nil) + err := shell.RemoveBlocks(c) + require.ErrorContains(t, err, expectedError.Error()) + }) + t.Run("Happy path", func(t *testing.T) { + set := flag.NewFlagSet("test", 0) + flagSetApplyFromAction(shell.RemoveBlocks, set, "") + require.NoError(t, set.Set("start", "10000")) + require.NoError(t, set.Set("evm-chain-id", "12")) + app.On("DeleteLogPollerDataAfter", mock.Anything, big.NewInt(12), int64(10000)).Return(nil).Once() + c := cli.NewContext(nil, set, nil) + err := shell.RemoveBlocks(c) + require.NoError(t, err) + }) +} diff --git a/core/internal/mocks/application.go b/core/internal/mocks/application.go index c83b37a0e5d..f845d46ca8d 100644 --- a/core/internal/mocks/application.go +++ b/core/internal/mocks/application.go @@ -23,6 +23,8 @@ import ( logger "github.com/smartcontractkit/chainlink/v2/core/logger" + logpoller "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + mock "github.com/stretchr/testify/mock" pipeline "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" @@ -147,6 +149,24 @@ func (_m *Application) DeleteJob(ctx context.Context, jobID int32) error { return r0 } +// DeleteLogPollerDataAfter provides a mock function with given fields: ctx, chainID, start +func (_m *Application) DeleteLogPollerDataAfter(ctx context.Context, chainID *big.Int, start int64) error { + ret := _m.Called(ctx, chainID, start) + + if len(ret) == 0 { + panic("no return value specified for DeleteLogPollerDataAfter") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *big.Int, int64) error); ok { + r0 = rf(ctx, chainID, start) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // EVMORM provides a mock function with given fields: func (_m *Application) EVMORM() types.Configs { ret := _m.Called() @@ -167,6 +187,36 @@ func (_m *Application) EVMORM() types.Configs { return r0 } +// FindLCA provides a mock function with given fields: ctx, chainID +func (_m *Application) FindLCA(ctx context.Context, chainID *big.Int) (*logpoller.LogPollerBlock, error) { + ret := _m.Called(ctx, chainID) + + if len(ret) == 0 { + panic("no return value specified for FindLCA") + } + + var r0 *logpoller.LogPollerBlock + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *big.Int) (*logpoller.LogPollerBlock, error)); ok { + return rf(ctx, chainID) + } + if rf, ok := ret.Get(0).(func(context.Context, *big.Int) *logpoller.LogPollerBlock); ok { + r0 = rf(ctx, chainID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*logpoller.LogPollerBlock) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *big.Int) error); ok { + r1 = rf(ctx, chainID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // GetAuditLogger provides a mock function with given fields: func (_m *Application) GetAuditLogger() audit.AuditLogger { ret := _m.Called() diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 2aebef3f8f7..ae3db2e7a73 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -22,7 +22,9 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils" "github.com/smartcontractkit/chainlink-common/pkg/utils/jsonserializable" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" + "github.com/smartcontractkit/chainlink/v2/core/capabilities" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/static" "github.com/smartcontractkit/chainlink/v2/core/bridges" @@ -115,6 +117,11 @@ type Application interface { ID() uuid.UUID SecretGenerator() SecretGenerator + + // FindLCA - finds last common ancestor for LogPoller's chain available in the database and RPC chain + FindLCA(ctx context.Context, chainID *big.Int) (*logpoller.LogPollerBlock, error) + // DeleteLogPollerDataAfter - delete LogPoller state starting from the specified block + DeleteLogPollerDataAfter(ctx context.Context, chainID *big.Int, start int64) error } // ChainlinkApplication contains fields for the JobSubscriber, Scheduler, @@ -886,3 +893,39 @@ func (app *ChainlinkApplication) GetWebAuthnConfiguration() sessions.WebAuthnCon func (app *ChainlinkApplication) ID() uuid.UUID { return app.Config.AppID() } + +// FindLCA - finds last common ancestor +func (app *ChainlinkApplication) FindLCA(ctx context.Context, chainID *big.Int) (*logpoller.LogPollerBlock, error) { + chain, err := app.GetRelayers().LegacyEVMChains().Get(chainID.String()) + if err != nil { + return nil, err + } + if !app.Config.Feature().LogPoller() { + return nil, fmt.Errorf("FindLCA is only available if LogPoller is enabled") + } + + lca, err := chain.LogPoller().FindLCA(ctx) + if err != nil { + return nil, fmt.Errorf("failed to find lca: %w", err) + } + + return lca, nil +} + +// DeleteLogPollerDataAfter - delete LogPoller state starting from the specified block +func (app *ChainlinkApplication) DeleteLogPollerDataAfter(ctx context.Context, chainID *big.Int, start int64) error { + chain, err := app.GetRelayers().LegacyEVMChains().Get(chainID.String()) + if err != nil { + return err + } + if !app.Config.Feature().LogPoller() { + return fmt.Errorf("DeleteLogPollerDataAfter is only available if LogPoller is enabled") + } + + err = chain.LogPoller().DeleteLogsAndBlocksAfter(ctx, start) + if err != nil { + return fmt.Errorf("failed to recover LogPoller: %w", err) + } + + return nil +} diff --git a/core/web/api.go b/core/web/api.go index 1f97d59c77d..51f7b855cd5 100644 --- a/core/web/api.go +++ b/core/web/api.go @@ -120,7 +120,7 @@ func ParsePaginatedResponse(input []byte, resource interface{}, links *jsonapi.L func parsePaginatedResponseToDocument(input []byte, resource interface{}, document *jsonapi.Document) error { err := ParseJSONAPIResponse(input, resource) if err != nil { - return errors.Wrap(err, "ParseJSONAPIResponse error") + return errors.Wrapf(err, "ParseJSONAPIResponse error body: %s", string(input)) } // Unmarshal using the stdlib Unmarshal to extract the links part of the document diff --git a/core/web/lca_controller.go b/core/web/lca_controller.go new file mode 100644 index 00000000000..bb4866c3d08 --- /dev/null +++ b/core/web/lca_controller.go @@ -0,0 +1,74 @@ +package web + +import ( + "errors" + "fmt" + "net/http" + + "github.com/gin-gonic/gin" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" +) + +type LCAController struct { + App chainlink.Application +} + +// FindLCA compares chain of blocks available in the DB with chain provided by an RPC and returns last common ancestor +// Example: +// +// "/v2/find_lca" +func (bdc *LCAController) FindLCA(c *gin.Context) { + chain, err := getChain(bdc.App.GetRelayers().LegacyEVMChains(), c.Query("evmChainID")) + if err != nil { + if errors.Is(err, ErrInvalidChainID) || errors.Is(err, ErrMultipleChains) || errors.Is(err, ErrMissingChainID) { + jsonAPIError(c, http.StatusUnprocessableEntity, err) + return + } + jsonAPIError(c, http.StatusInternalServerError, err) + return + } + chainID := chain.ID() + + lca, err := bdc.App.FindLCA(c.Request.Context(), chainID) + if err != nil { + jsonAPIError(c, http.StatusInternalServerError, err) + return + } + + if lca == nil { + jsonAPIError(c, http.StatusNotFound, fmt.Errorf("failed to find last common ancestor")) + return + } + + response := LCAResponse{ + BlockNumber: lca.BlockNumber, + Hash: lca.BlockHash.String(), + EVMChainID: big.New(chainID), + } + jsonAPIResponse(c, &response, "response") + +} + +type LCAResponse struct { + BlockNumber int64 `json:"blockNumber"` + Hash string `json:"hash"` + EVMChainID *big.Big `json:"evmChainID"` +} + +// GetID returns the jsonapi ID. +func (s LCAResponse) GetID() string { + return "LCAResponseID" +} + +// GetName returns the collection name for jsonapi. +func (LCAResponse) GetName() string { + return "lca_response" +} + +// SetID is used to conform to the UnmarshallIdentifier interface for +// deserializing from jsonapi documents. +func (*LCAResponse) SetID(string) error { + return nil +} diff --git a/core/web/lca_controller_test.go b/core/web/lca_controller_test.go new file mode 100644 index 00000000000..7ec476e8eca --- /dev/null +++ b/core/web/lca_controller_test.go @@ -0,0 +1,29 @@ +package web_test + +import ( + _ "embed" + "io" + "net/http" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" +) + +func TestLCAController_FindLCA(t *testing.T) { + cfg := configtest.NewTestGeneralConfig(t) + ec := setupEthClientForControllerTests(t) + app := cltest.NewApplicationWithConfigAndKey(t, cfg, cltest.DefaultP2PKey, ec) + require.NoError(t, app.Start(testutils.Context(t))) + client := app.NewHTTPClient(nil) + resp, cleanup := client.Get("/v2/find_lca?evmChainID=1") + t.Cleanup(cleanup) + assert.Equal(t, http.StatusUnprocessableEntity, resp.StatusCode) + b, err := io.ReadAll(resp.Body) + require.NoError(t, err) + assert.Contains(t, string(b), "chain id does not match any local chains") +} diff --git a/core/web/router.go b/core/web/router.go index c327583a005..158ea4b411f 100644 --- a/core/web/router.go +++ b/core/web/router.go @@ -292,6 +292,8 @@ func v2Routes(app chainlink.Application, r *gin.RouterGroup) { rc := ReplayController{app} authv2.POST("/replay_from_block/:number", auth.RequiresRunRole(rc.ReplayFromBlock)) + lcaC := LCAController{app} + authv2.GET("/find_lca", auth.RequiresRunRole(lcaC.FindLCA)) csakc := CSAKeysController{app} authv2.GET("/keys/csa", csakc.Index) diff --git a/testdata/scripts/blocks/help.txtar b/testdata/scripts/blocks/help.txtar index 55aaf71858d..5d362a082fd 100644 --- a/testdata/scripts/blocks/help.txtar +++ b/testdata/scripts/blocks/help.txtar @@ -9,7 +9,8 @@ USAGE: chainlink blocks command [command options] [arguments...] COMMANDS: - replay Replays block data from the given number + replay Replays block data from the given number + find-lca Find latest common block stored in DB and on chain OPTIONS: --help, -h show help diff --git a/testdata/scripts/help-all/help-all.txtar b/testdata/scripts/help-all/help-all.txtar index eeaf0da98d1..e111295abb4 100644 --- a/testdata/scripts/help-all/help-all.txtar +++ b/testdata/scripts/help-all/help-all.txtar @@ -16,6 +16,7 @@ admin users list # Lists all API users and their roles attempts # Commands for managing Ethereum Transaction Attempts attempts list # List the Transaction Attempts in descending order blocks # Commands for managing blocks +blocks find-lca # Find latest common block stored in DB and on chain blocks replay # Replays block data from the given number bridges # Commands for Bridges communicating with External Adapters bridges create # Create a new Bridge to an External Adapter @@ -132,6 +133,7 @@ node db status # Display the current database migration status. node db version # Display the current database version. node profile # Collects profile metrics from the node. node rebroadcast-transactions # Manually rebroadcast txs matching nonce range with the specified gas price. This is useful in emergencies e.g. high gas prices and/or network congestion to forcibly clear out the pending TX queue +node remove-blocks # Deletes block range and all associated data node start # Run the Chainlink node node status # Displays the health of various services running inside the node. node validate # Validate the TOML configuration and secrets that are passed as flags to the `node` command. Prints the full effective configuration, with defaults included diff --git a/testdata/scripts/node/help.txtar b/testdata/scripts/node/help.txtar index 33e1fdc90bc..875500b13df 100644 --- a/testdata/scripts/node/help.txtar +++ b/testdata/scripts/node/help.txtar @@ -13,6 +13,7 @@ COMMANDS: rebroadcast-transactions Manually rebroadcast txs matching nonce range with the specified gas price. This is useful in emergencies e.g. high gas prices and/or network congestion to forcibly clear out the pending TX queue validate Validate the TOML configuration and secrets that are passed as flags to the `node` command. Prints the full effective configuration, with defaults included db Commands for managing the database. + remove-blocks Deletes block range and all associated data OPTIONS: --config value, -c value TOML configuration file(s) via flag, or raw TOML via env var. If used, legacy env vars must not be set. Multiple files can be used (-c configA.toml -c configB.toml), and they are applied in order with duplicated fields overriding any earlier values. If the 'CL_CONFIG' env var is specified, it is always processed last with the effect of being the final override. [$CL_CONFIG] From 71eed2133fb86a065461787e31db5fb1b18b05de Mon Sep 17 00:00:00 2001 From: Tate Date: Fri, 26 Apr 2024 08:47:17 -0600 Subject: [PATCH 45/77] Fix Node Migration Test Check For Versions (#12982) --- .../action.yml | 1 + .github/workflows/integration-tests.yml | 90 ++++++++----------- 2 files changed, 40 insertions(+), 51 deletions(-) diff --git a/.github/actions/setup-create-base64-upgrade-config/action.yml b/.github/actions/setup-create-base64-upgrade-config/action.yml index ed25fd6375f..8f514784725 100644 --- a/.github/actions/setup-create-base64-upgrade-config/action.yml +++ b/.github/actions/setup-create-base64-upgrade-config/action.yml @@ -92,6 +92,7 @@ runs: [ChainlinkUpgradeImage] image="$UPGRADE_IMAGE" version="$UPGRADE_VERSION" + postgres_version="$CHAINLINK_POSTGRES_VERSION" [Logging] test_log_collect=$test_log_collect diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 1f3e093cfdc..8dcf32b127e 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -218,40 +218,6 @@ jobs: AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} dep_evm_sha: ${{ inputs.evm-ref }} - build-test-image: - if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'schedule' || contains(join(github.event.pull_request.labels.*.name, ' '), 'build-test-image') - environment: integration - permissions: - id-token: write - contents: read - name: Build Test Image - runs-on: ubuntu22.04-16cores-64GB - needs: [changes] - steps: - - name: Collect Metrics - if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 - with: - id: ${{ env.COLLECTION_ID }}-build-test-image - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Build Test Image - continue-on-error: true - - name: Checkout the repo - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - with: - repository: smartcontractkit/chainlink - ref: ${{ inputs.cl_ref || github.event.pull_request.head.sha || github.event.merge_group.head_sha }} - - name: Build Test Image - if: needs.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch' - uses: ./.github/actions/build-test-image - with: - QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} - QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} - compare-tests: needs: [changes] runs-on: ubuntu-latest @@ -726,7 +692,7 @@ jobs: cache_restore_only: "true" QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + QA_KUBECONFIG: "" should_tidy: "false" - name: Show Otel-Collector Logs if: steps.check-label.outputs.trace == 'true' && matrix.product.name == 'ocr2' && matrix.product.tag_suffix == '-plugins' @@ -830,6 +796,7 @@ jobs: # Run the setup if the matrix finishes but this time save the cache if we have a cache hit miss # this will also only run if both of the matrix jobs pass eth-smoke-go-mod-cache: + environment: integration needs: [eth-smoke-tests] runs-on: ubuntu-latest @@ -863,7 +830,7 @@ jobs: id-token: write contents: read runs-on: ubuntu-latest - needs: [build-chainlink, changes, build-test-image] + needs: [build-chainlink, changes] # Only run migration tests on new tags if: startsWith(github.ref, 'refs/tags/') env: @@ -876,6 +843,17 @@ jobs: TEST_LOG_LEVEL: debug TEST_SUITE: migration steps: + - name: Collect Metrics + id: collect-gha-metrics + uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + with: + id: ${{ env.COLLECTION_ID }}-migration-tests + org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} + this-job-name: Version Migration Tests + test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' + continue-on-error: true - name: Checkout the repo uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: @@ -886,7 +864,12 @@ jobs: run: | untrimmed_ver=$(curl --header "Authorization: token ${{ secrets.GITHUB_TOKEN }}" --request GET https://api.github.com/repos/${{ github.repository }}/releases/latest | jq -r .name) latest_version="${untrimmed_ver:1}" - echo "latest_version=${latest_version} | tee -a $GITHUB_OUTPUT" + # Check if latest_version is empty + if [ -z "$latest_version" ]; then + echo "Error: The latest_version is empty. The migration tests need a verison to run." + exit 1 + fi + echo "latest_version=${latest_version}" >> "$GITHUB_OUTPUT" - name: Name Versions run: | echo "Running migration tests from version '${{ steps.get_latest_version.outputs.latest_version }}' to: '${{ inputs.evm-ref || github.sha }}'" @@ -898,13 +881,22 @@ jobs: chainlinkVersion: ${{ steps.get_latest_version.outputs.latest_version }} upgradeImage: ${{ env.UPGRADE_IMAGE }} upgradeVersion: ${{ env.UPGRADE_VERSION }} + runId: ${{ github.run_id }} + testLogCollect: ${{ vars.TEST_LOG_COLLECT }} + lokiEndpoint: https://${{ secrets.GRAFANA_INTERNAL_HOST }}/loki/api/v1/push + lokiTenantId: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + lokiBasicAuth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + logstreamLogTargets: ${{ vars.LOGSTREAM_LOG_TARGETS }} + grafanaUrl: ${{ vars.GRAFANA_URL }} + grafanaDashboardUrl: "/d/ddf75041-1e39-42af-aa46-361fe4c36e9e/ci-e2e-tests-logs" - name: Run Migration Tests uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@519851800779323566b7b7c22cc21bff95dbb639 # v2.3.11 with: - test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json ./migration 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage + test_command_to_run: cd ./integration-tests && go test -timeout 20m -count=1 -json ./migration 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage test_download_vendor_packages_command: cd ./integration-tests && go mod download cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ steps.get_latest_version.outputs.latest_version }} + aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} artifacts_name: node-migration-test-logs artifacts_location: | ./integration-tests/migration/logs @@ -916,28 +908,24 @@ jobs: cache_restore_only: "true" QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} - QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + QA_KUBECONFIG: "" go_coverage_src_dir: /var/tmp/go-coverage go_coverage_dest_dir: ${{ github.workspace }}/.covdata + should_tidy: "false" - name: Upload Coverage Data uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: cl-node-coverage-data-migration-tests path: .covdata retention-days: 1 - - - name: Collect Metrics - if: always() - id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + - name: Notify Slack + if: failure() && github.event_name != 'workflow_dispatch' + uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 # v1.25.0 + env: + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} with: - id: ${{ env.COLLECTION_ID }}-migration-tests - org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} - basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} - hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} - this-job-name: Version Migration Tests - test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}' - continue-on-error: true + channel-id: "#team-test-tooling-internal" + slack-message: ":x: :mild-panic-intensifies: Node Migration Tests Failed: ${{ job.html_url }}\n${{ format('https://github.com/smartcontractkit/chainlink/actions/runs/{0}', github.run_id) }}" ## Solana Section get_solana_sha: From b1c8d74272e3b02e0a2a954c3d61b65ecb42f5cf Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Fri, 26 Apr 2024 16:53:31 +0200 Subject: [PATCH 46/77] fix: prevent query syntax error if allowlist is empty (#12912) Co-authored-by: Morgan Kuphal <87319522+KuphJr@users.noreply.github.com> --- .../services/gateway/handlers/functions/allowlist/orm.go | 5 +++++ .../gateway/handlers/functions/allowlist/orm_test.go | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/core/services/gateway/handlers/functions/allowlist/orm.go b/core/services/gateway/handlers/functions/allowlist/orm.go index 7867c06d5d4..20a8ed15252 100644 --- a/core/services/gateway/handlers/functions/allowlist/orm.go +++ b/core/services/gateway/handlers/functions/allowlist/orm.go @@ -67,6 +67,11 @@ func (o *orm) GetAllowedSenders(ctx context.Context, offset, limit uint) ([]comm } func (o *orm) CreateAllowedSenders(ctx context.Context, allowedSenders []common.Address) error { + if len(allowedSenders) == 0 { + o.lggr.Debugf("empty allowed senders list: %v for routerContractAddress: %s. skipping...", allowedSenders, o.routerContractAddress) + return nil + } + var valuesPlaceholder []string for i := 1; i <= len(allowedSenders)*2; i += 2 { valuesPlaceholder = append(valuesPlaceholder, fmt.Sprintf("($%d, $%d)", i, i+1)) diff --git a/core/services/gateway/handlers/functions/allowlist/orm_test.go b/core/services/gateway/handlers/functions/allowlist/orm_test.go index 2584e131968..388d47a769b 100644 --- a/core/services/gateway/handlers/functions/allowlist/orm_test.go +++ b/core/services/gateway/handlers/functions/allowlist/orm_test.go @@ -128,6 +128,15 @@ func TestORM_CreateAllowedSenders(t *testing.T) { require.Equal(t, expected[0], results[0]) require.Equal(t, expected[1], results[1]) }) + + // this scenario can happen if the allowlist is empty but we call CreateAllowedSenders + t.Run("OK-empty_list", func(t *testing.T) { + ctx := testutils.Context(t) + orm, err := setupORM(t) + require.NoError(t, err) + err = orm.CreateAllowedSenders(ctx, []common.Address{}) + require.NoError(t, err) + }) } func TestORM_DeleteAllowedSenders(t *testing.T) { From 0370aa94fbb236ce7ba268adf9a669831b0b40af Mon Sep 17 00:00:00 2001 From: frank zhu Date: Fri, 26 Apr 2024 09:23:44 -0700 Subject: [PATCH 47/77] update contracts README with changesets (#13002) * update contracts README with changesets * add date for 1.1.0 release * update with more explicit direction --- contracts/CHANGELOG.md | 4 ++-- contracts/README.md | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/contracts/CHANGELOG.md b/contracts/CHANGELOG.md index 667a5ad2529..3139312e325 100644 --- a/contracts/CHANGELOG.md +++ b/contracts/CHANGELOG.md @@ -1,6 +1,6 @@ -# @chainlink/contracts CHANGELOG.md +# @chainlink/contracts -## 1.1.0 +## 1.1.0 - 2024-04-23 ### Minor Changes diff --git a/contracts/README.md b/contracts/README.md index 8df69057229..26b0a823298 100644 --- a/contracts/README.md +++ b/contracts/README.md @@ -50,6 +50,22 @@ contribution information. Thank you! +### Changesets + +We use [changesets](https://github.com/changesets/changesets) to manage versioning the contracts. + +Every PR that modifies any configuration or code, should most likely accompanied by a changeset file. + +To install `changesets`: + 1. Install `pnpm` if it is not already installed - [docs](https://pnpm.io/installation). + 2. Run `pnpm install`. + +Either after or before you create a commit, run the `pnpm changeset` command in the `contracts` directory to create an accompanying changeset entry which will reflect on the CHANGELOG for the next release. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), + +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + ## License [MIT](https://choosealicense.com/licenses/mit/) From bcf76534862b32503f4192e38b7e1cb4dd7e312d Mon Sep 17 00:00:00 2001 From: Dmytro Haidashenko <34754799+dhaidashenko@users.noreply.github.com> Date: Fri, 26 Apr 2024 18:27:54 +0200 Subject: [PATCH 48/77] Wrap RPC errors (#12638) * Tag errors with msg that RPC Client returned the error and include RPC name * changeset * added tag to the changeset --- .changeset/quick-fishes-heal.md | 5 + common/client/models.go | 29 ++++ common/client/models_test.go | 16 ++ common/client/multi_node.go | 13 +- common/client/multi_node_test.go | 20 ++- core/chains/evm/client/rpc_client.go | 157 ++++++------------ core/chains/evm/client/sub_error_wrapper.go | 77 +++++++++ .../evm/client/sub_error_wrapper_test.go | 75 +++++++++ .../chains/evm/gas/block_history_estimator.go | 2 +- 9 files changed, 275 insertions(+), 119 deletions(-) create mode 100644 .changeset/quick-fishes-heal.md create mode 100644 common/client/models_test.go create mode 100644 core/chains/evm/client/sub_error_wrapper.go create mode 100644 core/chains/evm/client/sub_error_wrapper_test.go diff --git a/.changeset/quick-fishes-heal.md b/.changeset/quick-fishes-heal.md new file mode 100644 index 00000000000..966e74c843a --- /dev/null +++ b/.changeset/quick-fishes-heal.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- +#changed +Added prefix `RPCClient returned error ({RPC_NAME})` to RPC errors to simplify filtering of RPC related issues. diff --git a/common/client/models.go b/common/client/models.go index 66f1e9cf88b..fd0c3915940 100644 --- a/common/client/models.go +++ b/common/client/models.go @@ -28,6 +28,35 @@ var sendTxSevereErrors = []SendTxReturnCode{Fatal, Underpriced, Unsupported, Exc // sendTxSuccessfulCodes - error codes which signal that transaction was accepted by the node var sendTxSuccessfulCodes = []SendTxReturnCode{Successful, TransactionAlreadyKnown} +func (c SendTxReturnCode) String() string { + switch c { + case Successful: + return "Successful" + case Fatal: + return "Fatal" + case Retryable: + return "Retryable" + case Underpriced: + return "Underpriced" + case Unknown: + return "Unknown" + case Unsupported: + return "Unsupported" + case TransactionAlreadyKnown: + return "TransactionAlreadyKnown" + case InsufficientFunds: + return "InsufficientFunds" + case ExceedsMaxFee: + return "ExceedsMaxFee" + case FeeOutOfValidRange: + return "FeeOutOfValidRange" + case OutOfCounters: + return "OutOfCounters" + default: + return fmt.Sprintf("SendTxReturnCode(%d)", c) + } +} + type NodeTier int const ( diff --git a/common/client/models_test.go b/common/client/models_test.go new file mode 100644 index 00000000000..2d5dc31b373 --- /dev/null +++ b/common/client/models_test.go @@ -0,0 +1,16 @@ +package client + +import ( + "strings" + "testing" +) + +func TestSendTxReturnCode_String(t *testing.T) { + // ensure all the SendTxReturnCodes have proper name + for c := 1; c < int(sendTxReturnCodeLen); c++ { + strC := SendTxReturnCode(c).String() + if strings.Contains(strC, "SendTxReturnCode(") { + t.Errorf("Expected %s to have a proper string representation", strC) + } + } +} diff --git a/common/client/multi_node.go b/common/client/multi_node.go index cc8daed599c..fa413df91aa 100644 --- a/common/client/multi_node.go +++ b/common/client/multi_node.go @@ -561,6 +561,13 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP return n.RPC().PendingSequenceAt(ctx, addr) } +type sendTxErrors map[SendTxReturnCode][]error + +// String - returns string representation of the errors map. Required by logger to properly represent the value +func (errs sendTxErrors) String() string { + return fmt.Sprint(map[SendTxReturnCode][]error(errs)) +} + func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) SendEmptyTransaction( ctx context.Context, newTxAttempt func(seq SEQ, feeLimit uint32, fee FEE, fromAddress ADDR) (attempt any, err error), @@ -602,7 +609,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP ctx, cancel := c.chStop.Ctx(ctx) defer cancel() requiredResults := int(math.Ceil(float64(healthyNodesNum) * sendTxQuorum)) - errorsByCode := map[SendTxReturnCode][]error{} + errorsByCode := sendTxErrors{} var softTimeoutChan <-chan time.Time var resultsCount int loop: @@ -639,7 +646,7 @@ loop: func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OPS, TX_RECEIPT, FEE, HEAD, RPC_CLIENT, BATCH_ELEM]) reportSendTxAnomalies(tx TX, txResults <-chan sendTxResult) { defer c.wg.Done() - resultsByCode := map[SendTxReturnCode][]error{} + resultsByCode := sendTxErrors{} // txResults eventually will be closed for txResult := range txResults { resultsByCode[txResult.ResultCode] = append(resultsByCode[txResult.ResultCode], txResult.Err) @@ -653,7 +660,7 @@ func (c *multiNode[CHAIN_ID, SEQ, ADDR, BLOCK_HASH, TX, TX_HASH, EVENT, EVENT_OP } } -func aggregateTxResults(resultsByCode map[SendTxReturnCode][]error) (txResult error, err error) { +func aggregateTxResults(resultsByCode sendTxErrors) (txResult error, err error) { severeErrors, hasSevereErrors := findFirstIn(resultsByCode, sendTxSevereErrors) successResults, hasSuccess := findFirstIn(resultsByCode, sendTxSuccessfulCodes) if hasSuccess { diff --git a/common/client/multi_node_test.go b/common/client/multi_node_test.go index 9c09bd57d70..9f6904fcaf2 100644 --- a/common/client/multi_node_test.go +++ b/common/client/multi_node_test.go @@ -796,13 +796,13 @@ func TestMultiNode_SendTransaction_aggregateTxResults(t *testing.T) { Name string ExpectedTxResult string ExpectedCriticalErr string - ResultsByCode map[SendTxReturnCode][]error + ResultsByCode sendTxErrors }{ { Name: "Returns success and logs critical error on success and Fatal", ExpectedTxResult: "success", ExpectedCriticalErr: "found contradictions in nodes replies on SendTransaction: got success and severe error", - ResultsByCode: map[SendTxReturnCode][]error{ + ResultsByCode: sendTxErrors{ Successful: {errors.New("success")}, Fatal: {errors.New("fatal")}, }, @@ -811,7 +811,7 @@ func TestMultiNode_SendTransaction_aggregateTxResults(t *testing.T) { Name: "Returns TransactionAlreadyKnown and logs critical error on TransactionAlreadyKnown and Fatal", ExpectedTxResult: "tx_already_known", ExpectedCriticalErr: "found contradictions in nodes replies on SendTransaction: got success and severe error", - ResultsByCode: map[SendTxReturnCode][]error{ + ResultsByCode: sendTxErrors{ TransactionAlreadyKnown: {errors.New("tx_already_known")}, Unsupported: {errors.New("unsupported")}, }, @@ -820,7 +820,7 @@ func TestMultiNode_SendTransaction_aggregateTxResults(t *testing.T) { Name: "Prefers sever error to temporary", ExpectedTxResult: "underpriced", ExpectedCriticalErr: "", - ResultsByCode: map[SendTxReturnCode][]error{ + ResultsByCode: sendTxErrors{ Retryable: {errors.New("retryable")}, Underpriced: {errors.New("underpriced")}, }, @@ -829,7 +829,7 @@ func TestMultiNode_SendTransaction_aggregateTxResults(t *testing.T) { Name: "Returns temporary error", ExpectedTxResult: "retryable", ExpectedCriticalErr: "", - ResultsByCode: map[SendTxReturnCode][]error{ + ResultsByCode: sendTxErrors{ Retryable: {errors.New("retryable")}, }, }, @@ -837,7 +837,7 @@ func TestMultiNode_SendTransaction_aggregateTxResults(t *testing.T) { Name: "Insufficient funds is treated as error", ExpectedTxResult: "", ExpectedCriticalErr: "", - ResultsByCode: map[SendTxReturnCode][]error{ + ResultsByCode: sendTxErrors{ Successful: {nil}, InsufficientFunds: {errors.New("insufficientFunds")}, }, @@ -846,13 +846,13 @@ func TestMultiNode_SendTransaction_aggregateTxResults(t *testing.T) { Name: "Logs critical error on empty ResultsByCode", ExpectedTxResult: "expected at least one response on SendTransaction", ExpectedCriticalErr: "expected at least one response on SendTransaction", - ResultsByCode: map[SendTxReturnCode][]error{}, + ResultsByCode: sendTxErrors{}, }, { Name: "Zk out of counter error", ExpectedTxResult: "not enough keccak counters to continue the execution", ExpectedCriticalErr: "", - ResultsByCode: map[SendTxReturnCode][]error{ + ResultsByCode: sendTxErrors{ OutOfCounters: {errors.New("not enough keccak counters to continue the execution")}, }, }, @@ -870,6 +870,9 @@ func TestMultiNode_SendTransaction_aggregateTxResults(t *testing.T) { assert.EqualError(t, txResult, testCase.ExpectedTxResult) } + logger.Sugared(logger.Test(t)).Info("Map: " + fmt.Sprint(testCase.ResultsByCode)) + logger.Sugared(logger.Test(t)).Criticalw("observed invariant violation on SendTransaction", "resultsByCode", testCase.ResultsByCode, "err", err) + if testCase.ExpectedCriticalErr == "" { assert.NoError(t, err) } else { @@ -884,5 +887,4 @@ func TestMultiNode_SendTransaction_aggregateTxResults(t *testing.T) { delete(codesToCover, codeToIgnore) } assert.Empty(t, codesToCover, "all of the SendTxReturnCode must be covered by this test") - } diff --git a/core/chains/evm/client/rpc_client.go b/core/chains/evm/client/rpc_client.go index 255b038037a..548acf3206c 100644 --- a/core/chains/evm/client/rpc_client.go +++ b/core/chains/evm/client/rpc_client.go @@ -130,7 +130,7 @@ func (r *rpcClient) Dial(callerCtx context.Context) error { wsrpc, err := rpc.DialWebsocket(ctx, r.ws.uri.String(), "") if err != nil { promEVMPoolRPCNodeDialsFailed.WithLabelValues(r.chainID.String(), r.name).Inc() - return pkgerrors.Wrapf(err, "error while dialing websocket: %v", r.ws.uri.Redacted()) + return r.wrapRPCClientError(pkgerrors.Wrapf(err, "error while dialing websocket: %v", r.ws.uri.Redacted())) } r.ws.rpc = wsrpc @@ -159,7 +159,7 @@ func (r *rpcClient) DialHTTP() error { httprpc, err := rpc.DialHTTP(r.http.uri.String()) if err != nil { promEVMPoolRPCNodeDialsFailed.WithLabelValues(r.chainID.String(), r.name).Inc() - return pkgerrors.Wrapf(err, "error while dialing HTTP: %v", r.http.uri.Redacted()) + return r.wrapRPCClientError(pkgerrors.Wrapf(err, "error while dialing HTTP: %v", r.http.uri.Redacted())) } r.http.rpc = httprpc @@ -295,10 +295,7 @@ func (r *rpcClient) UnsubscribeAllExceptAliveLoop() { // CallContext implementation func (r *rpcClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return err - } + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr().With( "method", method, @@ -307,6 +304,7 @@ func (r *rpcClient) CallContext(ctx context.Context, result interface{}, method lggr.Debug("RPC call: evmclient.Client#CallContext") start := time.Now() + var err error if http != nil { err = r.wrapHTTP(http.rpc.CallContext(ctx, result, method, args...)) } else { @@ -320,15 +318,13 @@ func (r *rpcClient) CallContext(ctx context.Context, result interface{}, method } func (r *rpcClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return err - } + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr().With("nBatchElems", len(b), "batchElems", b) lggr.Trace("RPC call: evmclient.Client#BatchCallContext") start := time.Now() + var err error if http != nil { err = r.wrapHTTP(http.rpc.BatchCallContext(ctx, b)) } else { @@ -342,24 +338,23 @@ func (r *rpcClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) err } func (r *rpcClient) Subscribe(ctx context.Context, channel chan<- *evmtypes.Head, args ...interface{}) (commontypes.Subscription, error) { - ctx, cancel, ws, _, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return nil, err - } + ctx, cancel, ws, _ := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr().With("args", args) lggr.Debug("RPC call: evmclient.Client#EthSubscribe") start := time.Now() + var sub commontypes.Subscription sub, err := ws.rpc.EthSubscribe(ctx, channel, args...) if err == nil { + sub = newSubscriptionErrorWrapper(sub, r.rpcClientErrorPrefix()) r.registerSub(sub) } duration := time.Since(start) r.logResult(lggr, err, duration, r.getRPCDomain(), "EthSubscribe") - return sub, err + return sub, r.wrapWS(err) } // GethClient wrappers @@ -370,17 +365,14 @@ func (r *rpcClient) TransactionReceipt(ctx context.Context, txHash common.Hash) return nil, err } if receipt == nil { - err = ethereum.NotFound + err = r.wrapRPCClientError(ethereum.NotFound) return } return } func (r *rpcClient) TransactionReceiptGeth(ctx context.Context, txHash common.Hash) (receipt *types.Receipt, err error) { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return nil, err - } + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr().With("txHash", txHash) @@ -403,10 +395,7 @@ func (r *rpcClient) TransactionReceiptGeth(ctx context.Context, txHash common.Ha return } func (r *rpcClient) TransactionByHash(ctx context.Context, txHash common.Hash) (tx *types.Transaction, err error) { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return nil, err - } + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr().With("txHash", txHash) @@ -430,10 +419,7 @@ func (r *rpcClient) TransactionByHash(ctx context.Context, txHash common.Hash) ( } func (r *rpcClient) HeaderByNumber(ctx context.Context, number *big.Int) (header *types.Header, err error) { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return nil, err - } + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr().With("number", number) @@ -454,10 +440,7 @@ func (r *rpcClient) HeaderByNumber(ctx context.Context, number *big.Int) (header } func (r *rpcClient) HeaderByHash(ctx context.Context, hash common.Hash) (header *types.Header, err error) { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return nil, err - } + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr().With("hash", hash) @@ -494,7 +477,7 @@ func (r *rpcClient) blockByNumber(ctx context.Context, number string) (head *evm return nil, err } if head == nil { - err = ethereum.NotFound + err = r.wrapRPCClientError(ethereum.NotFound) return } head.EVMChainID = ubig.New(r.chainID) @@ -507,7 +490,7 @@ func (r *rpcClient) BlockByHash(ctx context.Context, hash common.Hash) (head *ev return nil, err } if head == nil { - err = ethereum.NotFound + err = r.wrapRPCClientError(ethereum.NotFound) return } head.EVMChainID = ubig.New(r.chainID) @@ -515,10 +498,7 @@ func (r *rpcClient) BlockByHash(ctx context.Context, hash common.Hash) (head *ev } func (r *rpcClient) BlockByHashGeth(ctx context.Context, hash common.Hash) (block *types.Block, err error) { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return nil, err - } + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr().With("hash", hash) @@ -541,10 +521,7 @@ func (r *rpcClient) BlockByHashGeth(ctx context.Context, hash common.Hash) (bloc } func (r *rpcClient) BlockByNumberGeth(ctx context.Context, number *big.Int) (block *types.Block, err error) { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return nil, err - } + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr().With("number", number) @@ -567,15 +544,13 @@ func (r *rpcClient) BlockByNumberGeth(ctx context.Context, number *big.Int) (blo } func (r *rpcClient) SendTransaction(ctx context.Context, tx *types.Transaction) error { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return err - } + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr().With("tx", tx) lggr.Debug("RPC call: evmclient.Client#SendTransaction") start := time.Now() + var err error if http != nil { err = r.wrapHTTP(http.geth.SendTransaction(ctx, tx)) } else { @@ -607,10 +582,7 @@ func (r *rpcClient) SendEmptyTransaction( // PendingSequenceAt returns one higher than the highest nonce from both mempool and mined transactions func (r *rpcClient) PendingSequenceAt(ctx context.Context, account common.Address) (nonce evmtypes.Nonce, err error) { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return 0, err - } + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr().With("account", account) @@ -639,10 +611,7 @@ func (r *rpcClient) PendingSequenceAt(ctx context.Context, account common.Addres // mined nonce at the given block number, but it actually returns the total // transaction count which is the highest mined nonce + 1 func (r *rpcClient) SequenceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (nonce evmtypes.Nonce, err error) { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return 0, err - } + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr().With("account", account, "blockNumber", blockNumber) @@ -668,10 +637,7 @@ func (r *rpcClient) SequenceAt(ctx context.Context, account common.Address, bloc } func (r *rpcClient) PendingCodeAt(ctx context.Context, account common.Address) (code []byte, err error) { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return nil, err - } + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr().With("account", account) @@ -694,10 +660,7 @@ func (r *rpcClient) PendingCodeAt(ctx context.Context, account common.Address) ( } func (r *rpcClient) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) (code []byte, err error) { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return nil, err - } + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr().With("account", account, "blockNumber", blockNumber) @@ -720,10 +683,7 @@ func (r *rpcClient) CodeAt(ctx context.Context, account common.Address, blockNum } func (r *rpcClient) EstimateGas(ctx context.Context, c interface{}) (gas uint64, err error) { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return 0, err - } + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() call := c.(ethereum.CallMsg) lggr := r.newRqLggr().With("call", call) @@ -747,10 +707,7 @@ func (r *rpcClient) EstimateGas(ctx context.Context, c interface{}) (gas uint64, } func (r *rpcClient) SuggestGasPrice(ctx context.Context) (price *big.Int, err error) { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return nil, err - } + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr() @@ -773,10 +730,7 @@ func (r *rpcClient) SuggestGasPrice(ctx context.Context) (price *big.Int, err er } func (r *rpcClient) CallContract(ctx context.Context, msg interface{}, blockNumber *big.Int) (val []byte, err error) { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return nil, err - } + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr().With("callMsg", msg, "blockNumber", blockNumber) message := msg.(ethereum.CallMsg) @@ -804,10 +758,7 @@ func (r *rpcClient) CallContract(ctx context.Context, msg interface{}, blockNumb } func (r *rpcClient) PendingCallContract(ctx context.Context, msg interface{}) (val []byte, err error) { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return nil, err - } + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr().With("callMsg", msg) message := msg.(ethereum.CallMsg) @@ -841,10 +792,7 @@ func (r *rpcClient) LatestBlockHeight(ctx context.Context) (*big.Int, error) { } func (r *rpcClient) BlockNumber(ctx context.Context) (height uint64, err error) { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return 0, err - } + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr() @@ -867,10 +815,7 @@ func (r *rpcClient) BlockNumber(ctx context.Context) (height uint64, err error) } func (r *rpcClient) BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (balance *big.Int, err error) { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return nil, err - } + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr().With("account", account.Hex(), "blockNumber", blockNumber) @@ -907,7 +852,7 @@ func (r *rpcClient) TokenBalance(ctx context.Context, address common.Address, co return numLinkBigInt, err } if _, ok := numLinkBigInt.SetString(result, 0); !ok { - return nil, fmt.Errorf("failed to parse int: %s", result) + return nil, r.wrapRPCClientError(fmt.Errorf("failed to parse int: %s", result)) } return numLinkBigInt, nil } @@ -926,10 +871,7 @@ func (r *rpcClient) FilterEvents(ctx context.Context, q ethereum.FilterQuery) ([ } func (r *rpcClient) FilterLogs(ctx context.Context, q ethereum.FilterQuery) (l []types.Log, err error) { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return nil, err - } + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr().With("q", q) @@ -957,10 +899,7 @@ func (r *rpcClient) ClientVersion(ctx context.Context) (version string, err erro } func (r *rpcClient) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) (sub ethereum.Subscription, err error) { - ctx, cancel, ws, _, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return nil, err - } + ctx, cancel, ws, _ := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr().With("q", q) @@ -968,6 +907,7 @@ func (r *rpcClient) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQu start := time.Now() sub, err = ws.geth.SubscribeFilterLogs(ctx, q, ch) if err == nil { + sub = newSubscriptionErrorWrapper(sub, r.rpcClientErrorPrefix()) r.registerSub(sub) } err = r.wrapWS(err) @@ -979,10 +919,7 @@ func (r *rpcClient) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQu } func (r *rpcClient) SuggestGasTipCap(ctx context.Context) (tipCap *big.Int, err error) { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return nil, err - } + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr() @@ -1007,7 +944,7 @@ func (r *rpcClient) SuggestGasTipCap(ctx context.Context) (tipCap *big.Int, err // Returns the ChainID according to the geth client. This is useful for functions like verify() // the common node. func (r *rpcClient) ChainID(ctx context.Context) (chainID *big.Int, err error) { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() @@ -1026,6 +963,15 @@ func (r *rpcClient) newRqLggr() logger.SugaredLogger { return r.rpcLog.With("requestID", uuid.New()) } +func (r *rpcClient) wrapRPCClientError(err error) error { + // simple add msg to the error without adding new stack trace + return pkgerrors.WithMessage(err, r.rpcClientErrorPrefix()) +} + +func (r *rpcClient) rpcClientErrorPrefix() string { + return fmt.Sprintf("RPCClient returned error (%s)", r.name) +} + func wrapCallError(err error, tp string) error { if err == nil { return nil @@ -1038,11 +984,12 @@ func wrapCallError(err error, tp string) error { func (r *rpcClient) wrapWS(err error) error { err = wrapCallError(err, fmt.Sprintf("%s websocket (%s)", r.tier.String(), r.ws.uri.Redacted())) - return err + return r.wrapRPCClientError(err) } func (r *rpcClient) wrapHTTP(err error) error { err = wrapCallError(err, fmt.Sprintf("%s http (%s)", r.tier.String(), r.http.uri.Redacted())) + err = r.wrapRPCClientError(err) if err != nil { r.rpcLog.Debugw("Call failed", "err", err) } else { @@ -1052,7 +999,7 @@ func (r *rpcClient) wrapHTTP(err error) error { } // makeLiveQueryCtxAndSafeGetClients wraps makeQueryCtx -func (r *rpcClient) makeLiveQueryCtxAndSafeGetClients(parentCtx context.Context) (ctx context.Context, cancel context.CancelFunc, ws rawclient, http *rawclient, err error) { +func (r *rpcClient) makeLiveQueryCtxAndSafeGetClients(parentCtx context.Context) (ctx context.Context, cancel context.CancelFunc, ws rawclient, http *rawclient) { // Need to wrap in mutex because state transition can cancel and replace the // context r.stateMu.RLock() @@ -1072,16 +1019,14 @@ func (r *rpcClient) makeQueryCtx(ctx context.Context) (context.Context, context. } func (r *rpcClient) IsSyncing(ctx context.Context) (bool, error) { - ctx, cancel, ws, http, err := r.makeLiveQueryCtxAndSafeGetClients(ctx) - if err != nil { - return false, err - } + ctx, cancel, ws, http := r.makeLiveQueryCtxAndSafeGetClients(ctx) defer cancel() lggr := r.newRqLggr() lggr.Debug("RPC call: evmclient.Client#SyncProgress") var syncProgress *ethereum.SyncProgress start := time.Now() + var err error if http != nil { syncProgress, err = http.geth.SyncProgress(ctx) err = r.wrapHTTP(err) diff --git a/core/chains/evm/client/sub_error_wrapper.go b/core/chains/evm/client/sub_error_wrapper.go new file mode 100644 index 00000000000..689991ce70f --- /dev/null +++ b/core/chains/evm/client/sub_error_wrapper.go @@ -0,0 +1,77 @@ +package client + +import ( + "fmt" + + commontypes "github.com/smartcontractkit/chainlink/v2/common/types" +) + +// subErrorWrapper - adds specified prefix to a subscription error +type subErrorWrapper struct { + sub commontypes.Subscription + errorPrefix string + + done chan struct{} + unSub chan struct{} + errorCh chan error +} + +func newSubscriptionErrorWrapper(sub commontypes.Subscription, errorPrefix string) *subErrorWrapper { + s := &subErrorWrapper{ + sub: sub, + errorPrefix: errorPrefix, + done: make(chan struct{}), + unSub: make(chan struct{}), + errorCh: make(chan error), + } + + go func() { + for { + select { + // sub.Err channel is closed by sub.Unsubscribe + case err, ok := <-sub.Err(): + if !ok { + // might only happen if someone terminated wrapped subscription + // in any case - do our best to release resources + // we can't call Unsubscribe on root sub as this might cause panic + close(s.errorCh) + close(s.done) + return + } + + select { + case s.errorCh <- fmt.Errorf("%s: %w", s.errorPrefix, err): + case <-s.unSub: + s.close() + return + } + case <-s.unSub: + s.close() + return + } + } + }() + + return s +} + +func (s *subErrorWrapper) close() { + s.sub.Unsubscribe() + close(s.errorCh) + close(s.done) +} + +func (s *subErrorWrapper) Unsubscribe() { + select { + // already unsubscribed + case <-s.done: + // signal unsubscribe + case s.unSub <- struct{}{}: + // wait for unsubscribe to complete + <-s.done + } +} + +func (s *subErrorWrapper) Err() <-chan error { + return s.errorCh +} diff --git a/core/chains/evm/client/sub_error_wrapper_test.go b/core/chains/evm/client/sub_error_wrapper_test.go new file mode 100644 index 00000000000..457d392a50e --- /dev/null +++ b/core/chains/evm/client/sub_error_wrapper_test.go @@ -0,0 +1,75 @@ +package client + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" +) + +func TestSubscriptionErrorWrapper(t *testing.T) { + t.Parallel() + t.Run("Unsubscribe wrapper releases resources", func(t *testing.T) { + t.Parallel() + + mockedSub := NewMockSubscription() + const prefix = "RPC returned error" + wrapper := newSubscriptionErrorWrapper(mockedSub, prefix) + wrapper.Unsubscribe() + + // mock's resources were relased + assert.True(t, mockedSub.unsubscribed) + _, ok := <-mockedSub.Err() + assert.False(t, ok) + // wrapper's channels are closed + _, ok = <-wrapper.Err() + assert.False(t, ok) + // subsequence unsubscribe does not causes panic + wrapper.Unsubscribe() + }) + t.Run("Unsubscribe interrupts error delivery", func(t *testing.T) { + t.Parallel() + sub := NewMockSubscription() + const prefix = "RPC returned error" + wrapper := newSubscriptionErrorWrapper(sub, prefix) + sub.Errors <- fmt.Errorf("error") + + wrapper.Unsubscribe() + _, ok := <-wrapper.Err() + assert.False(t, ok) + }) + t.Run("Successfully wraps error", func(t *testing.T) { + t.Parallel() + sub := NewMockSubscription() + const prefix = "RPC returned error" + wrapper := newSubscriptionErrorWrapper(sub, prefix) + sub.Errors <- fmt.Errorf("root error") + + err, ok := <-wrapper.Err() + assert.True(t, ok) + assert.Equal(t, "RPC returned error: root error", err.Error()) + + wrapper.Unsubscribe() + _, ok = <-wrapper.Err() + assert.False(t, ok) + }) + t.Run("Unsubscribe on root does not cause panic", func(t *testing.T) { + t.Parallel() + mockedSub := NewMockSubscription() + wrapper := newSubscriptionErrorWrapper(mockedSub, "") + + mockedSub.Unsubscribe() + // mock's resources were released + assert.True(t, mockedSub.unsubscribed) + _, ok := <-mockedSub.Err() + assert.False(t, ok) + // wrapper's channels are eventually closed + tests.AssertEventually(t, func() bool { + _, ok = <-wrapper.Err() + return !ok + }) + + }) +} diff --git a/core/chains/evm/gas/block_history_estimator.go b/core/chains/evm/gas/block_history_estimator.go index 8b8c626f725..0ae067e45bf 100644 --- a/core/chains/evm/gas/block_history_estimator.go +++ b/core/chains/evm/gas/block_history_estimator.go @@ -721,7 +721,7 @@ func (b *BlockHistoryEstimator) batchFetch(ctx context.Context, reqs []rpc.Batch err := b.ethClient.BatchCallContext(ctx, reqs[i:j]) if pkgerrors.Is(err, context.DeadlineExceeded) { // We ran out of time, return what we have - b.logger.Warnf("Batch fetching timed out; loaded %d/%d results", i, len(reqs)) + b.logger.Warnf("Batch fetching timed out; loaded %d/%d results: %v", i, len(reqs), err) for k := i; k < len(reqs); k++ { if k < j { reqs[k].Error = pkgerrors.Wrap(err, "request failed") From c98ea6413dcdc02a7d0c82b9b36d3fce97dac94b Mon Sep 17 00:00:00 2001 From: Oliver Townsend <133903322+ogtownsend@users.noreply.github.com> Date: Fri, 26 Apr 2024 09:48:56 -0700 Subject: [PATCH 49/77] Update log trigger log provider readMaxBatchSize to 56 (#12951) * Update log provider readMaxBatchSize to 56 * Adding changeset * Add changeset tag --- .changeset/tidy-trees-tie.md | 5 +++++ .../ocr2keeper/evmregistry/v21/logprovider/provider.go | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/tidy-trees-tie.md diff --git a/.changeset/tidy-trees-tie.md b/.changeset/tidy-trees-tie.md new file mode 100644 index 00000000000..7ff415e9de4 --- /dev/null +++ b/.changeset/tidy-trees-tie.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#changed Updating the log trigger log provider's readMaxBatchSize to 56 diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider.go index b07b08d3354..e2c1a1531e2 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/provider.go @@ -42,7 +42,7 @@ var ( readJobQueueSize = 64 readLogsTimeout = 10 * time.Second - readMaxBatchSize = 32 + readMaxBatchSize = 56 // reorgBuffer is the number of blocks to add as a buffer to the block range when reading logs. reorgBuffer = int64(32) readerThreads = 4 From 7338448469d014b4b1eb5aaedf0303f687e45f62 Mon Sep 17 00:00:00 2001 From: Dylan Tinianov Date: Fri, 26 Apr 2024 13:10:57 -0400 Subject: [PATCH 50/77] Create HeadPoller for Multi-Node (#12871) * Create polling transformer * Update poller * Rename to HeadPoller * lint * update poller * Update head poller * Update poller * lint * Refactor Poller * Update poller_test.go * Update poller * Synchronize tests * Refactor with timeout * Check test logs * Update Poller * Update poller_test.go * Update poller_test.go * Simplify poller * Set logging to warn --- common/client/poller.go | 98 +++++++++++++++++ common/client/poller_test.go | 207 +++++++++++++++++++++++++++++++++++ 2 files changed, 305 insertions(+) create mode 100644 common/client/poller.go create mode 100644 common/client/poller_test.go diff --git a/common/client/poller.go b/common/client/poller.go new file mode 100644 index 00000000000..b21f28fe604 --- /dev/null +++ b/common/client/poller.go @@ -0,0 +1,98 @@ +package client + +import ( + "context" + "sync" + "time" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-common/pkg/services" + + "github.com/smartcontractkit/chainlink/v2/common/types" +) + +// Poller is a component that polls a function at a given interval +// and delivers the result to a channel. It is used by multinode to poll +// for new heads and implements the Subscription interface. +type Poller[T any] struct { + services.StateMachine + pollingInterval time.Duration + pollingFunc func(ctx context.Context) (T, error) + pollingTimeout time.Duration + logger logger.Logger + channel chan<- T + errCh chan error + + stopCh services.StopChan + wg sync.WaitGroup +} + +// NewPoller creates a new Poller instance +func NewPoller[ + T any, +](pollingInterval time.Duration, pollingFunc func(ctx context.Context) (T, error), pollingTimeout time.Duration, channel chan<- T, logger logger.Logger) Poller[T] { + return Poller[T]{ + pollingInterval: pollingInterval, + pollingFunc: pollingFunc, + pollingTimeout: pollingTimeout, + channel: channel, + logger: logger, + errCh: make(chan error), + stopCh: make(chan struct{}), + } +} + +var _ types.Subscription = &Poller[any]{} + +func (p *Poller[T]) Start() error { + return p.StartOnce("Poller", func() error { + p.wg.Add(1) + go p.pollingLoop() + return nil + }) +} + +// Unsubscribe cancels the sending of events to the data channel +func (p *Poller[T]) Unsubscribe() { + _ = p.StopOnce("Poller", func() error { + close(p.stopCh) + p.wg.Wait() + close(p.errCh) + return nil + }) +} + +func (p *Poller[T]) Err() <-chan error { + return p.errCh +} + +func (p *Poller[T]) pollingLoop() { + defer p.wg.Done() + + ticker := time.NewTicker(p.pollingInterval) + defer ticker.Stop() + + for { + select { + case <-p.stopCh: + return + case <-ticker.C: + // Set polling timeout + pollingCtx, cancelPolling := context.WithTimeout(context.Background(), p.pollingTimeout) + p.stopCh.CtxCancel(pollingCtx, cancelPolling) + // Execute polling function + result, err := p.pollingFunc(pollingCtx) + cancelPolling() + if err != nil { + p.logger.Warnf("polling error: %v", err) + continue + } + // Send result to channel or block if channel is full + select { + case p.channel <- result: + case <-p.stopCh: + return + } + } + } +} diff --git a/common/client/poller_test.go b/common/client/poller_test.go new file mode 100644 index 00000000000..3f11c759adb --- /dev/null +++ b/common/client/poller_test.go @@ -0,0 +1,207 @@ +package client + +import ( + "context" + "fmt" + "math/big" + "sync" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" +) + +func Test_Poller(t *testing.T) { + lggr := logger.Test(t) + + t.Run("Test multiple start", func(t *testing.T) { + pollFunc := func(ctx context.Context) (Head, error) { + return nil, nil + } + + channel := make(chan Head, 1) + defer close(channel) + + poller := NewPoller[Head](time.Millisecond, pollFunc, time.Second, channel, lggr) + err := poller.Start() + require.NoError(t, err) + + err = poller.Start() + require.Error(t, err) + poller.Unsubscribe() + }) + + t.Run("Test polling for heads", func(t *testing.T) { + // Mock polling function that returns a new value every time it's called + var pollNumber int + pollLock := sync.Mutex{} + pollFunc := func(ctx context.Context) (Head, error) { + pollLock.Lock() + defer pollLock.Unlock() + pollNumber++ + h := head{ + BlockNumber: int64(pollNumber), + BlockDifficulty: big.NewInt(int64(pollNumber)), + } + return h.ToMockHead(t), nil + } + + // data channel to receive updates from the poller + channel := make(chan Head, 1) + defer close(channel) + + // Create poller and start to receive data + poller := NewPoller[Head](time.Millisecond, pollFunc, time.Second, channel, lggr) + require.NoError(t, poller.Start()) + defer poller.Unsubscribe() + + // Receive updates from the poller + pollCount := 0 + pollMax := 50 + for ; pollCount < pollMax; pollCount++ { + h := <-channel + assert.Equal(t, int64(pollCount+1), h.BlockNumber()) + } + }) + + t.Run("Test polling errors", func(t *testing.T) { + // Mock polling function that returns an error + var pollNumber int + pollLock := sync.Mutex{} + pollFunc := func(ctx context.Context) (Head, error) { + pollLock.Lock() + defer pollLock.Unlock() + pollNumber++ + return nil, fmt.Errorf("polling error %d", pollNumber) + } + + // data channel to receive updates from the poller + channel := make(chan Head, 1) + defer close(channel) + + olggr, observedLogs := logger.TestObserved(t, zap.WarnLevel) + + // Create poller and subscribe to receive data + poller := NewPoller[Head](time.Millisecond, pollFunc, time.Second, channel, olggr) + require.NoError(t, poller.Start()) + defer poller.Unsubscribe() + + // Ensure that all errors were logged as expected + logsSeen := func() bool { + for pollCount := 0; pollCount < 50; pollCount++ { + numLogs := observedLogs.FilterMessage(fmt.Sprintf("polling error: polling error %d", pollCount+1)).Len() + if numLogs != 1 { + return false + } + } + return true + } + require.Eventually(t, logsSeen, time.Second, time.Millisecond) + }) + + t.Run("Test polling timeout", func(t *testing.T) { + pollFunc := func(ctx context.Context) (Head, error) { + if <-ctx.Done(); true { + return nil, ctx.Err() + } + return nil, nil + } + + // Set instant timeout + pollingTimeout := time.Duration(0) + + // data channel to receive updates from the poller + channel := make(chan Head, 1) + defer close(channel) + + olggr, observedLogs := logger.TestObserved(t, zap.WarnLevel) + + // Create poller and subscribe to receive data + poller := NewPoller[Head](time.Millisecond, pollFunc, pollingTimeout, channel, olggr) + require.NoError(t, poller.Start()) + defer poller.Unsubscribe() + + // Ensure that timeout errors were logged as expected + logsSeen := func() bool { + return observedLogs.FilterMessage("polling error: context deadline exceeded").Len() >= 1 + } + require.Eventually(t, logsSeen, time.Second, time.Millisecond) + }) + + t.Run("Test unsubscribe during polling", func(t *testing.T) { + wait := make(chan struct{}) + pollFunc := func(ctx context.Context) (Head, error) { + close(wait) + // Block in polling function until context is cancelled + if <-ctx.Done(); true { + return nil, ctx.Err() + } + return nil, nil + } + + // Set long timeout + pollingTimeout := time.Minute + + // data channel to receive updates from the poller + channel := make(chan Head, 1) + defer close(channel) + + olggr, observedLogs := logger.TestObserved(t, zap.WarnLevel) + + // Create poller and subscribe to receive data + poller := NewPoller[Head](time.Millisecond, pollFunc, pollingTimeout, channel, olggr) + require.NoError(t, poller.Start()) + + // Unsubscribe while blocked in polling function + <-wait + poller.Unsubscribe() + + // Ensure error was logged + logsSeen := func() bool { + return observedLogs.FilterMessage("polling error: context canceled").Len() >= 1 + } + require.Eventually(t, logsSeen, time.Second, time.Millisecond) + }) +} + +func Test_Poller_Unsubscribe(t *testing.T) { + lggr := logger.Test(t) + pollFunc := func(ctx context.Context) (Head, error) { + select { + case <-ctx.Done(): + return nil, ctx.Err() + default: + h := head{ + BlockNumber: 0, + BlockDifficulty: big.NewInt(0), + } + return h.ToMockHead(t), nil + } + } + + t.Run("Test multiple unsubscribe", func(t *testing.T) { + channel := make(chan Head, 1) + poller := NewPoller[Head](time.Millisecond, pollFunc, time.Second, channel, lggr) + err := poller.Start() + require.NoError(t, err) + + <-channel + poller.Unsubscribe() + poller.Unsubscribe() + }) + + t.Run("Test unsubscribe with closed channel", func(t *testing.T) { + channel := make(chan Head, 1) + poller := NewPoller[Head](time.Millisecond, pollFunc, time.Second, channel, lggr) + err := poller.Start() + require.NoError(t, err) + + <-channel + close(channel) + poller.Unsubscribe() + }) +} From 2e994684de6d326ff3dc4674986a10fbf28e3511 Mon Sep 17 00:00:00 2001 From: HenryNguyen5 <6404866+HenryNguyen5@users.noreply.github.com> Date: Sat, 27 Apr 2024 13:04:49 -0400 Subject: [PATCH 51/77] Remove codecov (#13020) --- codecov.yml | 15 - tools/bin/codecov | 1888 --------------------------------------- tools/bin/go_core_tests | 2 - 3 files changed, 1905 deletions(-) delete mode 100644 codecov.yml delete mode 100755 tools/bin/codecov diff --git a/codecov.yml b/codecov.yml deleted file mode 100644 index a70f1961e36..00000000000 --- a/codecov.yml +++ /dev/null @@ -1,15 +0,0 @@ -comment: false - -coverage: - status: - project: - default: - threshold: 1% - -github_checks: - annotations: false - -ignore: - - 'contracts/' # Disabled due to solidity-coverage not reporting coverage - - 'core/internal' - - 'core/scripts' diff --git a/tools/bin/codecov b/tools/bin/codecov deleted file mode 100755 index 36513ce06df..00000000000 --- a/tools/bin/codecov +++ /dev/null @@ -1,1888 +0,0 @@ -#!/usr/bin/env bash - -# Apache License Version 2.0, January 2004 -# https://github.com/codecov/codecov-bash/blob/master/LICENSE - -set -e +o pipefail - -VERSION="1.0.6" - -codecov_flags=( ) -url="https://codecov.io" -env="$CODECOV_ENV" -service="" -token="" -search_in="" -# shellcheck disable=SC2153 -flags="$CODECOV_FLAGS" -exit_with=0 -curlargs="" -curlawsargs="" -dump="0" -clean="0" -curl_s="-s" -name="$CODECOV_NAME" -include_cov="" -exclude_cov="" -ddp="$HOME/Library/Developer/Xcode/DerivedData" -xp="" -files="" -save_to="" -direct_file_upload="" -cacert="$CODECOV_CA_BUNDLE" -gcov_ignore="-not -path './bower_components/**' -not -path './node_modules/**' -not -path './vendor/**'" -gcov_include="" - -ft_gcov="1" -ft_coveragepy="1" -ft_fix="1" -ft_search="1" -ft_s3="1" -ft_network="1" -ft_xcodellvm="1" -ft_xcodeplist="0" -ft_gcovout="1" -ft_html="0" -ft_yaml="0" - -_git_root=$(git rev-parse --show-toplevel 2>/dev/null || hg root 2>/dev/null || echo "$PWD") -git_root="$_git_root" -remote_addr="" -if [ "$git_root" = "$PWD" ]; -then - git_root="." -fi - -branch_o="" -build_o="" -commit_o="" -pr_o="" -prefix_o="" -network_filter_o="" -search_in_o="" -slug_o="" -tag_o="" -url_o="" -git_ls_files_recurse_submodules_o="" -package="bash" - -commit="$VCS_COMMIT_ID" -branch="$VCS_BRANCH_NAME" -pr="$VCS_PULL_REQUEST" -slug="$VCS_SLUG" -tag="$VCS_TAG" -build_url="$CI_BUILD_URL" -build="$CI_BUILD_ID" -job="$CI_JOB_ID" - -beta_xcode_partials="" - -proj_root="$git_root" -gcov_exe="gcov" -gcov_arg="" - -b="\033[0;36m" -g="\033[0;32m" -r="\033[0;31m" -e="\033[0;90m" -y="\033[0;33m" -x="\033[0m" - -show_help() { -cat << EOF - - Codecov Bash $VERSION - - Global report uploading tool for Codecov - Documentation at https://docs.codecov.io/docs - Contribute at https://github.com/codecov/codecov-bash - - - -h Display this help and exit - -f FILE Target file(s) to upload - - -f "path/to/file" only upload this file - skips searching unless provided patterns below - - -f '!*.bar' ignore all files at pattern *.bar - -f '*.foo' include all files at pattern *.foo - Must use single quotes. - This is non-exclusive, use -s "*.foo" to match specific paths. - - -s DIR Directory to search for coverage reports. - Already searches project root and artifact folders. - -t TOKEN Set the private repository token - (option) set environment variable CODECOV_TOKEN=:uuid - - -t @/path/to/token_file - -t uuid - - -n NAME Custom defined name of the upload. Visible in Codecov UI - - -e ENV Specify environment variables to be included with this build - Also accepting environment variables: CODECOV_ENV=VAR,VAR2 - - -e VAR,VAR2 - - -k prefix Prefix filepaths to help resolve path fixing - - -i prefix Only include files in the network with a certain prefix. Useful for upload-specific path fixing - - -X feature Toggle functionalities - - -X gcov Disable gcov - -X coveragepy Disable python coverage - -X fix Disable report fixing - -X search Disable searching for reports - -X xcode Disable xcode processing - -X network Disable uploading the file network - -X gcovout Disable gcov output - -X html Enable coverage for HTML files - -X recursesubs Enable recurse submodules in git projects when searching for source files - -X yaml Enable coverage for YAML files - - -N The commit SHA of the parent for which you are uploading coverage. If not present, - the parent will be determined using the API of your repository provider. - When using the repository provider's API, the parent is determined via finding - the closest ancestor to the commit. - - -R root dir Used when not in git/hg project to identify project root directory - -F flag Flag the upload to group coverage metrics - - -F unittests This upload is only unittests - -F integration This upload is only integration tests - -F ui,chrome This upload is Chrome - UI tests - - -c Move discovered coverage reports to the trash - -z FILE Upload specified file directly to Codecov and bypass all report generation. - This is inteded to be used only with a pre-formatted Codecov report and is not - expected to work under any other circumstances. - -Z Exit with 1 if not successful. Default will Exit with 0 - - -- xcode -- - -D Custom Derived Data Path for Coverage.profdata and gcov processing - Default '~/Library/Developer/Xcode/DerivedData' - -J Specify packages to build coverage. Uploader will only build these packages. - This can significantly reduces time to build coverage reports. - - -J 'MyAppName' Will match "MyAppName" and "MyAppNameTests" - -J '^ExampleApp$' Will match only "ExampleApp" not "ExampleAppTests" - - -- gcov -- - -g GLOB Paths to ignore during gcov gathering - -G GLOB Paths to include during gcov gathering - -p dir Project root directory - Also used when preparing gcov - -x gcovexe gcov executable to run. Defaults to 'gcov' - -a gcovargs extra arguments to pass to gcov - - -- Override CI Environment Variables -- - These variables are automatically detected by popular CI providers - - -B branch Specify the branch name - -C sha Specify the commit sha - -P pr Specify the pull request number - -b build Specify the build number - -T tag Specify the git tag - - -- Enterprise -- - -u URL Set the target url for Enterprise customers - Not required when retrieving the bash uploader from your CCE - (option) Set environment variable CODECOV_URL=https://my-hosted-codecov.com - -r SLUG owner/repo slug used instead of the private repo token in Enterprise - (option) set environment variable CODECOV_SLUG=:owner/:repo - (option) set in your codecov.yml "codecov.slug" - -S PATH File path to your cacert.pem file used to verify ssl with Codecov Enterprise (optional) - (option) Set environment variable: CODECOV_CA_BUNDLE="/path/to/ca.pem" - -U curlargs Extra curl arguments to communicate with Codecov. e.g., -U "--proxy http://http-proxy" - -A curlargs Extra curl arguments to communicate with AWS. - - -- Debugging -- - -d Don't upload, but dump upload file to stdout - -q PATH Write upload file to path - -K Remove color from the output - -v Verbose mode - -EOF -} - - -say() { - echo -e "$1" -} - - -urlencode() { - echo "$1" | curl -Gso /dev/null -w "%{url_effective}" --data-urlencode @- "" | cut -c 3- | sed -e 's/%0A//' -} - -swiftcov() { - _dir=$(dirname "$1" | sed 's/\(Build\).*/\1/g') - for _type in app framework xctest - do - find "$_dir" -name "*.$_type" | while read -r f - do - _proj=${f##*/} - _proj=${_proj%."$_type"} - if [ "$2" = "" ] || [ "$(echo "$_proj" | grep -i "$2")" != "" ]; - then - say " $g+$x Building reports for $_proj $_type" - dest=$([ -f "$f/$_proj" ] && echo "$f/$_proj" || echo "$f/Contents/MacOS/$_proj") - # shellcheck disable=SC2001 - _proj_name=$(echo "$_proj" | sed -e 's/[[:space:]]//g') - # shellcheck disable=SC2086 - xcrun llvm-cov show $beta_xcode_partials -instr-profile "$1" "$dest" > "$_proj_name.$_type.coverage.txt" \ - || say " ${r}x>${x} llvm-cov failed to produce results for $dest" - fi - done - done -} - - -# Credits to: https://gist.github.com/pkuczynski/8665367 -parse_yaml() { - local prefix=$2 - local s='[[:space:]]*' w='[a-zA-Z0-9_]*' - local fs - fs=$(echo @|tr @ '\034') - sed -ne "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \ - -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" "$1" | - awk -F"$fs" '{ - indent = length($1)/2; - vname[indent] = $2; - for (i in vname) {if (i > indent) {delete vname[i]}} - if (length($3) > 0) { - vn=""; if (indent > 0) {vn=(vn)(vname[0])("_")} - printf("%s%s%s=\"%s\"\n", "'"$prefix"'",vn, $2, $3); - } - }' -} - -if [ $# != 0 ]; -then - while getopts "a:A:b:B:cC:dD:e:f:F:g:G:hi:J:k:Kn:p:P:Q:q:r:R:s:S:t:T:u:U:vx:X:Zz:N:-" o - do - codecov_flags+=( "$o" ) - case "$o" in - "-") - echo -e "${r}Long options are not supported${x}" - exit 2 - ;; - "?") - ;; - "N") - parent=$OPTARG - ;; - "a") - gcov_arg=$OPTARG - ;; - "A") - curlawsargs="$OPTARG" - ;; - "b") - build_o="$OPTARG" - ;; - "B") - branch_o="$OPTARG" - ;; - "c") - clean="1" - ;; - "C") - commit_o="$OPTARG" - ;; - "d") - dump="1" - ;; - "D") - ddp="$OPTARG" - ;; - "e") - env="$env,$OPTARG" - ;; - "f") - if [ "${OPTARG::1}" = "!" ]; - then - exclude_cov="$exclude_cov -not -path '${OPTARG:1}'" - - elif [[ "$OPTARG" = *"*"* ]]; - then - include_cov="$include_cov -or -path '$OPTARG'" - - else - ft_search=0 - if [ "$files" = "" ]; - then - files="$OPTARG" - else - files="$files -$OPTARG" - fi - fi - ;; - "F") - if [ "$flags" = "" ]; - then - flags="$OPTARG" - else - flags="$flags,$OPTARG" - fi - ;; - "g") - gcov_ignore="$gcov_ignore -not -path '$OPTARG'" - ;; - "G") - gcov_include="$gcov_include -path '$OPTARG'" - ;; - "h") - show_help - exit 0; - ;; - "i") - network_filter_o="$OPTARG" - ;; - "J") - ft_xcodellvm="1" - ft_xcodeplist="0" - if [ "$xp" = "" ]; - then - xp="$OPTARG" - else - xp="$xp\|$OPTARG" - fi - ;; - "k") - prefix_o=$(echo "$OPTARG" | sed -e 's:^/*::' -e 's:/*$::') - ;; - "K") - b="" - g="" - r="" - e="" - x="" - ;; - "n") - name="$OPTARG" - ;; - "p") - proj_root="$OPTARG" - ;; - "P") - pr_o="$OPTARG" - ;; - "Q") - # this is only meant for Codecov packages to overwrite - package="$OPTARG" - ;; - "q") - save_to="$OPTARG" - ;; - "r") - slug_o="$OPTARG" - ;; - "R") - git_root="$OPTARG" - ;; - "s") - if [ "$search_in_o" = "" ]; - then - search_in_o="$OPTARG" - else - search_in_o="$search_in_o $OPTARG" - fi - ;; - "S") - # shellcheck disable=SC2089 - cacert="--cacert \"$OPTARG\"" - ;; - "t") - if [ "${OPTARG::1}" = "@" ]; - then - token=$(< "${OPTARG:1}" tr -d ' \n') - else - token="$OPTARG" - fi - ;; - "T") - tag_o="$OPTARG" - ;; - "u") - url_o=$(echo "$OPTARG" | sed -e 's/\/$//') - ;; - "U") - curlargs="$OPTARG" - ;; - "v") - set -x - curl_s="" - ;; - "x") - gcov_exe=$OPTARG - ;; - "X") - if [ "$OPTARG" = "gcov" ]; - then - ft_gcov="0" - elif [ "$OPTARG" = "coveragepy" ] || [ "$OPTARG" = "py" ]; - then - ft_coveragepy="0" - elif [ "$OPTARG" = "gcovout" ]; - then - ft_gcovout="0" - elif [ "$OPTARG" = "xcodellvm" ]; - then - ft_xcodellvm="1" - ft_xcodeplist="0" - elif [ "$OPTARG" = "fix" ] || [ "$OPTARG" = "fixes" ]; - then - ft_fix="0" - elif [ "$OPTARG" = "xcode" ]; - then - ft_xcodellvm="0" - ft_xcodeplist="0" - elif [ "$OPTARG" = "search" ]; - then - ft_search="0" - elif [ "$OPTARG" = "xcodepartials" ]; - then - beta_xcode_partials="-use-color" - elif [ "$OPTARG" = "network" ]; - then - ft_network="0" - elif [ "$OPTARG" = "s3" ]; - then - ft_s3="0" - elif [ "$OPTARG" = "html" ]; - then - ft_html="1" - elif [ "$OPTARG" = "recursesubs" ]; - then - git_ls_files_recurse_submodules_o="--recurse-submodules" - elif [ "$OPTARG" = "yaml" ]; - then - ft_yaml="1" - fi - ;; - "Z") - exit_with=1 - ;; - "z") - direct_file_upload="$OPTARG" - ft_gcov="0" - ft_coveragepy="0" - ft_fix="0" - ft_search="0" - ft_network="0" - ft_xcodellvm="0" - ft_gcovout="0" - include_cov="" - ;; - *) - echo -e "${r}Unexpected flag not supported${x}" - ;; - esac - done -fi - -say " - _____ _ - / ____| | | -| | ___ __| | ___ ___ _____ __ -| | / _ \\ / _\` |/ _ \\/ __/ _ \\ \\ / / -| |___| (_) | (_| | __/ (_| (_) \\ V / - \\_____\\___/ \\__,_|\\___|\\___\\___/ \\_/ - Bash-$VERSION - -" - -# check for installed tools -# git/hg -if [ "$direct_file_upload" = "" ]; -then - if [ -x "$(command -v git)" ]; - then - say "$b==>$x $(git --version) found" - else - say "$y==>$x git not installed, testing for mercurial" - if [ -x "$(command -v hg)" ]; - then - say "$b==>$x $(hg --version) found" - else - say "$r==>$x git nor mercurial are installed. Uploader may fail or have unintended consequences" - fi - fi -fi -# curl -if [ -x "$(command -v curl)" ]; -then - say "$b==>$x $(curl --version)" -else - say "$r==>$x curl not installed. Exiting." - exit ${exit_with}; -fi - -search_in="$proj_root" - -#shellcheck disable=SC2154 -if [ "$JENKINS_URL" != "" ]; -then - say "$e==>$x Jenkins CI detected." - # https://wiki.jenkins-ci.org/display/JENKINS/Building+a+software+project - # https://wiki.jenkins-ci.org/display/JENKINS/GitHub+pull+request+builder+plugin#GitHubpullrequestbuilderplugin-EnvironmentVariables - service="jenkins" - - # shellcheck disable=SC2154 - if [ "$ghprbSourceBranch" != "" ]; - then - branch="$ghprbSourceBranch" - elif [ "$GIT_BRANCH" != "" ]; - then - branch="$GIT_BRANCH" - elif [ "$BRANCH_NAME" != "" ]; - then - branch="$BRANCH_NAME" - fi - - # shellcheck disable=SC2154 - if [ "$ghprbActualCommit" != "" ]; - then - commit="$ghprbActualCommit" - elif [ "$GIT_COMMIT" != "" ]; - then - commit="$GIT_COMMIT" - fi - - # shellcheck disable=SC2154 - if [ "$ghprbPullId" != "" ]; - then - pr="$ghprbPullId" - elif [ "$CHANGE_ID" != "" ]; - then - pr="$CHANGE_ID" - fi - - build="$BUILD_NUMBER" - # shellcheck disable=SC2153 - build_url=$(urlencode "$BUILD_URL") - -elif [ "$CI" = "true" ] && [ "$TRAVIS" = "true" ] && [ "$SHIPPABLE" != "true" ]; -then - say "$e==>$x Travis CI detected." - # https://docs.travis-ci.com/user/environment-variables/ - service="travis" - commit="${TRAVIS_PULL_REQUEST_SHA:-$TRAVIS_COMMIT}" - build="$TRAVIS_JOB_NUMBER" - pr="$TRAVIS_PULL_REQUEST" - job="$TRAVIS_JOB_ID" - slug="$TRAVIS_REPO_SLUG" - env="$env,TRAVIS_OS_NAME" - tag="$TRAVIS_TAG" - if [ "$TRAVIS_BRANCH" != "$TRAVIS_TAG" ]; - then - branch="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" - fi - - language=$(compgen -A variable | grep "^TRAVIS_.*_VERSION$" | head -1) - if [ "$language" != "" ]; - then - env="$env,${!language}" - fi - -elif [ "$CODEBUILD_CI" = "true" ]; -then - say "$e==>$x AWS Codebuild detected." - # https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html - service="codebuild" - commit="$CODEBUILD_RESOLVED_SOURCE_VERSION" - build="$CODEBUILD_BUILD_ID" - branch="$(echo "$CODEBUILD_WEBHOOK_HEAD_REF" | sed 's/^refs\/heads\///')" - if [ "${CODEBUILD_SOURCE_VERSION/pr}" = "$CODEBUILD_SOURCE_VERSION" ] ; then - pr="false" - else - pr="$(echo "$CODEBUILD_SOURCE_VERSION" | sed 's/^pr\///')" - fi - job="$CODEBUILD_BUILD_ID" - slug="$(echo "$CODEBUILD_SOURCE_REPO_URL" | sed 's/^.*:\/\/[^\/]*\///' | sed 's/\.git$//')" - -elif [ "$CI" = "true" ] && [ "$CI_NAME" = "codeship" ]; -then - say "$e==>$x Codeship CI detected." - # https://www.codeship.io/documentation/continuous-integration/set-environment-variables/ - service="codeship" - branch="$CI_BRANCH" - build="$CI_BUILD_NUMBER" - build_url=$(urlencode "$CI_BUILD_URL") - commit="$CI_COMMIT_ID" - -elif [ -n "$CF_BUILD_URL" ] && [ -n "$CF_BUILD_ID" ]; -then - say "$e==>$x Codefresh CI detected." - # https://docs.codefresh.io/v1.0/docs/variables - service="codefresh" - branch="$CF_BRANCH" - build="$CF_BUILD_ID" - build_url=$(urlencode "$CF_BUILD_URL") - commit="$CF_REVISION" - -elif [ "$TEAMCITY_VERSION" != "" ]; -then - say "$e==>$x TeamCity CI detected." - # https://confluence.jetbrains.com/display/TCD8/Predefined+Build+Parameters - # https://confluence.jetbrains.com/plugins/servlet/mobile#content/view/74847298 - if [ "$TEAMCITY_BUILD_BRANCH" = '' ]; - then - echo " Teamcity does not automatically make build parameters available as environment variables." - echo " Add the following environment parameters to the build configuration" - echo " env.TEAMCITY_BUILD_BRANCH = %teamcity.build.branch%" - echo " env.TEAMCITY_BUILD_ID = %teamcity.build.id%" - echo " env.TEAMCITY_BUILD_URL = %teamcity.serverUrl%/viewLog.html?buildId=%teamcity.build.id%" - echo " env.TEAMCITY_BUILD_COMMIT = %system.build.vcs.number%" - echo " env.TEAMCITY_BUILD_REPOSITORY = %vcsroot..url%" - fi - service="teamcity" - branch="$TEAMCITY_BUILD_BRANCH" - build="$TEAMCITY_BUILD_ID" - build_url=$(urlencode "$TEAMCITY_BUILD_URL") - if [ "$TEAMCITY_BUILD_COMMIT" != "" ]; - then - commit="$TEAMCITY_BUILD_COMMIT" - else - commit="$BUILD_VCS_NUMBER" - fi - remote_addr="$TEAMCITY_BUILD_REPOSITORY" - -elif [ "$CI" = "true" ] && [ "$CIRCLECI" = "true" ]; -then - say "$e==>$x Circle CI detected." - # https://circleci.com/docs/environment-variables - service="circleci" - branch="$CIRCLE_BRANCH" - build="$CIRCLE_BUILD_NUM" - job="$CIRCLE_NODE_INDEX" - if [ "$CIRCLE_PROJECT_REPONAME" != "" ]; - then - slug="$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME" - else - # git@github.com:owner/repo.git - slug="${CIRCLE_REPOSITORY_URL##*:}" - # owner/repo.git - slug="${slug%%.git}" - fi - pr="${CIRCLE_PULL_REQUEST##*/}" - commit="$CIRCLE_SHA1" - search_in="$search_in $CIRCLE_ARTIFACTS $CIRCLE_TEST_REPORTS" - -elif [ "$BUDDYBUILD_BRANCH" != "" ]; -then - say "$e==>$x buddybuild detected" - # http://docs.buddybuild.com/v6/docs/custom-prebuild-and-postbuild-steps - service="buddybuild" - branch="$BUDDYBUILD_BRANCH" - build="$BUDDYBUILD_BUILD_NUMBER" - build_url="https://dashboard.buddybuild.com/public/apps/$BUDDYBUILD_APP_ID/build/$BUDDYBUILD_BUILD_ID" - # BUDDYBUILD_TRIGGERED_BY - if [ "$ddp" = "$HOME/Library/Developer/Xcode/DerivedData" ]; - then - ddp="/private/tmp/sandbox/${BUDDYBUILD_APP_ID}/bbtest" - fi - -elif [ "${bamboo_planRepository_revision}" != "" ]; -then - say "$e==>$x Bamboo detected" - # https://confluence.atlassian.com/bamboo/bamboo-variables-289277087.html#Bamboovariables-Build-specificvariables - service="bamboo" - commit="${bamboo_planRepository_revision}" - # shellcheck disable=SC2154 - branch="${bamboo_planRepository_branch}" - # shellcheck disable=SC2154 - build="${bamboo_buildNumber}" - # shellcheck disable=SC2154 - build_url="${bamboo_buildResultsUrl}" - # shellcheck disable=SC2154 - remote_addr="${bamboo_planRepository_repositoryUrl}" - -elif [ "$CI" = "true" ] && [ "$BITRISE_IO" = "true" ]; -then - # http://devcenter.bitrise.io/faq/available-environment-variables/ - say "$e==>$x Bitrise CI detected." - service="bitrise" - branch="$BITRISE_GIT_BRANCH" - build="$BITRISE_BUILD_NUMBER" - build_url=$(urlencode "$BITRISE_BUILD_URL") - pr="$BITRISE_PULL_REQUEST" - if [ "$GIT_CLONE_COMMIT_HASH" != "" ]; - then - commit="$GIT_CLONE_COMMIT_HASH" - fi - -elif [ "$CI" = "true" ] && [ "$SEMAPHORE" = "true" ]; -then - say "$e==>$x Semaphore CI detected." -# https://docs.semaphoreci.com/ci-cd-environment/environment-variables/#semaphore-related - service="semaphore" - branch="$SEMAPHORE_GIT_BRANCH" - build="$SEMAPHORE_WORKFLOW_NUMBER" - job="$SEMAPHORE_JOB_ID" - pr="$PULL_REQUEST_NUMBER" - slug="$SEMAPHORE_REPO_SLUG" - commit="$REVISION" - env="$env,SEMAPHORE_TRIGGER_SOURCE" - -elif [ "$CI" = "true" ] && [ "$BUILDKITE" = "true" ]; -then - say "$e==>$x Buildkite CI detected." - # https://buildkite.com/docs/guides/environment-variables - service="buildkite" - branch="$BUILDKITE_BRANCH" - build="$BUILDKITE_BUILD_NUMBER" - job="$BUILDKITE_JOB_ID" - build_url=$(urlencode "$BUILDKITE_BUILD_URL") - slug="$BUILDKITE_PROJECT_SLUG" - commit="$BUILDKITE_COMMIT" - if [[ "$BUILDKITE_PULL_REQUEST" != "false" ]]; then - pr="$BUILDKITE_PULL_REQUEST" - fi - tag="$BUILDKITE_TAG" - -elif [ "$CI" = "drone" ] || [ "$DRONE" = "true" ]; -then - say "$e==>$x Drone CI detected." - # http://docs.drone.io/env.html - # drone commits are not full shas - service="drone.io" - branch="$DRONE_BRANCH" - build="$DRONE_BUILD_NUMBER" - build_url=$(urlencode "${DRONE_BUILD_LINK}") - pr="$DRONE_PULL_REQUEST" - job="$DRONE_JOB_NUMBER" - tag="$DRONE_TAG" - -elif [ "$CI" = "true" ] && [ "$HEROKU_TEST_RUN_BRANCH" != "" ]; -then - say "$e==>$x Heroku CI detected." - # https://devcenter.heroku.com/articles/heroku-ci#environment-variables - service="heroku" - branch="$HEROKU_TEST_RUN_BRANCH" - build="$HEROKU_TEST_RUN_ID" - commit="$HEROKU_TEST_RUN_COMMIT_VERSION" - -elif [[ "$CI" = "true" || "$CI" = "True" ]] && [[ "$APPVEYOR" = "true" || "$APPVEYOR" = "True" ]]; -then - say "$e==>$x Appveyor CI detected." - # http://www.appveyor.com/docs/environment-variables - service="appveyor" - branch="$APPVEYOR_REPO_BRANCH" - build=$(urlencode "$APPVEYOR_JOB_ID") - pr="$APPVEYOR_PULL_REQUEST_NUMBER" - job="$APPVEYOR_ACCOUNT_NAME%2F$APPVEYOR_PROJECT_SLUG%2F$APPVEYOR_BUILD_VERSION" - slug="$APPVEYOR_REPO_NAME" - commit="$APPVEYOR_REPO_COMMIT" - build_url=$(urlencode "${APPVEYOR_URL}/project/${APPVEYOR_REPO_NAME}/builds/$APPVEYOR_BUILD_ID/job/${APPVEYOR_JOB_ID}") - -elif [ "$CI" = "true" ] && [ "$WERCKER_GIT_BRANCH" != "" ]; -then - say "$e==>$x Wercker CI detected." - # http://devcenter.wercker.com/articles/steps/variables.html - service="wercker" - branch="$WERCKER_GIT_BRANCH" - build="$WERCKER_MAIN_PIPELINE_STARTED" - slug="$WERCKER_GIT_OWNER/$WERCKER_GIT_REPOSITORY" - commit="$WERCKER_GIT_COMMIT" - -elif [ "$CI" = "true" ] && [ "$MAGNUM" = "true" ]; -then - say "$e==>$x Magnum CI detected." - # https://magnum-ci.com/docs/environment - service="magnum" - branch="$CI_BRANCH" - build="$CI_BUILD_NUMBER" - commit="$CI_COMMIT" - -elif [ "$SHIPPABLE" = "true" ]; -then - say "$e==>$x Shippable CI detected." - # http://docs.shippable.com/ci_configure/ - service="shippable" - # shellcheck disable=SC2153 - branch=$([ "$HEAD_BRANCH" != "" ] && echo "$HEAD_BRANCH" || echo "$BRANCH") - build="$BUILD_NUMBER" - build_url=$(urlencode "$BUILD_URL") - pr="$PULL_REQUEST" - slug="$REPO_FULL_NAME" - # shellcheck disable=SC2153 - commit="$COMMIT" - -elif [ "$TDDIUM" = "true" ]; -then - say "Solano CI detected." - # http://docs.solanolabs.com/Setup/tddium-set-environment-variables/ - service="solano" - commit="$TDDIUM_CURRENT_COMMIT" - branch="$TDDIUM_CURRENT_BRANCH" - build="$TDDIUM_TID" - pr="$TDDIUM_PR_ID" - -elif [ "$GREENHOUSE" = "true" ]; -then - say "$e==>$x Greenhouse CI detected." - # http://docs.greenhouseci.com/docs/environment-variables-files - service="greenhouse" - branch="$GREENHOUSE_BRANCH" - build="$GREENHOUSE_BUILD_NUMBER" - build_url=$(urlencode "$GREENHOUSE_BUILD_URL") - pr="$GREENHOUSE_PULL_REQUEST" - commit="$GREENHOUSE_COMMIT" - search_in="$search_in $GREENHOUSE_EXPORT_DIR" - -elif [ "$GITLAB_CI" != "" ]; -then - say "$e==>$x GitLab CI detected." - # http://doc.gitlab.com/ce/ci/variables/README.html - service="gitlab" - branch="${CI_BUILD_REF_NAME:-$CI_COMMIT_REF_NAME}" - build="${CI_BUILD_ID:-$CI_JOB_ID}" - remote_addr="${CI_BUILD_REPO:-$CI_REPOSITORY_URL}" - commit="${CI_BUILD_REF:-$CI_COMMIT_SHA}" - slug="${CI_PROJECT_PATH}" - -elif [ "$GITHUB_ACTIONS" != "" ]; -then - say "$e==>$x GitHub Actions detected." - say " Env vars used:" - say " -> GITHUB_ACTIONS: ${GITHUB_ACTIONS}" - say " -> GITHUB_HEAD_REF: ${GITHUB_HEAD_REF}" - say " -> GITHUB_REF: ${GITHUB_REF}" - say " -> GITHUB_REPOSITORY: ${GITHUB_REPOSITORY}" - say " -> GITHUB_RUN_ID: ${GITHUB_RUN_ID}" - say " -> GITHUB_SHA: ${GITHUB_SHA}" - say " -> GITHUB_WORKFLOW: ${GITHUB_WORKFLOW}" - - # https://github.com/features/actions - service="github-actions" - - # https://help.github.com/en/articles/virtual-environments-for-github-actions#environment-variables - branch="${GITHUB_REF#refs/heads/}" - if [ "$GITHUB_HEAD_REF" != "" ]; - then - # PR refs are in the format: refs/pull/7/merge - if [[ "$GITHUB_REF" =~ ^refs\/pull\/[0-9]+\/merge$ ]]; - then - pr="${GITHUB_REF#refs/pull/}" - pr="${pr%/merge}" - fi - branch="${GITHUB_HEAD_REF}" - fi - commit="${GITHUB_SHA}" - slug="${GITHUB_REPOSITORY}" - build="${GITHUB_RUN_ID}" - build_url=$(urlencode "${GITHUB_SERVER_URL:-https://github.com}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}") - job="$(urlencode "${GITHUB_WORKFLOW}")" - - # actions/checkout runs in detached HEAD - mc= - if [ -n "$pr" ] && [ "$pr" != false ] && [ "$commit_o" == "" ]; - then - mc=$(git show --no-patch --format="%P" 2>/dev/null || echo "") - - if [[ "$mc" =~ ^[a-z0-9]{40}[[:space:]][a-z0-9]{40}$ ]]; - then - mc=$(echo "$mc" | cut -d' ' -f2) - say " Fixing merge commit SHA $commit -> $mc" - commit=$mc - elif [[ "$mc" = "" ]]; - then - say "$r-> Issue detecting commit SHA. Please run actions/checkout with fetch-depth > 1 or set to 0$x" - fi - fi - -elif [ "$SYSTEM_TEAMFOUNDATIONSERVERURI" != "" ]; -then - say "$e==>$x Azure Pipelines detected." - # https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=vsts - # https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&viewFallbackFrom=vsts&tabs=yaml - service="azure_pipelines" - commit="$BUILD_SOURCEVERSION" - build="$BUILD_BUILDNUMBER" - if [ -z "$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" ]; - then - pr="$SYSTEM_PULLREQUEST_PULLREQUESTID" - else - pr="$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER" - fi - project="${SYSTEM_TEAMPROJECT}" - server_uri="${SYSTEM_TEAMFOUNDATIONSERVERURI}" - job="${BUILD_BUILDID}" - branch="${BUILD_SOURCEBRANCH#"refs/heads/"}" - build_url=$(urlencode "${SYSTEM_TEAMFOUNDATIONSERVERURI}${SYSTEM_TEAMPROJECT}/_build/results?buildId=${BUILD_BUILDID}") - - # azure/pipelines runs in detached HEAD - mc= - if [ -n "$pr" ] && [ "$pr" != false ]; - then - mc=$(git show --no-patch --format="%P" 2>/dev/null || echo "") - - if [[ "$mc" =~ ^[a-z0-9]{40}[[:space:]][a-z0-9]{40}$ ]]; - then - mc=$(echo "$mc" | cut -d' ' -f2) - say " Fixing merge commit SHA $commit -> $mc" - commit=$mc - fi - fi - -elif [ "$CI" = "true" ] && [ "$BITBUCKET_BUILD_NUMBER" != "" ]; -then - say "$e==>$x Bitbucket detected." - # https://confluence.atlassian.com/bitbucket/variables-in-pipelines-794502608.html - service="bitbucket" - branch="$BITBUCKET_BRANCH" - build="$BITBUCKET_BUILD_NUMBER" - slug="$BITBUCKET_REPO_OWNER/$BITBUCKET_REPO_SLUG" - job="$BITBUCKET_BUILD_NUMBER" - pr="$BITBUCKET_PR_ID" - commit="$BITBUCKET_COMMIT" - # See https://jira.atlassian.com/browse/BCLOUD-19393 - if [ "${#commit}" = 12 ]; - then - commit=$(git rev-parse "$BITBUCKET_COMMIT") - fi - -elif [ "$CI" = "true" ] && [ "$BUDDY" = "true" ]; -then - say "$e==>$x Buddy CI detected." - # https://buddy.works/docs/pipelines/environment-variables - service="buddy" - branch="$BUDDY_EXECUTION_BRANCH" - build="$BUDDY_EXECUTION_ID" - build_url=$(urlencode "$BUDDY_EXECUTION_URL") - commit="$BUDDY_EXECUTION_REVISION" - pr="$BUDDY_EXECUTION_PULL_REQUEST_NO" - tag="$BUDDY_EXECUTION_TAG" - slug="$BUDDY_REPO_SLUG" - -elif [ "$CIRRUS_CI" != "" ]; -then - say "$e==>$x Cirrus CI detected." - # https://cirrus-ci.org/guide/writing-tasks/#environment-variables - service="cirrus-ci" - slug="$CIRRUS_REPO_FULL_NAME" - branch="$CIRRUS_BRANCH" - pr="$CIRRUS_PR" - commit="$CIRRUS_CHANGE_IN_REPO" - build="$CIRRUS_BUILD_ID" - build_url=$(urlencode "https://cirrus-ci.com/task/$CIRRUS_TASK_ID") - job="$CIRRUS_TASK_NAME" - -elif [ "$DOCKER_REPO" != "" ]; -then - say "$e==>$x Docker detected." - # https://docs.docker.com/docker-cloud/builds/advanced/ - service="docker" - branch="$SOURCE_BRANCH" - commit="$SOURCE_COMMIT" - slug="$DOCKER_REPO" - tag="$CACHE_TAG" - env="$env,IMAGE_NAME" - -else - say "${r}x>${x} No CI provider detected." - say " Testing inside Docker? ${b}http://docs.codecov.io/docs/testing-with-docker${x}" - say " Testing with Tox? ${b}https://docs.codecov.io/docs/python#section-testing-with-tox${x}" - -fi - -say " ${e}current dir: ${x} $PWD" -say " ${e}project root:${x} $git_root" - -# find branch, commit, repo from git command -if [ "$GIT_BRANCH" != "" ]; -then - branch="$GIT_BRANCH" - -elif [ "$branch" = "" ]; -then - branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || hg branch 2>/dev/null || echo "") - if [ "$branch" = "HEAD" ]; - then - branch="" - fi -fi - -if [ "$commit_o" = "" ]; -then - if [ "$GIT_COMMIT" != "" ]; - then - commit="$GIT_COMMIT" - elif [ "$commit" = "" ]; - then - commit=$(git log -1 --format="%H" 2>/dev/null || hg id -i --debug 2>/dev/null | tr -d '+' || echo "") - fi -else - commit="$commit_o" -fi - -if [ "$CODECOV_TOKEN" != "" ] && [ "$token" = "" ]; -then - say "${e}-->${x} token set from env" - token="$CODECOV_TOKEN" -fi - -if [ "$CODECOV_URL" != "" ] && [ "$url_o" = "" ]; -then - say "${e}-->${x} url set from env" - url_o=$(echo "$CODECOV_URL" | sed -e 's/\/$//') -fi - -if [ "$CODECOV_SLUG" != "" ]; -then - say "${e}-->${x} slug set from env" - slug_o="$CODECOV_SLUG" - -elif [ "$slug" = "" ]; -then - if [ "$remote_addr" = "" ]; - then - remote_addr=$(git config --get remote.origin.url || hg paths default || echo '') - fi - if [ "$remote_addr" != "" ]; - then - if echo "$remote_addr" | grep -q "//"; then - # https - slug=$(echo "$remote_addr" | cut -d / -f 4,5 | sed -e 's/\.git$//') - else - # ssh - slug=$(echo "$remote_addr" | cut -d : -f 2 | sed -e 's/\.git$//') - fi - fi - if [ "$slug" = "/" ]; - then - slug="" - fi -fi - -yaml=$(cd "$git_root" && \ - git ls-files "*codecov.yml" "*codecov.yaml" 2>/dev/null \ - || hg locate "*codecov.yml" "*codecov.yaml" 2>/dev/null \ - || cd "$proj_root" && find . -maxdepth 1 -type f -name '*codecov.y*ml' 2>/dev/null \ - || echo '') -yaml=$(echo "$yaml" | head -1) - -if [ "$yaml" != "" ]; -then - say " ${e}Yaml found at:${x} $yaml" - if [[ "$yaml" != /* ]]; then - # relative path for yaml file given, assume relative to the repo root - yaml="$git_root/$yaml" - fi - config=$(parse_yaml "$yaml" || echo '') - - # TODO validate the yaml here - - if [ "$(echo "$config" | grep 'codecov_token="')" != "" ] && [ "$token" = "" ]; - then - say "${e}-->${x} token set from yaml" - token="$(echo "$config" | grep 'codecov_token="' | sed -e 's/codecov_token="//' | sed -e 's/"\.*//')" - fi - - if [ "$(echo "$config" | grep 'codecov_url="')" != "" ] && [ "$url_o" = "" ]; - then - say "${e}-->${x} url set from yaml" - url_o="$(echo "$config" | grep 'codecov_url="' | sed -e 's/codecov_url="//' | sed -e 's/"\.*//')" - fi - - if [ "$(echo "$config" | grep 'codecov_slug="')" != "" ] && [ "$slug_o" = "" ]; - then - say "${e}-->${x} slug set from yaml" - slug_o="$(echo "$config" | grep 'codecov_slug="' | sed -e 's/codecov_slug="//' | sed -e 's/"\.*//')" - fi -else - say " ${g}Yaml not found, that's ok! Learn more at${x} ${b}http://docs.codecov.io/docs/codecov-yaml${x}" -fi - -if [ "$branch_o" != "" ]; -then - branch=$(urlencode "$branch_o") -else - branch=$(urlencode "$branch") -fi - -if [ "$slug_o" = "" ]; -then - urlencoded_slug=$(urlencode "$slug") -else - urlencoded_slug=$(urlencode "$slug_o") -fi - -query="branch=$branch\ - &commit=$commit\ - &build=$([ "$build_o" = "" ] && echo "$build" || echo "$build_o")\ - &build_url=$build_url\ - &name=$(urlencode "$name")\ - &tag=$([ "$tag_o" = "" ] && echo "$tag" || echo "$tag_o")\ - &slug=$urlencoded_slug\ - &service=$service\ - &flags=$flags\ - &pr=$([ "$pr_o" = "" ] && echo "${pr##\#}" || echo "${pr_o##\#}")\ - &job=$job\ - &cmd_args=$(IFS=,; echo "${codecov_flags[*]}")" - -if [ -n "$project" ] && [ -n "$server_uri" ]; -then - query=$(echo "$query&project=$project&server_uri=$server_uri" | tr -d ' ') -fi - -if [ "$parent" != "" ]; -then - query=$(echo "parent=$parent&$query" | tr -d ' ') -fi - -if [ "$ft_search" = "1" ]; -then - # detect bower comoponents location - bower_components="bower_components" - bower_rc=$(cd "$git_root" && cat .bowerrc 2>/dev/null || echo "") - if [ "$bower_rc" != "" ]; - then - bower_components=$(echo "$bower_rc" | tr -d '\n' | grep '"directory"' | cut -d'"' -f4 | sed -e 's/\/$//') - if [ "$bower_components" = "" ]; - then - bower_components="bower_components" - fi - fi - - # Swift Coverage - if [ "$ft_xcodellvm" = "1" ] && [ -d "$ddp" ]; - then - say "${e}==>${x} Processing Xcode reports via llvm-cov" - say " DerivedData folder: $ddp" - profdata_files=$(find "$ddp" -name '*.profdata' 2>/dev/null || echo '') - if [ "$profdata_files" != "" ]; - then - # xcode via profdata - if [ "$xp" = "" ]; - then - # xp=$(xcodebuild -showBuildSettings 2>/dev/null | grep -i "^\s*PRODUCT_NAME" | sed -e 's/.*= \(.*\)/\1/') - # say " ${e}->${x} Speed up Xcode processing by adding ${e}-J '$xp'${x}" - say " ${g}hint${x} Speed up Swift processing by using use ${g}-J 'AppName'${x} (regexp accepted)" - say " ${g}hint${x} This will remove Pods/ from your report. Also ${b}https://docs.codecov.io/docs/ignoring-paths${x}" - fi - while read -r profdata; - do - if [ "$profdata" != "" ]; - then - swiftcov "$profdata" "$xp" - fi - done <<< "$profdata_files" - else - say " ${e}->${x} No Swift coverage found" - fi - - # Obj-C Gcov Coverage - if [ "$ft_gcov" = "1" ]; - then - say " ${e}->${x} Running $gcov_exe for Obj-C" - if [ "$ft_gcovout" = "0" ]; - then - # suppress gcov output - bash -c "find $ddp -type f -name '*.gcda' $gcov_include $gcov_ignore -exec $gcov_exe -p $gcov_arg {} +" >/dev/null 2>&1 || true - else - bash -c "find $ddp -type f -name '*.gcda' $gcov_include $gcov_ignore -exec $gcov_exe -p $gcov_arg {} +" || true - fi - fi - fi - - if [ "$ft_xcodeplist" = "1" ] && [ -d "$ddp" ]; - then - say "${e}==>${x} Processing Xcode plists" - plists_files=$(find "$ddp" -name '*.xccoverage' 2>/dev/null || echo '') - if [ "$plists_files" != "" ]; - then - while read -r plist; - do - if [ "$plist" != "" ]; - then - say " ${g}Found${x} plist file at $plist" - plutil -convert xml1 -o "$(basename "$plist").plist" -- "$plist" - fi - done <<< "$plists_files" - fi - fi - - # Gcov Coverage - if [ "$ft_gcov" = "1" ]; - then - say "${e}==>${x} Running $gcov_exe in $proj_root ${e}(disable via -X gcov)${x}" - if [ "$ft_gcovout" = "0" ]; - then - # suppress gcov output - bash -c "find $proj_root -type f -name '*.gcno' $gcov_include $gcov_ignore -exec $gcov_exe -pb $gcov_arg {} +" >/dev/null 2>&1 || true - else - bash -c "find $proj_root -type f -name '*.gcno' $gcov_include $gcov_ignore -exec $gcov_exe -pb $gcov_arg {} +" || true - fi - else - say "${e}==>${x} gcov disabled" - fi - - # Python Coverage - if [ "$ft_coveragepy" = "1" ]; - then - if [ ! -f coverage.xml ]; - then - if command -v coverage >/dev/null 2>&1; - then - say "${e}==>${x} Python coveragepy exists ${e}disable via -X coveragepy${x}" - - dotcoverage=$(find "$git_root" -name '.coverage' -or -name '.coverage.*' | head -1 || echo '') - if [ "$dotcoverage" != "" ]; - then - cd "$(dirname "$dotcoverage")" - if [ ! -f .coverage ]; - then - say " ${e}->${x} Running coverage combine" - coverage combine -a - fi - say " ${e}->${x} Running coverage xml" - if [ "$(coverage xml -i)" != "No data to report." ]; - then - files="$files -$PWD/coverage.xml" - else - say " ${r}No data to report.${x}" - fi - cd "$proj_root" - else - say " ${r}No .coverage file found.${x}" - fi - else - say "${e}==>${x} Python coveragepy not found" - fi - fi - else - say "${e}==>${x} Python coveragepy disabled" - fi - - if [ "$search_in_o" != "" ]; - then - # location override - search_in="$search_in_o" - fi - - say "$e==>$x Searching for coverage reports in:" - for _path in $search_in - do - say " ${g}+${x} $_path" - done - - patterns="find $search_in \( \ - -name vendor \ - -or -name '$bower_components' \ - -or -name '.egg-info*' \ - -or -name 'conftest_*.c.gcov' \ - -or -name .env \ - -or -name .envs \ - -or -name .git \ - -or -name .hg \ - -or -name .tox \ - -or -name .venv \ - -or -name .venvs \ - -or -name .virtualenv \ - -or -name .virtualenvs \ - -or -name .yarn-cache \ - -or -name __pycache__ \ - -or -name env \ - -or -name envs \ - -or -name htmlcov \ - -or -name js/generated/coverage \ - -or -name node_modules \ - -or -name venv \ - -or -name venvs \ - -or -name virtualenv \ - -or -name virtualenvs \ - \) -prune -or \ - -type f \( -name '*coverage*.*' \ - -or -name '*.clover' \ - -or -name '*.codecov.*' \ - -or -name '*.gcov' \ - -or -name '*.lcov' \ - -or -name '*.lst' \ - -or -name 'clover.xml' \ - -or -name 'cobertura.xml' \ - -or -name 'codecov.*' \ - -or -name 'cover.out' \ - -or -name 'codecov-result.json' \ - -or -name 'coverage-final.json' \ - -or -name 'excoveralls.json' \ - -or -name 'gcov.info' \ - -or -name 'jacoco*.xml' \ - -or -name '*Jacoco*.xml' \ - -or -name 'lcov.dat' \ - -or -name 'lcov.info' \ - -or -name 'luacov.report.out' \ - -or -name 'naxsi.info' \ - -or -name 'nosetests.xml' \ - -or -name 'report.xml' \ - $include_cov \) \ - $exclude_cov \ - -not -name '*.am' \ - -not -name '*.bash' \ - -not -name '*.bat' \ - -not -name '*.bw' \ - -not -name '*.cfg' \ - -not -name '*.class' \ - -not -name '*.cmake' \ - -not -name '*.cmake' \ - -not -name '*.conf' \ - -not -name '*.coverage' \ - -not -name '*.cp' \ - -not -name '*.cpp' \ - -not -name '*.crt' \ - -not -name '*.css' \ - -not -name '*.csv' \ - -not -name '*.csv' \ - -not -name '*.data' \ - -not -name '*.db' \ - -not -name '*.dox' \ - -not -name '*.ec' \ - -not -name '*.ec' \ - -not -name '*.egg' \ - -not -name '*.el' \ - -not -name '*.env' \ - -not -name '*.erb' \ - -not -name '*.exe' \ - -not -name '*.ftl' \ - -not -name '*.gif' \ - -not -name '*.gradle' \ - -not -name '*.gz' \ - -not -name '*.h' \ - -not -name '*.html' \ - -not -name '*.in' \ - -not -name '*.jade' \ - -not -name '*.jar*' \ - -not -name '*.jpeg' \ - -not -name '*.jpg' \ - -not -name '*.js' \ - -not -name '*.less' \ - -not -name '*.log' \ - -not -name '*.m4' \ - -not -name '*.mak*' \ - -not -name '*.md' \ - -not -name '*.o' \ - -not -name '*.p12' \ - -not -name '*.pem' \ - -not -name '*.png' \ - -not -name '*.pom*' \ - -not -name '*.profdata' \ - -not -name '*.proto' \ - -not -name '*.ps1' \ - -not -name '*.pth' \ - -not -name '*.py' \ - -not -name '*.pyc' \ - -not -name '*.pyo' \ - -not -name '*.rb' \ - -not -name '*.rsp' \ - -not -name '*.rst' \ - -not -name '*.ru' \ - -not -name '*.sbt' \ - -not -name '*.scss' \ - -not -name '*.scss' \ - -not -name '*.serialized' \ - -not -name '*.sh' \ - -not -name '*.snapshot' \ - -not -name '*.sql' \ - -not -name '*.svg' \ - -not -name '*.tar.tz' \ - -not -name '*.template' \ - -not -name '*.whl' \ - -not -name '*.xcconfig' \ - -not -name '*.xcoverage.*' \ - -not -name '*/classycle/report.xml' \ - -not -name '*codecov.yml' \ - -not -name '*~' \ - -not -name '.*coveragerc' \ - -not -name '.coverage*' \ - -not -name 'coverage-summary.json' \ - -not -name 'createdFiles.lst' \ - -not -name 'fullLocaleNames.lst' \ - -not -name 'include.lst' \ - -not -name 'inputFiles.lst' \ - -not -name 'phpunit-code-coverage.xml' \ - -not -name 'phpunit-coverage.xml' \ - -not -name 'remapInstanbul.coverage*.json' \ - -not -name 'scoverage.measurements.*' \ - -not -name 'test_*_coverage.txt' \ - -not -name 'testrunner-coverage*' \ - -print 2>/dev/null" - files=$(eval "$patterns" || echo '') - -elif [ "$include_cov" != "" ]; -then - files=$(eval "find $search_in -type f \( ${include_cov:5} \)$exclude_cov 2>/dev/null" || echo '') -elif [ "$direct_file_upload" != "" ]; -then - files=$direct_file_upload -fi - -num_of_files=$(echo "$files" | wc -l | tr -d ' ') -if [ "$num_of_files" != '' ] && [ "$files" != '' ]; -then - say " ${e}->${x} Found $num_of_files reports" -fi - -# no files found -if [ "$files" = "" ]; -then - say "${r}-->${x} No coverage report found." - say " Please visit ${b}http://docs.codecov.io/docs/supported-languages${x}" - exit ${exit_with}; -fi - -if [ "$ft_network" == "1" ]; -then - say "${e}==>${x} Detecting git/mercurial file structure" - network=$(cd "$git_root" && git ls-files $git_ls_files_recurse_submodules_o 2>/dev/null || hg locate 2>/dev/null || echo "") - if [ "$network" = "" ]; - then - network=$(find "$git_root" \( \ - -name virtualenv \ - -name .virtualenv \ - -name virtualenvs \ - -name .virtualenvs \ - -name '*.png' \ - -name '*.gif' \ - -name '*.jpg' \ - -name '*.jpeg' \ - -name '*.md' \ - -name .env \ - -name .envs \ - -name env \ - -name envs \ - -name .venv \ - -name .venvs \ - -name venv \ - -name venvs \ - -name .git \ - -name .egg-info \ - -name shunit2-2.1.6 \ - -name vendor \ - -name __pycache__ \ - -name node_modules \ - -path "*/$bower_components/*" \ - -path '*/target/delombok/*' \ - -path '*/build/lib/*' \ - -path '*/js/generated/coverage/*' \ - \) -prune -or \ - -type f -print 2>/dev/null || echo '') - fi - - if [ "$network_filter_o" != "" ]; - then - network=$(echo "$network" | grep -e "$network_filter_o/*") - fi - if [ "$prefix_o" != "" ]; - then - network=$(echo "$network" | awk "{print \"$prefix_o/\"\$0}") - fi -fi - -upload_file=$(mktemp /tmp/codecov.XXXXXX) -adjustments_file=$(mktemp /tmp/codecov.adjustments.XXXXXX) - -cleanup() { - rm -f "$upload_file" "$adjustments_file" "$upload_file.gz" -} - -trap cleanup INT ABRT TERM - - -if [ "$env" != "" ]; -then - inc_env="" - say "${e}==>${x} Appending build variables" - for varname in $(echo "$env" | tr ',' ' ') - do - if [ "$varname" != "" ]; - then - say " ${g}+${x} $varname" - inc_env="${inc_env}${varname}=$(eval echo "\$${varname}") -" - fi - done - echo "$inc_env<<<<<< ENV" >> "$upload_file" -fi - -# Append git file list -# write discovered yaml location -if [ "$direct_file_upload" = "" ]; -then - echo "$yaml" >> "$upload_file" -fi - -if [ "$ft_network" == "1" ]; -then - i="woff|eot|otf" # fonts - i="$i|gif|png|jpg|jpeg|psd" # images - i="$i|ptt|pptx|numbers|pages|md|txt|xlsx|docx|doc|pdf|csv" # docs - i="$i|.gitignore" # supporting docs - - if [ "$ft_html" != "1" ]; - then - i="$i|html" - fi - - if [ "$ft_yaml" != "1" ]; - then - i="$i|yml|yaml" - fi - - echo "$network" | grep -vwE "($i)$" >> "$upload_file" -fi -echo "<<<<<< network" >> "$upload_file" - -if [ "$direct_file_upload" = "" ]; -then - fr=0 - say "${e}==>${x} Reading reports" - while IFS='' read -r file; - do - # read the coverage file - if [ "$(echo "$file" | tr -d ' ')" != '' ]; - then - if [ -f "$file" ]; - then - report_len=$(wc -c < "$file") - if [ "$report_len" -ne 0 ]; - then - say " ${g}+${x} $file ${e}bytes=$(echo "$report_len" | tr -d ' ')${x}" - # append to to upload - _filename=$(basename "$file") - if [ "${_filename##*.}" = 'gcov' ]; - then - { - echo "# path=$(echo "$file.reduced" | sed "s|^$git_root/||")"; - # get file name - head -1 "$file"; - } >> "$upload_file" - # 1. remove source code - # 2. remove ending bracket lines - # 3. remove whitespace - # 4. remove contextual lines - # 5. remove function names - awk -F': *' '{print $1":"$2":"}' "$file" \ - | sed '\/: *} *$/d' \ - | sed 's/^ *//' \ - | sed '/^-/d' \ - | sed 's/^function.*/func/' >> "$upload_file" - else - { - echo "# path=${file//^$git_root/||}"; - cat "$file"; - } >> "$upload_file" - fi - echo "<<<<<< EOF" >> "$upload_file" - fr=1 - if [ "$clean" = "1" ]; - then - rm "$file" - fi - else - say " ${r}-${x} Skipping empty file $file" - fi - else - say " ${r}-${x} file not found at $file" - fi - fi - done <<< "$(echo -e "$files")" - - if [ "$fr" = "0" ]; - then - say "${r}-->${x} No coverage data found." - say " Please visit ${b}http://docs.codecov.io/docs/supported-languages${x}" - say " search for your projects language to learn how to collect reports." - exit ${exit_with}; - fi -else - cp "$direct_file_upload" "$upload_file" - if [ "$clean" = "1" ]; - then - rm "$direct_file_upload" - fi -fi - -if [ "$ft_fix" = "1" ]; -then - say "${e}==>${x} Appending adjustments" - say " ${b}https://docs.codecov.io/docs/fixing-reports${x}" - - empty_line='^[[:space:]]*$' - # // - syntax_comment='^[[:space:]]*//.*' - # /* or */ - syntax_comment_block='^[[:space:]]*(\/\*|\*\/)[[:space:]]*$' - # { or } - syntax_bracket='^[[:space:]]*[\{\}][[:space:]]*(//.*)?$' - # [ or ] - syntax_list='^[[:space:]]*[][][[:space:]]*(//.*)?$' - # func ... { - syntax_go_func='^[[:space:]]*func[[:space:]]*[\{][[:space:]]*$' - - # shellcheck disable=SC2089 - skip_dirs="-not -path '*/$bower_components/*' \ - -not -path '*/node_modules/*'" - - cut_and_join() { - awk 'BEGIN { FS=":" } - $3 ~ /\/\*/ || $3 ~ /\*\// { print $0 ; next } - $1!=key { if (key!="") print out ; key=$1 ; out=$1":"$2 ; next } - { out=out","$2 } - END { print out }' 2>/dev/null - } - - if echo "$network" | grep -m1 '.kt$' 1>/dev/null; - then - # skip brackets and comments - cd "$git_root" && \ - find . -type f \ - -name '*.kt' \ - -exec \ - grep -nIHE -e "$syntax_bracket" \ - -e "$syntax_comment_block" {} \; \ - | cut_and_join \ - >> "$adjustments_file" \ - || echo '' - - # last line in file - cd "$git_root" && \ - find . -type f \ - -name '*.kt' -exec \ - wc -l {} \; \ - | while read -r l; do echo "EOF: $l"; done \ - 2>/dev/null \ - >> "$adjustments_file" \ - || echo '' - fi - - if echo "$network" | grep -m1 '.go$' 1>/dev/null; - then - # skip empty lines, comments, and brackets - cd "$git_root" && \ - find . -type f \ - -not -path '*/vendor/*' \ - -not -path '*/caches/*' \ - -name '*.go' \ - -exec \ - grep -nIHE \ - -e "$empty_line" \ - -e "$syntax_comment" \ - -e "$syntax_comment_block" \ - -e "$syntax_bracket" \ - -e "$syntax_go_func" \ - {} \; \ - | cut_and_join \ - >> "$adjustments_file" \ - || echo '' - fi - - if echo "$network" | grep -m1 '.dart$' 1>/dev/null; - then - # skip brackets - cd "$git_root" && \ - find . -type f \ - -name '*.dart' \ - -exec \ - grep -nIHE \ - -e "$syntax_bracket" \ - {} \; \ - | cut_and_join \ - >> "$adjustments_file" \ - || echo '' - fi - - if echo "$network" | grep -m1 '.php$' 1>/dev/null; - then - # skip empty lines, comments, and brackets - cd "$git_root" && \ - find . -type f \ - -not -path "*/vendor/*" \ - -name '*.php' \ - -exec \ - grep -nIHE \ - -e "$syntax_list" \ - -e "$syntax_bracket" \ - -e '^[[:space:]]*\);[[:space:]]*(//.*)?$' \ - {} \; \ - | cut_and_join \ - >> "$adjustments_file" \ - || echo '' - fi - - if echo "$network" | grep -m1 '\(.c\.cpp\|.cxx\|.h\|.hpp\|.m\|.swift\|.vala\)$' 1>/dev/null; - then - # skip brackets - # shellcheck disable=SC2086,SC2090 - cd "$git_root" && \ - find . -type f \ - $skip_dirs \ - \( \ - -name '*.c' \ - -or -name '*.cpp' \ - -or -name '*.cxx' \ - -or -name '*.h' \ - -or -name '*.hpp' \ - -or -name '*.m' \ - -or -name '*.swift' \ - -or -name '*.vala' \ - \) -exec \ - grep -nIHE \ - -e "$empty_line" \ - -e "$syntax_bracket" \ - -e '// LCOV_EXCL' \ - {} \; \ - | cut_and_join \ - >> "$adjustments_file" \ - || echo '' - - # skip brackets - # shellcheck disable=SC2086,SC2090 - cd "$git_root" && \ - find . -type f \ - $skip_dirs \ - \( \ - -name '*.c' \ - -or -name '*.cpp' \ - -or -name '*.cxx' \ - -or -name '*.h' \ - -or -name '*.hpp' \ - -or -name '*.m' \ - -or -name '*.swift' \ - -or -name '*.vala' \ - \) -exec \ - grep -nIH '// LCOV_EXCL' \ - {} \; \ - >> "$adjustments_file" \ - || echo '' - - fi - - found=$(< "$adjustments_file" tr -d ' ') - - if [ "$found" != "" ]; - then - say " ${g}+${x} Found adjustments" - { - echo "# path=fixes"; - cat "$adjustments_file"; - echo "<<<<<< EOF"; - } >> "$upload_file" - rm -rf "$adjustments_file" - else - say " ${e}->${x} No adjustments found" - fi -fi - -if [ "$url_o" != "" ]; -then - url="$url_o" -fi - -if [ "$dump" != "0" ]; -then - # trim whitespace from query - say " ${e}->${x} Dumping upload file (no upload)" - echo "$url/upload/v4?$(echo "package=$package-$VERSION&$query" | tr -d ' ')" - cat "$upload_file" -else - if [ "$save_to" != "" ]; - then - say "${e}==>${x} Copying upload file to ${save_to}" - mkdir -p "$(dirname "$save_to")" - cp "$upload_file" "$save_to" - fi - - say "${e}==>${x} Gzipping contents" - gzip -nf9 "$upload_file" - say " $(du -h "$upload_file.gz")" - - query=$(echo "${query}" | tr -d ' ') - say "${e}==>${x} Uploading reports" - say " ${e}url:${x} $url" - say " ${e}query:${x} $query" - - # Full query (to display on terminal output) - query=$(echo "package=$package-$VERSION&token=$token&$query" | tr -d ' ') - queryNoToken=$(echo "package=$package-$VERSION&token=&$query" | tr -d ' ') - - if [ "$ft_s3" = "1" ]; - then - say "${e}->${x} Pinging Codecov" - say "$url/upload/v4?$queryNoToken" - # shellcheck disable=SC2086,2090 - res=$(curl $curl_s -X POST $cacert \ - --retry 5 --retry-delay 2 --connect-timeout 2 \ - -H 'X-Reduced-Redundancy: false' \ - -H 'X-Content-Type: application/x-gzip' \ - -H 'Content-Length: 0' \ - -H "X-Upload-Token: ${token}" \ - --write-out "\n%{response_code}\n" \ - $curlargs \ - "$url/upload/v4?$query" || true) - # a good reply is "https://codecov.io" + "\n" + "https://storage.googleapis.com/codecov/..." - s3target=$(echo "$res" | sed -n 2p) - status=$(tail -n1 <<< "$res") - - if [ "$status" = "200" ] && [ "$s3target" != "" ]; - then - say "${e}->${x} Uploading to" - say "${s3target}" - - # shellcheck disable=SC2086 - s3=$(curl -fiX PUT \ - --data-binary @"$upload_file.gz" \ - -H 'Content-Type: application/x-gzip' \ - -H 'Content-Encoding: gzip' \ - $curlawsargs \ - "$s3target" || true) - - if [ "$s3" != "" ]; - then - say " ${g}->${x} Reports have been successfully queued for processing at ${b}$(echo "$res" | sed -n 1p)${x}" - exit 0 - else - say " ${r}X>${x} Failed to upload" - fi - elif [ "$status" = "400" ]; - then - # 400 Error - say "${r}${res}${x}" - exit ${exit_with} - else - say "${r}${res}${x}" - fi - fi - - say "${e}==>${x} Uploading to Codecov" - - # shellcheck disable=SC2086,2090 - res=$(curl -X POST $cacert \ - --data-binary @"$upload_file.gz" \ - --retry 5 --retry-delay 2 --connect-timeout 2 \ - -H 'Content-Type: text/plain' \ - -H 'Content-Encoding: gzip' \ - -H 'X-Content-Encoding: gzip' \ - -H "X-Upload-Token: ${token}" \ - -H 'Accept: text/plain' \ - $curlargs \ - "$url/upload/v2?$query&attempt=$i" || echo 'HTTP 500') - # {"message": "Coverage reports upload successfully", "uploaded": true, "queued": true, "id": "...", "url": "https://codecov.io/..."\} - uploaded=$(grep -o '\"uploaded\": [a-z]*' <<< "$res" | head -1 | cut -d' ' -f2) - if [ "$uploaded" = "true" ] - then - say " Reports have been successfully queued for processing at ${b}$(echo "$res" | head -2 | tail -1)${x}" - exit 0 - else - say " ${g}${res}${x}" - exit ${exit_with} - fi - - say " ${r}X> Failed to upload coverage reports${x}" -fi - -exit ${exit_with} diff --git a/tools/bin/go_core_tests b/tools/bin/go_core_tests index 694a51d1f82..c0b0f43aed4 100755 --- a/tools/bin/go_core_tests +++ b/tools/bin/go_core_tests @@ -32,7 +32,5 @@ if [[ $EXITCODE != 0 ]]; then echo "Encountered test failures." else echo "All tests passed!" - # uploading coverage.txt to CodeCov - $(dirname "$0")/codecov -f coverage.txt fi exit $EXITCODE From 0a37c0ed5346df509b545c88278c026cb2adf375 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deividas=20Kar=C5=BEinauskas?= Date: Mon, 29 Apr 2024 08:32:38 +0300 Subject: [PATCH 52/77] CapabilityRegistry: add capability version (#12996) * Add capability response type and configuration contract * MUST NOT override existing capability version * MUST match configuration contract interface * Add wrappers * Include a tag to core changeset * Update ICapabilityConfiguration * Regen wrappers --- .changeset/curvy-weeks-cover.md | 5 ++ contracts/.changeset/funny-eagles-know.md | 5 ++ .../src/v0.8/keystone/CapabilityRegistry.sol | 58 +++++++++++++ .../interfaces/ICapabilityConfiguration.sol | 27 ++++++ .../src/v0.8/keystone/test/BaseTest.t.sol | 3 + ...CapabilityRegistry_AddCapabilityTest.t.sol | 82 +++++++++++++++++-- .../mocks/CapabilityConfigurationContract.sol | 13 +++ .../keystone_capability_registry.go | 10 ++- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 9 files changed, 195 insertions(+), 10 deletions(-) create mode 100644 .changeset/curvy-weeks-cover.md create mode 100644 contracts/.changeset/funny-eagles-know.md create mode 100644 contracts/src/v0.8/keystone/interfaces/ICapabilityConfiguration.sol create mode 100644 contracts/src/v0.8/keystone/test/mocks/CapabilityConfigurationContract.sol diff --git a/.changeset/curvy-weeks-cover.md b/.changeset/curvy-weeks-cover.md new file mode 100644 index 00000000000..0b19df8ad16 --- /dev/null +++ b/.changeset/curvy-weeks-cover.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#wip Keystone contract wrappers updated diff --git a/contracts/.changeset/funny-eagles-know.md b/contracts/.changeset/funny-eagles-know.md new file mode 100644 index 00000000000..46827824ad8 --- /dev/null +++ b/contracts/.changeset/funny-eagles-know.md @@ -0,0 +1,5 @@ +--- +"@chainlink/contracts": patch +--- + +#wip addCapability udpates diff --git a/contracts/src/v0.8/keystone/CapabilityRegistry.sol b/contracts/src/v0.8/keystone/CapabilityRegistry.sol index faedd858bef..17f5a3dd73f 100644 --- a/contracts/src/v0.8/keystone/CapabilityRegistry.sol +++ b/contracts/src/v0.8/keystone/CapabilityRegistry.sol @@ -3,8 +3,14 @@ pragma solidity ^0.8.0; import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol"; import {OwnerIsCreator} from "../shared/access/OwnerIsCreator.sol"; +import {IERC165} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol"; +import {EnumerableSet} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol"; +import {ICapabilityConfiguration} from "./interfaces/ICapabilityConfiguration.sol"; contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { + // Add the library methods + using EnumerableSet for EnumerableSet.Bytes32Set; + struct NodeOperator { /// @notice The address of the admin that can manage a node /// operator @@ -13,6 +19,16 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { string name; } + // CapabilityResponseType indicates whether remote response requires + // aggregation or is an already aggregated report. There are multiple + // possible ways to aggregate. + enum CapabilityResponseType { + // No additional aggregation is needed on the remote response. + REPORT, + // A number of identical observations need to be aggregated. + OBSERVATION_IDENTICAL + } + struct Capability { // Capability type, e.g. "data-streams-reports" // bytes32(string); validation regex: ^[a-z0-9_\-:]{1,32}$ @@ -21,12 +37,39 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { // Semver, e.g., "1.2.3" // bytes32(string); must be valid Semver + max 32 characters. bytes32 version; + // responseType indicates whether remote response requires + // aggregation or is an OCR report. There are multiple possible + // ways to aggregate. + CapabilityResponseType responseType; + // An address to the capability configuration contract. Having this defined + // on a capability enforces consistent configuration across DON instances + // serving the same capability. Configuration contract MUST implement + // CapabilityConfigurationContractInterface. + // + // The main use cases are: + // 1) Sharing capability configuration across DON instances + // 2) Inspect and modify on-chain configuration without off-chain + // capability code. + // + // It is not recommended to store configuration which requires knowledge of + // the DON membership. + address configurationContract; } /// @notice This error is thrown when trying to set a node operator's /// admin address to the zero address error InvalidNodeOperatorAdmin(); + /// @notice This error is thrown when trying add a capability that already + /// exists. + error CapabilityAlreadyExists(); + + /// @notice This error is thrown when trying to add a capability with a + /// configuration contract that does not implement the required interface. + /// @param proposedConfigurationContract The address of the proposed + /// configuration contract. + error InvalidCapabilityConfigurationContractInterface(address proposedConfigurationContract); + /// @notice This event is emitted when a new node operator is added /// @param nodeOperatorId The ID of the newly added node operator /// @param admin The address of the admin that can manage the node @@ -43,6 +86,7 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { event CapabilityAdded(bytes32 indexed capabilityId); mapping(bytes32 => Capability) private s_capabilities; + EnumerableSet.Bytes32Set private s_capabilityIds; /// @notice Mapping of node operators mapping(uint256 nodeOperatorId => NodeOperator) private s_nodeOperators; @@ -87,7 +131,21 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { function addCapability(Capability calldata capability) external onlyOwner { bytes32 capabilityId = getCapabilityID(capability.capabilityType, capability.version); + + if (s_capabilityIds.contains(capabilityId)) revert CapabilityAlreadyExists(); + + if (capability.configurationContract != address(0)) { + if ( + capability.configurationContract.code.length == 0 || + !IERC165(capability.configurationContract).supportsInterface( + ICapabilityConfiguration.getCapabilityConfiguration.selector + ) + ) revert InvalidCapabilityConfigurationContractInterface(capability.configurationContract); + } + + s_capabilityIds.add(capabilityId); s_capabilities[capabilityId] = capability; + emit CapabilityAdded(capabilityId); } diff --git a/contracts/src/v0.8/keystone/interfaces/ICapabilityConfiguration.sol b/contracts/src/v0.8/keystone/interfaces/ICapabilityConfiguration.sol new file mode 100644 index 00000000000..20447c9680a --- /dev/null +++ b/contracts/src/v0.8/keystone/interfaces/ICapabilityConfiguration.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +/// @notice Interface for capability configuration contract. It MUST be +/// implemented for a contract to be used as a capability configuration. +/// The contract MAY store configuration that is shared across multiple +/// DON instances and capability versions. +/// @dev This interface does not guarantee the configuration contract's +/// correctness. It is the responsibility of the contract owner to ensure +/// that the configuration contract emits the CapabilityConfigurationSet +/// event when the configuration is set. +interface ICapabilityConfiguration { + /// @notice Emitted when a capability configuration is set. + event CapabilityConfigurationSet(); + + /// @notice Returns the capability configuration for a particular DON instance. + /// @dev donId is required to get DON-specific configuration. It avoids a + /// situation where configuration size grows too large. + /// @param donId The DON instance ID. These are stored in the CapabilityRegistry. + /// @return configuration DON's configuration for the capability. + function getCapabilityConfiguration(uint256 donId) external view returns (bytes memory configuration); + + // Solidity does not support generic returns types, so this cannot be part of + // the interface. However, the implementation contract MAY implement this + // function to enable configuration decoding on-chain. + // function decodeCapabilityConfiguration(bytes configuration) external returns (TypedCapabilityConfigStruct config) +} diff --git a/contracts/src/v0.8/keystone/test/BaseTest.t.sol b/contracts/src/v0.8/keystone/test/BaseTest.t.sol index 5c4b4c91809..4517a256b15 100644 --- a/contracts/src/v0.8/keystone/test/BaseTest.t.sol +++ b/contracts/src/v0.8/keystone/test/BaseTest.t.sol @@ -3,14 +3,17 @@ pragma solidity ^0.8.19; import {Test} from "forge-std/Test.sol"; import {Constants} from "./Constants.t.sol"; +import {CapabilityConfigurationContract} from "./mocks/CapabilityConfigurationContract.sol"; import {CapabilityRegistry} from "../CapabilityRegistry.sol"; contract BaseTest is Test, Constants { CapabilityRegistry internal s_capabilityRegistry; + CapabilityConfigurationContract internal s_capabilityConfigurationContract; function setUp() public virtual { vm.startPrank(ADMIN); s_capabilityRegistry = new CapabilityRegistry(); + s_capabilityConfigurationContract = new CapabilityConfigurationContract(); } function _getNodeOperators() internal view returns (CapabilityRegistry.NodeOperator[] memory) { diff --git a/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddCapabilityTest.t.sol b/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddCapabilityTest.t.sol index 6fbdc43a2c7..d9e4b6b8383 100644 --- a/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddCapabilityTest.t.sol +++ b/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddCapabilityTest.t.sol @@ -2,16 +2,88 @@ pragma solidity ^0.8.19; import {BaseTest} from "./BaseTest.t.sol"; +import {CapabilityConfigurationContract} from "./mocks/CapabilityConfigurationContract.sol"; + import {CapabilityRegistry} from "../CapabilityRegistry.sol"; contract CapabilityRegistry_AddCapabilityTest is BaseTest { - function test_AddCapability() public { - s_capabilityRegistry.addCapability(CapabilityRegistry.Capability("data-streams-reports", "1.0.0")); + CapabilityRegistry.Capability private basicCapability = + CapabilityRegistry.Capability({ + capabilityType: "data-streams-reports", + version: "1.0.0", + responseType: CapabilityRegistry.CapabilityResponseType.REPORT, + configurationContract: address(0) + }); + + CapabilityRegistry.Capability private capabilityWithConfigurationContract = + CapabilityRegistry.Capability({ + capabilityType: "read-ethereum-mainnet-gas-price", + version: "1.0.2", + responseType: CapabilityRegistry.CapabilityResponseType.OBSERVATION_IDENTICAL, + configurationContract: address(s_capabilityConfigurationContract) + }); + + function test_RevertWhen_CalledByNonAdmin() public { + changePrank(STRANGER); + + vm.expectRevert("Only callable by owner"); + s_capabilityRegistry.addCapability(basicCapability); + } + + function test_RevertWhen_CapabilityExists() public { + // Successfully add the capability the first time + s_capabilityRegistry.addCapability(basicCapability); + + // Try to add the same capability again + vm.expectRevert(CapabilityRegistry.CapabilityAlreadyExists.selector); + s_capabilityRegistry.addCapability(basicCapability); + } + + function test_RevertWhen_ConfigurationContractNotDeployed() public { + address nonExistentContract = address(1); + capabilityWithConfigurationContract.configurationContract = nonExistentContract; + + vm.expectRevert( + abi.encodeWithSelector( + CapabilityRegistry.InvalidCapabilityConfigurationContractInterface.selector, + nonExistentContract + ) + ); + s_capabilityRegistry.addCapability(capabilityWithConfigurationContract); + } + + function test_RevertWhen_ConfigurationContractDoesNotMatchInterface() public { + CapabilityRegistry contractWithoutERC165 = new CapabilityRegistry(); + + vm.expectRevert(); + capabilityWithConfigurationContract.configurationContract = address(contractWithoutERC165); + s_capabilityRegistry.addCapability(capabilityWithConfigurationContract); + } + + function test_AddCapability_NoConfigurationContract() public { + s_capabilityRegistry.addCapability(basicCapability); bytes32 capabilityId = s_capabilityRegistry.getCapabilityID(bytes32("data-streams-reports"), bytes32("1.0.0")); - CapabilityRegistry.Capability memory capability = s_capabilityRegistry.getCapability(capabilityId); + CapabilityRegistry.Capability memory storedCapability = s_capabilityRegistry.getCapability(capabilityId); + + assertEq(storedCapability.capabilityType, basicCapability.capabilityType); + assertEq(storedCapability.version, basicCapability.version); + assertEq(uint256(storedCapability.responseType), uint256(basicCapability.responseType)); + assertEq(storedCapability.configurationContract, basicCapability.configurationContract); + } + + function test_AddCapability_WithConfiguration() public { + s_capabilityRegistry.addCapability(capabilityWithConfigurationContract); + + bytes32 capabilityId = s_capabilityRegistry.getCapabilityID( + bytes32(capabilityWithConfigurationContract.capabilityType), + bytes32(capabilityWithConfigurationContract.version) + ); + CapabilityRegistry.Capability memory storedCapability = s_capabilityRegistry.getCapability(capabilityId); - assertEq(capability.capabilityType, "data-streams-reports"); - assertEq(capability.version, "1.0.0"); + assertEq(storedCapability.capabilityType, capabilityWithConfigurationContract.capabilityType); + assertEq(storedCapability.version, capabilityWithConfigurationContract.version); + assertEq(uint256(storedCapability.responseType), uint256(capabilityWithConfigurationContract.responseType)); + assertEq(storedCapability.configurationContract, capabilityWithConfigurationContract.configurationContract); } } diff --git a/contracts/src/v0.8/keystone/test/mocks/CapabilityConfigurationContract.sol b/contracts/src/v0.8/keystone/test/mocks/CapabilityConfigurationContract.sol new file mode 100644 index 00000000000..0c3d8e0597d --- /dev/null +++ b/contracts/src/v0.8/keystone/test/mocks/CapabilityConfigurationContract.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {ICapabilityConfiguration} from "../../interfaces/ICapabilityConfiguration.sol"; +import {ERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165.sol"; + +contract CapabilityConfigurationContract is ICapabilityConfiguration, ERC165 { + mapping(uint256 => bytes) private s_donConfiguration; + + function getCapabilityConfiguration(uint256 donId) external view returns (bytes memory configuration) { + return s_donConfiguration[donId]; + } +} diff --git a/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go b/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go index 47c65d5276b..7e3ca7027eb 100644 --- a/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go +++ b/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go @@ -31,8 +31,10 @@ var ( ) type CapabilityRegistryCapability struct { - CapabilityType [32]byte - Version [32]byte + CapabilityType [32]byte + Version [32]byte + ResponseType uint8 + ConfigurationContract common.Address } type CapabilityRegistryNodeOperator struct { @@ -41,8 +43,8 @@ type CapabilityRegistryNodeOperator struct { } var CapabilityRegistryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"InvalidNodeOperatorAdmin\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"NodeOperatorRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"capability\",\"type\":\"tuple\"}],\"name\":\"addCapability\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"addNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityID\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"name\":\"getCapabilityID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"getNodeOperator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint256[]\"}],\"name\":\"removeNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b610ef1806101576000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c80636e5f2869116100765780638da5cb5b1161005b5780638da5cb5b146101b65780639cb7c5f4146101de578063f2fde38b1461024557600080fd5b80636e5f28691461019b57806379ba5097146101ae57600080fd5b8063229111f5116100a7578063229111f514610120578063398f37731461016857806365c14dc71461017b57600080fd5b8063181f5a77146100c35780631cdf63431461010b575b600080fd5b604080518082018252601881527f4361706162696c697479526567697374727920312e302e300000000000000000602082015290516101029190610957565b60405180910390f35b61011e6101193660046109bd565b610258565b005b61015a61012e3660046109ff565b604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b604051908152602001610102565b61011e6101763660046109bd565b61031b565b61018e610189366004610a21565b6104b4565b6040516101029190610a3a565b61011e6101a9366004610a7d565b61059a565b61011e610617565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610102565b61022a6101ec366004610a21565b604080518082019091526000808252602082015250600090815260026020908152604091829020825180840190935280548352600101549082015290565b60408051825181526020928301519281019290925201610102565b61011e610253366004610abe565b610719565b61026061072d565b60005b8181101561031657600083838381811061027f5761027f610ad9565b60209081029290920135600081815260039093526040832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001681559093509190506102d060018301826108a5565b50506040518181527f1e5877d7b3001d1569bf733b76c7eceda58bd6c031e5b8d0b7042308ba2e9d4f9060200160405180910390a15061030f81610b08565b9050610263565b505050565b61032361072d565b60005b8181101561031657600083838381811061034257610342610ad9565b90506020028101906103549190610b67565b61035d90610c4c565b805190915073ffffffffffffffffffffffffffffffffffffffff166103ae576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600454604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815260008681526003909252939020825181547fffffffffffffffffffffffff0000000000000000000000000000000000000000169216919091178155915190919060018201906104319082610db1565b5090505060046000815461044490610b08565b909155508151602083015160405173ffffffffffffffffffffffffffffffffffffffff909216917fda6697b182650034bd205cdc2dbfabb06bdb3a0a83a2b45bfefa3c4881284e0b9161049991859190610ecb565b60405180910390a25050806104ad90610b08565b9050610326565b6040805180820190915260008152606060208201526000828152600360209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff168352600181018054919284019161051190610d16565b80601f016020809104026020016040519081016040528092919081815260200182805461053d90610d16565b801561058a5780601f1061055f5761010080835404028352916020019161058a565b820191906000526020600020905b81548152906001019060200180831161056d57829003601f168201915b5050505050815250509050919050565b6105a261072d565b60408051823560208083018290528085013583850181905284518085038601815260609094018086528451948301949094206000818152600290935294822092835560019092019190915582917f65610e5677eedff94555572640e442f89848a109ef8593fa927ac30b2565ff069190a25050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461069d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61072161072d565b61072a816107b0565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610694565b565b3373ffffffffffffffffffffffffffffffffffffffff82160361082f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610694565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b5080546108b190610d16565b6000825580601f106108c1575050565b601f01602090049060005260206000209081019061072a91905b808211156108ef57600081556001016108db565b5090565b6000815180845260005b81811015610919576020818501810151868301820152016108fd565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061096a60208301846108f3565b9392505050565b60008083601f84011261098357600080fd5b50813567ffffffffffffffff81111561099b57600080fd5b6020830191508360208260051b85010111156109b657600080fd5b9250929050565b600080602083850312156109d057600080fd5b823567ffffffffffffffff8111156109e757600080fd5b6109f385828601610971565b90969095509350505050565b60008060408385031215610a1257600080fd5b50508035926020909101359150565b600060208284031215610a3357600080fd5b5035919050565b6020815273ffffffffffffffffffffffffffffffffffffffff825116602082015260006020830151604080840152610a7560608401826108f3565b949350505050565b600060408284031215610a8f57600080fd5b50919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610ab957600080fd5b919050565b600060208284031215610ad057600080fd5b61096a82610a95565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610b60577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610b9b57600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610bf757610bf7610ba5565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610c4457610c44610ba5565b604052919050565b600060408236031215610c5e57600080fd5b610c66610bd4565b610c6f83610a95565b815260208084013567ffffffffffffffff80821115610c8d57600080fd5b9085019036601f830112610ca057600080fd5b813581811115610cb257610cb2610ba5565b610ce2847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610bfd565b91508082523684828501011115610cf857600080fd5b80848401858401376000908201840152918301919091525092915050565b600181811c90821680610d2a57607f821691505b602082108103610a8f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b601f82111561031657600081815260208120601f850160051c81016020861015610d8a5750805b601f850160051c820191505b81811015610da957828155600101610d96565b505050505050565b815167ffffffffffffffff811115610dcb57610dcb610ba5565b610ddf81610dd98454610d16565b84610d63565b602080601f831160018114610e325760008415610dfc5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610da9565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015610e7f57888601518255948401946001909101908401610e60565b5085821015610ebb57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b828152604060208201526000610a7560408301846108f356fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[],\"name\":\"CapabilityAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedConfigurationContract\",\"type\":\"address\"}],\"name\":\"InvalidCapabilityConfigurationContractInterface\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeOperatorAdmin\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"NodeOperatorRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"capability\",\"type\":\"tuple\"}],\"name\":\"addCapability\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"addNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityID\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"name\":\"getCapabilityID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"getNodeOperator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint256[]\"}],\"name\":\"removeNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6112cb806101576000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c806365c14dc7116100765780638da5cb5b1161005b5780638da5cb5b1461018f5780639cb7c5f4146101b7578063f2fde38b146101d757600080fd5b806365c14dc71461016757806379ba50971461018757600080fd5b80631cdf6343116100a75780631cdf634314610120578063229111f514610133578063398f37731461015457600080fd5b8063117392ce146100c3578063181f5a77146100d8575b600080fd5b6100d66100d1366004610b88565b6101ea565b005b604080518082018252601881527f4361706162696c697479526567697374727920312e302e300000000000000000602082015290516101179190610c04565b60405180910390f35b6100d661012e366004610c63565b610420565b610146610141366004610ca5565b6104e3565b604051908152602001610117565b6100d6610162366004610c63565b610512565b61017a610175366004610cc7565b6106ab565b6040516101179190610ce0565b6100d6610791565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610117565b6101ca6101c5366004610cc7565b61088e565b6040516101179190610d52565b6100d66101e5366004610df0565b610938565b6101f261094c565b6000610203823560208401356104e3565b90506102106003826109cf565b15610247576040517fe288638f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102596080840160608501610df0565b73ffffffffffffffffffffffffffffffffffffffff16146103c9576102846080830160608401610df0565b73ffffffffffffffffffffffffffffffffffffffff163b158061036457506102b26080830160608401610df0565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f884efe6100000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff91909116906301ffc9a790602401602060405180830381865afa15801561033e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103629190610e0d565b155b156103c9576103796080830160608401610df0565b6040517fabb5e3fd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024015b60405180910390fd5b6103d46003826109ea565b50600081815260026020526040902082906103ef8282610e2f565b505060405181907f65610e5677eedff94555572640e442f89848a109ef8593fa927ac30b2565ff0690600090a25050565b61042861094c565b60005b818110156104de57600083838381811061044757610447610eb1565b60209081029290920135600081815260059093526040832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001681559093509190506104986001830182610b3a565b50506040518181527f1e5877d7b3001d1569bf733b76c7eceda58bd6c031e5b8d0b7042308ba2e9d4f9060200160405180910390a1506104d781610ee0565b905061042b565b505050565b604080516020808201859052818301849052825180830384018152606090920190925280519101205b92915050565b61051a61094c565b60005b818110156104de57600083838381811061053957610539610eb1565b905060200281019061054b9190610f3f565b61055490611024565b805190915073ffffffffffffffffffffffffffffffffffffffff166105a5576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600654604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815260008681526005909252939020825181547fffffffffffffffffffffffff000000000000000000000000000000000000000016921691909117815591519091906001820190610628908261118b565b5090505060066000815461063b90610ee0565b909155508151602083015160405173ffffffffffffffffffffffffffffffffffffffff909216917fda6697b182650034bd205cdc2dbfabb06bdb3a0a83a2b45bfefa3c4881284e0b91610690918591906112a5565b60405180910390a25050806106a490610ee0565b905061051d565b6040805180820190915260008152606060208201526000828152600560209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff1683526001810180549192840191610708906110f0565b80601f0160208091040260200160405190810160405280929190818152602001828054610734906110f0565b80156107815780601f1061075657610100808354040283529160200191610781565b820191906000526020600020905b81548152906001019060200180831161076457829003601f168201915b5050505050815250509050919050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610812576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016103c0565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b604080516080808201835260008083526020808401829052838501829052606084018290528582526002808252918590208551938401865280548452600180820154928501929092529182015493949293919284019160ff16908111156108f7576108f7610d23565b600181111561090857610908610d23565b815260029190910154610100900473ffffffffffffffffffffffffffffffffffffffff1660209091015292915050565b61094061094c565b610949816109f6565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146109cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103c0565b565b600081815260018301602052604081205415155b9392505050565b60006109e38383610aeb565b3373ffffffffffffffffffffffffffffffffffffffff821603610a75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103c0565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000818152600183016020526040812054610b325750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561050c565b50600061050c565b508054610b46906110f0565b6000825580601f10610b56575050565b601f01602090049060005260206000209081019061094991905b80821115610b845760008155600101610b70565b5090565b600060808284031215610b9a57600080fd5b50919050565b6000815180845260005b81811015610bc657602081850181015186830182015201610baa565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006109e36020830184610ba0565b60008083601f840112610c2957600080fd5b50813567ffffffffffffffff811115610c4157600080fd5b6020830191508360208260051b8501011115610c5c57600080fd5b9250929050565b60008060208385031215610c7657600080fd5b823567ffffffffffffffff811115610c8d57600080fd5b610c9985828601610c17565b90969095509350505050565b60008060408385031215610cb857600080fd5b50508035926020909101359150565b600060208284031215610cd957600080fd5b5035919050565b6020815273ffffffffffffffffffffffffffffffffffffffff825116602082015260006020830151604080840152610d1b6060840182610ba0565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b81518152602080830151908201526040820151608082019060028110610da1577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8060408401525073ffffffffffffffffffffffffffffffffffffffff606084015116606083015292915050565b73ffffffffffffffffffffffffffffffffffffffff8116811461094957600080fd5b600060208284031215610e0257600080fd5b81356109e381610dce565b600060208284031215610e1f57600080fd5b815180151581146109e357600080fd5b813581556020820135600182015560028101604083013560028110610e5357600080fd5b81546060850135610e6381610dce565b74ffffffffffffffffffffffffffffffffffffffff008160081b1660ff84167fffffffffffffffffffffff000000000000000000000000000000000000000000841617178455505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610f38577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610f7357600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610fcf57610fcf610f7d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561101c5761101c610f7d565b604052919050565b60006040823603121561103657600080fd5b61103e610fac565b823561104981610dce565b815260208381013567ffffffffffffffff8082111561106757600080fd5b9085019036601f83011261107a57600080fd5b81358181111561108c5761108c610f7d565b6110bc847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610fd5565b915080825236848285010111156110d257600080fd5b80848401858401376000908201840152918301919091525092915050565b600181811c9082168061110457607f821691505b602082108103610b9a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b601f8211156104de57600081815260208120601f850160051c810160208610156111645750805b601f850160051c820191505b8181101561118357828155600101611170565b505050505050565b815167ffffffffffffffff8111156111a5576111a5610f7d565b6111b9816111b384546110f0565b8461113d565b602080601f83116001811461120c57600084156111d65750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611183565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156112595788860151825594840194600190910190840161123a565b508582101561129557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b828152604060208201526000610d1b6040830184610ba056fea164736f6c6343000813000a", } var CapabilityRegistryABI = CapabilityRegistryMetaData.ABI diff --git a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 62a75a8a644..66d26cead2d 100644 --- a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,4 +1,4 @@ GETH_VERSION: 1.13.8 forwarder: ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.bin b4c900aae9e022f01abbac7993d41f93912247613ac6270b0c4da4ef6f2016e3 -keystone_capability_registry: ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.abi ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.bin 9eaa36e45c1b33c1fa72b7e25d6d1ca351413225611abb84ae053270b569cca4 +keystone_capability_registry: ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.abi ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.bin d526b850decbf88dbe3dd66ed2160f1c311fb4ee6df0ac50c91f31521b361a52 ocr3_capability: ../../../contracts/solc/v0.8.19/OCR3Capability/OCR3Capability.abi ../../../contracts/solc/v0.8.19/OCR3Capability/OCR3Capability.bin 9dcbdf55bd5729ba266148da3f17733eb592c871c2108ccca546618628fd9ad2 From 929312681fb27529915912e8bd6e4000559ea77f Mon Sep 17 00:00:00 2001 From: Christopher Dimitri Sastropranoto Date: Mon, 29 Apr 2024 18:15:28 +0700 Subject: [PATCH 53/77] Implement update node operators in capability registry (#12991) * implement update node operators in capability registry * address PR feedback * cache owner call * Validate config on NewApplication (#12997) * validate config on new application spawn * Add changeset * Check config only in the rebroadcast-transactions command * Configurable Mercury transmitter parameters (#12680) * Configurable Mercury transmitter parameters * Changeset * Remove commented code * add tag * Rename * LogPoller CLI command to resolve reorg greater than finality depth (#12867) * find lca and remove block after CLI * fix sort.Find typo * make RemoveBlocks local cmd * tests * added changeset * added tags to the changeset * fixed tests * make cmds, vars cases consistent * Fix Node Migration Test Check For Versions (#12982) * fix: prevent query syntax error if allowlist is empty (#12912) Co-authored-by: Morgan Kuphal <87319522+KuphJr@users.noreply.github.com> * Update wrappers * Formatting --------- Co-authored-by: george-dorin <120329946+george-dorin@users.noreply.github.com> Co-authored-by: Sam Co-authored-by: Dmytro Haidashenko <34754799+dhaidashenko@users.noreply.github.com> Co-authored-by: Tate Co-authored-by: Gabriel Paradiso Co-authored-by: Morgan Kuphal <87319522+KuphJr@users.noreply.github.com> Co-authored-by: DeividasK --- .changeset/early-paws-end.md | 5 + contracts/.changeset/lucky-bugs-buy.md | 5 + .../src/v0.8/keystone/CapabilityRegistry.sol | 40 +++++ ...lityRegistry_UpdateNodeOperatorsTest.t.sol | 60 +++++++ .../keystone_capability_registry.go | 159 +++++++++++++++++- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 6 files changed, 268 insertions(+), 3 deletions(-) create mode 100644 .changeset/early-paws-end.md create mode 100644 contracts/.changeset/lucky-bugs-buy.md create mode 100644 contracts/src/v0.8/keystone/test/CapabilityRegistry_UpdateNodeOperatorsTest.t.sol diff --git a/.changeset/early-paws-end.md b/.changeset/early-paws-end.md new file mode 100644 index 00000000000..1a3edb5083f --- /dev/null +++ b/.changeset/early-paws-end.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +generate gethwrappers for updating node operators in capability registry #internal diff --git a/contracts/.changeset/lucky-bugs-buy.md b/contracts/.changeset/lucky-bugs-buy.md new file mode 100644 index 00000000000..98a17d74af9 --- /dev/null +++ b/contracts/.changeset/lucky-bugs-buy.md @@ -0,0 +1,5 @@ +--- +"@chainlink/contracts": patch +--- + +Add function to update node operator' diff --git a/contracts/src/v0.8/keystone/CapabilityRegistry.sol b/contracts/src/v0.8/keystone/CapabilityRegistry.sol index 17f5a3dd73f..ddf1d9b5635 100644 --- a/contracts/src/v0.8/keystone/CapabilityRegistry.sol +++ b/contracts/src/v0.8/keystone/CapabilityRegistry.sol @@ -56,6 +56,16 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { address configurationContract; } + /// @notice This error is thrown when a caller is not allowed + /// to execute the transaction + error AccessForbidden(); + + /// @notice This error is thrown when there is a mismatch between + /// array arguments + /// @param lengthOne The length of the first array argument + /// @param lengthTwo The length of the second array argument + error LengthMismatch(uint256 lengthOne, uint256 lengthTwo); + /// @notice This error is thrown when trying to set a node operator's /// admin address to the zero address error InvalidNodeOperatorAdmin(); @@ -81,6 +91,12 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { /// @param nodeOperatorId The ID of the node operator that was removed event NodeOperatorRemoved(uint256 nodeOperatorId); + /// @notice This event is emitted when a node operator is updated + /// @param nodeOperatorId The ID of the node operator that was updated + /// @param admin The address of the node operator's admin + /// @param name The node operator's human readable name + event NodeOperatorUpdated(uint256 nodeOperatorId, address indexed admin, string name); + /// @notice This event is emitted when a new capability is added /// @param capabilityId The ID of the newly added capability event CapabilityAdded(bytes32 indexed capabilityId); @@ -122,6 +138,30 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { } } + /// @notice Updates a node operator + /// @param nodeOperatorIds The ID of the node operator being updated + function updateNodeOperators(uint256[] calldata nodeOperatorIds, NodeOperator[] calldata nodeOperators) external { + if (nodeOperatorIds.length != nodeOperators.length) + revert LengthMismatch(nodeOperatorIds.length, nodeOperators.length); + + address owner = owner(); + for (uint256 i; i < nodeOperatorIds.length; ++i) { + uint256 nodeOperatorId = nodeOperatorIds[i]; + NodeOperator memory nodeOperator = nodeOperators[i]; + if (nodeOperator.admin == address(0)) revert InvalidNodeOperatorAdmin(); + if (msg.sender != nodeOperator.admin && msg.sender != owner) revert AccessForbidden(); + + if ( + s_nodeOperators[nodeOperatorId].admin != nodeOperator.admin || + keccak256(abi.encode(s_nodeOperators[nodeOperatorId].name)) != keccak256(abi.encode(nodeOperator.name)) + ) { + s_nodeOperators[nodeOperatorId].admin = nodeOperator.admin; + s_nodeOperators[nodeOperatorId].name = nodeOperator.name; + emit NodeOperatorUpdated(nodeOperatorId, nodeOperator.admin, nodeOperator.name); + } + } + } + /// @notice Gets a node operator's data /// @param nodeOperatorId The ID of the node operator to query for /// @return NodeOperator The node operator data diff --git a/contracts/src/v0.8/keystone/test/CapabilityRegistry_UpdateNodeOperatorsTest.t.sol b/contracts/src/v0.8/keystone/test/CapabilityRegistry_UpdateNodeOperatorsTest.t.sol new file mode 100644 index 00000000000..4be8010dcb1 --- /dev/null +++ b/contracts/src/v0.8/keystone/test/CapabilityRegistry_UpdateNodeOperatorsTest.t.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {BaseTest} from "./BaseTest.t.sol"; +import {CapabilityRegistry} from "../CapabilityRegistry.sol"; + +contract CapabilityRegistry_UpdateNodeOperatorTest is BaseTest { + event NodeOperatorUpdated(uint256 nodeOperatorId, address indexed admin, string name); + + uint256 private constant TEST_NODE_OPERATOR_ID = 0; + address private constant NEW_NODE_OPERATOR_ADMIN = address(3); + string private constant NEW_NODE_OPERATOR_NAME = "new-node-operator"; + + function setUp() public override { + BaseTest.setUp(); + changePrank(ADMIN); + s_capabilityRegistry.addNodeOperators(_getNodeOperators()); + } + + function test_RevertWhen_CalledByNonAdminAndNonOwner() public { + changePrank(STRANGER); + vm.expectRevert(CapabilityRegistry.AccessForbidden.selector); + + CapabilityRegistry.NodeOperator[] memory nodeOperators = new CapabilityRegistry.NodeOperator[](1); + nodeOperators[0] = CapabilityRegistry.NodeOperator({admin: NEW_NODE_OPERATOR_ADMIN, name: NEW_NODE_OPERATOR_NAME}); + + uint256[] memory nodeOperatorIds = new uint256[](1); + nodeOperatorIds[0] = TEST_NODE_OPERATOR_ID; + s_capabilityRegistry.updateNodeOperators(nodeOperatorIds, nodeOperators); + } + + function test_RevertWhen_NodeOperatorAdminIsZeroAddress() public { + changePrank(ADMIN); + vm.expectRevert(CapabilityRegistry.InvalidNodeOperatorAdmin.selector); + CapabilityRegistry.NodeOperator[] memory nodeOperators = new CapabilityRegistry.NodeOperator[](1); + nodeOperators[0] = CapabilityRegistry.NodeOperator({admin: address(0), name: NEW_NODE_OPERATOR_NAME}); + + uint256[] memory nodeOperatorIds = new uint256[](1); + nodeOperatorIds[0] = TEST_NODE_OPERATOR_ID; + s_capabilityRegistry.updateNodeOperators(nodeOperatorIds, nodeOperators); + } + + function test_UpdatesNodeOperator() public { + changePrank(ADMIN); + + CapabilityRegistry.NodeOperator[] memory nodeOperators = new CapabilityRegistry.NodeOperator[](1); + nodeOperators[0] = CapabilityRegistry.NodeOperator({admin: NEW_NODE_OPERATOR_ADMIN, name: NEW_NODE_OPERATOR_NAME}); + + uint256[] memory nodeOperatorIds = new uint256[](1); + nodeOperatorIds[0] = TEST_NODE_OPERATOR_ID; + + vm.expectEmit(true, true, true, true, address(s_capabilityRegistry)); + emit NodeOperatorUpdated(TEST_NODE_OPERATOR_ID, NEW_NODE_OPERATOR_ADMIN, NEW_NODE_OPERATOR_NAME); + s_capabilityRegistry.updateNodeOperators(nodeOperatorIds, nodeOperators); + + CapabilityRegistry.NodeOperator memory nodeOperator = s_capabilityRegistry.getNodeOperator(0); + assertEq(nodeOperator.admin, NEW_NODE_OPERATOR_ADMIN); + assertEq(nodeOperator.name, NEW_NODE_OPERATOR_NAME); + } +} diff --git a/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go b/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go index 7e3ca7027eb..61060bcb8ea 100644 --- a/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go +++ b/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go @@ -43,8 +43,8 @@ type CapabilityRegistryNodeOperator struct { } var CapabilityRegistryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"CapabilityAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedConfigurationContract\",\"type\":\"address\"}],\"name\":\"InvalidCapabilityConfigurationContractInterface\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeOperatorAdmin\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"NodeOperatorRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"capability\",\"type\":\"tuple\"}],\"name\":\"addCapability\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"addNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityID\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"name\":\"getCapabilityID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"getNodeOperator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint256[]\"}],\"name\":\"removeNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6112cb806101576000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c806365c14dc7116100765780638da5cb5b1161005b5780638da5cb5b1461018f5780639cb7c5f4146101b7578063f2fde38b146101d757600080fd5b806365c14dc71461016757806379ba50971461018757600080fd5b80631cdf6343116100a75780631cdf634314610120578063229111f514610133578063398f37731461015457600080fd5b8063117392ce146100c3578063181f5a77146100d8575b600080fd5b6100d66100d1366004610b88565b6101ea565b005b604080518082018252601881527f4361706162696c697479526567697374727920312e302e300000000000000000602082015290516101179190610c04565b60405180910390f35b6100d661012e366004610c63565b610420565b610146610141366004610ca5565b6104e3565b604051908152602001610117565b6100d6610162366004610c63565b610512565b61017a610175366004610cc7565b6106ab565b6040516101179190610ce0565b6100d6610791565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610117565b6101ca6101c5366004610cc7565b61088e565b6040516101179190610d52565b6100d66101e5366004610df0565b610938565b6101f261094c565b6000610203823560208401356104e3565b90506102106003826109cf565b15610247576040517fe288638f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102596080840160608501610df0565b73ffffffffffffffffffffffffffffffffffffffff16146103c9576102846080830160608401610df0565b73ffffffffffffffffffffffffffffffffffffffff163b158061036457506102b26080830160608401610df0565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f884efe6100000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff91909116906301ffc9a790602401602060405180830381865afa15801561033e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103629190610e0d565b155b156103c9576103796080830160608401610df0565b6040517fabb5e3fd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024015b60405180910390fd5b6103d46003826109ea565b50600081815260026020526040902082906103ef8282610e2f565b505060405181907f65610e5677eedff94555572640e442f89848a109ef8593fa927ac30b2565ff0690600090a25050565b61042861094c565b60005b818110156104de57600083838381811061044757610447610eb1565b60209081029290920135600081815260059093526040832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001681559093509190506104986001830182610b3a565b50506040518181527f1e5877d7b3001d1569bf733b76c7eceda58bd6c031e5b8d0b7042308ba2e9d4f9060200160405180910390a1506104d781610ee0565b905061042b565b505050565b604080516020808201859052818301849052825180830384018152606090920190925280519101205b92915050565b61051a61094c565b60005b818110156104de57600083838381811061053957610539610eb1565b905060200281019061054b9190610f3f565b61055490611024565b805190915073ffffffffffffffffffffffffffffffffffffffff166105a5576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600654604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815260008681526005909252939020825181547fffffffffffffffffffffffff000000000000000000000000000000000000000016921691909117815591519091906001820190610628908261118b565b5090505060066000815461063b90610ee0565b909155508151602083015160405173ffffffffffffffffffffffffffffffffffffffff909216917fda6697b182650034bd205cdc2dbfabb06bdb3a0a83a2b45bfefa3c4881284e0b91610690918591906112a5565b60405180910390a25050806106a490610ee0565b905061051d565b6040805180820190915260008152606060208201526000828152600560209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff1683526001810180549192840191610708906110f0565b80601f0160208091040260200160405190810160405280929190818152602001828054610734906110f0565b80156107815780601f1061075657610100808354040283529160200191610781565b820191906000526020600020905b81548152906001019060200180831161076457829003601f168201915b5050505050815250509050919050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610812576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016103c0565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b604080516080808201835260008083526020808401829052838501829052606084018290528582526002808252918590208551938401865280548452600180820154928501929092529182015493949293919284019160ff16908111156108f7576108f7610d23565b600181111561090857610908610d23565b815260029190910154610100900473ffffffffffffffffffffffffffffffffffffffff1660209091015292915050565b61094061094c565b610949816109f6565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146109cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103c0565b565b600081815260018301602052604081205415155b9392505050565b60006109e38383610aeb565b3373ffffffffffffffffffffffffffffffffffffffff821603610a75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103c0565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000818152600183016020526040812054610b325750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561050c565b50600061050c565b508054610b46906110f0565b6000825580601f10610b56575050565b601f01602090049060005260206000209081019061094991905b80821115610b845760008155600101610b70565b5090565b600060808284031215610b9a57600080fd5b50919050565b6000815180845260005b81811015610bc657602081850181015186830182015201610baa565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006109e36020830184610ba0565b60008083601f840112610c2957600080fd5b50813567ffffffffffffffff811115610c4157600080fd5b6020830191508360208260051b8501011115610c5c57600080fd5b9250929050565b60008060208385031215610c7657600080fd5b823567ffffffffffffffff811115610c8d57600080fd5b610c9985828601610c17565b90969095509350505050565b60008060408385031215610cb857600080fd5b50508035926020909101359150565b600060208284031215610cd957600080fd5b5035919050565b6020815273ffffffffffffffffffffffffffffffffffffffff825116602082015260006020830151604080840152610d1b6060840182610ba0565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b81518152602080830151908201526040820151608082019060028110610da1577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8060408401525073ffffffffffffffffffffffffffffffffffffffff606084015116606083015292915050565b73ffffffffffffffffffffffffffffffffffffffff8116811461094957600080fd5b600060208284031215610e0257600080fd5b81356109e381610dce565b600060208284031215610e1f57600080fd5b815180151581146109e357600080fd5b813581556020820135600182015560028101604083013560028110610e5357600080fd5b81546060850135610e6381610dce565b74ffffffffffffffffffffffffffffffffffffffff008160081b1660ff84167fffffffffffffffffffffff000000000000000000000000000000000000000000841617178455505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610f38577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610f7357600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610fcf57610fcf610f7d565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561101c5761101c610f7d565b604052919050565b60006040823603121561103657600080fd5b61103e610fac565b823561104981610dce565b815260208381013567ffffffffffffffff8082111561106757600080fd5b9085019036601f83011261107a57600080fd5b81358181111561108c5761108c610f7d565b6110bc847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610fd5565b915080825236848285010111156110d257600080fd5b80848401858401376000908201840152918301919091525092915050565b600181811c9082168061110457607f821691505b602082108103610b9a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b601f8211156104de57600081815260208120601f850160051c810160208610156111645750805b601f850160051c820191505b8181101561118357828155600101611170565b505050505050565b815167ffffffffffffffff8111156111a5576111a5610f7d565b6111b9816111b384546110f0565b8461113d565b602080601f83116001811461120c57600084156111d65750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611183565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156112595788860151825594840194600190910190840161123a565b508582101561129557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b828152604060208201526000610d1b6040830184610ba056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CapabilityAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedConfigurationContract\",\"type\":\"address\"}],\"name\":\"InvalidCapabilityConfigurationContractInterface\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeOperatorAdmin\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"lengthOne\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lengthTwo\",\"type\":\"uint256\"}],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"NodeOperatorRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"capability\",\"type\":\"tuple\"}],\"name\":\"addCapability\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"addNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityID\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"name\":\"getCapabilityID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"getNodeOperator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint256[]\"}],\"name\":\"removeNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"updateNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611702806101576000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c8063398f3773116100815780638da5cb5b1161005b5780638da5cb5b146101ad5780639cb7c5f4146101d5578063f2fde38b146101f557600080fd5b8063398f37731461017257806365c14dc71461018557806379ba5097146101a557600080fd5b8063181f5a77116100b2578063181f5a77146100f65780631cdf63431461013e578063229111f51461015157600080fd5b80630c5801e3146100ce578063117392ce146100e3575b600080fd5b6100e16100dc366004610efe565b610208565b005b6100e16100f1366004610f6a565b610519565b604080518082018252601881527f4361706162696c697479526567697374727920312e302e300000000000000000602082015290516101359190610fe6565b60405180910390f35b6100e161014c366004610ff9565b61074a565b61016461015f36600461103b565b61080d565b604051908152602001610135565b6100e1610180366004610ff9565b61083c565b61019861019336600461105d565b6109d5565b6040516101359190611076565b6100e1610abb565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610135565b6101e86101e336600461105d565b610bb8565b60405161013591906110e8565b6100e1610203366004611186565b610c62565b828114610250576040517fab8b67c600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff16905b84811015610511576000868683818110610288576102886111a3565b90506020020135905060008585848181106102a5576102a56111a3565b90506020028101906102b791906111d2565b6102c0906112b7565b805190915073ffffffffffffffffffffffffffffffffffffffff16610311576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805173ffffffffffffffffffffffffffffffffffffffff16331480159061034e57503373ffffffffffffffffffffffffffffffffffffffff851614155b15610385576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160008381526005602052604090205473ffffffffffffffffffffffffffffffffffffffff908116911614158061043757506020808201516040516103cb9201610fe6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012060008681526005835292909220919261041e9260010191016113d0565b6040516020818303038152906040528051906020012014155b156104fe578051600083815260056020908152604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9093169290921782558201516001909101906104a490826114bf565b50806000015173ffffffffffffffffffffffffffffffffffffffff167f14c8f513e8a6d86d2d16b0cb64976de4e72386c4f8068eca3b7354373f8fe97a8383602001516040516104f59291906115d9565b60405180910390a25b50508061050a906115f2565b905061026c565b505050505050565b610521610c76565b60006105328235602084013561080d565b905061053f600382610cf9565b15610576576040517fe288638f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105886080840160608501611186565b73ffffffffffffffffffffffffffffffffffffffff16146106f3576105b36080830160608401611186565b73ffffffffffffffffffffffffffffffffffffffff163b158061069357506105e16080830160608401611186565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f884efe6100000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff91909116906301ffc9a790602401602060405180830381865afa15801561066d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106919190611651565b155b156106f3576106a86080830160608401611186565b6040517fabb5e3fd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610247565b6106fe600382610d14565b50600081815260026020526040902082906107198282611673565b505060405181907f65610e5677eedff94555572640e442f89848a109ef8593fa927ac30b2565ff0690600090a25050565b610752610c76565b60005b81811015610808576000838383818110610771576107716111a3565b60209081029290920135600081815260059093526040832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001681559093509190506107c26001830182610e64565b50506040518181527f1e5877d7b3001d1569bf733b76c7eceda58bd6c031e5b8d0b7042308ba2e9d4f9060200160405180910390a150610801816115f2565b9050610755565b505050565b604080516020808201859052818301849052825180830384018152606090920190925280519101205b92915050565b610844610c76565b60005b81811015610808576000838383818110610863576108636111a3565b905060200281019061087591906111d2565b61087e906112b7565b805190915073ffffffffffffffffffffffffffffffffffffffff166108cf576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600654604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815260008681526005909252939020825181547fffffffffffffffffffffffff00000000000000000000000000000000000000001692169190911781559151909190600182019061095290826114bf565b50905050600660008154610965906115f2565b909155508151602083015160405173ffffffffffffffffffffffffffffffffffffffff909216917fda6697b182650034bd205cdc2dbfabb06bdb3a0a83a2b45bfefa3c4881284e0b916109ba918591906115d9565b60405180910390a25050806109ce906115f2565b9050610847565b6040805180820190915260008152606060208201526000828152600560209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff1683526001810180549192840191610a3290611383565b80601f0160208091040260200160405190810160405280929190818152602001828054610a5e90611383565b8015610aab5780601f10610a8057610100808354040283529160200191610aab565b820191906000526020600020905b815481529060010190602001808311610a8e57829003601f168201915b5050505050815250509050919050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b3c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610247565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b604080516080808201835260008083526020808401829052838501829052606084018290528582526002808252918590208551938401865280548452600180820154928501929092529182015493949293919284019160ff1690811115610c2157610c216110b9565b6001811115610c3257610c326110b9565b815260029190910154610100900473ffffffffffffffffffffffffffffffffffffffff1660209091015292915050565b610c6a610c76565b610c7381610d20565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610cf7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610247565b565b600081815260018301602052604081205415155b9392505050565b6000610d0d8383610e15565b3373ffffffffffffffffffffffffffffffffffffffff821603610d9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610247565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000818152600183016020526040812054610e5c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610836565b506000610836565b508054610e7090611383565b6000825580601f10610e80575050565b601f016020900490600052602060002090810190610c7391905b80821115610eae5760008155600101610e9a565b5090565b60008083601f840112610ec457600080fd5b50813567ffffffffffffffff811115610edc57600080fd5b6020830191508360208260051b8501011115610ef757600080fd5b9250929050565b60008060008060408587031215610f1457600080fd5b843567ffffffffffffffff80821115610f2c57600080fd5b610f3888838901610eb2565b90965094506020870135915080821115610f5157600080fd5b50610f5e87828801610eb2565b95989497509550505050565b600060808284031215610f7c57600080fd5b50919050565b6000815180845260005b81811015610fa857602081850181015186830182015201610f8c565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610d0d6020830184610f82565b6000806020838503121561100c57600080fd5b823567ffffffffffffffff81111561102357600080fd5b61102f85828601610eb2565b90969095509350505050565b6000806040838503121561104e57600080fd5b50508035926020909101359150565b60006020828403121561106f57600080fd5b5035919050565b6020815273ffffffffffffffffffffffffffffffffffffffff8251166020820152600060208301516040808401526110b16060840182610f82565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b81518152602080830151908201526040820151608082019060028110611137577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8060408401525073ffffffffffffffffffffffffffffffffffffffff606084015116606083015292915050565b73ffffffffffffffffffffffffffffffffffffffff81168114610c7357600080fd5b60006020828403121561119857600080fd5b8135610d0d81611164565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261120657600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561126257611262611210565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156112af576112af611210565b604052919050565b6000604082360312156112c957600080fd5b6112d161123f565b82356112dc81611164565b815260208381013567ffffffffffffffff808211156112fa57600080fd5b9085019036601f83011261130d57600080fd5b81358181111561131f5761131f611210565b61134f847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611268565b9150808252368482850101111561136557600080fd5b80848401858401376000908201840152918301919091525092915050565b600181811c9082168061139757607f821691505b602082108103610f7c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020808352600084546113e481611383565b80848701526040600180841660008114611405576001811461143d5761146b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a0101955061146b565b896000528660002060005b858110156114635781548b8201860152908301908801611448565b8a0184019650505b509398975050505050505050565b601f82111561080857600081815260208120601f850160051c810160208610156114a05750805b601f850160051c820191505b81811015610511578281556001016114ac565b815167ffffffffffffffff8111156114d9576114d9611210565b6114ed816114e78454611383565b84611479565b602080601f831160018114611540576000841561150a5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610511565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561158d5788860151825594840194600190910190840161156e565b50858210156115c957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b8281526040602082015260006110b16040830184610f82565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361164a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60006020828403121561166357600080fd5b81518015158114610d0d57600080fd5b81358155602082013560018201556002810160408301356002811061169757600080fd5b815460608501356116a781611164565b74ffffffffffffffffffffffffffffffffffffffff008160081b1660ff84167fffffffffffffffffffffff00000000000000000000000000000000000000000084161717845550505050505056fea164736f6c6343000813000a", } var CapabilityRegistryABI = CapabilityRegistryMetaData.ABI @@ -353,6 +353,18 @@ func (_CapabilityRegistry *CapabilityRegistryTransactorSession) TransferOwnershi return _CapabilityRegistry.Contract.TransferOwnership(&_CapabilityRegistry.TransactOpts, to) } +func (_CapabilityRegistry *CapabilityRegistryTransactor) UpdateNodeOperators(opts *bind.TransactOpts, nodeOperatorIds []*big.Int, nodeOperators []CapabilityRegistryNodeOperator) (*types.Transaction, error) { + return _CapabilityRegistry.contract.Transact(opts, "updateNodeOperators", nodeOperatorIds, nodeOperators) +} + +func (_CapabilityRegistry *CapabilityRegistrySession) UpdateNodeOperators(nodeOperatorIds []*big.Int, nodeOperators []CapabilityRegistryNodeOperator) (*types.Transaction, error) { + return _CapabilityRegistry.Contract.UpdateNodeOperators(&_CapabilityRegistry.TransactOpts, nodeOperatorIds, nodeOperators) +} + +func (_CapabilityRegistry *CapabilityRegistryTransactorSession) UpdateNodeOperators(nodeOperatorIds []*big.Int, nodeOperators []CapabilityRegistryNodeOperator) (*types.Transaction, error) { + return _CapabilityRegistry.Contract.UpdateNodeOperators(&_CapabilityRegistry.TransactOpts, nodeOperatorIds, nodeOperators) +} + type CapabilityRegistryCapabilityAddedIterator struct { Event *CapabilityRegistryCapabilityAdded @@ -726,6 +738,135 @@ func (_CapabilityRegistry *CapabilityRegistryFilterer) ParseNodeOperatorRemoved( return event, nil } +type CapabilityRegistryNodeOperatorUpdatedIterator struct { + Event *CapabilityRegistryNodeOperatorUpdated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CapabilityRegistryNodeOperatorUpdatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CapabilityRegistryNodeOperatorUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CapabilityRegistryNodeOperatorUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CapabilityRegistryNodeOperatorUpdatedIterator) Error() error { + return it.fail +} + +func (it *CapabilityRegistryNodeOperatorUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CapabilityRegistryNodeOperatorUpdated struct { + NodeOperatorId *big.Int + Admin common.Address + Name string + Raw types.Log +} + +func (_CapabilityRegistry *CapabilityRegistryFilterer) FilterNodeOperatorUpdated(opts *bind.FilterOpts, admin []common.Address) (*CapabilityRegistryNodeOperatorUpdatedIterator, error) { + + var adminRule []interface{} + for _, adminItem := range admin { + adminRule = append(adminRule, adminItem) + } + + logs, sub, err := _CapabilityRegistry.contract.FilterLogs(opts, "NodeOperatorUpdated", adminRule) + if err != nil { + return nil, err + } + return &CapabilityRegistryNodeOperatorUpdatedIterator{contract: _CapabilityRegistry.contract, event: "NodeOperatorUpdated", logs: logs, sub: sub}, nil +} + +func (_CapabilityRegistry *CapabilityRegistryFilterer) WatchNodeOperatorUpdated(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryNodeOperatorUpdated, admin []common.Address) (event.Subscription, error) { + + var adminRule []interface{} + for _, adminItem := range admin { + adminRule = append(adminRule, adminItem) + } + + logs, sub, err := _CapabilityRegistry.contract.WatchLogs(opts, "NodeOperatorUpdated", adminRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CapabilityRegistryNodeOperatorUpdated) + if err := _CapabilityRegistry.contract.UnpackLog(event, "NodeOperatorUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CapabilityRegistry *CapabilityRegistryFilterer) ParseNodeOperatorUpdated(log types.Log) (*CapabilityRegistryNodeOperatorUpdated, error) { + event := new(CapabilityRegistryNodeOperatorUpdated) + if err := _CapabilityRegistry.contract.UnpackLog(event, "NodeOperatorUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type CapabilityRegistryOwnershipTransferRequestedIterator struct { Event *CapabilityRegistryOwnershipTransferRequested @@ -1006,6 +1147,8 @@ func (_CapabilityRegistry *CapabilityRegistry) ParseLog(log types.Log) (generate return _CapabilityRegistry.ParseNodeOperatorAdded(log) case _CapabilityRegistry.abi.Events["NodeOperatorRemoved"].ID: return _CapabilityRegistry.ParseNodeOperatorRemoved(log) + case _CapabilityRegistry.abi.Events["NodeOperatorUpdated"].ID: + return _CapabilityRegistry.ParseNodeOperatorUpdated(log) case _CapabilityRegistry.abi.Events["OwnershipTransferRequested"].ID: return _CapabilityRegistry.ParseOwnershipTransferRequested(log) case _CapabilityRegistry.abi.Events["OwnershipTransferred"].ID: @@ -1028,6 +1171,10 @@ func (CapabilityRegistryNodeOperatorRemoved) Topic() common.Hash { return common.HexToHash("0x1e5877d7b3001d1569bf733b76c7eceda58bd6c031e5b8d0b7042308ba2e9d4f") } +func (CapabilityRegistryNodeOperatorUpdated) Topic() common.Hash { + return common.HexToHash("0x14c8f513e8a6d86d2d16b0cb64976de4e72386c4f8068eca3b7354373f8fe97a") +} + func (CapabilityRegistryOwnershipTransferRequested) Topic() common.Hash { return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") } @@ -1061,6 +1208,8 @@ type CapabilityRegistryInterface interface { TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + UpdateNodeOperators(opts *bind.TransactOpts, nodeOperatorIds []*big.Int, nodeOperators []CapabilityRegistryNodeOperator) (*types.Transaction, error) + FilterCapabilityAdded(opts *bind.FilterOpts, capabilityId [][32]byte) (*CapabilityRegistryCapabilityAddedIterator, error) WatchCapabilityAdded(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryCapabilityAdded, capabilityId [][32]byte) (event.Subscription, error) @@ -1079,6 +1228,12 @@ type CapabilityRegistryInterface interface { ParseNodeOperatorRemoved(log types.Log) (*CapabilityRegistryNodeOperatorRemoved, error) + FilterNodeOperatorUpdated(opts *bind.FilterOpts, admin []common.Address) (*CapabilityRegistryNodeOperatorUpdatedIterator, error) + + WatchNodeOperatorUpdated(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryNodeOperatorUpdated, admin []common.Address) (event.Subscription, error) + + ParseNodeOperatorUpdated(log types.Log) (*CapabilityRegistryNodeOperatorUpdated, error) + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CapabilityRegistryOwnershipTransferRequestedIterator, error) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) diff --git a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 66d26cead2d..e137d35ea5e 100644 --- a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,4 +1,4 @@ GETH_VERSION: 1.13.8 forwarder: ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.bin b4c900aae9e022f01abbac7993d41f93912247613ac6270b0c4da4ef6f2016e3 -keystone_capability_registry: ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.abi ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.bin d526b850decbf88dbe3dd66ed2160f1c311fb4ee6df0ac50c91f31521b361a52 +keystone_capability_registry: ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.abi ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.bin 5f801185084a6d6bcc08e0a37574d80f5092bc0dcd40808e9e04804064db0a56 ocr3_capability: ../../../contracts/solc/v0.8.19/OCR3Capability/OCR3Capability.abi ../../../contracts/solc/v0.8.19/OCR3Capability/OCR3Capability.bin 9dcbdf55bd5729ba266148da3f17733eb592c871c2108ccca546618628fd9ad2 From c97781582bbe0333332b985fb10a06edeaafa524 Mon Sep 17 00:00:00 2001 From: Dimitris Grigoriou Date: Mon, 29 Apr 2024 15:25:33 +0300 Subject: [PATCH 54/77] Transfer testutils (#12968) * Add first version of evm utils * Remove unused context util * Add WSServer tests * Add NewLegacyTransaction test * Update NewTestChainScopedConfig to apply correct defaults * Move testutils * Fix lint * Add changeset --- .changeset/fresh-rice-learn.md | 5 + core/chains/evm/testutils/client.go | 198 +++++++++++++++++++++++ core/chains/evm/testutils/config.go | 29 ++++ core/chains/evm/testutils/config_test.go | 22 +++ core/chains/evm/testutils/evmtypes.go | 76 +++++++++ core/chains/evm/testutils/timeout.go | 41 +++++ 6 files changed, 371 insertions(+) create mode 100644 .changeset/fresh-rice-learn.md create mode 100644 core/chains/evm/testutils/client.go create mode 100644 core/chains/evm/testutils/config.go create mode 100644 core/chains/evm/testutils/config_test.go create mode 100644 core/chains/evm/testutils/evmtypes.go create mode 100644 core/chains/evm/testutils/timeout.go diff --git a/.changeset/fresh-rice-learn.md b/.changeset/fresh-rice-learn.md new file mode 100644 index 00000000000..6425cdd4581 --- /dev/null +++ b/.changeset/fresh-rice-learn.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +Moved test functions under evm package to support evm extraction #internal diff --git a/core/chains/evm/testutils/client.go b/core/chains/evm/testutils/client.go new file mode 100644 index 00000000000..31ad23eeb81 --- /dev/null +++ b/core/chains/evm/testutils/client.go @@ -0,0 +1,198 @@ +package testutils + +import ( + "fmt" + "math/big" + "net/http" + "net/http/httptest" + "net/url" + "sync" + "testing" + "time" + + "github.com/gorilla/websocket" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/tidwall/gjson" + + evmclmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" +) + +func NewEthClientMock(t *testing.T) *evmclmocks.Client { + return evmclmocks.NewClient(t) +} + +func NewEthClientMockWithDefaultChain(t *testing.T) *evmclmocks.Client { + c := NewEthClientMock(t) + c.On("ConfiguredChainID").Return(FixtureChainID).Maybe() + //c.On("IsL2").Return(false).Maybe() + return c +} + +// JSONRPCHandler is called with the method and request param(s). +// respResult will be sent immediately. notifyResult is optional, and sent after a short delay. +type JSONRPCHandler func(reqMethod string, reqParams gjson.Result) JSONRPCResponse + +type JSONRPCResponse struct { + Result, Notify string // raw JSON (i.e. quoted strings etc.) + + Error struct { + Code int + Message string + } +} + +type testWSServer struct { + t *testing.T + s *httptest.Server + mu sync.RWMutex + wsconns []*websocket.Conn + wg sync.WaitGroup +} + +// NewWSServer starts a websocket server which invokes callback for each message received. +// If chainID is set, then eth_chainId calls will be automatically handled. +func NewWSServer(t *testing.T, chainID *big.Int, callback JSONRPCHandler) (ts *testWSServer) { + ts = new(testWSServer) + ts.t = t + ts.wsconns = make([]*websocket.Conn, 0) + handler := ts.newWSHandler(chainID, callback) + ts.s = httptest.NewServer(handler) + t.Cleanup(ts.Close) + return +} + +func (ts *testWSServer) Close() { + if func() bool { + ts.mu.Lock() + defer ts.mu.Unlock() + if ts.wsconns == nil { + ts.t.Log("Test WS server already closed") + return false + } + ts.s.CloseClientConnections() + ts.s.Close() + for _, ws := range ts.wsconns { + ws.Close() + } + ts.wsconns = nil // nil indicates server closed + return true + }() { + ts.wg.Wait() + } +} + +func (ts *testWSServer) WSURL() *url.URL { + return WSServerURL(ts.t, ts.s) +} + +// WSServerURL returns a ws:// url for the server +func WSServerURL(t *testing.T, s *httptest.Server) *url.URL { + u, err := url.Parse(s.URL) + require.NoError(t, err, "Failed to parse url") + u.Scheme = "ws" + return u +} + +func (ts *testWSServer) MustWriteBinaryMessageSync(t *testing.T, msg string) { + ts.mu.Lock() + defer ts.mu.Unlock() + conns := ts.wsconns + if len(conns) != 1 { + t.Fatalf("expected 1 conn, got %d", len(conns)) + } + conn := conns[0] + err := conn.WriteMessage(websocket.BinaryMessage, []byte(msg)) + require.NoError(t, err) +} + +func (ts *testWSServer) newWSHandler(chainID *big.Int, callback JSONRPCHandler) (handler http.HandlerFunc) { + if callback == nil { + callback = func(method string, params gjson.Result) (resp JSONRPCResponse) { return } + } + t := ts.t + upgrader := websocket.Upgrader{ + CheckOrigin: func(r *http.Request) bool { return true }, + } + return func(w http.ResponseWriter, r *http.Request) { + ts.mu.Lock() + if ts.wsconns == nil { // closed + ts.mu.Unlock() + return + } + ts.wg.Add(1) + defer ts.wg.Done() + conn, err := upgrader.Upgrade(w, r, nil) + if !assert.NoError(t, err, "Failed to upgrade WS connection") { + ts.mu.Unlock() + return + } + defer conn.Close() + ts.wsconns = append(ts.wsconns, conn) + ts.mu.Unlock() + + for { + _, data, err := conn.ReadMessage() + if err != nil { + if websocket.IsCloseError(err, websocket.CloseNormalClosure, websocket.CloseAbnormalClosure) { + ts.t.Log("Websocket closing") + return + } + ts.t.Logf("Failed to read message: %v", err) + return + } + ts.t.Log("Received message", string(data)) + req := gjson.ParseBytes(data) + if !req.IsObject() { + ts.t.Logf("Request must be object: %v", req.Type) + return + } + if e := req.Get("error"); e.Exists() { + ts.t.Logf("Received jsonrpc error: %v", e) + continue + } + m := req.Get("method") + if m.Type != gjson.String { + ts.t.Logf("Method must be string: %v", m.Type) + return + } + + var resp JSONRPCResponse + if chainID != nil && m.String() == "eth_chainId" { + resp.Result = `"0x` + chainID.Text(16) + `"` + } else if m.String() == "eth_syncing" { + resp.Result = "false" + } else { + resp = callback(m.String(), req.Get("params")) + } + id := req.Get("id") + var msg string + if resp.Error.Message != "" { + msg = fmt.Sprintf(`{"jsonrpc":"2.0","id":%s,"error":{"code":%d,"message":"%s"}}`, id, resp.Error.Code, resp.Error.Message) + } else { + msg = fmt.Sprintf(`{"jsonrpc":"2.0","id":%s,"result":%s}`, id, resp.Result) + } + ts.t.Logf("Sending message: %v", msg) + ts.mu.Lock() + err = conn.WriteMessage(websocket.BinaryMessage, []byte(msg)) + ts.mu.Unlock() + if err != nil { + ts.t.Logf("Failed to write message: %v", err) + return + } + + if resp.Notify != "" { + time.Sleep(100 * time.Millisecond) + msg := fmt.Sprintf(`{"jsonrpc":"2.0","method":"eth_subscription","params":{"subscription":"0x00","result":%s}}`, resp.Notify) + ts.t.Log("Sending message", msg) + ts.mu.Lock() + err = conn.WriteMessage(websocket.BinaryMessage, []byte(msg)) + ts.mu.Unlock() + if err != nil { + ts.t.Logf("Failed to write message: %v", err) + return + } + } + } + } +} diff --git a/core/chains/evm/testutils/config.go b/core/chains/evm/testutils/config.go new file mode 100644 index 00000000000..3d1425c5333 --- /dev/null +++ b/core/chains/evm/testutils/config.go @@ -0,0 +1,29 @@ +package testutils + +import ( + "testing" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" +) + +func NewTestChainScopedConfig(t testing.TB, overrideFn func(c *toml.EVMConfig)) config.ChainScopedConfig { + var chainID = (*big.Big)(FixtureChainID) + evmCfg := &toml.EVMConfig{ + ChainID: chainID, + Chain: toml.Defaults(chainID), + } + + if overrideFn != nil { + // We need to get the chainID from the override function first to load the correct chain defaults. + // Then we apply the override values on top + overrideFn(evmCfg) + evmCfg.Chain = toml.Defaults(evmCfg.ChainID) + overrideFn(evmCfg) + } + + return config.NewTOMLChainScopedConfig(evmCfg, logger.Test(t)) +} diff --git a/core/chains/evm/testutils/config_test.go b/core/chains/evm/testutils/config_test.go new file mode 100644 index 00000000000..0cbcc5eb63b --- /dev/null +++ b/core/chains/evm/testutils/config_test.go @@ -0,0 +1,22 @@ +package testutils + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" +) + +func TestNewTestChainScopedConfigOverride(t *testing.T) { + c := NewTestChainScopedConfig(t, func(c *toml.EVMConfig) { + finalityDepth := uint32(100) + c.FinalityDepth = &finalityDepth + }) + + // Overrides values + assert.Equal(t, uint32(100), c.EVM().FinalityDepth()) + // fallback.toml values + assert.Equal(t, false, c.EVM().GasEstimator().EIP1559DynamicFees()) + +} diff --git a/core/chains/evm/testutils/evmtypes.go b/core/chains/evm/testutils/evmtypes.go new file mode 100644 index 00000000000..5f9ae83d1b7 --- /dev/null +++ b/core/chains/evm/testutils/evmtypes.go @@ -0,0 +1,76 @@ +package testutils + +import ( + "crypto/rand" + "fmt" + "math" + "math/big" + mrand "math/rand" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + evmutils "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" +) + +// FixtureChainID matches the chain always added by fixtures.sql +// It is set to 0 since no real chain ever has this ID and allows a virtual +// "test" chain ID to be used without clashes +var FixtureChainID = big.NewInt(0) + +// SimulatedChainID is the chain ID for the go-ethereum simulated backend +var SimulatedChainID = big.NewInt(1337) + +// NewRandomEVMChainID returns a suitable random chain ID that will not conflict +// with fixtures +func NewRandomEVMChainID() *big.Int { + id := mrand.Int63n(math.MaxInt32) + 10000 + return big.NewInt(id) +} + +// NewAddress return a random new address +func NewAddress() common.Address { + return common.BytesToAddress(randomBytes(20)) +} + +func randomBytes(n int) []byte { + b := make([]byte, n) + _, err := rand.Read(b) + if err != nil { + panic(err) + } + return b +} + +// Head given the value convert it into an Head +func Head(val interface{}) *evmtypes.Head { + var h evmtypes.Head + time := uint64(0) + switch t := val.(type) { + case int: + h = evmtypes.NewHead(big.NewInt(int64(t)), evmutils.NewHash(), evmutils.NewHash(), time, ubig.New(FixtureChainID)) + case uint64: + h = evmtypes.NewHead(big.NewInt(int64(t)), evmutils.NewHash(), evmutils.NewHash(), time, ubig.New(FixtureChainID)) + case int64: + h = evmtypes.NewHead(big.NewInt(t), evmutils.NewHash(), evmutils.NewHash(), time, ubig.New(FixtureChainID)) + case *big.Int: + h = evmtypes.NewHead(t, evmutils.NewHash(), evmutils.NewHash(), time, ubig.New(FixtureChainID)) + default: + panic(fmt.Sprintf("Could not convert %v of type %T to Head", val, val)) + } + return &h +} + +func NewLegacyTransaction(nonce uint64, to common.Address, value *big.Int, gasLimit uint32, gasPrice *big.Int, data []byte) *types.Transaction { + tx := types.LegacyTx{ + Nonce: nonce, + To: &to, + Value: value, + Gas: uint64(gasLimit), + GasPrice: gasPrice, + Data: data, + } + return types.NewTx(&tx) +} diff --git a/core/chains/evm/testutils/timeout.go b/core/chains/evm/testutils/timeout.go new file mode 100644 index 00000000000..4c7864f1191 --- /dev/null +++ b/core/chains/evm/testutils/timeout.go @@ -0,0 +1,41 @@ +package testutils + +import ( + "testing" + "time" +) + +type Awaiter chan struct{} + +func NewAwaiter() Awaiter { return make(Awaiter) } + +func (a Awaiter) ItHappened() { close(a) } + +func (a Awaiter) AssertHappened(t *testing.T, expected bool) { + t.Helper() + select { + case <-a: + if !expected { + t.Fatal("It happened") + } + default: + if expected { + t.Fatal("It didn't happen") + } + } +} + +func (a Awaiter) AwaitOrFail(t testing.TB, durationParams ...time.Duration) { + t.Helper() + + duration := 10 * time.Second + if len(durationParams) > 0 { + duration = durationParams[0] + } + + select { + case <-a: + case <-time.After(duration): + t.Fatal("Timed out waiting for Awaiter to get ItHappened") + } +} From 1b994043b00cad9e0c900b6d12173dd1008480a5 Mon Sep 17 00:00:00 2001 From: Matthew Pendrey Date: Mon, 29 Apr 2024 16:16:07 +0100 Subject: [PATCH 55/77] =?UTF-8?q?BCF-3168:=20changes=20required=20to=20int?= =?UTF-8?q?egrate=20with=20the=20RelayerSet=20from=20chai=E2=80=A6=20(#130?= =?UTF-8?q?00)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * BCF-3168: changes required to integrate with the RelayerSet from chainlink common * lint * lint * goimports --- .changeset/beige-socks-cover.md | 5 + core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- .../mocks/relayer_chain_interoperators.go | 4 + .../chainlink/relayer_chain_interoperators.go | 13 +- core/services/chainlink/relayer_factory.go | 2 +- core/services/job/spawner_test.go | 4 + core/services/ocr2/delegate.go | 29 +-- .../ocr2/plugins/generic/relayerset.go | 87 ++++++++ .../ocr2/plugins/generic/relayerset_test.go | 173 ++++++++++++++++ core/services/ocrbootstrap/delegate.go | 1 + core/services/relay/evm/loop_impl.go | 2 +- core/services/relay/evm/relayer_extender.go | 4 +- core/services/relay/grpc_provider_server.go | 68 ------- .../relay/grpc_provider_server_test.go | 28 --- core/services/relay/relay.go | 38 ---- core/services/relay/relay_test.go | 191 ------------------ go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- plugins/medianpoc/plugin.go | 1 + 24 files changed, 318 insertions(+), 356 deletions(-) create mode 100644 .changeset/beige-socks-cover.md create mode 100644 core/services/ocr2/plugins/generic/relayerset.go create mode 100644 core/services/ocr2/plugins/generic/relayerset_test.go delete mode 100644 core/services/relay/grpc_provider_server.go delete mode 100644 core/services/relay/grpc_provider_server_test.go delete mode 100644 core/services/relay/relay.go delete mode 100644 core/services/relay/relay_test.go diff --git a/.changeset/beige-socks-cover.md b/.changeset/beige-socks-cover.md new file mode 100644 index 00000000000..0b7c22d01e5 --- /dev/null +++ b/.changeset/beige-socks-cover.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#internal changes to core required by change BCF3168 in common to add relayer set diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 08050c32167..3963538b2c3 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -21,7 +21,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink-automation v1.0.3 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 48a66de1ec3..daedbe64eb3 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1185,8 +1185,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfsE3+8OEzT3Q0Z9au0z1BPWs= github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 h1:54hM3/SrOM166it2K35hGb5K7gQ49/Op0aHp9WkqpqU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb h1:nJ9dkgvX5vdpFWhYufnRUAiNvNHsXkoBL6C0bDerq/k= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee h1:eFuBKyEbL2b+eyfgV/Eu9+8HuCEev+IcBi+K9l1dG7g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= diff --git a/core/services/chainlink/mocks/relayer_chain_interoperators.go b/core/services/chainlink/mocks/relayer_chain_interoperators.go index 6e47f6a1f9b..5b0815b6569 100644 --- a/core/services/chainlink/mocks/relayer_chain_interoperators.go +++ b/core/services/chainlink/mocks/relayer_chain_interoperators.go @@ -43,6 +43,10 @@ func (f *FakeRelayerChainInteroperators) Get(id types.RelayID) (loop.Relayer, er panic("unimplemented") } +func (f *FakeRelayerChainInteroperators) GetIDToRelayerMap() (map[types.RelayID]loop.Relayer, error) { + panic("unimplemented") +} + func (f *FakeRelayerChainInteroperators) Slice() []loop.Relayer { return f.Relayers } diff --git a/core/services/chainlink/relayer_chain_interoperators.go b/core/services/chainlink/relayer_chain_interoperators.go index e17d4d516e9..3ed3c3242ba 100644 --- a/core/services/chainlink/relayer_chain_interoperators.go +++ b/core/services/chainlink/relayer_chain_interoperators.go @@ -8,6 +8,7 @@ import ( "sync" "github.com/smartcontractkit/chainlink-common/pkg/loop" + relay "github.com/smartcontractkit/chainlink-common/pkg/loop/adapters/relay" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos" "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/adapters" @@ -16,7 +17,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/services" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" ) var ErrNoSuchRelayer = errors.New("relayer does not exist") @@ -183,6 +183,17 @@ func (rs *CoreRelayerChainInteroperators) Get(id types.RelayID) (loop.Relayer, e return lr, nil } +func (rs *CoreRelayerChainInteroperators) GetIDToRelayerMap() (map[types.RelayID]loop.Relayer, error) { + rs.mu.Lock() + defer rs.mu.Unlock() + result := make(map[types.RelayID]loop.Relayer) + for id, relayer := range rs.loopRelayers { + result[id] = relayer + } + + return result, nil +} + // LegacyEVMChains returns a container with all the evm chains // TODO BCF-2511 func (rs *CoreRelayerChainInteroperators) LegacyEVMChains() legacyevm.LegacyChainContainer { diff --git a/core/services/chainlink/relayer_factory.go b/core/services/chainlink/relayer_factory.go index 31645b7c54d..8bb06538f03 100644 --- a/core/services/chainlink/relayer_factory.go +++ b/core/services/chainlink/relayer_factory.go @@ -8,6 +8,7 @@ import ( "github.com/pelletier/go-toml/v2" "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink-common/pkg/loop/adapters/relay" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos" @@ -23,7 +24,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/config/env" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" "github.com/smartcontractkit/chainlink/v2/plugins" diff --git a/core/services/job/spawner_test.go b/core/services/job/spawner_test.go index 7b4ab138e7c..ef55021dabf 100644 --- a/core/services/job/spawner_test.go +++ b/core/services/job/spawner_test.go @@ -73,6 +73,10 @@ func (g *relayGetter) Get(id types.RelayID) (loop.Relayer, error) { return evmrelayer.NewLoopRelayServerAdapter(g.r, g.e), nil } +func (g *relayGetter) GetIDToRelayerMap() (map[types.RelayID]loop.Relayer, error) { + return map[types.RelayID]loop.Relayer{}, nil +} + func TestSpawner_CreateJobDeleteJob(t *testing.T) { t.Parallel() ctx := testutils.Context(t) diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index 4e1eb0cc623..7747cad3360 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -25,26 +25,22 @@ import ( ocr2keepers20runner "github.com/smartcontractkit/chainlink-automation/pkg/v2/runner" ocr2keepers21config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" ocr2keepers21 "github.com/smartcontractkit/chainlink-automation/pkg/v3/plugin" - "github.com/smartcontractkit/chainlink-common/pkg/loop/reportingplugins/ocr3" - "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" - - "github.com/smartcontractkit/chainlink/v2/core/config/env" - - "github.com/smartcontractkit/chainlink-vrf/altbn_128" - dkgpkg "github.com/smartcontractkit/chainlink-vrf/dkg" - "github.com/smartcontractkit/chainlink-vrf/ocr2vrf" - commonlogger "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/loop" "github.com/smartcontractkit/chainlink-common/pkg/loop/reportingplugins" + "github.com/smartcontractkit/chainlink-common/pkg/loop/reportingplugins/ocr3" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/core" llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" - + "github.com/smartcontractkit/chainlink-vrf/altbn_128" + dkgpkg "github.com/smartcontractkit/chainlink-vrf/dkg" + "github.com/smartcontractkit/chainlink-vrf/ocr2vrf" "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" coreconfig "github.com/smartcontractkit/chainlink/v2/core/config" + "github.com/smartcontractkit/chainlink/v2/core/config/env" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" @@ -71,7 +67,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" functionsRelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/functions" evmmercury "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" @@ -108,6 +103,7 @@ func (e ErrRelayNotEnabled) Error() string { type RelayGetter interface { Get(id types.RelayID) (loop.Relayer, error) + GetIDToRelayerMap() (map[types.RelayID]loop.Relayer, error) } type Delegate struct { ds sqlutil.DataSource @@ -567,6 +563,11 @@ func (d *Delegate) newServicesGenericPlugin( return nil, ErrJobSpecNoRelayer{PluginName: pCfg.PluginName, Err: err} } + relayerSet, err := generic.NewRelayerSet(d.RelayGetter, jb.ExternalJobID, jb.ID, d.isNewlyCreatedJob) + if err != nil { + return nil, fmt.Errorf("failed to create relayer set: %w", err) + } + relayer, err := d.RelayGetter.Get(rid) if err != nil { return nil, ErrRelayNotEnabled{Err: err, Relay: spec.Relay, PluginName: pCfg.PluginName} @@ -620,7 +621,7 @@ func (d *Delegate) newServicesGenericPlugin( //TODO: remove this workaround when the EVM relayer is running inside of an LOOPP d.lggr.Info("provider is not a LOOPP provider, switching to provider server") - ps, err2 := relay.NewProviderServer(provider, types.OCR2PluginType(pCfg.ProviderType), d.lggr) + ps, err2 := loop.NewProviderServer(provider, types.OCR2PluginType(pCfg.ProviderType), d.lggr) if err2 != nil { return nil, fmt.Errorf("cannot start EVM provider server: %s", err2) } @@ -657,7 +658,7 @@ func (d *Delegate) newServicesGenericPlugin( switch pCfg.OCRVersion { case 2: plugin := reportingplugins.NewLOOPPService(pluginLggr, grpcOpts, cmdFn, pluginConfig, providerClientConn, pr, ta, - errorLog, keyValueStore) + errorLog, keyValueStore, relayerSet) oracleArgs := libocr2.OCR2OracleArgs{ BinaryNetworkEndpointFactory: d.peerWrapper.Peer2, V2Bootstrappers: bootstrapPeers, @@ -683,7 +684,7 @@ func (d *Delegate) newServicesGenericPlugin( case 3: //OCR3 with OCR2 OnchainKeyring and ContractTransmitter plugin := ocr3.NewLOOPPService(pluginLggr, grpcOpts, cmdFn, pluginConfig, providerClientConn, pr, ta, errorLog, - capabilitiesRegistry, keyValueStore) + capabilitiesRegistry, keyValueStore, relayerSet) contractTransmitter := ocrcommon.NewOCR3ContractTransmitterAdapter(provider.ContractTransmitter()) oracleArgs := libocr2.OCR3OracleArgs[[]byte]{ BinaryNetworkEndpointFactory: d.peerWrapper.Peer2, diff --git a/core/services/ocr2/plugins/generic/relayerset.go b/core/services/ocr2/plugins/generic/relayerset.go new file mode 100644 index 00000000000..0586f600c50 --- /dev/null +++ b/core/services/ocr2/plugins/generic/relayerset.go @@ -0,0 +1,87 @@ +package generic + +import ( + "context" + "fmt" + + "github.com/google/uuid" + + "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/core" +) + +type RelayGetter interface { + GetIDToRelayerMap() (map[types.RelayID]loop.Relayer, error) +} + +type RelayerSet struct { + wrappedRelayers map[types.RelayID]core.Relayer +} + +func NewRelayerSet(relayGetter RelayGetter, externalJobID uuid.UUID, jobID int32, isNew bool) (*RelayerSet, error) { + + wrappedRelayers := map[types.RelayID]core.Relayer{} + + relayers, err := relayGetter.GetIDToRelayerMap() + if err != nil { + return nil, fmt.Errorf("failed to get relayers: %w", err) + } + + for id, relayer := range relayers { + wrappedRelayers[id] = relayerWrapper{Relayer: relayer, ExternalJobID: externalJobID, JobID: jobID, New: isNew} + } + + return &RelayerSet{wrappedRelayers: wrappedRelayers}, nil +} + +func (r *RelayerSet) Get(_ context.Context, id types.RelayID) (core.Relayer, error) { + if relayer, ok := r.wrappedRelayers[id]; ok { + return relayer, nil + } + + return nil, fmt.Errorf("relayer with id %s not found", id) +} + +func (r *RelayerSet) List(_ context.Context, relayIDs ...types.RelayID) (map[types.RelayID]core.Relayer, error) { + + if len(relayIDs) == 0 { + return r.wrappedRelayers, nil + } + + filterer := map[types.RelayID]bool{} + for _, id := range relayIDs { + filterer[id] = true + } + + result := map[types.RelayID]core.Relayer{} + for id, relayer := range r.wrappedRelayers { + if _, ok := filterer[id]; ok { + result[id] = relayer + } + } + + return result, nil +} + +type relayerWrapper struct { + loop.Relayer + ExternalJobID uuid.UUID + JobID int32 + New bool // Whether this is a first time job add. +} + +func (r relayerWrapper) NewPluginProvider(ctx context.Context, rargs core.RelayArgs, pargs core.PluginArgs) (types.PluginProvider, error) { + + relayArgs := types.RelayArgs{ + ExternalJobID: r.ExternalJobID, + JobID: r.JobID, + ContractID: rargs.ContractID, + New: r.New, + RelayConfig: rargs.RelayConfig, + ProviderType: rargs.ProviderType, + MercuryCredentials: rargs.MercuryCredentials, + } + + return r.Relayer.NewPluginProvider(ctx, relayArgs, types.PluginArgs(pargs)) +} diff --git a/core/services/ocr2/plugins/generic/relayerset_test.go b/core/services/ocr2/plugins/generic/relayerset_test.go new file mode 100644 index 00000000000..9aef7e29d78 --- /dev/null +++ b/core/services/ocr2/plugins/generic/relayerset_test.go @@ -0,0 +1,173 @@ +package generic + +import ( + "context" + "fmt" + "math/big" + "testing" + + "github.com/google/uuid" + "github.com/stretchr/testify/assert" + + "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/types/core" +) + +func TestRelayerSet_List(t *testing.T) { + + testRelayersMap := map[types.RelayID]loop.Relayer{} + testRelayersMap[types.RelayID{Network: "N1", ChainID: "C1"}] = &TestRelayer{} + testRelayersMap[types.RelayID{Network: "N2", ChainID: "C2"}] = &TestRelayer{} + testRelayersMap[types.RelayID{Network: "N3", ChainID: "C3"}] = &TestRelayer{} + + testGetter := TestRelayGetter{relayers: testRelayersMap} + + relayerSet, err := NewRelayerSet(testGetter, uuid.New(), 1, true) + assert.NoError(t, err) + relayers, err := relayerSet.List(context.Background()) + assert.NoError(t, err) + + assert.Equal(t, len(relayers), 3) + + relayers, err = relayerSet.List(context.Background(), types.RelayID{Network: "N1", ChainID: "C1"}, types.RelayID{Network: "N3", ChainID: "C3"}) + assert.NoError(t, err) + + assert.Equal(t, len(relayers), 2) + + _, ok := relayers[types.RelayID{Network: "N1", ChainID: "C1"}] + assert.True(t, ok) + + _, ok = relayers[types.RelayID{Network: "N3", ChainID: "C3"}] + assert.True(t, ok) +} + +func TestRelayerSet_Get(t *testing.T) { + + testRelayersMap := map[types.RelayID]loop.Relayer{} + testRelayersMap[types.RelayID{Network: "N1", ChainID: "C1"}] = &TestRelayer{} + testRelayersMap[types.RelayID{Network: "N2", ChainID: "C2"}] = &TestRelayer{} + testRelayersMap[types.RelayID{Network: "N3", ChainID: "C3"}] = &TestRelayer{} + + testGetter := TestRelayGetter{relayers: testRelayersMap} + + relayerSet, err := NewRelayerSet(testGetter, uuid.New(), 1, true) + assert.NoError(t, err) + + _, err = relayerSet.Get(context.Background(), types.RelayID{Network: "N1", ChainID: "C1"}) + assert.NoError(t, err) + + _, err = relayerSet.Get(context.Background(), types.RelayID{Network: "N4", ChainID: "C4"}) + assert.NotNil(t, err) +} + +func TestRelayerSet_NewPluginProvider(t *testing.T) { + testRelayersMap := map[types.RelayID]loop.Relayer{} + testRelayer := &TestRelayer{} + testRelayersMap[types.RelayID{Network: "N1", ChainID: "C1"}] = testRelayer + testRelayersMap[types.RelayID{Network: "N2", ChainID: "C2"}] = &TestRelayer{} + testRelayersMap[types.RelayID{Network: "N3", ChainID: "C3"}] = &TestRelayer{} + + testGetter := TestRelayGetter{relayers: testRelayersMap} + + externalJobID := uuid.New() + relayerSet, err := NewRelayerSet(testGetter, externalJobID, 1, true) + assert.NoError(t, err) + + relayer, err := relayerSet.Get(context.Background(), types.RelayID{Network: "N1", ChainID: "C1"}) + assert.NoError(t, err) + + _, err = relayer.NewPluginProvider(context.Background(), core.RelayArgs{ + ContractID: "c1", + RelayConfig: []byte("relayconfig"), + ProviderType: "p1", + MercuryCredentials: &types.MercuryCredentials{ + LegacyURL: "legacy", + URL: "url", + Username: "user", + Password: "pass", + }, + }, core.PluginArgs{ + TransmitterID: "t1", + PluginConfig: []byte("pluginconfig"), + }) + assert.NoError(t, err) + + assert.Equal(t, types.RelayArgs{ + ExternalJobID: externalJobID, + JobID: 1, + ContractID: "c1", + New: true, + RelayConfig: []byte("relayconfig"), + ProviderType: "p1", + MercuryCredentials: &types.MercuryCredentials{ + LegacyURL: "legacy", + URL: "url", + Username: "user", + Password: "pass", + }, + }, testRelayer.relayArgs) + + assert.Equal(t, types.PluginArgs{ + TransmitterID: "t1", + PluginConfig: []byte("pluginconfig"), + }, testRelayer.pluginArgs) +} + +type TestRelayGetter struct { + relayers map[types.RelayID]loop.Relayer +} + +func (t TestRelayGetter) Get(id types.RelayID) (loop.Relayer, error) { + if relayer, ok := t.relayers[id]; ok { + return relayer, nil + } + + return nil, fmt.Errorf("relayer with id %s not found", id) +} + +func (t TestRelayGetter) GetIDToRelayerMap() (map[types.RelayID]loop.Relayer, error) { + return t.relayers, nil +} + +type TestRelayer struct { + relayArgs types.RelayArgs + pluginArgs types.PluginArgs +} + +func (t *TestRelayer) NewPluginProvider(ctx context.Context, args types.RelayArgs, args2 types.PluginArgs) (types.PluginProvider, error) { + t.relayArgs = args + t.pluginArgs = args2 + + return nil, nil +} + +func (t *TestRelayer) Name() string { panic("implement me") } + +func (t *TestRelayer) Start(ctx context.Context) error { panic("implement me") } + +func (t *TestRelayer) Close() error { panic("implement me") } + +func (t *TestRelayer) Ready() error { panic("implement me") } + +func (t *TestRelayer) HealthReport() map[string]error { panic("implement me") } + +func (t *TestRelayer) GetChainStatus(ctx context.Context) (types.ChainStatus, error) { + panic("implement me") +} + +func (t *TestRelayer) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) (stats []types.NodeStatus, nextPageToken string, total int, err error) { + panic("implement me") +} + +func (t *TestRelayer) Transact(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error { + panic("implement me") +} + +func (t *TestRelayer) NewConfigProvider(ctx context.Context, args types.RelayArgs) (types.ConfigProvider, error) { + panic("implement me") +} + +func (t *TestRelayer) NewLLOProvider(ctx context.Context, args types.RelayArgs, args2 types.PluginArgs) (types.LLOProvider, error) { + panic("implement me") +} diff --git a/core/services/ocrbootstrap/delegate.go b/core/services/ocrbootstrap/delegate.go index 0bb7a0ca2ba..4f927faa009 100644 --- a/core/services/ocrbootstrap/delegate.go +++ b/core/services/ocrbootstrap/delegate.go @@ -22,6 +22,7 @@ import ( type RelayGetter interface { Get(types.RelayID) (loop.Relayer, error) + GetIDToRelayerMap() (map[types.RelayID]loop.Relayer, error) } // Delegate creates Bootstrap jobs diff --git a/core/services/relay/evm/loop_impl.go b/core/services/relay/evm/loop_impl.go index 57a09dd49ae..7f9d405847d 100644 --- a/core/services/relay/evm/loop_impl.go +++ b/core/services/relay/evm/loop_impl.go @@ -2,9 +2,9 @@ package evm import ( "github.com/smartcontractkit/chainlink-common/pkg/loop" + relay "github.com/smartcontractkit/chainlink-common/pkg/loop/adapters/relay" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" - "github.com/smartcontractkit/chainlink/v2/core/services/relay" ) //go:generate mockery --quiet --name LoopRelayAdapter --output ./mocks/ --case=underscore diff --git a/core/services/relay/evm/relayer_extender.go b/core/services/relay/evm/relayer_extender.go index 83f03b47f9e..5f49a0b16c9 100644 --- a/core/services/relay/evm/relayer_extender.go +++ b/core/services/relay/evm/relayer_extender.go @@ -8,7 +8,7 @@ import ( "github.com/pkg/errors" "go.uber.org/multierr" - "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink-common/pkg/loop/adapters/relay" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" @@ -19,7 +19,7 @@ import ( var ErrNoChains = errors.New("no EVM chains loaded") type EVMChainRelayerExtender interface { - loop.RelayerExt + relay.RelayerExt Chain() legacyevm.Chain } diff --git a/core/services/relay/grpc_provider_server.go b/core/services/relay/grpc_provider_server.go deleted file mode 100644 index 67bbb8c6c2a..00000000000 --- a/core/services/relay/grpc_provider_server.go +++ /dev/null @@ -1,68 +0,0 @@ -package relay - -import ( - "context" - "net" - - "go.uber.org/multierr" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" - - "github.com/smartcontractkit/chainlink-common/pkg/loop" - "github.com/smartcontractkit/chainlink-common/pkg/types" - "github.com/smartcontractkit/chainlink/v2/core/logger" -) - -type ProviderServer struct { - s *grpc.Server - lis net.Listener - lggr logger.Logger - conns []*grpc.ClientConn -} - -func (p *ProviderServer) Start(ctx context.Context) error { - p.serve() - return nil -} - -func (p *ProviderServer) Close() error { - var err error - for _, c := range p.conns { - err = multierr.Combine(err, c.Close()) - } - p.s.Stop() - return err -} - -func (p *ProviderServer) GetConn() (*grpc.ClientConn, error) { - cc, err := grpc.Dial(p.lis.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) - p.conns = append(p.conns, cc) - return cc, err -} - -// NewProviderServer creates a GRPC server that will wrap a provider, this is a workaround to test the Node API PoC until the EVM relayer is loopifyed -func NewProviderServer(p types.PluginProvider, pType types.OCR2PluginType, lggr logger.Logger) (*ProviderServer, error) { - lis, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - return nil, err - } - ps := ProviderServer{ - s: grpc.NewServer(), - lis: lis, - lggr: lggr.Named("EVM.ProviderServer"), - } - err = loop.RegisterStandAloneProvider(ps.s, p, pType) - if err != nil { - return nil, err - } - - return &ps, nil -} - -func (p *ProviderServer) serve() { - go func() { - if err := p.s.Serve(p.lis); err != nil { - p.lggr.Errorf("Failed to serve EVM provider server: %v", err) - } - }() -} diff --git a/core/services/relay/grpc_provider_server_test.go b/core/services/relay/grpc_provider_server_test.go deleted file mode 100644 index 72bbbca0f44..00000000000 --- a/core/services/relay/grpc_provider_server_test.go +++ /dev/null @@ -1,28 +0,0 @@ -package relay - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink-common/pkg/types" - - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/logger" -) - -func TestProviderServer(t *testing.T) { - r := &mockRelayer{} - sa := NewServerAdapter(r, mockRelayerExt{}) - mp, _ := sa.NewPluginProvider(testutils.Context(t), types.RelayArgs{ProviderType: string(types.Median)}, types.PluginArgs{}) - - lggr := logger.TestLogger(t) - _, err := NewProviderServer(mp, "unsupported-type", lggr) - require.ErrorContains(t, err, "unsupported-type") - - ps, err := NewProviderServer(staticMedianProvider{}, types.Median, lggr) - require.NoError(t, err) - - _, err = ps.GetConn() - require.NoError(t, err) -} diff --git a/core/services/relay/relay.go b/core/services/relay/relay.go deleted file mode 100644 index b4cc4517390..00000000000 --- a/core/services/relay/relay.go +++ /dev/null @@ -1,38 +0,0 @@ -package relay - -import ( - "context" - "fmt" - - "github.com/smartcontractkit/chainlink-common/pkg/loop" - "github.com/smartcontractkit/chainlink-common/pkg/types" -) - -// ServerAdapter extends [loop.RelayerAdapter] by overriding NewPluginProvider to dispatches calls according to `RelayArgs.ProviderType`. -// This should only be used to adapt relayers not running via GRPC in a LOOPP. -type ServerAdapter struct { - loop.RelayerAdapter -} - -// NewServerAdapter returns a new ServerAdapter. -func NewServerAdapter(r types.Relayer, e loop.RelayerExt) *ServerAdapter { //nolint:staticcheck - return &ServerAdapter{RelayerAdapter: loop.RelayerAdapter{Relayer: r, RelayerExt: e}} -} - -func (r *ServerAdapter) NewPluginProvider(ctx context.Context, rargs types.RelayArgs, pargs types.PluginArgs) (types.PluginProvider, error) { - switch types.OCR2PluginType(rargs.ProviderType) { - case types.Median: - return r.NewMedianProvider(ctx, rargs, pargs) - case types.Functions: - return r.NewFunctionsProvider(ctx, rargs, pargs) - case types.Mercury: - return r.NewMercuryProvider(ctx, rargs, pargs) - case types.OCR2Keeper: - return r.NewAutomationProvider(ctx, rargs, pargs) - case types.DKG, types.OCR2VRF, types.GenericPlugin: - return r.RelayerAdapter.NewPluginProvider(ctx, rargs, pargs) - case types.LLO, types.CCIPCommit, types.CCIPExecution: - return nil, fmt.Errorf("provider type not supported: %s", rargs.ProviderType) - } - return nil, fmt.Errorf("provider type not recognized: %s", rargs.ProviderType) -} diff --git a/core/services/relay/relay_test.go b/core/services/relay/relay_test.go deleted file mode 100644 index c0b2248ed1a..00000000000 --- a/core/services/relay/relay_test.go +++ /dev/null @@ -1,191 +0,0 @@ -package relay - -import ( - "context" - "testing" - - "github.com/stretchr/testify/assert" - - "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" - ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - - "github.com/smartcontractkit/chainlink-common/pkg/loop" - "github.com/smartcontractkit/chainlink-common/pkg/types" - - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" -) - -type staticMedianProvider struct { -} - -var _ types.MedianProvider = staticMedianProvider{} - -// ContractConfigTracker implements types.MedianProvider. -func (s staticMedianProvider) ContractConfigTracker() ocr2types.ContractConfigTracker { - return nil -} - -// ContractTransmitter implements types.MedianProvider. -func (s staticMedianProvider) ContractTransmitter() ocr2types.ContractTransmitter { - return nil -} - -// MedianContract implements types.MedianProvider. -func (s staticMedianProvider) MedianContract() median.MedianContract { - return nil -} - -// OffchainConfigDigester implements types.MedianProvider. -func (s staticMedianProvider) OffchainConfigDigester() ocr2types.OffchainConfigDigester { - return nil -} - -// OnchainConfigCodec implements types.MedianProvider. -func (s staticMedianProvider) OnchainConfigCodec() median.OnchainConfigCodec { - return nil -} - -// ReportCodec implements types.MedianProvider. -func (s staticMedianProvider) ReportCodec() median.ReportCodec { - return nil -} - -// ChainReader implements types.MedianProvider. -func (s staticMedianProvider) ChainReader() types.ChainReader { - return nil -} - -// Close implements types.MedianProvider. -func (s staticMedianProvider) Close() error { - return nil -} - -// Codec implements types.MedianProvider. -func (s staticMedianProvider) Codec() types.Codec { - return nil -} - -// HealthReport implements types.MedianProvider. -func (s staticMedianProvider) HealthReport() map[string]error { - return nil -} - -// Name implements types.MedianProvider. -func (s staticMedianProvider) Name() string { - return "" -} - -// Ready implements types.MedianProvider. -func (s staticMedianProvider) Ready() error { - return nil -} - -// Start implements types.MedianProvider. -func (s staticMedianProvider) Start(context.Context) error { - return nil -} - -type staticFunctionsProvider struct { - types.FunctionsProvider -} - -type staticMercuryProvider struct { - types.MercuryProvider -} - -type staticAutomationProvider struct { - types.AutomationProvider -} - -type staticPluginProvider struct { - types.PluginProvider -} - -type mockRelayer struct { - types.Relayer -} - -func (m *mockRelayer) NewMedianProvider(rargs types.RelayArgs, pargs types.PluginArgs) (types.MedianProvider, error) { - return staticMedianProvider{}, nil -} - -func (m *mockRelayer) NewFunctionsProvider(rargs types.RelayArgs, pargs types.PluginArgs) (types.FunctionsProvider, error) { - return staticFunctionsProvider{}, nil -} - -func (m *mockRelayer) NewMercuryProvider(rargs types.RelayArgs, pargs types.PluginArgs) (types.MercuryProvider, error) { - return staticMercuryProvider{}, nil -} - -func (m *mockRelayer) NewAutomationProvider(rargs types.RelayArgs, pargs types.PluginArgs) (types.AutomationProvider, error) { - return staticAutomationProvider{}, nil -} - -func (m *mockRelayer) NewPluginProvider(rargs types.RelayArgs, pargs types.PluginArgs) (types.PluginProvider, error) { - return staticPluginProvider{}, nil -} - -type mockRelayerExt struct { - loop.RelayerExt -} - -func isType[T any](p any) bool { - _, ok := p.(T) - return ok -} - -func TestRelayerServerAdapter(t *testing.T) { - r := &mockRelayer{} - sa := NewServerAdapter(r, mockRelayerExt{}) - - testCases := []struct { - ProviderType string - Test func(p any) bool - Error string - }{ - { - ProviderType: string(types.Median), - Test: isType[types.MedianProvider], - }, - { - ProviderType: string(types.Functions), - Test: isType[types.FunctionsProvider], - }, - { - ProviderType: string(types.Mercury), - Test: isType[types.MercuryProvider], - }, - { - ProviderType: string(types.CCIPCommit), - Error: "provider type not supported", - }, - { - ProviderType: string(types.CCIPExecution), - Error: "provider type not supported", - }, - { - ProviderType: "unknown", - Error: "provider type not recognized", - }, - { - ProviderType: string(types.GenericPlugin), - Test: isType[types.PluginProvider], - }, - } - - ctx := testutils.Context(t) - for _, tc := range testCases { - pp, err := sa.NewPluginProvider( - ctx, - types.RelayArgs{ProviderType: tc.ProviderType}, - types.PluginArgs{}, - ) - - if tc.Error != "" { - assert.ErrorContains(t, err, tc.Error) - } else { - assert.NoError(t, err) - assert.True(t, tc.Test(pp)) - } - } -} diff --git a/go.mod b/go.mod index 6e081467bc0..923e4b87b0d 100644 --- a/go.mod +++ b/go.mod @@ -72,7 +72,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chain-selectors v1.0.10 github.com/smartcontractkit/chainlink-automation v1.0.3 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab diff --git a/go.sum b/go.sum index 50cb9f3b44f..90faeacb057 100644 --- a/go.sum +++ b/go.sum @@ -1180,8 +1180,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfsE3+8OEzT3Q0Z9au0z1BPWs= github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 h1:54hM3/SrOM166it2K35hGb5K7gQ49/Op0aHp9WkqpqU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb h1:nJ9dkgvX5vdpFWhYufnRUAiNvNHsXkoBL6C0bDerq/k= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee h1:eFuBKyEbL2b+eyfgV/Eu9+8HuCEev+IcBi+K9l1dG7g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 69c09244ef8..0903711f16e 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -25,7 +25,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.3 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb github.com/smartcontractkit/chainlink-testing-framework v1.28.4 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index e2be6f36438..d9bb628d861 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1517,8 +1517,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfsE3+8OEzT3Q0Z9au0z1BPWs= github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 h1:54hM3/SrOM166it2K35hGb5K7gQ49/Op0aHp9WkqpqU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb h1:nJ9dkgvX5vdpFWhYufnRUAiNvNHsXkoBL6C0bDerq/k= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee h1:eFuBKyEbL2b+eyfgV/Eu9+8HuCEev+IcBi+K9l1dG7g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 128c611c04d..a4c5b67c204 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.30.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.3 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb github.com/smartcontractkit/chainlink-testing-framework v1.28.4 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 291f221f4b8..e2d5b5270ff 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1500,8 +1500,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfsE3+8OEzT3Q0Z9au0z1BPWs= github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73 h1:54hM3/SrOM166it2K35hGb5K7gQ49/Op0aHp9WkqpqU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240424132620-add4946c1c73/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb h1:nJ9dkgvX5vdpFWhYufnRUAiNvNHsXkoBL6C0bDerq/k= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb/go.mod h1:GTDBbovHUSAUk+fuGIySF2A/whhdtHGaWmU61BoERks= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee h1:eFuBKyEbL2b+eyfgV/Eu9+8HuCEev+IcBi+K9l1dG7g= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240419213354-ea34a948e2ee/go.mod h1:uATrrJ8IsuBkOBJ46USuf73gz9gZy5k5bzGE5/ji/rc= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= diff --git a/plugins/medianpoc/plugin.go b/plugins/medianpoc/plugin.go index b937361b9ec..bbd9d437e3a 100644 --- a/plugins/medianpoc/plugin.go +++ b/plugins/medianpoc/plugin.go @@ -66,6 +66,7 @@ func (p *Plugin) NewReportingPluginFactory( telemetry core.TelemetryClient, errorLog core.ErrorLog, keyValueStore core.KeyValueStore, + relayerSet core.RelayerSet, ) (types.ReportingPluginFactory, error) { f, err := p.newFactory(ctx, config, provider, pipelineRunner, telemetry, errorLog) if err != nil { From 208801569f215c904d8c051a3f677b51be60c7b5 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Mon, 29 Apr 2024 18:58:00 +0200 Subject: [PATCH 56/77] [TT-970] Migrate Atlas-specific contracts to Seth (#13027) * use latest Seth * WIP#1 * migrate Atlas-specific contracts to Seth * use latest CTF * remove trash * fix mock deployment * use latest CTF * update CTF again * update CTF * use CTF release version --- go.mod | 1 - .../contracts/contract_deployer.go | 10 +- .../contracts/etherem_contracts_atlas_seth.go | 392 ++++++++++++++++++ .../contracts/ethereum_contracts.go | 106 ++--- integration-tests/go.mod | 4 +- integration-tests/go.sum | 8 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 8 files changed, 459 insertions(+), 68 deletions(-) create mode 100644 integration-tests/contracts/etherem_contracts_atlas_seth.go diff --git a/go.mod b/go.mod index 923e4b87b0d..3e691e95405 100644 --- a/go.mod +++ b/go.mod @@ -353,5 +353,4 @@ replace ( // until merged upstream: https://github.com/mwitkow/grpc-proxy/pull/69 github.com/mwitkow/grpc-proxy => github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f - ) diff --git a/integration-tests/contracts/contract_deployer.go b/integration-tests/contracts/contract_deployer.go index c85c927b8d4..e2511c7292e 100644 --- a/integration-tests/contracts/contract_deployer.go +++ b/integration-tests/contracts/contract_deployer.go @@ -435,7 +435,7 @@ func (e *EthereumContractDeployer) DeployStakingEventsMock() (StakingEventsMock, if err != nil { return nil, err } - return &EthereumStakingEventsMock{ + return &LegacyEthereumStakingEventsMock{ client: e.client, eventsMock: instance.(*eth_contracts.StakingEventsMock), address: address, @@ -452,7 +452,7 @@ func (e *EthereumContractDeployer) DeployFunctionsV1EventsMock() (FunctionsV1Eve if err != nil { return nil, err } - return &EthereumFunctionsV1EventsMock{ + return &LegacyEthereumFunctionsV1EventsMock{ client: e.client, eventsMock: instance.(*functions_v1_events_mock.FunctionsV1EventsMock), address: address, @@ -469,7 +469,7 @@ func (e *EthereumContractDeployer) DeployKeeperRegistry11Mock() (KeeperRegistry1 if err != nil { return nil, err } - return &EthereumKeeperRegistry11Mock{ + return &LegacyEthereumKeeperRegistry11Mock{ client: e.client, registryMock: instance.(*keeper_registry_wrapper1_1_mock.KeeperRegistryMock), address: address, @@ -486,7 +486,7 @@ func (e *EthereumContractDeployer) DeployKeeperRegistrar12Mock() (KeeperRegistra if err != nil { return nil, err } - return &EthereumKeeperRegistrar12Mock{ + return &LegacyEthereumKeeperRegistrar12Mock{ client: e.client, registrarMock: instance.(*keeper_registrar_wrapper1_2_mock.KeeperRegistrarMock), address: address, @@ -503,7 +503,7 @@ func (e *EthereumContractDeployer) DeployKeeperGasWrapperMock() (KeeperGasWrappe if err != nil { return nil, err } - return &EthereumKeeperGasWrapperMock{ + return &LegacyEthereumKeeperGasWrapperMock{ client: e.client, gasWrapperMock: instance.(*gas_wrapper_mock.KeeperRegistryCheckUpkeepGasUsageWrapperMock), address: address, diff --git a/integration-tests/contracts/etherem_contracts_atlas_seth.go b/integration-tests/contracts/etherem_contracts_atlas_seth.go new file mode 100644 index 00000000000..c28e5198682 --- /dev/null +++ b/integration-tests/contracts/etherem_contracts_atlas_seth.go @@ -0,0 +1,392 @@ +package contracts + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/seth" + + eth_contracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" + "github.com/smartcontractkit/chainlink/integration-tests/wrappers" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_v1_events_mock" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/gas_wrapper_mock" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registrar_wrapper1_2_mock" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_1_mock" +) + +// EthereumFunctionsV1EventsMock represents the basic functions v1 events mock contract +type EthereumFunctionsV1EventsMock struct { + client *seth.Client + eventsMock *functions_v1_events_mock.FunctionsV1EventsMock + address *common.Address +} + +func (f *EthereumFunctionsV1EventsMock) Address() string { + return f.address.Hex() +} + +func (f *EthereumFunctionsV1EventsMock) EmitRequestProcessed(requestId [32]byte, subscriptionId uint64, totalCostJuels *big.Int, transmitter common.Address, resultCode uint8, response []byte, errByte []byte, callbackReturnData []byte) error { + _, err := f.client.Decode(f.eventsMock.EmitRequestProcessed(f.client.NewTXOpts(), requestId, subscriptionId, totalCostJuels, transmitter, resultCode, response, errByte, callbackReturnData)) + return err +} + +func (f *EthereumFunctionsV1EventsMock) EmitRequestStart(requestId [32]byte, donId [32]byte, subscriptionId uint64, subscriptionOwner common.Address, requestingContract common.Address, requestInitiator common.Address, data []byte, dataVersion uint16, callbackGasLimit uint32, estimatedTotalCostJuels *big.Int) error { + _, err := f.client.Decode(f.eventsMock.EmitRequestStart(f.client.NewTXOpts(), requestId, donId, subscriptionId, subscriptionOwner, requestingContract, requestInitiator, data, dataVersion, callbackGasLimit, estimatedTotalCostJuels)) + return err +} + +func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionCanceled(subscriptionId uint64, fundsRecipient common.Address, fundsAmount *big.Int) error { + _, err := f.client.Decode(f.eventsMock.EmitSubscriptionCanceled(f.client.NewTXOpts(), subscriptionId, fundsRecipient, fundsAmount)) + return err +} + +func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionConsumerAdded(subscriptionId uint64, consumer common.Address) error { + _, err := f.client.Decode(f.eventsMock.EmitSubscriptionConsumerAdded(f.client.NewTXOpts(), subscriptionId, consumer)) + return err +} + +func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionConsumerRemoved(subscriptionId uint64, consumer common.Address) error { + _, err := f.client.Decode(f.eventsMock.EmitSubscriptionConsumerRemoved(f.client.NewTXOpts(), subscriptionId, consumer)) + return err +} + +func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionCreated(subscriptionId uint64, owner common.Address) error { + _, err := f.client.Decode(f.eventsMock.EmitSubscriptionCreated(f.client.NewTXOpts(), subscriptionId, owner)) + return err +} + +func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionFunded(subscriptionId uint64, oldBalance *big.Int, newBalance *big.Int) error { + _, err := f.client.Decode(f.eventsMock.EmitSubscriptionFunded(f.client.NewTXOpts(), subscriptionId, oldBalance, newBalance)) + return err +} + +func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionOwnerTransferred(subscriptionId uint64, from common.Address, to common.Address) error { + _, err := f.client.Decode(f.eventsMock.EmitSubscriptionOwnerTransferred(f.client.NewTXOpts(), subscriptionId, from, to)) + return err +} + +func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionOwnerTransferRequested(subscriptionId uint64, from common.Address, to common.Address) error { + _, err := f.client.Decode(f.eventsMock.EmitSubscriptionOwnerTransferRequested(f.client.NewTXOpts(), subscriptionId, from, to)) + return err +} + +func (f *EthereumFunctionsV1EventsMock) EmitRequestNotProcessed(requestId [32]byte, coordinator common.Address, transmitter common.Address, resultCode uint8) error { + _, err := f.client.Decode(f.eventsMock.EmitRequestNotProcessed(f.client.NewTXOpts(), requestId, coordinator, transmitter, resultCode)) + return err +} + +func (f *EthereumFunctionsV1EventsMock) EmitContractUpdated(id [32]byte, from common.Address, to common.Address) error { + _, err := f.client.Decode(f.eventsMock.EmitContractUpdated(f.client.NewTXOpts(), id, from, to)) + return err +} + +// DeployFunctionsV1EventsMock deploys a new instance of the FunctionsV1EventsMock contract +func DeployFunctionsV1EventsMock(client *seth.Client) (FunctionsV1EventsMock, error) { + abi, err := functions_v1_events_mock.FunctionsV1EventsMockMetaData.GetAbi() + if err != nil { + return &EthereumFunctionsV1EventsMock{}, fmt.Errorf("failed to get FunctionsV1EventsMock ABI: %w", err) + } + client.ContractStore.AddABI("FunctionsV1EventsMock", *abi) + client.ContractStore.AddBIN("FunctionsV1EventsMock", common.FromHex(functions_v1_events_mock.FunctionsV1EventsMockMetaData.Bin)) + + data, err := client.DeployContract(client.NewTXOpts(), "FunctionsV1EventsMock", *abi, common.FromHex(functions_v1_events_mock.FunctionsV1EventsMockMetaData.Bin)) + + if err != nil { + return &EthereumFunctionsV1EventsMock{}, fmt.Errorf("FunctionsV1EventsMock instance deployment have failed: %w", err) + } + + instance, err := functions_v1_events_mock.NewFunctionsV1EventsMock(data.Address, wrappers.MustNewWrappedContractBackend(nil, client)) + if err != nil { + return &EthereumFunctionsV1EventsMock{}, fmt.Errorf("failed to instantiate FunctionsV1EventsMock instance: %w", err) + } + + return &EthereumFunctionsV1EventsMock{ + client: client, + eventsMock: instance, + address: &data.Address, + }, nil +} + +// EthereumKeeperRegistry11Mock represents the basic keeper registry 1.1 mock contract +type EthereumKeeperRegistry11Mock struct { + client *seth.Client + registryMock *keeper_registry_wrapper1_1_mock.KeeperRegistryMock + address *common.Address +} + +func (f *EthereumKeeperRegistry11Mock) Address() string { + return f.address.Hex() +} + +func (f *EthereumKeeperRegistry11Mock) EmitUpkeepPerformed(id *big.Int, success bool, from common.Address, payment *big.Int, performData []byte) error { + _, err := f.client.Decode(f.registryMock.EmitUpkeepPerformed(f.client.NewTXOpts(), id, success, from, payment, performData)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) EmitUpkeepCanceled(id *big.Int, atBlockHeight uint64) error { + _, err := f.client.Decode(f.registryMock.EmitUpkeepCanceled(f.client.NewTXOpts(), id, atBlockHeight)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) EmitFundsWithdrawn(id *big.Int, amount *big.Int, to common.Address) error { + _, err := f.client.Decode(f.registryMock.EmitFundsWithdrawn(f.client.NewTXOpts(), id, amount, to)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) EmitKeepersUpdated(keepers []common.Address, payees []common.Address) error { + _, err := f.client.Decode(f.registryMock.EmitKeepersUpdated(f.client.NewTXOpts(), keepers, payees)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) EmitUpkeepRegistered(id *big.Int, executeGas uint32, admin common.Address) error { + _, err := f.client.Decode(f.registryMock.EmitUpkeepRegistered(f.client.NewTXOpts(), id, executeGas, admin)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) EmitFundsAdded(id *big.Int, from common.Address, amount *big.Int) error { + _, err := f.client.Decode(f.registryMock.EmitFundsAdded(f.client.NewTXOpts(), id, from, amount)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) SetUpkeepCount(upkeepCount *big.Int) error { + _, err := f.client.Decode(f.registryMock.SetUpkeepCount(f.client.NewTXOpts(), upkeepCount)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) SetCanceledUpkeepList(canceledUpkeepList []*big.Int) error { + _, err := f.client.Decode(f.registryMock.SetCanceledUpkeepList(f.client.NewTXOpts(), canceledUpkeepList)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) SetKeeperList(keepers []common.Address) error { + _, err := f.client.Decode(f.registryMock.SetKeeperList(f.client.NewTXOpts(), keepers)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) SetConfig(paymentPremiumPPB uint32, flatFeeMicroLink uint32, blockCountPerTurn *big.Int, checkGasLimit uint32, stalenessSeconds *big.Int, gasCeilingMultiplier uint16, fallbackGasPrice *big.Int, fallbackLinkPrice *big.Int) error { + _, err := f.client.Decode(f.registryMock.SetConfig(f.client.NewTXOpts(), paymentPremiumPPB, flatFeeMicroLink, blockCountPerTurn, checkGasLimit, stalenessSeconds, gasCeilingMultiplier, fallbackGasPrice, fallbackLinkPrice)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) SetUpkeep(id *big.Int, target common.Address, executeGas uint32, balance *big.Int, admin common.Address, maxValidBlocknumber uint64, lastKeeper common.Address, checkData []byte) error { + _, err := f.client.Decode(f.registryMock.SetUpkeep(f.client.NewTXOpts(), id, target, executeGas, balance, admin, maxValidBlocknumber, lastKeeper, checkData)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) SetMinBalance(id *big.Int, minBalance *big.Int) error { + _, err := f.client.Decode(f.registryMock.SetMinBalance(f.client.NewTXOpts(), id, minBalance)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) SetCheckUpkeepData(id *big.Int, performData []byte, maxLinkPayment *big.Int, gasLimit *big.Int, adjustedGasWei *big.Int, linkEth *big.Int) error { + _, err := f.client.Decode(f.registryMock.SetCheckUpkeepData(f.client.NewTXOpts(), id, performData, maxLinkPayment, gasLimit, adjustedGasWei, linkEth)) + return err +} + +func (f *EthereumKeeperRegistry11Mock) SetPerformUpkeepSuccess(id *big.Int, success bool) error { + _, err := f.client.Decode(f.registryMock.SetPerformUpkeepSuccess(f.client.NewTXOpts(), id, success)) + return err +} + +func DeployKeeperRegistry11Mock(client *seth.Client) (KeeperRegistry11Mock, error) { + abi, err := keeper_registry_wrapper1_1_mock.KeeperRegistryMockMetaData.GetAbi() + if err != nil { + return &EthereumKeeperRegistry11Mock{}, fmt.Errorf("failed to get KeeperRegistry11Mock ABI: %w", err) + } + client.ContractStore.AddABI("KeeperRegistry11Mock", *abi) + client.ContractStore.AddBIN("KeeperRegistry11Mock", common.FromHex(keeper_registry_wrapper1_1_mock.KeeperRegistryMockMetaData.Bin)) + + data, err := client.DeployContract(client.NewTXOpts(), "KeeperRegistry11Mock", *abi, common.FromHex(keeper_registry_wrapper1_1_mock.KeeperRegistryMockMetaData.Bin)) + + if err != nil { + return &EthereumKeeperRegistry11Mock{}, fmt.Errorf("KeeperRegistry11Mock instance deployment have failed: %w", err) + } + + instance, err := keeper_registry_wrapper1_1_mock.NewKeeperRegistryMock(data.Address, wrappers.MustNewWrappedContractBackend(nil, client)) + if err != nil { + return &EthereumKeeperRegistry11Mock{}, fmt.Errorf("failed to instantiate KeeperRegistry11Mock instance: %w", err) + } + + return &EthereumKeeperRegistry11Mock{ + client: client, + registryMock: instance, + address: &data.Address, + }, nil +} + +// EthereumKeeperRegistrar12Mock represents the basic keeper registrar 1.2 mock contract +type EthereumKeeperRegistrar12Mock struct { + client *seth.Client + registrarMock *keeper_registrar_wrapper1_2_mock.KeeperRegistrarMock + address *common.Address +} + +func (f *EthereumKeeperRegistrar12Mock) Address() string { + return f.address.Hex() +} + +func (f *EthereumKeeperRegistrar12Mock) EmitRegistrationRequested(hash [32]byte, name string, encryptedEmail []byte, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, checkData []byte, amount *big.Int, source uint8) error { + _, err := f.client.Decode(f.registrarMock.EmitRegistrationRequested(f.client.NewTXOpts(), hash, name, encryptedEmail, upkeepContract, gasLimit, adminAddress, checkData, amount, source)) + return err +} + +func (f *EthereumKeeperRegistrar12Mock) EmitRegistrationApproved(hash [32]byte, displayName string, upkeepId *big.Int) error { + _, err := f.client.Decode(f.registrarMock.EmitRegistrationApproved(f.client.NewTXOpts(), hash, displayName, upkeepId)) + return err +} + +func (f *EthereumKeeperRegistrar12Mock) SetRegistrationConfig(autoApproveConfigType uint8, autoApproveMaxAllowed uint32, approvedCount uint32, keeperRegistry common.Address, minLINKJuels *big.Int) error { + _, err := f.client.Decode(f.registrarMock.SetRegistrationConfig(f.client.NewTXOpts(), autoApproveConfigType, autoApproveMaxAllowed, approvedCount, keeperRegistry, minLINKJuels)) + return err +} + +func DeployKeeperRegistrar12Mock(client *seth.Client) (KeeperRegistrar12Mock, error) { + abi, err := keeper_registrar_wrapper1_2_mock.KeeperRegistrarMockMetaData.GetAbi() + if err != nil { + return &EthereumKeeperRegistrar12Mock{}, fmt.Errorf("failed to get KeeperRegistrar12Mock ABI: %w", err) + } + client.ContractStore.AddABI("KeeperRegistrar12Mock", *abi) + client.ContractStore.AddBIN("KeeperRegistrar12Mock", common.FromHex(keeper_registrar_wrapper1_2_mock.KeeperRegistrarMockMetaData.Bin)) + + data, err := client.DeployContract(client.NewTXOpts(), "KeeperRegistrar12Mock", *abi, common.FromHex(keeper_registrar_wrapper1_2_mock.KeeperRegistrarMockMetaData.Bin)) + + if err != nil { + return &EthereumKeeperRegistrar12Mock{}, fmt.Errorf("KeeperRegistrar12Mock instance deployment have failed: %w", err) + } + + instance, err := keeper_registrar_wrapper1_2_mock.NewKeeperRegistrarMock(data.Address, wrappers.MustNewWrappedContractBackend(nil, client)) + if err != nil { + return &EthereumKeeperRegistrar12Mock{}, fmt.Errorf("failed to instantiate KeeperRegistrar12Mock instance: %w", err) + } + + return &EthereumKeeperRegistrar12Mock{ + client: client, + registrarMock: instance, + address: &data.Address, + }, nil +} + +// EthereumKeeperGasWrapperMock represents the basic keeper gas wrapper mock contract +type EthereumKeeperGasWrapperMock struct { + client *seth.Client + gasWrapperMock *gas_wrapper_mock.KeeperRegistryCheckUpkeepGasUsageWrapperMock + address *common.Address +} + +func (f *EthereumKeeperGasWrapperMock) Address() string { + return f.address.Hex() +} + +func (f *EthereumKeeperGasWrapperMock) SetMeasureCheckGasResult(result bool, payload []byte, gas *big.Int) error { + _, err := f.client.Decode(f.gasWrapperMock.SetMeasureCheckGasResult(f.client.NewTXOpts(), result, payload, gas)) + return err +} + +func DeployKeeperGasWrapperMock(client *seth.Client) (KeeperGasWrapperMock, error) { + abi, err := gas_wrapper_mock.KeeperRegistryCheckUpkeepGasUsageWrapperMockMetaData.GetAbi() + if err != nil { + return &EthereumKeeperGasWrapperMock{}, fmt.Errorf("failed to get KeeperGasWrapperMock ABI: %w", err) + } + client.ContractStore.AddABI("KeeperGasWrapperMock", *abi) + client.ContractStore.AddBIN("KeeperGasWrapperMock", common.FromHex(gas_wrapper_mock.KeeperRegistryCheckUpkeepGasUsageWrapperMockMetaData.Bin)) + + data, err := client.DeployContract(client.NewTXOpts(), "KeeperGasWrapperMock", *abi, common.FromHex(gas_wrapper_mock.KeeperRegistryCheckUpkeepGasUsageWrapperMockMetaData.Bin)) + + if err != nil { + return &EthereumKeeperGasWrapperMock{}, fmt.Errorf("KeeperGasWrapperMock instance deployment have failed: %w", err) + } + + instance, err := gas_wrapper_mock.NewKeeperRegistryCheckUpkeepGasUsageWrapperMock(data.Address, wrappers.MustNewWrappedContractBackend(nil, client)) + if err != nil { + return &EthereumKeeperGasWrapperMock{}, fmt.Errorf("failed to instantiate KeeperGasWrapperMock instance: %w", err) + } + + return &EthereumKeeperGasWrapperMock{ + client: client, + gasWrapperMock: instance, + address: &data.Address, + }, nil +} + +// EthereumStakingEventsMock represents the basic events mock contract +type EthereumStakingEventsMock struct { + client *seth.Client + eventsMock *eth_contracts.StakingEventsMock + address *common.Address +} + +func (f *EthereumStakingEventsMock) Address() string { + return f.address.Hex() +} + +func (f *EthereumStakingEventsMock) MaxCommunityStakeAmountIncreased(maxStakeAmount *big.Int) error { + _, err := f.client.Decode(f.eventsMock.EmitMaxCommunityStakeAmountIncreased(f.client.NewTXOpts(), maxStakeAmount)) + return err +} + +func (f *EthereumStakingEventsMock) PoolSizeIncreased(maxPoolSize *big.Int) error { + _, err := f.client.Decode(f.eventsMock.EmitPoolSizeIncreased(f.client.NewTXOpts(), maxPoolSize)) + return err +} + +func (f *EthereumStakingEventsMock) MaxOperatorStakeAmountIncreased(maxStakeAmount *big.Int) error { + _, err := f.client.Decode(f.eventsMock.EmitMaxOperatorStakeAmountIncreased(f.client.NewTXOpts(), maxStakeAmount)) + return err +} + +func (f *EthereumStakingEventsMock) RewardInitialized(rate *big.Int, available *big.Int, startTimestamp *big.Int, endTimestamp *big.Int) error { + _, err := f.client.Decode(f.eventsMock.EmitRewardInitialized(f.client.NewTXOpts(), rate, available, startTimestamp, endTimestamp)) + return err +} + +func (f *EthereumStakingEventsMock) AlertRaised(alerter common.Address, roundId *big.Int, rewardAmount *big.Int) error { + _, err := f.client.Decode(f.eventsMock.EmitAlertRaised(f.client.NewTXOpts(), alerter, roundId, rewardAmount)) + return err +} + +func (f *EthereumStakingEventsMock) Staked(staker common.Address, newStake *big.Int, totalStake *big.Int) error { + _, err := f.client.Decode(f.eventsMock.EmitStaked(f.client.NewTXOpts(), staker, newStake, totalStake)) + return err +} + +func (f *EthereumStakingEventsMock) OperatorAdded(operator common.Address) error { + _, err := f.client.Decode(f.eventsMock.EmitOperatorAdded(f.client.NewTXOpts(), operator)) + return err +} + +func (f *EthereumStakingEventsMock) OperatorRemoved(operator common.Address, amount *big.Int) error { + _, err := f.client.Decode(f.eventsMock.EmitOperatorRemoved(f.client.NewTXOpts(), operator, amount)) + return err +} + +func (f *EthereumStakingEventsMock) FeedOperatorsSet(feedOperators []common.Address) error { + _, err := f.client.Decode(f.eventsMock.EmitFeedOperatorsSet(f.client.NewTXOpts(), feedOperators)) + return err +} + +func DeployStakingEventsMock(client *seth.Client) (StakingEventsMock, error) { + abi, err := eth_contracts.StakingEventsMockMetaData.GetAbi() + if err != nil { + return &EthereumStakingEventsMock{}, fmt.Errorf("failed to get StakingEventsMock ABI: %w", err) + } + client.ContractStore.AddABI("StakingEventsMock", *abi) + client.ContractStore.AddBIN("StakingEventsMock", common.FromHex(eth_contracts.StakingEventsMockMetaData.Bin)) + + data, err := client.DeployContract(client.NewTXOpts(), "StakingEventsMock", *abi, common.FromHex(eth_contracts.StakingEventsMockMetaData.Bin)) + + if err != nil { + return &EthereumStakingEventsMock{}, fmt.Errorf("StakingEventsMock instance deployment have failed: %w", err) + } + + instance, err := eth_contracts.NewStakingEventsMock(data.Address, wrappers.MustNewWrappedContractBackend(nil, client)) + if err != nil { + return &EthereumStakingEventsMock{}, fmt.Errorf("failed to instantiate StakingEventsMock instance: %w", err) + } + + return &EthereumStakingEventsMock{ + client: client, + eventsMock: instance, + address: &data.Address, + }, nil +} diff --git a/integration-tests/contracts/ethereum_contracts.go b/integration-tests/contracts/ethereum_contracts.go index e8b2f184ce9..adf4dcffe80 100644 --- a/integration-tests/contracts/ethereum_contracts.go +++ b/integration-tests/contracts/ethereum_contracts.go @@ -350,18 +350,18 @@ func (f *EthereumFunctionsBillingRegistryEventsMock) BillingEnd(requestId [32]by return f.client.ProcessTransaction(tx) } -// EthereumStakingEventsMock represents the basic events mock contract -type EthereumStakingEventsMock struct { +// LegacyEthereumStakingEventsMock represents the basic events mock contract +type LegacyEthereumStakingEventsMock struct { client blockchain.EVMClient eventsMock *eth_contracts.StakingEventsMock address *common.Address } -func (f *EthereumStakingEventsMock) Address() string { +func (f *LegacyEthereumStakingEventsMock) Address() string { return f.address.Hex() } -func (f *EthereumStakingEventsMock) MaxCommunityStakeAmountIncreased(maxStakeAmount *big.Int) error { +func (f *LegacyEthereumStakingEventsMock) MaxCommunityStakeAmountIncreased(maxStakeAmount *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -373,7 +373,7 @@ func (f *EthereumStakingEventsMock) MaxCommunityStakeAmountIncreased(maxStakeAmo return f.client.ProcessTransaction(tx) } -func (f *EthereumStakingEventsMock) PoolSizeIncreased(maxPoolSize *big.Int) error { +func (f *LegacyEthereumStakingEventsMock) PoolSizeIncreased(maxPoolSize *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -385,7 +385,7 @@ func (f *EthereumStakingEventsMock) PoolSizeIncreased(maxPoolSize *big.Int) erro return f.client.ProcessTransaction(tx) } -func (f *EthereumStakingEventsMock) MaxOperatorStakeAmountIncreased(maxStakeAmount *big.Int) error { +func (f *LegacyEthereumStakingEventsMock) MaxOperatorStakeAmountIncreased(maxStakeAmount *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -397,7 +397,7 @@ func (f *EthereumStakingEventsMock) MaxOperatorStakeAmountIncreased(maxStakeAmou return f.client.ProcessTransaction(tx) } -func (f *EthereumStakingEventsMock) RewardInitialized(rate *big.Int, available *big.Int, startTimestamp *big.Int, endTimestamp *big.Int) error { +func (f *LegacyEthereumStakingEventsMock) RewardInitialized(rate *big.Int, available *big.Int, startTimestamp *big.Int, endTimestamp *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -409,7 +409,7 @@ func (f *EthereumStakingEventsMock) RewardInitialized(rate *big.Int, available * return f.client.ProcessTransaction(tx) } -func (f *EthereumStakingEventsMock) AlertRaised(alerter common.Address, roundId *big.Int, rewardAmount *big.Int) error { +func (f *LegacyEthereumStakingEventsMock) AlertRaised(alerter common.Address, roundId *big.Int, rewardAmount *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -421,7 +421,7 @@ func (f *EthereumStakingEventsMock) AlertRaised(alerter common.Address, roundId return f.client.ProcessTransaction(tx) } -func (f *EthereumStakingEventsMock) Staked(staker common.Address, newStake *big.Int, totalStake *big.Int) error { +func (f *LegacyEthereumStakingEventsMock) Staked(staker common.Address, newStake *big.Int, totalStake *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -433,7 +433,7 @@ func (f *EthereumStakingEventsMock) Staked(staker common.Address, newStake *big. return f.client.ProcessTransaction(tx) } -func (f *EthereumStakingEventsMock) OperatorAdded(operator common.Address) error { +func (f *LegacyEthereumStakingEventsMock) OperatorAdded(operator common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -445,7 +445,7 @@ func (f *EthereumStakingEventsMock) OperatorAdded(operator common.Address) error return f.client.ProcessTransaction(tx) } -func (f *EthereumStakingEventsMock) OperatorRemoved(operator common.Address, amount *big.Int) error { +func (f *LegacyEthereumStakingEventsMock) OperatorRemoved(operator common.Address, amount *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -457,7 +457,7 @@ func (f *EthereumStakingEventsMock) OperatorRemoved(operator common.Address, amo return f.client.ProcessTransaction(tx) } -func (f *EthereumStakingEventsMock) FeedOperatorsSet(feedOperators []common.Address) error { +func (f *LegacyEthereumStakingEventsMock) FeedOperatorsSet(feedOperators []common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -504,18 +504,18 @@ func (f *EthereumOffchainAggregatorEventsMock) NewTransmission(aggregatorRoundId return f.client.ProcessTransaction(tx) } -// EthereumKeeperRegistry11Mock represents the basic keeper registry 1.1 mock contract -type EthereumKeeperRegistry11Mock struct { +// LegacyEthereumKeeperRegistry11Mock represents the basic keeper registry 1.1 mock contract +type LegacyEthereumKeeperRegistry11Mock struct { client blockchain.EVMClient registryMock *keeper_registry_wrapper1_1_mock.KeeperRegistryMock address *common.Address } -func (f *EthereumKeeperRegistry11Mock) Address() string { +func (f *LegacyEthereumKeeperRegistry11Mock) Address() string { return f.address.Hex() } -func (f *EthereumKeeperRegistry11Mock) EmitUpkeepPerformed(id *big.Int, success bool, from common.Address, payment *big.Int, performData []byte) error { +func (f *LegacyEthereumKeeperRegistry11Mock) EmitUpkeepPerformed(id *big.Int, success bool, from common.Address, payment *big.Int, performData []byte) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -527,7 +527,7 @@ func (f *EthereumKeeperRegistry11Mock) EmitUpkeepPerformed(id *big.Int, success return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) EmitUpkeepCanceled(id *big.Int, atBlockHeight uint64) error { +func (f *LegacyEthereumKeeperRegistry11Mock) EmitUpkeepCanceled(id *big.Int, atBlockHeight uint64) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -539,7 +539,7 @@ func (f *EthereumKeeperRegistry11Mock) EmitUpkeepCanceled(id *big.Int, atBlockHe return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) EmitFundsWithdrawn(id *big.Int, amount *big.Int, to common.Address) error { +func (f *LegacyEthereumKeeperRegistry11Mock) EmitFundsWithdrawn(id *big.Int, amount *big.Int, to common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -551,7 +551,7 @@ func (f *EthereumKeeperRegistry11Mock) EmitFundsWithdrawn(id *big.Int, amount *b return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) EmitKeepersUpdated(keepers []common.Address, payees []common.Address) error { +func (f *LegacyEthereumKeeperRegistry11Mock) EmitKeepersUpdated(keepers []common.Address, payees []common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -563,7 +563,7 @@ func (f *EthereumKeeperRegistry11Mock) EmitKeepersUpdated(keepers []common.Addre return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) EmitUpkeepRegistered(id *big.Int, executeGas uint32, admin common.Address) error { +func (f *LegacyEthereumKeeperRegistry11Mock) EmitUpkeepRegistered(id *big.Int, executeGas uint32, admin common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -575,7 +575,7 @@ func (f *EthereumKeeperRegistry11Mock) EmitUpkeepRegistered(id *big.Int, execute return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) EmitFundsAdded(id *big.Int, from common.Address, amount *big.Int) error { +func (f *LegacyEthereumKeeperRegistry11Mock) EmitFundsAdded(id *big.Int, from common.Address, amount *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -587,7 +587,7 @@ func (f *EthereumKeeperRegistry11Mock) EmitFundsAdded(id *big.Int, from common.A return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) SetUpkeepCount(_upkeepCount *big.Int) error { +func (f *LegacyEthereumKeeperRegistry11Mock) SetUpkeepCount(_upkeepCount *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -599,7 +599,7 @@ func (f *EthereumKeeperRegistry11Mock) SetUpkeepCount(_upkeepCount *big.Int) err return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) SetCanceledUpkeepList(_canceledUpkeepList []*big.Int) error { +func (f *LegacyEthereumKeeperRegistry11Mock) SetCanceledUpkeepList(_canceledUpkeepList []*big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -611,7 +611,7 @@ func (f *EthereumKeeperRegistry11Mock) SetCanceledUpkeepList(_canceledUpkeepList return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) SetKeeperList(_keepers []common.Address) error { +func (f *LegacyEthereumKeeperRegistry11Mock) SetKeeperList(_keepers []common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -623,7 +623,7 @@ func (f *EthereumKeeperRegistry11Mock) SetKeeperList(_keepers []common.Address) return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) SetConfig(_paymentPremiumPPB uint32, _flatFeeMicroLink uint32, _blockCountPerTurn *big.Int, _checkGasLimit uint32, _stalenessSeconds *big.Int, _gasCeilingMultiplier uint16, _fallbackGasPrice *big.Int, _fallbackLinkPrice *big.Int) error { +func (f *LegacyEthereumKeeperRegistry11Mock) SetConfig(_paymentPremiumPPB uint32, _flatFeeMicroLink uint32, _blockCountPerTurn *big.Int, _checkGasLimit uint32, _stalenessSeconds *big.Int, _gasCeilingMultiplier uint16, _fallbackGasPrice *big.Int, _fallbackLinkPrice *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -635,7 +635,7 @@ func (f *EthereumKeeperRegistry11Mock) SetConfig(_paymentPremiumPPB uint32, _fla return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) SetUpkeep(id *big.Int, _target common.Address, _executeGas uint32, _balance *big.Int, _admin common.Address, _maxValidBlocknumber uint64, _lastKeeper common.Address, _checkData []byte) error { +func (f *LegacyEthereumKeeperRegistry11Mock) SetUpkeep(id *big.Int, _target common.Address, _executeGas uint32, _balance *big.Int, _admin common.Address, _maxValidBlocknumber uint64, _lastKeeper common.Address, _checkData []byte) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -647,7 +647,7 @@ func (f *EthereumKeeperRegistry11Mock) SetUpkeep(id *big.Int, _target common.Add return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) SetMinBalance(id *big.Int, minBalance *big.Int) error { +func (f *LegacyEthereumKeeperRegistry11Mock) SetMinBalance(id *big.Int, minBalance *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -659,7 +659,7 @@ func (f *EthereumKeeperRegistry11Mock) SetMinBalance(id *big.Int, minBalance *bi return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) SetCheckUpkeepData(id *big.Int, performData []byte, maxLinkPayment *big.Int, gasLimit *big.Int, adjustedGasWei *big.Int, linkEth *big.Int) error { +func (f *LegacyEthereumKeeperRegistry11Mock) SetCheckUpkeepData(id *big.Int, performData []byte, maxLinkPayment *big.Int, gasLimit *big.Int, adjustedGasWei *big.Int, linkEth *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -671,7 +671,7 @@ func (f *EthereumKeeperRegistry11Mock) SetCheckUpkeepData(id *big.Int, performDa return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistry11Mock) SetPerformUpkeepSuccess(id *big.Int, success bool) error { +func (f *LegacyEthereumKeeperRegistry11Mock) SetPerformUpkeepSuccess(id *big.Int, success bool) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -683,18 +683,18 @@ func (f *EthereumKeeperRegistry11Mock) SetPerformUpkeepSuccess(id *big.Int, succ return f.client.ProcessTransaction(tx) } -// EthereumKeeperRegistrar12Mock represents the basic keeper registrar 1.2 mock contract -type EthereumKeeperRegistrar12Mock struct { +// LegacyEthereumKeeperRegistrar12Mock represents the basic keeper registrar 1.2 mock contract +type LegacyEthereumKeeperRegistrar12Mock struct { client blockchain.EVMClient registrarMock *keeper_registrar_wrapper1_2_mock.KeeperRegistrarMock address *common.Address } -func (f *EthereumKeeperRegistrar12Mock) Address() string { +func (f *LegacyEthereumKeeperRegistrar12Mock) Address() string { return f.address.Hex() } -func (f *EthereumKeeperRegistrar12Mock) EmitRegistrationRequested(hash [32]byte, name string, encryptedEmail []byte, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, checkData []byte, amount *big.Int, source uint8) error { +func (f *LegacyEthereumKeeperRegistrar12Mock) EmitRegistrationRequested(hash [32]byte, name string, encryptedEmail []byte, upkeepContract common.Address, gasLimit uint32, adminAddress common.Address, checkData []byte, amount *big.Int, source uint8) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -706,7 +706,7 @@ func (f *EthereumKeeperRegistrar12Mock) EmitRegistrationRequested(hash [32]byte, return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistrar12Mock) EmitRegistrationApproved(hash [32]byte, displayName string, upkeepId *big.Int) error { +func (f *LegacyEthereumKeeperRegistrar12Mock) EmitRegistrationApproved(hash [32]byte, displayName string, upkeepId *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -718,7 +718,7 @@ func (f *EthereumKeeperRegistrar12Mock) EmitRegistrationApproved(hash [32]byte, return f.client.ProcessTransaction(tx) } -func (f *EthereumKeeperRegistrar12Mock) SetRegistrationConfig(_autoApproveConfigType uint8, _autoApproveMaxAllowed uint32, _approvedCount uint32, _keeperRegistry common.Address, _minLINKJuels *big.Int) error { +func (f *LegacyEthereumKeeperRegistrar12Mock) SetRegistrationConfig(_autoApproveConfigType uint8, _autoApproveMaxAllowed uint32, _approvedCount uint32, _keeperRegistry common.Address, _minLINKJuels *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -730,18 +730,18 @@ func (f *EthereumKeeperRegistrar12Mock) SetRegistrationConfig(_autoApproveConfig return f.client.ProcessTransaction(tx) } -// EthereumKeeperGasWrapperMock represents the basic keeper gas wrapper mock contract -type EthereumKeeperGasWrapperMock struct { +// LegacyEthereumKeeperGasWrapperMock represents the basic keeper gas wrapper mock contract +type LegacyEthereumKeeperGasWrapperMock struct { client blockchain.EVMClient gasWrapperMock *gas_wrapper_mock.KeeperRegistryCheckUpkeepGasUsageWrapperMock address *common.Address } -func (f *EthereumKeeperGasWrapperMock) Address() string { +func (f *LegacyEthereumKeeperGasWrapperMock) Address() string { return f.address.Hex() } -func (f *EthereumKeeperGasWrapperMock) SetMeasureCheckGasResult(result bool, payload []byte, gas *big.Int) error { +func (f *LegacyEthereumKeeperGasWrapperMock) SetMeasureCheckGasResult(result bool, payload []byte, gas *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -753,18 +753,18 @@ func (f *EthereumKeeperGasWrapperMock) SetMeasureCheckGasResult(result bool, pay return f.client.ProcessTransaction(tx) } -// EthereumFunctionsV1EventsMock represents the basic functions v1 events mock contract -type EthereumFunctionsV1EventsMock struct { +// LegacyEthereumFunctionsV1EventsMock represents the basic functions v1 events mock contract +type LegacyEthereumFunctionsV1EventsMock struct { client blockchain.EVMClient eventsMock *functions_v1_events_mock.FunctionsV1EventsMock address *common.Address } -func (f *EthereumFunctionsV1EventsMock) Address() string { +func (f *LegacyEthereumFunctionsV1EventsMock) Address() string { return f.address.Hex() } -func (f *EthereumFunctionsV1EventsMock) EmitRequestProcessed(requestId [32]byte, subscriptionId uint64, totalCostJuels *big.Int, transmitter common.Address, resultCode uint8, response []byte, errByte []byte, callbackReturnData []byte) error { +func (f *LegacyEthereumFunctionsV1EventsMock) EmitRequestProcessed(requestId [32]byte, subscriptionId uint64, totalCostJuels *big.Int, transmitter common.Address, resultCode uint8, response []byte, errByte []byte, callbackReturnData []byte) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -776,7 +776,7 @@ func (f *EthereumFunctionsV1EventsMock) EmitRequestProcessed(requestId [32]byte, return f.client.ProcessTransaction(tx) } -func (f *EthereumFunctionsV1EventsMock) EmitRequestStart(requestId [32]byte, donId [32]byte, subscriptionId uint64, subscriptionOwner common.Address, requestingContract common.Address, requestInitiator common.Address, data []byte, dataVersion uint16, callbackGasLimit uint32, estimatedTotalCostJuels *big.Int) error { +func (f *LegacyEthereumFunctionsV1EventsMock) EmitRequestStart(requestId [32]byte, donId [32]byte, subscriptionId uint64, subscriptionOwner common.Address, requestingContract common.Address, requestInitiator common.Address, data []byte, dataVersion uint16, callbackGasLimit uint32, estimatedTotalCostJuels *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -788,7 +788,7 @@ func (f *EthereumFunctionsV1EventsMock) EmitRequestStart(requestId [32]byte, don return f.client.ProcessTransaction(tx) } -func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionCanceled(subscriptionId uint64, fundsRecipient common.Address, fundsAmount *big.Int) error { +func (f *LegacyEthereumFunctionsV1EventsMock) EmitSubscriptionCanceled(subscriptionId uint64, fundsRecipient common.Address, fundsAmount *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -800,7 +800,7 @@ func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionCanceled(subscriptionId return f.client.ProcessTransaction(tx) } -func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionConsumerAdded(subscriptionId uint64, consumer common.Address) error { +func (f *LegacyEthereumFunctionsV1EventsMock) EmitSubscriptionConsumerAdded(subscriptionId uint64, consumer common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -812,7 +812,7 @@ func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionConsumerAdded(subscripti return f.client.ProcessTransaction(tx) } -func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionConsumerRemoved(subscriptionId uint64, consumer common.Address) error { +func (f *LegacyEthereumFunctionsV1EventsMock) EmitSubscriptionConsumerRemoved(subscriptionId uint64, consumer common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -824,7 +824,7 @@ func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionConsumerRemoved(subscrip return f.client.ProcessTransaction(tx) } -func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionCreated(subscriptionId uint64, owner common.Address) error { +func (f *LegacyEthereumFunctionsV1EventsMock) EmitSubscriptionCreated(subscriptionId uint64, owner common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -836,7 +836,7 @@ func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionCreated(subscriptionId u return f.client.ProcessTransaction(tx) } -func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionFunded(subscriptionId uint64, oldBalance *big.Int, newBalance *big.Int) error { +func (f *LegacyEthereumFunctionsV1EventsMock) EmitSubscriptionFunded(subscriptionId uint64, oldBalance *big.Int, newBalance *big.Int) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -848,7 +848,7 @@ func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionFunded(subscriptionId ui return f.client.ProcessTransaction(tx) } -func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionOwnerTransferred(subscriptionId uint64, from common.Address, to common.Address) error { +func (f *LegacyEthereumFunctionsV1EventsMock) EmitSubscriptionOwnerTransferred(subscriptionId uint64, from common.Address, to common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -860,7 +860,7 @@ func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionOwnerTransferred(subscri return f.client.ProcessTransaction(tx) } -func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionOwnerTransferRequested(subscriptionId uint64, from common.Address, to common.Address) error { +func (f *LegacyEthereumFunctionsV1EventsMock) EmitSubscriptionOwnerTransferRequested(subscriptionId uint64, from common.Address, to common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -872,7 +872,7 @@ func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionOwnerTransferRequested(s return f.client.ProcessTransaction(tx) } -func (f *EthereumFunctionsV1EventsMock) EmitRequestNotProcessed(requestId [32]byte, coordinator common.Address, transmitter common.Address, resultCode uint8) error { +func (f *LegacyEthereumFunctionsV1EventsMock) EmitRequestNotProcessed(requestId [32]byte, coordinator common.Address, transmitter common.Address, resultCode uint8) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err @@ -884,7 +884,7 @@ func (f *EthereumFunctionsV1EventsMock) EmitRequestNotProcessed(requestId [32]by return f.client.ProcessTransaction(tx) } -func (f *EthereumFunctionsV1EventsMock) EmitContractUpdated(id [32]byte, from common.Address, to common.Address) error { +func (f *LegacyEthereumFunctionsV1EventsMock) EmitContractUpdated(id [32]byte, from common.Address, to common.Address) error { opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet()) if err != nil { return err diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 0903711f16e..3d76a656be5 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -26,11 +26,11 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.3 github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb - github.com/smartcontractkit/chainlink-testing-framework v1.28.4 + github.com/smartcontractkit/chainlink-testing-framework v1.28.7 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c - github.com/smartcontractkit/seth v0.1.6 + github.com/smartcontractkit/seth v0.1.6-0.20240429143720-cacb8160ecec github.com/smartcontractkit/wasp v0.4.5 github.com/spf13/cobra v1.8.0 github.com/stretchr/testify v1.9.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index d9bb628d861..61fef05bbad 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1529,8 +1529,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba5 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58/go.mod h1:oV5gIuSKrPEcjQ6uB6smBsm5kXHxyydVLNyAs4V9CoQ= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595 h1:y6ks0HsSOhPUueOmTcoxDQ50RCS1XINlRDTemZyHjFw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595/go.mod h1:vV6WfnVIbK5Q1JsIru4YcTG0T1uRpLJm6t2BgCnCSsg= -github.com/smartcontractkit/chainlink-testing-framework v1.28.4 h1:/OOPH76VFQlG5HEXrXgBVDv1fjuasQzMV1EyeaaXWzM= -github.com/smartcontractkit/chainlink-testing-framework v1.28.4/go.mod h1:jN+HgXbriq6fKRlIqLw9F3I81aYImV6kBJkIfz0mdIA= +github.com/smartcontractkit/chainlink-testing-framework v1.28.7 h1:Yr93tBl5jVx1cfKywt0C0cbuObDPJ6JIU4FIsZ6bZlM= +github.com/smartcontractkit/chainlink-testing-framework v1.28.7/go.mod h1:x1zDOz8zcLjEvs9fNA9y/DMguLam/2+CJdpxX0+rM8A= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868/go.mod h1:Kn1Hape05UzFZ7bOUnm3GVsHzP0TNrVmpfXYNHdqGGs= github.com/smartcontractkit/go-plugin v0.0.0-20240208201424-b3b91517de16 h1:TFe+FvzxClblt6qRfqEhUfa4kFQx5UobuoFGO2W4mMo= @@ -1539,8 +1539,8 @@ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJ github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0= github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c h1:lIyMbTaF2H0Q71vkwZHX/Ew4KF2BxiKhqEXwF8rn+KI= github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c/go.mod h1:fb1ZDVXACvu4frX3APHZaEBp0xi1DIm34DcA0CwTsZM= -github.com/smartcontractkit/seth v0.1.6 h1:exU96KiKM/gxvp7OR8KkOXnTgbtFNepdhMBvyobFKCw= -github.com/smartcontractkit/seth v0.1.6/go.mod h1:2TMOZQ8WTAw7rR1YBbXpnad6VmT/+xDd/nXLmB7Eero= +github.com/smartcontractkit/seth v0.1.6-0.20240429143720-cacb8160ecec h1:BT1loU6TT2YqMenD7XE+aw7IeeTiC25+r1TLKAySVIg= +github.com/smartcontractkit/seth v0.1.6-0.20240429143720-cacb8160ecec/go.mod h1:2TMOZQ8WTAw7rR1YBbXpnad6VmT/+xDd/nXLmB7Eero= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE= github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index a4c5b67c204..c8fde175cab 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -17,7 +17,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.3 github.com/smartcontractkit/chainlink-common v0.1.7-0.20240429120925-907b29311feb - github.com/smartcontractkit/chainlink-testing-framework v1.28.4 + github.com/smartcontractkit/chainlink-testing-framework v1.28.7 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index e2d5b5270ff..46646e6b289 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1512,8 +1512,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba5 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240422172640-59d47c73ba58/go.mod h1:oV5gIuSKrPEcjQ6uB6smBsm5kXHxyydVLNyAs4V9CoQ= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595 h1:y6ks0HsSOhPUueOmTcoxDQ50RCS1XINlRDTemZyHjFw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240325075535-0f7eb05ee595/go.mod h1:vV6WfnVIbK5Q1JsIru4YcTG0T1uRpLJm6t2BgCnCSsg= -github.com/smartcontractkit/chainlink-testing-framework v1.28.4 h1:/OOPH76VFQlG5HEXrXgBVDv1fjuasQzMV1EyeaaXWzM= -github.com/smartcontractkit/chainlink-testing-framework v1.28.4/go.mod h1:jN+HgXbriq6fKRlIqLw9F3I81aYImV6kBJkIfz0mdIA= +github.com/smartcontractkit/chainlink-testing-framework v1.28.7 h1:Yr93tBl5jVx1cfKywt0C0cbuObDPJ6JIU4FIsZ6bZlM= +github.com/smartcontractkit/chainlink-testing-framework v1.28.7/go.mod h1:x1zDOz8zcLjEvs9fNA9y/DMguLam/2+CJdpxX0+rM8A= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240227164431-18a7065e23ea h1:ZdLmNAfKRjH8AYUvjiiDGUgiWQfq/7iNpxyTkvjx/ko= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240227164431-18a7065e23ea/go.mod h1:gCKC9w6XpNk6jm+XIk2psrkkfxhi421N9NSiFceXW88= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= From 8cb83a4d553fa425aec67269d56f12f0efcc4a92 Mon Sep 17 00:00:00 2001 From: frank zhu Date: Mon, 29 Apr 2024 10:19:33 -0700 Subject: [PATCH 57/77] add version to changeset release preview pr (#13032) * add version to changeset release preview pr * add more perm for gh token * add GITHUB_TOKEN env to run changeset version * add workflow perm * workflows * test new perm * fix github_output bug and remove a perm * remove test branch trigger * remove test changeset --- .github/workflows/cicd-changesets.yml | 28 ++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cicd-changesets.yml b/.github/workflows/cicd-changesets.yml index 0bfec7b22f2..96363588319 100644 --- a/.github/workflows/cicd-changesets.yml +++ b/.github/workflows/cicd-changesets.yml @@ -16,6 +16,7 @@ jobs: permissions: id-token: write contents: read + actions: read steps: - name: Checkout repository uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 @@ -28,6 +29,31 @@ jobs: core-changeset: - added: '.changeset/**' + - name: Setup pnpm + uses: pnpm/action-setup@a3252b78c470c02df07e9d59298aecedc3ccdd6d # v3.0.0 + if: steps.changeset-added.outputs.core-changeset == 'true' + with: + version: ^8.0.0 + + - name: Setup node + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + if: steps.changeset-added.outputs.core-changeset == 'true' + with: + node-version: 20 + cache: pnpm + cache-dependency-path: ./pnpm-lock.yaml + + - name: Run changeset version + run: pnpm install && pnpm changeset version + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + if: steps.changeset-added.outputs.core-changeset == 'true' + + - name: Get release version + if: steps.changeset-added.outputs.core-changeset == 'true' + id: get-release-version + run: echo "version=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT + - name: cicd-changesets if: steps.changeset-added.outputs.core-changeset == 'true' uses: smartcontractkit/.github/actions/cicd-changesets@6da79c7b9f14bec077df2c1ad40d53823b409d9c # cicd-changesets@0.3.3 @@ -37,7 +63,7 @@ jobs: git-email: app-token-issuer-releng[bot]@users.noreply.github.com pnpm-use-cache: false pr-draft: true - pr-title: "[DO NOT MERGE] Release Preview - Changeset" + pr-title: "[DO NOT MERGE] Changeset Release Preview - v${{ steps.get-release-version.outputs.version }}" # aws inputs aws-region: ${{ secrets.AWS_REGION }} aws-role-arn: ${{ secrets.AWS_OIDC_CHAINLINK_CI_AUTO_PR_TOKEN_ISSUER_ROLE_ARN }} From e482c7982278e232acaaa4b3e9a79165faa35d1c Mon Sep 17 00:00:00 2001 From: HenryNguyen5 <6404866+HenryNguyen5@users.noreply.github.com> Date: Mon, 29 Apr 2024 19:46:47 -0400 Subject: [PATCH 58/77] [Keystone] Improve workflow engine test times (#12959) * Improve workflow engine test times * Extract graph traversal initalization logic --- .changeset/fast-students-accept.md | 5 + core/services/workflows/engine.go | 207 +++++++++++++--------- core/services/workflows/engine_test.go | 85 +++++---- core/services/workflows/retry.go | 53 ++++++ core/services/workflows/retryable_test.go | 113 ++++++++++++ 5 files changed, 339 insertions(+), 124 deletions(-) create mode 100644 .changeset/fast-students-accept.md create mode 100644 core/services/workflows/retry.go create mode 100644 core/services/workflows/retryable_test.go diff --git a/.changeset/fast-students-accept.md b/.changeset/fast-students-accept.md new file mode 100644 index 00000000000..8813f3a7812 --- /dev/null +++ b/.changeset/fast-students-accept.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal Optimize workflow engine tests diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go index 0ecc311acac..040e123567e 100644 --- a/core/services/workflows/engine.go +++ b/core/services/workflows/engine.go @@ -45,6 +45,14 @@ type Engine struct { // Used for testing to wait for an execution to complete xxxExecutionFinished chan string + // testing lifecycle hook to signal initialization status + afterInit func(success bool) + // Used for testing to control the number of retries + // we'll do when initializing the engine. + maxRetries int + // Used for testing to control the retry interval + // when initializing the engine. + retryMs int } func (e *Engine) Start(ctx context.Context) error { @@ -60,94 +68,67 @@ func (e *Engine) Start(ctx context.Context) error { }) } -// init does the following: -// -// 1. Resolves the underlying capability for each trigger -// 2. Registers each step's capability to this workflow -// 3. Registers for trigger events now that all capabilities are resolved +// resolveWorkflowCapabilities does the following: // -// Steps 1 and 2 are retried every 5 seconds until successful. -func (e *Engine) init(ctx context.Context) { - defer e.wg.Done() - - retrySec := 5 - ticker := time.NewTicker(time.Duration(retrySec) * time.Second) - defer ticker.Stop() - -LOOP: - for { - select { - case <-ctx.Done(): - return - case <-ticker.C: - initSuccessful := true - // Resolve the underlying capability for each trigger - for _, t := range e.workflow.triggers { - tg, err := e.registry.GetTrigger(ctx, t.Type) - if err != nil { - initSuccessful = false - e.logger.Errorf("failed to get trigger capability: %s, retrying in %d seconds", err, retrySec) - continue - } - t.trigger = tg - } - if !initSuccessful { - continue - } - - // Walk the graph and initialize each step. - // This means: - // - fetching the capability - // - register the capability to this workflow - // - initializing the step's executionStrategy - err := e.workflow.walkDo(keywordTrigger, func(s *step) error { - // The graph contains a dummy step for triggers, but - // we handle triggers separately since there might be more than one. - if s.Ref == keywordTrigger { - return nil - } - - err := e.initializeCapability(ctx, s, retrySec) - if err != nil { - return err - } - - return e.initializeExecutionStrategy(s) - }) - if err != nil { - initSuccessful = false - e.logger.Error(err) - } - - if initSuccessful { - break LOOP - } +// 1. Resolves the underlying capability for each trigger +// 2. Registers each step's capability to this workflow +func (e *Engine) resolveWorkflowCapabilities(ctx context.Context) error { + // + // Step 1. Resolve the underlying capability for each trigger + // + triggersInitialized := true + for _, t := range e.workflow.triggers { + tg, err := e.registry.GetTrigger(ctx, t.Type) + if err != nil { + e.logger.Errorf("failed to get trigger capability: %s", err) + // we don't immediately return here, since we want to retry all triggers + // to notify the user of all errors at once. + triggersInitialized = false + } else { + t.trigger = tg } } + if !triggersInitialized { + return fmt.Errorf("failed to resolve triggers") + } + + // Step 2. Walk the graph and register each step's capability to this workflow + // + // This means: + // - fetching the capability + // - register the capability to this workflow + // - initializing the step's executionStrategy + capabilityRegistrationErr := e.workflow.walkDo(keywordTrigger, func(s *step) error { + // The graph contains a dummy step for triggers, but + // we handle triggers separately since there might be more than one + // trigger registered to a workflow. + if s.Ref == keywordTrigger { + return nil + } - // We have all needed capabilities, now we can register for trigger events - for _, t := range e.workflow.triggers { - err := e.registerTrigger(ctx, t) + err := e.initializeCapability(ctx, s) if err != nil { - e.logger.Errorf("failed to register trigger: %s", err) + return err } - } - e.logger.Info("engine initialized") + return e.initializeExecutionStrategy(s) + }) + + return capabilityRegistrationErr } -func (e *Engine) initializeCapability(ctx context.Context, s *step, retrySec int) error { +func (e *Engine) initializeCapability(ctx context.Context, s *step) error { // If the capability already exists, that means we've already registered it if s.capability != nil { return nil } - cp, innerErr := e.registry.Get(ctx, s.Type) - if innerErr != nil { - return fmt.Errorf("failed to get capability with ref %s: %s, retrying in %d seconds", s.Type, innerErr, retrySec) + cp, err := e.registry.Get(ctx, s.Type) + if err != nil { + return fmt.Errorf("failed to get capability with ref %s: %s", s.Type, err) } - // We only need to configure actions, consensus and targets here, and + // We configure actions, consensus and targets here, and // they all satisfy the `CallbackCapability` interface cc, ok := cp.(capabilities.CallbackCapability) if !ok { @@ -155,29 +136,65 @@ func (e *Engine) initializeCapability(ctx context.Context, s *step, retrySec int } if s.config == nil { - configMap, ierr := values.NewMap(s.Config) - if ierr != nil { - return fmt.Errorf("failed to convert config to values.Map: %s", ierr) + configMap, newMapErr := values.NewMap(s.Config) + if newMapErr != nil { + return fmt.Errorf("failed to convert config to values.Map: %s", newMapErr) } s.config = configMap } - reg := capabilities.RegisterToWorkflowRequest{ + registrationRequest := capabilities.RegisterToWorkflowRequest{ Metadata: capabilities.RegistrationMetadata{ WorkflowID: e.workflow.id, }, Config: s.config, } - innerErr = cc.RegisterToWorkflow(ctx, reg) - if innerErr != nil { - return fmt.Errorf("failed to register to workflow (%+v): %w", reg, innerErr) + err = cc.RegisterToWorkflow(ctx, registrationRequest) + if err != nil { + return fmt.Errorf("failed to register to workflow (%+v): %w", registrationRequest, err) } s.capability = cc return nil } +// init does the following: +// +// 1. Resolves the underlying capability for each trigger +// 2. Registers each step's capability to this workflow +// 3. Registers for trigger events now that all capabilities are resolved +// +// Steps 1 and 2 are retried every 5 seconds until successful. +func (e *Engine) init(ctx context.Context) { + defer e.wg.Done() + + retryErr := retryable(ctx, e.logger, e.retryMs, e.maxRetries, func() error { + err := e.resolveWorkflowCapabilities(ctx) + if err != nil { + return fmt.Errorf("failed to resolve workflow: %s", err) + } + return nil + }) + + if retryErr != nil { + e.logger.Errorf("initialization failed: %s", retryErr) + e.afterInit(false) + return + } + + e.logger.Debug("capabilities resolved, registering triggers") + for _, t := range e.workflow.triggers { + err := e.registerTrigger(ctx, t) + if err != nil { + e.logger.Errorf("failed to register trigger: %s", err) + } + } + + e.logger.Info("engine initialized") + e.afterInit(true) +} + // initializeExecutionStrategy for `step`. // Broadly speaking, we'll use `immediateExecution` for non-target steps // and `scheduledExecution` for targets. If we don't have the necessary @@ -609,6 +626,7 @@ func (e *Engine) deregisterTrigger(ctx context.Context, t *triggerCapability) er func (e *Engine) Close() error { return e.StopOnce("Engine", func() error { + e.logger.Info("shutting down engine") ctx := context.Background() // To shut down the engine, we'll start by deregistering // any triggers to ensure no new executions are triggered, @@ -668,6 +686,11 @@ type Config struct { NewWorkerTimeout time.Duration DONInfo *capabilities.DON PeerID func() *p2ptypes.PeerID + + // For testing purposes only + maxRetries int + retryMs int + afterInit func(success bool) } const ( @@ -689,6 +712,14 @@ func NewEngine(cfg Config) (engine *Engine, err error) { cfg.NewWorkerTimeout = defaultNewWorkerTimeout } + if cfg.retryMs == 0 { + cfg.retryMs = 5000 + } + + if cfg.afterInit == nil { + cfg.afterInit = func(success bool) {} + } + // TODO: validation of the workflow spec // We'll need to check, among other things: // - that there are no step `ref` called `trigger` as this is reserved for any triggers @@ -718,14 +749,18 @@ func NewEngine(cfg Config) (engine *Engine, err error) { DON: cfg.DONInfo, PeerID: cfg.PeerID, }, - executionStates: newInMemoryStore(), - pendingStepRequests: make(chan stepRequest, cfg.QueueSize), - newWorkerCh: newWorkerCh, - stepUpdateCh: make(chan stepState), - triggerEvents: make(chan capabilities.CapabilityResponse), - stopCh: make(chan struct{}), - newWorkerTimeout: cfg.NewWorkerTimeout, + executionStates: newInMemoryStore(), + pendingStepRequests: make(chan stepRequest, cfg.QueueSize), + newWorkerCh: newWorkerCh, + stepUpdateCh: make(chan stepState), + triggerEvents: make(chan capabilities.CapabilityResponse), + stopCh: make(chan struct{}), + newWorkerTimeout: cfg.NewWorkerTimeout, + // For testing purposes only xxxExecutionFinished: make(chan string), + afterInit: cfg.afterInit, + maxRetries: cfg.maxRetries, + retryMs: cfg.retryMs, } return engine, nil } diff --git a/core/services/workflows/engine_test.go b/core/services/workflows/engine_test.go index d82c9d4b7d2..4821b5800c7 100644 --- a/core/services/workflows/engine_test.go +++ b/core/services/workflows/engine_test.go @@ -65,6 +65,44 @@ targets: abi: "receive(report bytes)" ` +// newTestEngine creates a new engine with some test defaults. +func newTestEngine(t *testing.T, reg *coreCap.Registry, spec string) (eng *Engine, initFailed chan struct{}) { + peerID := p2ptypes.PeerID{} + initFailed = make(chan struct{}) + cfg := Config{ + Lggr: logger.TestLogger(t), + Registry: reg, + Spec: spec, + DONInfo: nil, + PeerID: func() *p2ptypes.PeerID { return &peerID }, + maxRetries: 1, + retryMs: 100, + afterInit: func(success bool) { + if !success { + close(initFailed) + } + }, + } + eng, err := NewEngine(cfg) + require.NoError(t, err) + return eng, initFailed +} + +// getExecutionId returns the execution id of the workflow that is +// currently being executed by the engine. +// +// If the engine fails to initialize, the test will fail rather +// than blocking indefinitely. +func getExecutionId(t *testing.T, eng *Engine, initFailed <-chan struct{}) string { + var eid string + select { + case <-initFailed: + t.FailNow() + case eid = <-eng.xxxExecutionFinished: + } + return eid +} + type mockCapability struct { capabilities.CapabilityInfo capabilities.CallbackExecutable @@ -148,23 +186,13 @@ func TestEngineWithHardcodedWorkflow(t *testing.T) { ) require.NoError(t, reg.Add(ctx, target2)) - lggr := logger.TestLogger(t) - peerID := p2ptypes.PeerID{} - cfg := Config{ - Lggr: lggr, - Registry: reg, - Spec: hardcodedWorkflow, - DONInfo: nil, - PeerID: func() *p2ptypes.PeerID { return &peerID }, - } - eng, err := NewEngine(cfg) - require.NoError(t, err) + eng, initFailed := newTestEngine(t, reg, hardcodedWorkflow) - err = eng.Start(ctx) + err := eng.Start(ctx) require.NoError(t, err) defer eng.Close() - eid := <-eng.xxxExecutionFinished + eid := getExecutionId(t, eng, initFailed) assert.Equal(t, cr, <-target1.response) assert.Equal(t, cr, <-target2.response) @@ -312,22 +340,13 @@ func TestEngine_ErrorsTheWorkflowIfAStepErrors(t *testing.T) { require.NoError(t, reg.Add(ctx, mockFailingConsensus())) require.NoError(t, reg.Add(ctx, mockTarget())) - peerID := p2ptypes.PeerID{} - cfg := Config{ - Lggr: logger.TestLogger(t), - Registry: reg, - Spec: simpleWorkflow, - DONInfo: nil, - PeerID: func() *p2ptypes.PeerID { return &peerID }, - } - eng, err := NewEngine(cfg) - require.NoError(t, err) + eng, initFailed := newTestEngine(t, reg, simpleWorkflow) - err = eng.Start(ctx) + err := eng.Start(ctx) require.NoError(t, err) defer eng.Close() - eid := <-eng.xxxExecutionFinished + eid := getExecutionId(t, eng, initFailed) state, err := eng.executionStates.get(ctx, eid) require.NoError(t, err) @@ -420,22 +439,12 @@ func TestEngine_MultiStepDependencies(t *testing.T) { action, out := mockAction() require.NoError(t, reg.Add(ctx, action)) - peerID := p2ptypes.PeerID{} - cfg := Config{ - Lggr: logger.TestLogger(t), - Registry: reg, - Spec: multiStepWorkflow, - DONInfo: nil, - PeerID: func() *p2ptypes.PeerID { return &peerID }, - } - eng, err := NewEngine(cfg) - require.NoError(t, err) - - err = eng.Start(ctx) + eng, initFailed := newTestEngine(t, reg, multiStepWorkflow) + err := eng.Start(ctx) require.NoError(t, err) defer eng.Close() - eid := <-eng.xxxExecutionFinished + eid := getExecutionId(t, eng, initFailed) state, err := eng.executionStates.get(ctx, eid) require.NoError(t, err) diff --git a/core/services/workflows/retry.go b/core/services/workflows/retry.go new file mode 100644 index 00000000000..e3f04353e7f --- /dev/null +++ b/core/services/workflows/retry.go @@ -0,0 +1,53 @@ +package workflows + +import ( + "context" + "fmt" + "time" + + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +// retryable is a helper function that retries a function until it succeeds. +// +// It will retry every `retryMs` milliseconds, up to `maxRetries` times. +// +// If `maxRetries` is 0, it will retry indefinitely. +// +// retryable will return an error in the following conditions: +// - the context is cancelled: the error returned is the context error +// - the retry limit has been hit: the error returned is the last error returned by `fn` +func retryable(ctx context.Context, lggr logger.Logger, retryMs int, maxRetries int, fn func() error) error { + ticker := time.NewTicker(time.Duration(retryMs) * time.Millisecond) + defer ticker.Stop() + + // immediately try once + err := fn() + if err == nil { + return nil + } + retries := 0 + + for { + // if maxRetries is 0, we'll retry indefinitely + if maxRetries > 0 { + if retries >= maxRetries { + lggr.Errorf("%s", err) + return fmt.Errorf("max retries reached, aborting") + } + } + lggr.Errorf("%s, retrying in %.2fs", err, float64(retryMs)/1000) + + select { + case <-ctx.Done(): + return ctx.Err() + case <-ticker.C: + err = fn() + if err == nil { + return nil + } + } + + retries++ + } +} diff --git a/core/services/workflows/retryable_test.go b/core/services/workflows/retryable_test.go new file mode 100644 index 00000000000..1a17ac55fae --- /dev/null +++ b/core/services/workflows/retryable_test.go @@ -0,0 +1,113 @@ +package workflows + +import ( + "context" + "errors" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func TestRetryableZeroMaxRetries(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond) + defer cancel() + + fn := func() error { + return errors.New("test error") + } + + err := retryable(ctx, logger.NullLogger, 100, 0, fn) + assert.ErrorIs(t, err, context.DeadlineExceeded, "Expected context deadline exceeded error") +} + +func TestRetryableSuccessOnFirstAttempt(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + fn := func() error { + return nil + } + + err := retryable(ctx, logger.NullLogger, 100, 3, fn) + require.NoError(t, err, "Expected no error as function succeeds on first attempt") +} + +func TestRetryableSuccessAfterRetries(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + retries := 0 + fn := func() error { + if retries < 2 { + retries++ + return errors.New("test error") + } + return nil + } + + err := retryable(ctx, logger.NullLogger, 100, 5, fn) + assert.NoError(t, err, "Expected no error after successful retry") + assert.Equal(t, 2, retries, "Expected two retries before success") +} + +func TestRetryableErrorOnFirstTryNoRetries(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + fn := func() error { + return errors.New("immediate failure") + } + + err := retryable(ctx, logger.NullLogger, 100, 1, fn) + require.Error(t, err, "Expected an error on the first try with no retries allowed") + assert.Equal(t, "max retries reached, aborting", err.Error(), "Expected function to abort after the first try") +} + +func TestRetryableErrorAfterMultipleRetries(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + attempts := 0 + fn := func() error { + attempts++ + return errors.New("persistent error") + } + + maxRetries := 3 + err := retryable(ctx, logger.NullLogger, 100, maxRetries, fn) + require.Error(t, err, "Expected an error after multiple retries") + assert.Equal(t, "max retries reached, aborting", err.Error(), "Expected the max retries reached error message") + assert.Equal(t, maxRetries+1, attempts, "Expected the function to be executed retry + 1 times") +} + +func TestRetryableCancellationHandling(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + + fn := func() error { + return errors.New("test error") + } + + go func() { + time.Sleep(150 * time.Millisecond) + cancel() + }() + + err := retryable(ctx, logger.NullLogger, 100, 5, fn) + assert.ErrorIs(t, err, context.Canceled, "Expected context cancellation error") +} From 5872c452c7dace148431e49c6a8480171ea5d192 Mon Sep 17 00:00:00 2001 From: HenryNguyen5 <6404866+HenryNguyen5@users.noreply.github.com> Date: Mon, 29 Apr 2024 20:06:23 -0400 Subject: [PATCH 59/77] chore/fix incorrect flakey tests (#13021) * Add exit logs for go_core_tests * Print each iteration of a flakey test execution * DRY up env var usage to prevent typos * Remove .sh prefix on go_core_tests log Co-authored-by: Jordan Krage --------- Co-authored-by: Jordan Krage --- tools/bin/go_core_tests | 1 + tools/flakeytests/runner.go | 4 ++-- tools/flakeytests/runner_test.go | 23 +++++++++++++++++------ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/tools/bin/go_core_tests b/tools/bin/go_core_tests index c0b0f43aed4..074527698b3 100755 --- a/tools/bin/go_core_tests +++ b/tools/bin/go_core_tests @@ -33,4 +33,5 @@ if [[ $EXITCODE != 0 ]]; then else echo "All tests passed!" fi +echo "go_core_tests exiting with code $EXITCODE" exit $EXITCODE diff --git a/tools/flakeytests/runner.go b/tools/flakeytests/runner.go index 88ab647e7c1..a37b123d5cf 100644 --- a/tools/flakeytests/runner.go +++ b/tools/flakeytests/runner.go @@ -219,8 +219,8 @@ func (r *Runner) runTests(rep *Report) (*Report, error) { ts = append(ts, test) } - log.Printf("[FLAKEY_TEST] Executing test command with parameters: pkg=%s, tests=%+v, numReruns=%d\n", pkg, ts, r.numReruns) for i := 0; i < r.numReruns; i++ { + log.Printf("[FLAKEY_TEST] Executing test command with parameters: pkg=%s, tests=%+v, numReruns=%d currentRun=%d\n", pkg, ts, r.numReruns, i) pr, err := r.runTest(pkg, ts) if err != nil { return report, err @@ -237,8 +237,8 @@ func (r *Runner) runTests(rep *Report) (*Report, error) { } for pkg := range rep.packagePanics { - log.Printf("[PACKAGE_PANIC]: Executing test command with parameters: pkg=%s, numReruns=%d\n", pkg, r.numReruns) for i := 0; i < r.numReruns; i++ { + log.Printf("[PACKAGE_PANIC]: Executing test command with parameters: pkg=%s, numReruns=%d currentRun=%d\n", pkg, r.numReruns, i) pr, err := r.runTest(pkg, []string{}) if err != nil { return report, err diff --git a/tools/flakeytests/runner_test.go b/tools/flakeytests/runner_test.go index ee069a1655d..8f9433a427b 100644 --- a/tools/flakeytests/runner_test.go +++ b/tools/flakeytests/runner_test.go @@ -14,6 +14,17 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" ) +// This test suite has two sets of tests that are run in two different modes: +// 1. Normal mode: The tests are run as usual. All tests that start with TestSkippedForTests will be skipped. +// There are a set of integration tests that will run this same test suite in integration mode. +// 2. Integration mode: The tests are run with an environment variable set to run the tests that were skipped in normal mode. +// Their output is captured and parsed to check if the flake runner is behaving as expected. +// +// In summary, the first set of tests are executed by the user, and these tests will trigger the second set of tests to run. +var runInIntegrationTestModeEnvKey = "FLAKEY_TEST_RUNNER_RUN_FIXTURE_TEST" +var skipIntegrationTestMode = os.Getenv(runInIntegrationTestModeEnvKey) != "1" +var runInIntegrationTestModeEnv = runInIntegrationTestModeEnvKey + "=1" + type mockReporter struct { report *Report } @@ -307,7 +318,7 @@ func TestRunner_RerunWithNonZeroExitCodeDoesntStopCommand(t *testing.T) { // Used for integration tests func TestSkippedForTests_Subtests(t *testing.T) { - if os.Getenv("FLAKEY_TEST_RUNNER_RUN_FIXTURE_TEST") != "1" { + if skipIntegrationTestMode { t.Skip() } @@ -322,7 +333,7 @@ func TestSkippedForTests_Subtests(t *testing.T) { // Used for integration tests func TestSkippedForTests(t *testing.T) { - if os.Getenv("FLAKEY_TEST_RUNNER_RUN_FIXTURE_TEST") != "1" { + if skipIntegrationTestMode { t.Skip() } @@ -333,7 +344,7 @@ func TestSkippedForTests(t *testing.T) { // Used for integration tests func TestSkippedForTests_Success(t *testing.T) { - if os.Getenv("FLAKEY_TEST_RUNNER_RUN_FIXTURE_TEST") != "1" { + if skipIntegrationTestMode { t.Skip() } @@ -356,7 +367,7 @@ func TestIntegration_DealsWithSubtests(t *testing.T) { repo: "github.com/smartcontractkit/chainlink/v2/tools/flakeytests", command: "../bin/go_core_tests", overrides: func(cmd *exec.Cmd) { - cmd.Env = append(cmd.Env, "FLAKEY_TESTRUNNER_RUN_FIXTURE_TEST=1") + cmd.Env = append(cmd.Env, runInIntegrationTestModeEnv) cmd.Stdout = io.Discard cmd.Stderr = io.Discard }, @@ -392,7 +403,7 @@ func TestIntegration_ParsesPanics(t *testing.T) { repo: "github.com/smartcontractkit/chainlink/v2/tools/flakeytests", command: "../bin/go_core_tests", overrides: func(cmd *exec.Cmd) { - cmd.Env = append(cmd.Env, "FLAKEY_TESTRUNNER_RUN_FIXTURE_TEST=1") + cmd.Env = append(cmd.Env, runInIntegrationTestModeEnv) cmd.Stdout = io.Discard cmd.Stderr = io.Discard }, @@ -423,7 +434,7 @@ func TestIntegration(t *testing.T) { repo: "github.com/smartcontractkit/chainlink/v2/tools/flakeytests", command: "../bin/go_core_tests", overrides: func(cmd *exec.Cmd) { - cmd.Env = append(cmd.Env, "FLAKEY_TESTRUNNER_RUN_FIXTURE_TEST=1") + cmd.Env = append(cmd.Env, runInIntegrationTestModeEnv) cmd.Stdout = io.Discard cmd.Stderr = io.Discard }, From f376a123dadd810e3efeb5b9a066b4615ff893ee Mon Sep 17 00:00:00 2001 From: HenryNguyen5 <6404866+HenryNguyen5@users.noreply.github.com> Date: Tue, 30 Apr 2024 00:04:58 -0400 Subject: [PATCH 60/77] Make sure short tests are actually passing (#12989) --- .github/workflows/ci-core.yml | 9 +++++++-- core/chains/evm/config/config_test.go | 2 ++ core/services/chainlink/config_database_test.go | 2 ++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index 394faf71e2f..e1891770930 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -77,6 +77,10 @@ jobs: slack-message: "golangci-lint failed: ${{ job.html_url }}\n${{ format('https://github.com/smartcontractkit/chainlink/actions/runs/{0}', github.run_id) }}" core: + env: + # We explicitly have this env var not be "CL_DATABASE_URL" to avoid having it be used by core related tests + # when they should not be using it, while still allowing us to DRY up the setup + DB_URL: postgresql://postgres:postgres@localhost:5432/chainlink_test?sslmode=disable strategy: fail-fast: false matrix: @@ -92,8 +96,6 @@ jobs: if: github.actor != 'dependabot[bot]' needs: [filter] runs-on: ubuntu-latest-64cores-256GB - env: - CL_DATABASE_URL: postgresql://postgres:postgres@localhost:5432/chainlink_test?sslmode=disable steps: - name: Checkout the repo uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 @@ -136,6 +138,8 @@ jobs: - name: Setup DB if: ${{ needs.filter.outputs.changes == 'true' }} run: ./chainlink.test local db preparetest + env: + CL_DATABASE_URL: ${{ env.DB_URL }} - name: Install LOOP Plugins if: ${{ needs.filter.outputs.changes == 'true' }} run: | @@ -165,6 +169,7 @@ jobs: env: OUTPUT_FILE: ./output.txt USE_TEE: false + CL_DATABASE_URL: ${{ env.DB_URL }} run: ./tools/bin/${{ matrix.type.cmd }} ./... - name: Print Filtered Test Results if: ${{ failure() && matrix.type.cmd == 'go_core_tests' && needs.filter.outputs.changes == 'true' }} diff --git a/core/chains/evm/config/config_test.go b/core/chains/evm/config/config_test.go index e1c7a9f48cc..9553f59ad61 100644 --- a/core/chains/evm/config/config_test.go +++ b/core/chains/evm/config/config_test.go @@ -23,6 +23,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/store/models" ) func TestChainScopedConfig(t *testing.T) { @@ -380,6 +381,7 @@ func TestChainScopedConfig_HeadTracker(t *testing.T) { func Test_chainScopedConfig_Validate(t *testing.T) { configWithChains := func(t *testing.T, id int64, chains ...*toml.Chain) config.AppConfig { return configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { + s.Database.URL = models.MustSecretURL("postgresql://doesnotexist:justtopassvalidationtests@localhost:5432/chainlink_na_test") chainID := ubig.NewI(id) c.EVM[0] = &toml.EVMConfig{ChainID: chainID, Enabled: ptr(true), Chain: toml.Defaults(chainID, chains...), Nodes: toml.EVMNodes{{ diff --git a/core/services/chainlink/config_database_test.go b/core/services/chainlink/config_database_test.go index 9cde07c9a63..b52d17452aa 100644 --- a/core/services/chainlink/config_database_test.go +++ b/core/services/chainlink/config_database_test.go @@ -14,6 +14,8 @@ import ( func TestDatabaseConfig(t *testing.T) { opts := GeneralConfigOpts{ ConfigStrings: []string{fullTOML}, + SecretsStrings: []string{`[Database] +URL = "postgresql://doesnotexist:justtopassvalidationtests@localhost:5432/chainlink_na_test"`}, } cfg, err := opts.New() require.NoError(t, err) From d50936ce3824d7ad6026f630172e9764a34cc08b Mon Sep 17 00:00:00 2001 From: Mateusz Sekara Date: Tue, 30 Apr 2024 09:15:37 +0200 Subject: [PATCH 61/77] Added support for retention in the contract_transmitter.go (#12998) --- .changeset/witty-numbers-sleep.md | 5 +++++ .../relay/evm/contract_transmitter.go | 19 ++++++++++++++++++- core/services/relay/evm/evm.go | 10 ++++++---- core/services/relay/evm/ocr2keeper.go | 2 +- core/services/relay/evm/ocr2vrf.go | 4 ++-- 5 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 .changeset/witty-numbers-sleep.md diff --git a/.changeset/witty-numbers-sleep.md b/.changeset/witty-numbers-sleep.md new file mode 100644 index 00000000000..d42664d9f76 --- /dev/null +++ b/.changeset/witty-numbers-sleep.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Support for retention in LogPoller's filters registered by ContractTransmitter #changed diff --git a/core/services/relay/evm/contract_transmitter.go b/core/services/relay/evm/contract_transmitter.go index af0f83f6979..724bbbe4aa0 100644 --- a/core/services/relay/evm/contract_transmitter.go +++ b/core/services/relay/evm/contract_transmitter.go @@ -5,6 +5,7 @@ import ( "database/sql" "encoding/hex" "math/big" + "time" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi" @@ -63,13 +64,29 @@ func NewOCRContractTransmitter( lp logpoller.LogPoller, lggr logger.Logger, reportToEvmTxMeta ReportToEthMetadata, +) (*contractTransmitter, error) { + return NewOCRContractTransmitterWithRetention(ctx, address, caller, contractABI, transmitter, lp, lggr, reportToEvmTxMeta, 0) +} + +func NewOCRContractTransmitterWithRetention( + ctx context.Context, + address gethcommon.Address, + caller contractReader, + contractABI abi.ABI, + transmitter Transmitter, + lp logpoller.LogPoller, + lggr logger.Logger, + reportToEvmTxMeta ReportToEthMetadata, + retention time.Duration, ) (*contractTransmitter, error) { transmitted, ok := contractABI.Events["Transmitted"] if !ok { return nil, errors.New("invalid ABI, missing transmitted") } - err := lp.RegisterFilter(ctx, logpoller.Filter{Name: transmitterFilterName(address), EventSigs: []common.Hash{transmitted.ID}, Addresses: []common.Address{address}}) + // TODO It would be better to keep MaxLogsKept = 1 for the OCR contract transmitter instead of Retention. We are always interested only in the latest log. + // Although MaxLogsKept is present in the Filter struct, it is not supported by LogPoller yet. + err := lp.RegisterFilter(ctx, logpoller.Filter{Name: transmitterFilterName(address), EventSigs: []common.Hash{transmitted.ID}, Addresses: []common.Address{address}, Retention: retention}) if err != nil { return nil, err } diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index 737a8e7561e..585d20df3ab 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -7,6 +7,7 @@ import ( "fmt" "strings" "sync" + "time" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" @@ -172,7 +173,7 @@ func (r *Relayer) NewPluginProvider(rargs commontypes.RelayArgs, pargs commontyp return nil, err } - transmitter, err := newOnChainContractTransmitter(ctx, r.lggr, rargs, pargs.TransmitterID, r.ks.Eth(), configWatcher, configTransmitterOpts{}, OCR2AggregatorTransmissionContractABI) + transmitter, err := newOnChainContractTransmitter(ctx, r.lggr, rargs, pargs.TransmitterID, r.ks.Eth(), configWatcher, configTransmitterOpts{}, OCR2AggregatorTransmissionContractABI, 0) if err != nil { return nil, err } @@ -476,7 +477,7 @@ type configTransmitterOpts struct { } // newOnChainContractTransmitter creates a new contract transmitter. -func newOnChainContractTransmitter(ctx context.Context, lggr logger.Logger, rargs commontypes.RelayArgs, transmitterID string, ethKeystore keystore.Eth, configWatcher *configWatcher, opts configTransmitterOpts, transmissionContractABI abi.ABI) (*contractTransmitter, error) { +func newOnChainContractTransmitter(ctx context.Context, lggr logger.Logger, rargs commontypes.RelayArgs, transmitterID string, ethKeystore keystore.Eth, configWatcher *configWatcher, opts configTransmitterOpts, transmissionContractABI abi.ABI, transmissionContractRetention time.Duration) (*contractTransmitter, error) { var relayConfig types.RelayConfig if err := json.Unmarshal(rargs.RelayConfig, &relayConfig); err != nil { return nil, err @@ -540,7 +541,7 @@ func newOnChainContractTransmitter(ctx context.Context, lggr logger.Logger, rarg return nil, pkgerrors.Wrap(err, "failed to create transmitter") } - return NewOCRContractTransmitter( + return NewOCRContractTransmitterWithRetention( ctx, configWatcher.contractAddress, configWatcher.chain.Client(), @@ -549,6 +550,7 @@ func newOnChainContractTransmitter(ctx context.Context, lggr logger.Logger, rarg configWatcher.chain.LogPoller(), lggr, nil, + transmissionContractRetention, ) } @@ -578,7 +580,7 @@ func (r *Relayer) NewMedianProvider(rargs commontypes.RelayArgs, pargs commontyp reportCodec := evmreportcodec.ReportCodec{} - contractTransmitter, err := newOnChainContractTransmitter(ctx, lggr, rargs, pargs.TransmitterID, r.ks.Eth(), configWatcher, configTransmitterOpts{}, OCR2AggregatorTransmissionContractABI) + contractTransmitter, err := newOnChainContractTransmitter(ctx, lggr, rargs, pargs.TransmitterID, r.ks.Eth(), configWatcher, configTransmitterOpts{}, OCR2AggregatorTransmissionContractABI, 0) if err != nil { return nil, err } diff --git a/core/services/relay/evm/ocr2keeper.go b/core/services/relay/evm/ocr2keeper.go index 78f4b43b43f..a839ce8430e 100644 --- a/core/services/relay/evm/ocr2keeper.go +++ b/core/services/relay/evm/ocr2keeper.go @@ -91,7 +91,7 @@ func (r *ocr2keeperRelayer) NewOCR2KeeperProvider(rargs commontypes.RelayArgs, p } gasLimit := cfgWatcher.chain.Config().EVM().OCR2().Automation().GasLimit() - contractTransmitter, err := newOnChainContractTransmitter(ctx, r.lggr, rargs, pargs.TransmitterID, r.ethKeystore, cfgWatcher, configTransmitterOpts{pluginGasLimit: &gasLimit}, OCR2AggregatorTransmissionContractABI) + contractTransmitter, err := newOnChainContractTransmitter(ctx, r.lggr, rargs, pargs.TransmitterID, r.ethKeystore, cfgWatcher, configTransmitterOpts{pluginGasLimit: &gasLimit}, OCR2AggregatorTransmissionContractABI, 0) if err != nil { return nil, err } diff --git a/core/services/relay/evm/ocr2vrf.go b/core/services/relay/evm/ocr2vrf.go index a108151be47..b83ce0fd81e 100644 --- a/core/services/relay/evm/ocr2vrf.go +++ b/core/services/relay/evm/ocr2vrf.go @@ -64,7 +64,7 @@ func (r *ocr2vrfRelayer) NewDKGProvider(rargs commontypes.RelayArgs, pargs commo if err != nil { return nil, err } - contractTransmitter, err := newOnChainContractTransmitter(ctx, r.lggr, rargs, pargs.TransmitterID, r.ethKeystore, configWatcher, configTransmitterOpts{}, OCR2AggregatorTransmissionContractABI) + contractTransmitter, err := newOnChainContractTransmitter(ctx, r.lggr, rargs, pargs.TransmitterID, r.ethKeystore, configWatcher, configTransmitterOpts{}, OCR2AggregatorTransmissionContractABI, 0) if err != nil { return nil, err } @@ -91,7 +91,7 @@ func (r *ocr2vrfRelayer) NewOCR2VRFProvider(rargs commontypes.RelayArgs, pargs c if err != nil { return nil, err } - contractTransmitter, err := newOnChainContractTransmitter(ctx, r.lggr, rargs, pargs.TransmitterID, r.ethKeystore, configWatcher, configTransmitterOpts{}, OCR2AggregatorTransmissionContractABI) + contractTransmitter, err := newOnChainContractTransmitter(ctx, r.lggr, rargs, pargs.TransmitterID, r.ethKeystore, configWatcher, configTransmitterOpts{}, OCR2AggregatorTransmissionContractABI, 0) if err != nil { return nil, err } From e21be2a890a50bd3cbac60c450e3c2d68ddefbd3 Mon Sep 17 00:00:00 2001 From: Mateusz Sekara Date: Tue, 30 Apr 2024 09:49:36 +0200 Subject: [PATCH 62/77] CCIP-2207 Boosting LogPoller performance by fixing how order by clauses are written (#13026) * Boosting LogPoller performance by fixing how order by clauses are written * Boosting LogPoller performance by fixing how order by clauses are written --- .changeset/proud-toys-travel.md | 5 +++++ core/chains/evm/logpoller/orm.go | 33 +++++++++++++++++--------------- 2 files changed, 23 insertions(+), 15 deletions(-) create mode 100644 .changeset/proud-toys-travel.md diff --git a/.changeset/proud-toys-travel.md b/.changeset/proud-toys-travel.md new file mode 100644 index 00000000000..e2b1f0c7269 --- /dev/null +++ b/.changeset/proud-toys-travel.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Improving LogPoller read queries by properly sorting by multiple columns #updated diff --git a/core/chains/evm/logpoller/orm.go b/core/chains/evm/logpoller/orm.go index 5e0a74a9183..d065553886e 100644 --- a/core/chains/evm/logpoller/orm.go +++ b/core/chains/evm/logpoller/orm.go @@ -224,7 +224,9 @@ func (o *DSORM) SelectLatestLogByEventSigWithConfs(ctx context.Context, eventSig AND event_sig = :event_sig AND address = :address AND block_number <= %s - ORDER BY (block_number, log_index) DESC LIMIT 1`, nestedBlockNumberQuery(confs)) + ORDER BY block_number desc, log_index DESC + LIMIT 1 + `, nestedBlockNumberQuery(confs)) var l Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -425,7 +427,7 @@ func (o *DSORM) SelectLogsByBlockRange(ctx context.Context, start, end int64) ([ WHERE evm_chain_id = :evm_chain_id AND block_number >= :start_block AND block_number <= :end_block - ORDER BY (block_number, log_index)` + ORDER BY block_number, log_index` var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -456,7 +458,7 @@ func (o *DSORM) SelectLogs(ctx context.Context, start, end int64, address common AND event_sig = :event_sig AND block_number >= :start_block AND block_number <= :end_block - ORDER BY (block_number, log_index)` + ORDER BY block_number, log_index` var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -488,7 +490,7 @@ func (o *DSORM) SelectLogsCreatedAfter(ctx context.Context, address common.Addre AND event_sig = :event_sig AND block_timestamp > :block_timestamp_after AND block_number <= %s - ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY block_number, log_index`, nestedBlockNumberQuery(confs)) var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -520,7 +522,7 @@ func (o *DSORM) SelectLogsWithSigs(ctx context.Context, start, end int64, addres AND address = :address AND event_sig = ANY(:event_sig_array) AND block_number BETWEEN :start_block AND :end_block - ORDER BY (block_number, log_index)` + ORDER BY block_number, log_index` query, sqlArgs, err := o.ds.BindNamed(query, args) if err != nil { @@ -647,7 +649,7 @@ func (o *DSORM) SelectLogsDataWordRange(ctx context.Context, address common.Addr AND substring(data from 32*:word_index+1 for 32) >= :word_value_min AND substring(data from 32*:word_index+1 for 32) <= :word_value_max AND block_number <= %s - ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY block_number, log_index`, nestedBlockNumberQuery(confs)) var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -678,7 +680,7 @@ func (o *DSORM) SelectLogsDataWordGreaterThan(ctx context.Context, address commo AND event_sig = :event_sig AND substring(data from 32*:word_index+1 for 32) >= :word_value_min AND block_number <= %s - ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY block_number, log_index`, nestedBlockNumberQuery(confs)) var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -710,7 +712,7 @@ func (o *DSORM) SelectLogsDataWordBetween(ctx context.Context, address common.Ad AND substring(data from 32*:word_index_min+1 for 32) <= :word_value AND substring(data from 32*:word_index_max+1 for 32) >= :word_value AND block_number <= %s - ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY block_number, log_index`, nestedBlockNumberQuery(confs)) var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -741,7 +743,7 @@ func (o *DSORM) SelectIndexedLogsTopicGreaterThan(ctx context.Context, address c AND event_sig = :event_sig AND topics[:topic_index] >= :topic_value_min AND block_number <= %s - ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY block_number, log_index`, nestedBlockNumberQuery(confs)) var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -774,7 +776,7 @@ func (o *DSORM) SelectIndexedLogsTopicRange(ctx context.Context, address common. AND topics[:topic_index] >= :topic_value_min AND topics[:topic_index] <= :topic_value_max AND block_number <= %s - ORDER BY (evm.logs.block_number, evm.logs.log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY block_number, log_index`, nestedBlockNumberQuery(confs)) var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -805,7 +807,7 @@ func (o *DSORM) SelectIndexedLogs(ctx context.Context, address common.Address, e AND event_sig = :event_sig AND topics[:topic_index] = ANY(:topic_values) AND block_number <= %s - ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY block_number, log_index`, nestedBlockNumberQuery(confs)) var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -838,7 +840,7 @@ func (o *DSORM) SelectIndexedLogsByBlockRange(ctx context.Context, start, end in AND topics[:topic_index] = ANY(:topic_values) AND block_number >= :start_block AND block_number <= :end_block - ORDER BY (block_number, log_index)` + ORDER BY block_number, log_index` var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -872,7 +874,8 @@ func (o *DSORM) SelectIndexedLogsCreatedAfter(ctx context.Context, address commo AND topics[:topic_index] = ANY(:topic_values) AND block_timestamp > :block_timestamp_after AND block_number <= %s - ORDER BY (block_number, log_index)`, nestedBlockNumberQuery(confs)) + ORDER BY block_number, log_index + `, nestedBlockNumberQuery(confs)) var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -901,7 +904,7 @@ func (o *DSORM) SelectIndexedLogsByTxHash(ctx context.Context, address common.Ad AND address = :address AND event_sig = :event_sig AND tx_hash = :tx_hash - ORDER BY (block_number, log_index)` + ORDER BY block_number, log_index` var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) @@ -949,7 +952,7 @@ func (o *DSORM) SelectIndexedLogsWithSigsExcluding(ctx context.Context, sigA, si AND b.event_sig = :sigB AND b.block_number BETWEEN :start_block AND :end_block AND b.block_number <= %s - ORDER BY block_number,log_index ASC`, nestedQuery, nestedQuery) + ORDER BY block_number, log_index`, nestedQuery, nestedQuery) var logs []Log query, sqlArgs, err := o.ds.BindNamed(query, args) From 04b42f1dd7db449e5267e2491a9ba6971f41b1bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deividas=20Kar=C5=BEinauskas?= Date: Tue, 30 Apr 2024 12:41:07 +0300 Subject: [PATCH 63/77] Add getCapabilities to the CapabilityRegistry (#13031) * Add getCapabilities * Fix comments --- .changeset/early-cats-check.md | 5 ++ contracts/.changeset/bright-dingos-attend.md | 5 ++ .../src/v0.8/keystone/CapabilityRegistry.sol | 16 ++++++ .../src/v0.8/keystone/test/BaseTest.t.sol | 16 ++++++ ...CapabilityRegistry_AddCapabilityTest.t.sol | 54 +++++++------------ .../CapabilityRegistry_GetCapabilityIds.t.sol | 29 ++++++++++ .../src/v0.8/keystone/test/Constants.t.sol | 2 - .../mocks/CapabilityConfigurationContract.sol | 4 ++ .../keystone_capability_registry.go | 28 +++++++++- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 10 files changed, 121 insertions(+), 40 deletions(-) create mode 100644 .changeset/early-cats-check.md create mode 100644 contracts/.changeset/bright-dingos-attend.md create mode 100644 contracts/src/v0.8/keystone/test/CapabilityRegistry_GetCapabilityIds.t.sol diff --git a/.changeset/early-cats-check.md b/.changeset/early-cats-check.md new file mode 100644 index 00000000000..0408383bd03 --- /dev/null +++ b/.changeset/early-cats-check.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal diff --git a/contracts/.changeset/bright-dingos-attend.md b/contracts/.changeset/bright-dingos-attend.md new file mode 100644 index 00000000000..9d376e40c05 --- /dev/null +++ b/contracts/.changeset/bright-dingos-attend.md @@ -0,0 +1,5 @@ +--- +"@chainlink/contracts": patch +--- + +#internal diff --git a/contracts/src/v0.8/keystone/CapabilityRegistry.sol b/contracts/src/v0.8/keystone/CapabilityRegistry.sol index ddf1d9b5635..540bbed9bab 100644 --- a/contracts/src/v0.8/keystone/CapabilityRegistry.sol +++ b/contracts/src/v0.8/keystone/CapabilityRegistry.sol @@ -193,6 +193,22 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { return s_capabilities[capabilityID]; } + /// @notice Returns all capabilities. This operation will copy capabilities + /// to memory, which can be quite expensive. This is designed to mostly be + /// used by view accessors that are queried without any gas fees. + /// @return Capability[] An array of capabilities + function getCapabilities() external view returns (Capability[] memory) { + bytes32[] memory capabilityIds = s_capabilityIds.values(); + Capability[] memory capabilities = new Capability[](capabilityIds.length); + + for (uint256 i; i < capabilityIds.length; ++i) { + bytes32 capabilityId = capabilityIds[i]; + capabilities[i] = getCapability(capabilityId); + } + + return capabilities; + } + /// @notice This functions returns a Capability ID packed into a bytes32 for cheaper access /// @return bytes32 A unique identifier for the capability function getCapabilityID(bytes32 capabilityType, bytes32 version) public pure returns (bytes32) { diff --git a/contracts/src/v0.8/keystone/test/BaseTest.t.sol b/contracts/src/v0.8/keystone/test/BaseTest.t.sol index 4517a256b15..a2b1b3a53eb 100644 --- a/contracts/src/v0.8/keystone/test/BaseTest.t.sol +++ b/contracts/src/v0.8/keystone/test/BaseTest.t.sol @@ -9,11 +9,27 @@ import {CapabilityRegistry} from "../CapabilityRegistry.sol"; contract BaseTest is Test, Constants { CapabilityRegistry internal s_capabilityRegistry; CapabilityConfigurationContract internal s_capabilityConfigurationContract; + CapabilityRegistry.Capability internal s_basicCapability; + CapabilityRegistry.Capability internal s_capabilityWithConfigurationContract; function setUp() public virtual { vm.startPrank(ADMIN); s_capabilityRegistry = new CapabilityRegistry(); s_capabilityConfigurationContract = new CapabilityConfigurationContract(); + + s_basicCapability = CapabilityRegistry.Capability({ + capabilityType: "data-streams-reports", + version: "1.0.0", + responseType: CapabilityRegistry.CapabilityResponseType.REPORT, + configurationContract: address(0) + }); + + s_capabilityWithConfigurationContract = CapabilityRegistry.Capability({ + capabilityType: "read-ethereum-mainnet-gas-price", + version: "1.0.2", + responseType: CapabilityRegistry.CapabilityResponseType.OBSERVATION_IDENTICAL, + configurationContract: address(s_capabilityConfigurationContract) + }); } function _getNodeOperators() internal view returns (CapabilityRegistry.NodeOperator[] memory) { diff --git a/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddCapabilityTest.t.sol b/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddCapabilityTest.t.sol index d9e4b6b8383..cf1bc6c8d73 100644 --- a/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddCapabilityTest.t.sol +++ b/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddCapabilityTest.t.sol @@ -7,41 +7,25 @@ import {CapabilityConfigurationContract} from "./mocks/CapabilityConfigurationCo import {CapabilityRegistry} from "../CapabilityRegistry.sol"; contract CapabilityRegistry_AddCapabilityTest is BaseTest { - CapabilityRegistry.Capability private basicCapability = - CapabilityRegistry.Capability({ - capabilityType: "data-streams-reports", - version: "1.0.0", - responseType: CapabilityRegistry.CapabilityResponseType.REPORT, - configurationContract: address(0) - }); - - CapabilityRegistry.Capability private capabilityWithConfigurationContract = - CapabilityRegistry.Capability({ - capabilityType: "read-ethereum-mainnet-gas-price", - version: "1.0.2", - responseType: CapabilityRegistry.CapabilityResponseType.OBSERVATION_IDENTICAL, - configurationContract: address(s_capabilityConfigurationContract) - }); - function test_RevertWhen_CalledByNonAdmin() public { changePrank(STRANGER); vm.expectRevert("Only callable by owner"); - s_capabilityRegistry.addCapability(basicCapability); + s_capabilityRegistry.addCapability(s_basicCapability); } function test_RevertWhen_CapabilityExists() public { // Successfully add the capability the first time - s_capabilityRegistry.addCapability(basicCapability); + s_capabilityRegistry.addCapability(s_basicCapability); // Try to add the same capability again vm.expectRevert(CapabilityRegistry.CapabilityAlreadyExists.selector); - s_capabilityRegistry.addCapability(basicCapability); + s_capabilityRegistry.addCapability(s_basicCapability); } function test_RevertWhen_ConfigurationContractNotDeployed() public { address nonExistentContract = address(1); - capabilityWithConfigurationContract.configurationContract = nonExistentContract; + s_capabilityWithConfigurationContract.configurationContract = nonExistentContract; vm.expectRevert( abi.encodeWithSelector( @@ -49,41 +33,41 @@ contract CapabilityRegistry_AddCapabilityTest is BaseTest { nonExistentContract ) ); - s_capabilityRegistry.addCapability(capabilityWithConfigurationContract); + s_capabilityRegistry.addCapability(s_capabilityWithConfigurationContract); } function test_RevertWhen_ConfigurationContractDoesNotMatchInterface() public { CapabilityRegistry contractWithoutERC165 = new CapabilityRegistry(); vm.expectRevert(); - capabilityWithConfigurationContract.configurationContract = address(contractWithoutERC165); - s_capabilityRegistry.addCapability(capabilityWithConfigurationContract); + s_capabilityWithConfigurationContract.configurationContract = address(contractWithoutERC165); + s_capabilityRegistry.addCapability(s_capabilityWithConfigurationContract); } function test_AddCapability_NoConfigurationContract() public { - s_capabilityRegistry.addCapability(basicCapability); + s_capabilityRegistry.addCapability(s_basicCapability); bytes32 capabilityId = s_capabilityRegistry.getCapabilityID(bytes32("data-streams-reports"), bytes32("1.0.0")); CapabilityRegistry.Capability memory storedCapability = s_capabilityRegistry.getCapability(capabilityId); - assertEq(storedCapability.capabilityType, basicCapability.capabilityType); - assertEq(storedCapability.version, basicCapability.version); - assertEq(uint256(storedCapability.responseType), uint256(basicCapability.responseType)); - assertEq(storedCapability.configurationContract, basicCapability.configurationContract); + assertEq(storedCapability.capabilityType, s_basicCapability.capabilityType); + assertEq(storedCapability.version, s_basicCapability.version); + assertEq(uint256(storedCapability.responseType), uint256(s_basicCapability.responseType)); + assertEq(storedCapability.configurationContract, s_basicCapability.configurationContract); } function test_AddCapability_WithConfiguration() public { - s_capabilityRegistry.addCapability(capabilityWithConfigurationContract); + s_capabilityRegistry.addCapability(s_capabilityWithConfigurationContract); bytes32 capabilityId = s_capabilityRegistry.getCapabilityID( - bytes32(capabilityWithConfigurationContract.capabilityType), - bytes32(capabilityWithConfigurationContract.version) + bytes32(s_capabilityWithConfigurationContract.capabilityType), + bytes32(s_capabilityWithConfigurationContract.version) ); CapabilityRegistry.Capability memory storedCapability = s_capabilityRegistry.getCapability(capabilityId); - assertEq(storedCapability.capabilityType, capabilityWithConfigurationContract.capabilityType); - assertEq(storedCapability.version, capabilityWithConfigurationContract.version); - assertEq(uint256(storedCapability.responseType), uint256(capabilityWithConfigurationContract.responseType)); - assertEq(storedCapability.configurationContract, capabilityWithConfigurationContract.configurationContract); + assertEq(storedCapability.capabilityType, s_capabilityWithConfigurationContract.capabilityType); + assertEq(storedCapability.version, s_capabilityWithConfigurationContract.version); + assertEq(uint256(storedCapability.responseType), uint256(s_capabilityWithConfigurationContract.responseType)); + assertEq(storedCapability.configurationContract, s_capabilityWithConfigurationContract.configurationContract); } } diff --git a/contracts/src/v0.8/keystone/test/CapabilityRegistry_GetCapabilityIds.t.sol b/contracts/src/v0.8/keystone/test/CapabilityRegistry_GetCapabilityIds.t.sol new file mode 100644 index 00000000000..de7810b4c15 --- /dev/null +++ b/contracts/src/v0.8/keystone/test/CapabilityRegistry_GetCapabilityIds.t.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {BaseTest} from "./BaseTest.t.sol"; +import {CapabilityRegistry} from "../CapabilityRegistry.sol"; + +contract CapabilityRegistry_GetCapabilitiesTest is BaseTest { + function test_ReturnsCapabilities() public { + s_capabilityRegistry.addCapability(s_basicCapability); + s_capabilityRegistry.addCapability(s_capabilityWithConfigurationContract); + + CapabilityRegistry.Capability[] memory capabilities = s_capabilityRegistry.getCapabilities(); + + assertEq(capabilities.length, 2); + + assertEq(capabilities[0].capabilityType, "data-streams-reports"); + assertEq(capabilities[0].version, "1.0.0"); + assertEq(uint256(capabilities[0].responseType), uint256(CapabilityRegistry.CapabilityResponseType.REPORT)); + assertEq(capabilities[0].configurationContract, address(0)); + + assertEq(capabilities[1].capabilityType, "read-ethereum-mainnet-gas-price"); + assertEq(capabilities[1].version, "1.0.2"); + assertEq( + uint256(capabilities[1].responseType), + uint256(CapabilityRegistry.CapabilityResponseType.OBSERVATION_IDENTICAL) + ); + assertEq(capabilities[1].configurationContract, address(s_capabilityConfigurationContract)); + } +} diff --git a/contracts/src/v0.8/keystone/test/Constants.t.sol b/contracts/src/v0.8/keystone/test/Constants.t.sol index b7eb85debb1..6f0b7ef43f3 100644 --- a/contracts/src/v0.8/keystone/test/Constants.t.sol +++ b/contracts/src/v0.8/keystone/test/Constants.t.sol @@ -1,8 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -import {Test} from "forge-std/Test.sol"; - contract Constants { address internal ADMIN = address(1); address internal STRANGER = address(2); diff --git a/contracts/src/v0.8/keystone/test/mocks/CapabilityConfigurationContract.sol b/contracts/src/v0.8/keystone/test/mocks/CapabilityConfigurationContract.sol index 0c3d8e0597d..6f3a28b7ca0 100644 --- a/contracts/src/v0.8/keystone/test/mocks/CapabilityConfigurationContract.sol +++ b/contracts/src/v0.8/keystone/test/mocks/CapabilityConfigurationContract.sol @@ -10,4 +10,8 @@ contract CapabilityConfigurationContract is ICapabilityConfiguration, ERC165 { function getCapabilityConfiguration(uint256 donId) external view returns (bytes memory configuration) { return s_donConfiguration[donId]; } + + function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { + return interfaceId == this.getCapabilityConfiguration.selector; + } } diff --git a/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go b/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go index 61060bcb8ea..d1f789f4408 100644 --- a/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go +++ b/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go @@ -43,8 +43,8 @@ type CapabilityRegistryNodeOperator struct { } var CapabilityRegistryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CapabilityAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedConfigurationContract\",\"type\":\"address\"}],\"name\":\"InvalidCapabilityConfigurationContractInterface\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeOperatorAdmin\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"lengthOne\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lengthTwo\",\"type\":\"uint256\"}],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"NodeOperatorRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"capability\",\"type\":\"tuple\"}],\"name\":\"addCapability\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"addNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityID\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"name\":\"getCapabilityID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"getNodeOperator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint256[]\"}],\"name\":\"removeNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"updateNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611702806101576000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c8063398f3773116100815780638da5cb5b1161005b5780638da5cb5b146101ad5780639cb7c5f4146101d5578063f2fde38b146101f557600080fd5b8063398f37731461017257806365c14dc71461018557806379ba5097146101a557600080fd5b8063181f5a77116100b2578063181f5a77146100f65780631cdf63431461013e578063229111f51461015157600080fd5b80630c5801e3146100ce578063117392ce146100e3575b600080fd5b6100e16100dc366004610efe565b610208565b005b6100e16100f1366004610f6a565b610519565b604080518082018252601881527f4361706162696c697479526567697374727920312e302e300000000000000000602082015290516101359190610fe6565b60405180910390f35b6100e161014c366004610ff9565b61074a565b61016461015f36600461103b565b61080d565b604051908152602001610135565b6100e1610180366004610ff9565b61083c565b61019861019336600461105d565b6109d5565b6040516101359190611076565b6100e1610abb565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610135565b6101e86101e336600461105d565b610bb8565b60405161013591906110e8565b6100e1610203366004611186565b610c62565b828114610250576040517fab8b67c600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff16905b84811015610511576000868683818110610288576102886111a3565b90506020020135905060008585848181106102a5576102a56111a3565b90506020028101906102b791906111d2565b6102c0906112b7565b805190915073ffffffffffffffffffffffffffffffffffffffff16610311576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805173ffffffffffffffffffffffffffffffffffffffff16331480159061034e57503373ffffffffffffffffffffffffffffffffffffffff851614155b15610385576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160008381526005602052604090205473ffffffffffffffffffffffffffffffffffffffff908116911614158061043757506020808201516040516103cb9201610fe6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012060008681526005835292909220919261041e9260010191016113d0565b6040516020818303038152906040528051906020012014155b156104fe578051600083815260056020908152604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9093169290921782558201516001909101906104a490826114bf565b50806000015173ffffffffffffffffffffffffffffffffffffffff167f14c8f513e8a6d86d2d16b0cb64976de4e72386c4f8068eca3b7354373f8fe97a8383602001516040516104f59291906115d9565b60405180910390a25b50508061050a906115f2565b905061026c565b505050505050565b610521610c76565b60006105328235602084013561080d565b905061053f600382610cf9565b15610576576040517fe288638f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105886080840160608501611186565b73ffffffffffffffffffffffffffffffffffffffff16146106f3576105b36080830160608401611186565b73ffffffffffffffffffffffffffffffffffffffff163b158061069357506105e16080830160608401611186565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f884efe6100000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff91909116906301ffc9a790602401602060405180830381865afa15801561066d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106919190611651565b155b156106f3576106a86080830160608401611186565b6040517fabb5e3fd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610247565b6106fe600382610d14565b50600081815260026020526040902082906107198282611673565b505060405181907f65610e5677eedff94555572640e442f89848a109ef8593fa927ac30b2565ff0690600090a25050565b610752610c76565b60005b81811015610808576000838383818110610771576107716111a3565b60209081029290920135600081815260059093526040832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001681559093509190506107c26001830182610e64565b50506040518181527f1e5877d7b3001d1569bf733b76c7eceda58bd6c031e5b8d0b7042308ba2e9d4f9060200160405180910390a150610801816115f2565b9050610755565b505050565b604080516020808201859052818301849052825180830384018152606090920190925280519101205b92915050565b610844610c76565b60005b81811015610808576000838383818110610863576108636111a3565b905060200281019061087591906111d2565b61087e906112b7565b805190915073ffffffffffffffffffffffffffffffffffffffff166108cf576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600654604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815260008681526005909252939020825181547fffffffffffffffffffffffff00000000000000000000000000000000000000001692169190911781559151909190600182019061095290826114bf565b50905050600660008154610965906115f2565b909155508151602083015160405173ffffffffffffffffffffffffffffffffffffffff909216917fda6697b182650034bd205cdc2dbfabb06bdb3a0a83a2b45bfefa3c4881284e0b916109ba918591906115d9565b60405180910390a25050806109ce906115f2565b9050610847565b6040805180820190915260008152606060208201526000828152600560209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff1683526001810180549192840191610a3290611383565b80601f0160208091040260200160405190810160405280929190818152602001828054610a5e90611383565b8015610aab5780601f10610a8057610100808354040283529160200191610aab565b820191906000526020600020905b815481529060010190602001808311610a8e57829003601f168201915b5050505050815250509050919050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b3c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610247565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b604080516080808201835260008083526020808401829052838501829052606084018290528582526002808252918590208551938401865280548452600180820154928501929092529182015493949293919284019160ff1690811115610c2157610c216110b9565b6001811115610c3257610c326110b9565b815260029190910154610100900473ffffffffffffffffffffffffffffffffffffffff1660209091015292915050565b610c6a610c76565b610c7381610d20565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610cf7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610247565b565b600081815260018301602052604081205415155b9392505050565b6000610d0d8383610e15565b3373ffffffffffffffffffffffffffffffffffffffff821603610d9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610247565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000818152600183016020526040812054610e5c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610836565b506000610836565b508054610e7090611383565b6000825580601f10610e80575050565b601f016020900490600052602060002090810190610c7391905b80821115610eae5760008155600101610e9a565b5090565b60008083601f840112610ec457600080fd5b50813567ffffffffffffffff811115610edc57600080fd5b6020830191508360208260051b8501011115610ef757600080fd5b9250929050565b60008060008060408587031215610f1457600080fd5b843567ffffffffffffffff80821115610f2c57600080fd5b610f3888838901610eb2565b90965094506020870135915080821115610f5157600080fd5b50610f5e87828801610eb2565b95989497509550505050565b600060808284031215610f7c57600080fd5b50919050565b6000815180845260005b81811015610fa857602081850181015186830182015201610f8c565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610d0d6020830184610f82565b6000806020838503121561100c57600080fd5b823567ffffffffffffffff81111561102357600080fd5b61102f85828601610eb2565b90969095509350505050565b6000806040838503121561104e57600080fd5b50508035926020909101359150565b60006020828403121561106f57600080fd5b5035919050565b6020815273ffffffffffffffffffffffffffffffffffffffff8251166020820152600060208301516040808401526110b16060840182610f82565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b81518152602080830151908201526040820151608082019060028110611137577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8060408401525073ffffffffffffffffffffffffffffffffffffffff606084015116606083015292915050565b73ffffffffffffffffffffffffffffffffffffffff81168114610c7357600080fd5b60006020828403121561119857600080fd5b8135610d0d81611164565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261120657600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561126257611262611210565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156112af576112af611210565b604052919050565b6000604082360312156112c957600080fd5b6112d161123f565b82356112dc81611164565b815260208381013567ffffffffffffffff808211156112fa57600080fd5b9085019036601f83011261130d57600080fd5b81358181111561131f5761131f611210565b61134f847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611268565b9150808252368482850101111561136557600080fd5b80848401858401376000908201840152918301919091525092915050565b600181811c9082168061139757607f821691505b602082108103610f7c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020808352600084546113e481611383565b80848701526040600180841660008114611405576001811461143d5761146b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a0101955061146b565b896000528660002060005b858110156114635781548b8201860152908301908801611448565b8a0184019650505b509398975050505050505050565b601f82111561080857600081815260208120601f850160051c810160208610156114a05750805b601f850160051c820191505b81811015610511578281556001016114ac565b815167ffffffffffffffff8111156114d9576114d9611210565b6114ed816114e78454611383565b84611479565b602080601f831160018114611540576000841561150a5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610511565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561158d5788860151825594840194600190910190840161156e565b50858210156115c957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b8281526040602082015260006110b16040830184610f82565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361164a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60006020828403121561166357600080fd5b81518015158114610d0d57600080fd5b81358155602082013560018201556002810160408301356002811061169757600080fd5b815460608501356116a781611164565b74ffffffffffffffffffffffffffffffffffffffff008160081b1660ff84167fffffffffffffffffffffff00000000000000000000000000000000000000000084161717845550505050505056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CapabilityAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedConfigurationContract\",\"type\":\"address\"}],\"name\":\"InvalidCapabilityConfigurationContractInterface\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeOperatorAdmin\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"lengthOne\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lengthTwo\",\"type\":\"uint256\"}],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"NodeOperatorRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"capability\",\"type\":\"tuple\"}],\"name\":\"addCapability\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"addNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilities\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityID\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"name\":\"getCapabilityID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"getNodeOperator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint256[]\"}],\"name\":\"removeNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"updateNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6118e3806101576000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c806365c14dc7116100815780639cb7c5f41161005b5780639cb7c5f4146101e0578063ddbe4f8214610200578063f2fde38b1461021557600080fd5b806365c14dc71461019057806379ba5097146101b05780638da5cb5b146101b857600080fd5b80631cdf6343116100b25780631cdf634314610149578063229111f51461015c578063398f37731461017d57600080fd5b80630c5801e3146100d9578063117392ce146100ee578063181f5a7714610101575b600080fd5b6100ec6100e736600461108f565b610228565b005b6100ec6100fc3660046110fb565b610539565b604080518082018252601881527f4361706162696c697479526567697374727920312e302e300000000000000000602082015290516101409190611177565b60405180910390f35b6100ec61015736600461118a565b61076a565b61016f61016a3660046111cc565b61082d565b604051908152602001610140565b6100ec61018b36600461118a565b61085c565b6101a361019e3660046111ee565b6109f5565b6040516101409190611207565b6100ec610adb565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610140565b6101f36101ee3660046111ee565b610bd8565b60405161014091906112e9565b610208610c82565b60405161014091906112f7565b6100ec610223366004611367565b610d8a565b828114610270576040517fab8b67c600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff16905b848110156105315760008686838181106102a8576102a8611384565b90506020020135905060008585848181106102c5576102c5611384565b90506020028101906102d791906113b3565b6102e090611498565b805190915073ffffffffffffffffffffffffffffffffffffffff16610331576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805173ffffffffffffffffffffffffffffffffffffffff16331480159061036e57503373ffffffffffffffffffffffffffffffffffffffff851614155b156103a5576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160008381526005602052604090205473ffffffffffffffffffffffffffffffffffffffff908116911614158061045757506020808201516040516103eb9201611177565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012060008681526005835292909220919261043e9260010191016115b1565b6040516020818303038152906040528051906020012014155b1561051e578051600083815260056020908152604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9093169290921782558201516001909101906104c490826116a0565b50806000015173ffffffffffffffffffffffffffffffffffffffff167f14c8f513e8a6d86d2d16b0cb64976de4e72386c4f8068eca3b7354373f8fe97a8383602001516040516105159291906117ba565b60405180910390a25b50508061052a906117d3565b905061028c565b505050505050565b610541610d9e565b60006105528235602084013561082d565b905061055f600382610e21565b15610596576040517fe288638f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105a86080840160608501611367565b73ffffffffffffffffffffffffffffffffffffffff1614610713576105d36080830160608401611367565b73ffffffffffffffffffffffffffffffffffffffff163b15806106b357506106016080830160608401611367565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f884efe6100000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff91909116906301ffc9a790602401602060405180830381865afa15801561068d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106b19190611832565b155b15610713576106c86080830160608401611367565b6040517fabb5e3fd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610267565b61071e600382610e3c565b50600081815260026020526040902082906107398282611854565b505060405181907f65610e5677eedff94555572640e442f89848a109ef8593fa927ac30b2565ff0690600090a25050565b610772610d9e565b60005b8181101561082857600083838381811061079157610791611384565b60209081029290920135600081815260059093526040832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001681559093509190506107e26001830182610ff5565b50506040518181527f1e5877d7b3001d1569bf733b76c7eceda58bd6c031e5b8d0b7042308ba2e9d4f9060200160405180910390a150610821816117d3565b9050610775565b505050565b604080516020808201859052818301849052825180830384018152606090920190925280519101205b92915050565b610864610d9e565b60005b8181101561082857600083838381811061088357610883611384565b905060200281019061089591906113b3565b61089e90611498565b805190915073ffffffffffffffffffffffffffffffffffffffff166108ef576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600654604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815260008681526005909252939020825181547fffffffffffffffffffffffff00000000000000000000000000000000000000001692169190911781559151909190600182019061097290826116a0565b50905050600660008154610985906117d3565b909155508151602083015160405173ffffffffffffffffffffffffffffffffffffffff909216917fda6697b182650034bd205cdc2dbfabb06bdb3a0a83a2b45bfefa3c4881284e0b916109da918591906117ba565b60405180910390a25050806109ee906117d3565b9050610867565b6040805180820190915260008152606060208201526000828152600560209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff1683526001810180549192840191610a5290611564565b80601f0160208091040260200160405190810160405280929190818152602001828054610a7e90611564565b8015610acb5780601f10610aa057610100808354040283529160200191610acb565b820191906000526020600020905b815481529060010190602001808311610aae57829003601f168201915b5050505050815250509050919050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610267565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b604080516080808201835260008083526020808401829052838501829052606084018290528582526002808252918590208551938401865280548452600180820154928501929092529182015493949293919284019160ff1690811115610c4157610c4161124a565b6001811115610c5257610c5261124a565b815260029190910154610100900473ffffffffffffffffffffffffffffffffffffffff1660209091015292915050565b60606000610c906003610e48565b90506000815167ffffffffffffffff811115610cae57610cae6113f1565b604051908082528060200260200182016040528015610d1e57816020015b6040805160808101825260008082526020808301829052928201819052606082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181610ccc5790505b50905060005b8251811015610d83576000838281518110610d4157610d41611384565b60200260200101519050610d5481610bd8565b838381518110610d6657610d66611384565b60200260200101819052505080610d7c906117d3565b9050610d24565b5092915050565b610d92610d9e565b610d9b81610e55565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610267565b565b600081815260018301602052604081205415155b9392505050565b6000610e358383610f4a565b60606000610e3583610f99565b3373ffffffffffffffffffffffffffffffffffffffff821603610ed4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610267565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000818152600183016020526040812054610f9157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610856565b506000610856565b606081600001805480602002602001604051908101604052809291908181526020018280548015610fe957602002820191906000526020600020905b815481526020019060010190808311610fd5575b50505050509050919050565b50805461100190611564565b6000825580601f10611011575050565b601f016020900490600052602060002090810190610d9b91905b8082111561103f576000815560010161102b565b5090565b60008083601f84011261105557600080fd5b50813567ffffffffffffffff81111561106d57600080fd5b6020830191508360208260051b850101111561108857600080fd5b9250929050565b600080600080604085870312156110a557600080fd5b843567ffffffffffffffff808211156110bd57600080fd5b6110c988838901611043565b909650945060208701359150808211156110e257600080fd5b506110ef87828801611043565b95989497509550505050565b60006080828403121561110d57600080fd5b50919050565b6000815180845260005b818110156111395760208185018101518683018201520161111d565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610e356020830184611113565b6000806020838503121561119d57600080fd5b823567ffffffffffffffff8111156111b457600080fd5b6111c085828601611043565b90969095509350505050565b600080604083850312156111df57600080fd5b50508035926020909101359150565b60006020828403121561120057600080fd5b5035919050565b6020815273ffffffffffffffffffffffffffffffffffffffff8251166020820152600060208301516040808401526112426060840182611113565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b80518252602081015160208301526040810151600281106112c3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b604083015260609081015173ffffffffffffffffffffffffffffffffffffffff16910152565b608081016108568284611279565b6020808252825182820181905260009190848201906040850190845b8181101561133957611326838551611279565b9284019260809290920191600101611313565b50909695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610d9b57600080fd5b60006020828403121561137957600080fd5b8135610e3581611345565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126113e757600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611443576114436113f1565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611490576114906113f1565b604052919050565b6000604082360312156114aa57600080fd5b6114b2611420565b82356114bd81611345565b815260208381013567ffffffffffffffff808211156114db57600080fd5b9085019036601f8301126114ee57600080fd5b813581811115611500576115006113f1565b611530847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611449565b9150808252368482850101111561154657600080fd5b80848401858401376000908201840152918301919091525092915050565b600181811c9082168061157857607f821691505b60208210810361110d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020808352600084546115c581611564565b808487015260406001808416600081146115e6576001811461161e5761164c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a0101955061164c565b896000528660002060005b858110156116445781548b8201860152908301908801611629565b8a0184019650505b509398975050505050505050565b601f82111561082857600081815260208120601f850160051c810160208610156116815750805b601f850160051c820191505b818110156105315782815560010161168d565b815167ffffffffffffffff8111156116ba576116ba6113f1565b6116ce816116c88454611564565b8461165a565b602080601f83116001811461172157600084156116eb5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610531565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561176e5788860151825594840194600190910190840161174f565b50858210156117aa57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b8281526040602082015260006112426040830184611113565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361182b577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60006020828403121561184457600080fd5b81518015158114610e3557600080fd5b81358155602082013560018201556002810160408301356002811061187857600080fd5b8154606085013561188881611345565b74ffffffffffffffffffffffffffffffffffffffff008160081b1660ff84167fffffffffffffffffffffff00000000000000000000000000000000000000000084161717845550505050505056fea164736f6c6343000813000a", } var CapabilityRegistryABI = CapabilityRegistryMetaData.ABI @@ -183,6 +183,28 @@ func (_CapabilityRegistry *CapabilityRegistryTransactorRaw) Transact(opts *bind. return _CapabilityRegistry.Contract.contract.Transact(opts, method, params...) } +func (_CapabilityRegistry *CapabilityRegistryCaller) GetCapabilities(opts *bind.CallOpts) ([]CapabilityRegistryCapability, error) { + var out []interface{} + err := _CapabilityRegistry.contract.Call(opts, &out, "getCapabilities") + + if err != nil { + return *new([]CapabilityRegistryCapability), err + } + + out0 := *abi.ConvertType(out[0], new([]CapabilityRegistryCapability)).(*[]CapabilityRegistryCapability) + + return out0, err + +} + +func (_CapabilityRegistry *CapabilityRegistrySession) GetCapabilities() ([]CapabilityRegistryCapability, error) { + return _CapabilityRegistry.Contract.GetCapabilities(&_CapabilityRegistry.CallOpts) +} + +func (_CapabilityRegistry *CapabilityRegistryCallerSession) GetCapabilities() ([]CapabilityRegistryCapability, error) { + return _CapabilityRegistry.Contract.GetCapabilities(&_CapabilityRegistry.CallOpts) +} + func (_CapabilityRegistry *CapabilityRegistryCaller) GetCapability(opts *bind.CallOpts, capabilityID [32]byte) (CapabilityRegistryCapability, error) { var out []interface{} err := _CapabilityRegistry.contract.Call(opts, &out, "getCapability", capabilityID) @@ -1188,6 +1210,8 @@ func (_CapabilityRegistry *CapabilityRegistry) Address() common.Address { } type CapabilityRegistryInterface interface { + GetCapabilities(opts *bind.CallOpts) ([]CapabilityRegistryCapability, error) + GetCapability(opts *bind.CallOpts, capabilityID [32]byte) (CapabilityRegistryCapability, error) GetCapabilityID(opts *bind.CallOpts, capabilityType [32]byte, version [32]byte) ([32]byte, error) diff --git a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt index e137d35ea5e..efe3e4eaf90 100644 --- a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,4 +1,4 @@ GETH_VERSION: 1.13.8 forwarder: ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.bin b4c900aae9e022f01abbac7993d41f93912247613ac6270b0c4da4ef6f2016e3 -keystone_capability_registry: ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.abi ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.bin 5f801185084a6d6bcc08e0a37574d80f5092bc0dcd40808e9e04804064db0a56 +keystone_capability_registry: ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.abi ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.bin ae9e077854854fa066746eaa354324c7dac2a13bc38b81a66c856fddfc3b79bf ocr3_capability: ../../../contracts/solc/v0.8.19/OCR3Capability/OCR3Capability.abi ../../../contracts/solc/v0.8.19/OCR3Capability/OCR3Capability.bin 9dcbdf55bd5729ba266148da3f17733eb592c871c2108ccca546618628fd9ad2 From 77efb61e562fb456ac5bef3b6a528904cda000ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deividas=20Kar=C5=BEinauskas?= Date: Tue, 30 Apr 2024 14:49:29 +0300 Subject: [PATCH 64/77] Add deprecateCapability (#13036) * Add getCapabilities * Fix comments * Add deprecateCapability * Wrappers + changesets * Name fixes --- .changeset/beige-papayas-develop.md | 5 + contracts/.changeset/plenty-ligers-joke.md | 5 + .../src/v0.8/keystone/CapabilityRegistry.sol | 47 ++++- ...pabilityRegistry_DeprecateCapability.t.sol | 69 +++++++ .../CapabilityRegistry_GetCapabilities.t.sol | 52 +++++ .../keystone_capability_registry.go | 181 +++++++++++++++++- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 7 files changed, 356 insertions(+), 5 deletions(-) create mode 100644 .changeset/beige-papayas-develop.md create mode 100644 contracts/.changeset/plenty-ligers-joke.md create mode 100644 contracts/src/v0.8/keystone/test/CapabilityRegistry_DeprecateCapability.t.sol create mode 100644 contracts/src/v0.8/keystone/test/CapabilityRegistry_GetCapabilities.t.sol diff --git a/.changeset/beige-papayas-develop.md b/.changeset/beige-papayas-develop.md new file mode 100644 index 00000000000..0408383bd03 --- /dev/null +++ b/.changeset/beige-papayas-develop.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal diff --git a/contracts/.changeset/plenty-ligers-joke.md b/contracts/.changeset/plenty-ligers-joke.md new file mode 100644 index 00000000000..9d376e40c05 --- /dev/null +++ b/contracts/.changeset/plenty-ligers-joke.md @@ -0,0 +1,5 @@ +--- +"@chainlink/contracts": patch +--- + +#internal diff --git a/contracts/src/v0.8/keystone/CapabilityRegistry.sol b/contracts/src/v0.8/keystone/CapabilityRegistry.sol index 540bbed9bab..9d627c2afb5 100644 --- a/contracts/src/v0.8/keystone/CapabilityRegistry.sol +++ b/contracts/src/v0.8/keystone/CapabilityRegistry.sol @@ -74,6 +74,16 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { /// exists. error CapabilityAlreadyExists(); + /// @notice This error is thrown when a capability with the provided ID is + /// not found. + /// @param capabilityId The ID used for the lookup. + error CapabilityDoesNotExist(bytes32 capabilityId); + + /// @notice This error is thrown when trying to deprecate a capability that + /// is already deprecated. + /// @param capabilityId The ID of the capability that is already deprecated. + error CapabilityAlreadyDeprecated(bytes32 capabilityId); + /// @notice This error is thrown when trying to add a capability with a /// configuration contract that does not implement the required interface. /// @param proposedConfigurationContract The address of the proposed @@ -101,8 +111,13 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { /// @param capabilityId The ID of the newly added capability event CapabilityAdded(bytes32 indexed capabilityId); + /// @notice This event is emitted when a capability is deprecated + /// @param capabilityId The ID of the deprecated capability + event CapabilityDeprecated(bytes32 indexed capabilityId); + mapping(bytes32 => Capability) private s_capabilities; EnumerableSet.Bytes32Set private s_capabilityIds; + EnumerableSet.Bytes32Set private s_deprecatedCapabilityIds; /// @notice Mapping of node operators mapping(uint256 nodeOperatorId => NodeOperator) private s_nodeOperators; @@ -189,6 +204,16 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { emit CapabilityAdded(capabilityId); } + /// @notice Deprecates a capability by adding it to the deprecated list + /// @param capabilityId The ID of the capability to deprecate + function deprecateCapability(bytes32 capabilityId) external onlyOwner { + if (!s_capabilityIds.contains(capabilityId)) revert CapabilityDoesNotExist(capabilityId); + if (s_deprecatedCapabilityIds.contains(capabilityId)) revert CapabilityAlreadyDeprecated(capabilityId); + + s_deprecatedCapabilityIds.add(capabilityId); + emit CapabilityDeprecated(capabilityId); + } + function getCapability(bytes32 capabilityID) public view returns (Capability memory) { return s_capabilities[capabilityID]; } @@ -199,11 +224,22 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { /// @return Capability[] An array of capabilities function getCapabilities() external view returns (Capability[] memory) { bytes32[] memory capabilityIds = s_capabilityIds.values(); - Capability[] memory capabilities = new Capability[](capabilityIds.length); + + // Solidity does not support dynamic arrays in memory, so we create a + // fixed-size array and copy the capabilities into it. + Capability[] memory capabilities = new Capability[](capabilityIds.length - s_deprecatedCapabilityIds.length()); + + // We need to keep track of the new index because we are skipping + // deprecated capabilities. + uint256 newIndex; for (uint256 i; i < capabilityIds.length; ++i) { bytes32 capabilityId = capabilityIds[i]; - capabilities[i] = getCapability(capabilityId); + + if (!s_deprecatedCapabilityIds.contains(capabilityId)) { + capabilities[newIndex] = getCapability(capabilityId); + newIndex++; + } } return capabilities; @@ -214,4 +250,11 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { function getCapabilityID(bytes32 capabilityType, bytes32 version) public pure returns (bytes32) { return keccak256(abi.encodePacked(capabilityType, version)); } + + /// @notice Returns whether a capability is deprecated + /// @param capabilityId The ID of the capability to check + /// @return bool True if the capability is deprecated, false otherwise + function isCapabilityDeprecated(bytes32 capabilityId) external view returns (bool) { + return s_deprecatedCapabilityIds.contains(capabilityId); + } } diff --git a/contracts/src/v0.8/keystone/test/CapabilityRegistry_DeprecateCapability.t.sol b/contracts/src/v0.8/keystone/test/CapabilityRegistry_DeprecateCapability.t.sol new file mode 100644 index 00000000000..ceefdf431cf --- /dev/null +++ b/contracts/src/v0.8/keystone/test/CapabilityRegistry_DeprecateCapability.t.sol @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {BaseTest} from "./BaseTest.t.sol"; + +import {CapabilityRegistry} from "../CapabilityRegistry.sol"; + +contract CapabilityRegistry_AddCapabilityTest is BaseTest { + event CapabilityDeprecated(bytes32 indexed capabilityId); + + function setUp() public override { + BaseTest.setUp(); + + s_capabilityRegistry.addCapability(s_basicCapability); + s_capabilityRegistry.addCapability(s_capabilityWithConfigurationContract); + } + + function test_RevertWhen_CalledByNonAdmin() public { + changePrank(STRANGER); + bytes32 capabilityId = s_capabilityRegistry.getCapabilityID( + s_basicCapability.capabilityType, + s_basicCapability.version + ); + + vm.expectRevert("Only callable by owner"); + s_capabilityRegistry.deprecateCapability(capabilityId); + } + + function test_RevertWhen_CapabilityDoesNotExist() public { + bytes32 capabilityId = s_capabilityRegistry.getCapabilityID("non-existent-capability", "1.0.0"); + + vm.expectRevert(abi.encodeWithSelector(CapabilityRegistry.CapabilityDoesNotExist.selector, capabilityId)); + s_capabilityRegistry.deprecateCapability(capabilityId); + } + + function test_RevertWhen_CapabilityAlreadyDeprecated() public { + bytes32 capabilityId = s_capabilityRegistry.getCapabilityID( + s_basicCapability.capabilityType, + s_basicCapability.version + ); + + s_capabilityRegistry.deprecateCapability(capabilityId); + + vm.expectRevert(abi.encodeWithSelector(CapabilityRegistry.CapabilityAlreadyDeprecated.selector, capabilityId)); + s_capabilityRegistry.deprecateCapability(capabilityId); + } + + function test_DeprecatesCapability() public { + bytes32 capabilityId = s_capabilityRegistry.getCapabilityID( + s_basicCapability.capabilityType, + s_basicCapability.version + ); + + s_capabilityRegistry.deprecateCapability(capabilityId); + + assertEq(s_capabilityRegistry.isCapabilityDeprecated(capabilityId), true); + } + + function test_EmitsEvent() public { + bytes32 capabilityId = s_capabilityRegistry.getCapabilityID( + s_basicCapability.capabilityType, + s_basicCapability.version + ); + + vm.expectEmit(address(s_capabilityRegistry)); + emit CapabilityDeprecated(capabilityId); + s_capabilityRegistry.deprecateCapability(capabilityId); + } +} diff --git a/contracts/src/v0.8/keystone/test/CapabilityRegistry_GetCapabilities.t.sol b/contracts/src/v0.8/keystone/test/CapabilityRegistry_GetCapabilities.t.sol new file mode 100644 index 00000000000..b14397ba4ef --- /dev/null +++ b/contracts/src/v0.8/keystone/test/CapabilityRegistry_GetCapabilities.t.sol @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {BaseTest} from "./BaseTest.t.sol"; +import {CapabilityRegistry} from "../CapabilityRegistry.sol"; + +contract CapabilityRegistry_GetCapabilitiesTest is BaseTest { + function setUp() public override { + BaseTest.setUp(); + + s_capabilityRegistry.addCapability(s_basicCapability); + s_capabilityRegistry.addCapability(s_capabilityWithConfigurationContract); + } + + function test_ReturnsCapabilities() public view { + CapabilityRegistry.Capability[] memory capabilities = s_capabilityRegistry.getCapabilities(); + + assertEq(capabilities.length, 2); + + assertEq(capabilities[0].capabilityType, "data-streams-reports"); + assertEq(capabilities[0].version, "1.0.0"); + assertEq(uint256(capabilities[0].responseType), uint256(CapabilityRegistry.CapabilityResponseType.REPORT)); + assertEq(capabilities[0].configurationContract, address(0)); + + assertEq(capabilities[1].capabilityType, "read-ethereum-mainnet-gas-price"); + assertEq(capabilities[1].version, "1.0.2"); + assertEq( + uint256(capabilities[1].responseType), + uint256(CapabilityRegistry.CapabilityResponseType.OBSERVATION_IDENTICAL) + ); + assertEq(capabilities[1].configurationContract, address(s_capabilityConfigurationContract)); + } + + function test_ExcludesDeprecatedCapabilities() public { + bytes32 capabilityId = s_capabilityRegistry.getCapabilityID( + s_basicCapability.capabilityType, + s_basicCapability.version + ); + s_capabilityRegistry.deprecateCapability(capabilityId); + + CapabilityRegistry.Capability[] memory capabilities = s_capabilityRegistry.getCapabilities(); + assertEq(capabilities.length, 1); + + assertEq(capabilities[0].capabilityType, "read-ethereum-mainnet-gas-price"); + assertEq(capabilities[0].version, "1.0.2"); + assertEq( + uint256(capabilities[0].responseType), + uint256(CapabilityRegistry.CapabilityResponseType.OBSERVATION_IDENTICAL) + ); + assertEq(capabilities[0].configurationContract, address(s_capabilityConfigurationContract)); + } +} diff --git a/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go b/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go index d1f789f4408..4bac3789a33 100644 --- a/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go +++ b/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go @@ -43,8 +43,8 @@ type CapabilityRegistryNodeOperator struct { } var CapabilityRegistryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CapabilityAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedConfigurationContract\",\"type\":\"address\"}],\"name\":\"InvalidCapabilityConfigurationContractInterface\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeOperatorAdmin\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"lengthOne\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lengthTwo\",\"type\":\"uint256\"}],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"NodeOperatorRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"capability\",\"type\":\"tuple\"}],\"name\":\"addCapability\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"addNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilities\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityID\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"name\":\"getCapabilityID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"getNodeOperator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint256[]\"}],\"name\":\"removeNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"updateNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6118e3806101576000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c806365c14dc7116100815780639cb7c5f41161005b5780639cb7c5f4146101e0578063ddbe4f8214610200578063f2fde38b1461021557600080fd5b806365c14dc71461019057806379ba5097146101b05780638da5cb5b146101b857600080fd5b80631cdf6343116100b25780631cdf634314610149578063229111f51461015c578063398f37731461017d57600080fd5b80630c5801e3146100d9578063117392ce146100ee578063181f5a7714610101575b600080fd5b6100ec6100e736600461108f565b610228565b005b6100ec6100fc3660046110fb565b610539565b604080518082018252601881527f4361706162696c697479526567697374727920312e302e300000000000000000602082015290516101409190611177565b60405180910390f35b6100ec61015736600461118a565b61076a565b61016f61016a3660046111cc565b61082d565b604051908152602001610140565b6100ec61018b36600461118a565b61085c565b6101a361019e3660046111ee565b6109f5565b6040516101409190611207565b6100ec610adb565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610140565b6101f36101ee3660046111ee565b610bd8565b60405161014091906112e9565b610208610c82565b60405161014091906112f7565b6100ec610223366004611367565b610d8a565b828114610270576040517fab8b67c600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff16905b848110156105315760008686838181106102a8576102a8611384565b90506020020135905060008585848181106102c5576102c5611384565b90506020028101906102d791906113b3565b6102e090611498565b805190915073ffffffffffffffffffffffffffffffffffffffff16610331576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805173ffffffffffffffffffffffffffffffffffffffff16331480159061036e57503373ffffffffffffffffffffffffffffffffffffffff851614155b156103a5576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160008381526005602052604090205473ffffffffffffffffffffffffffffffffffffffff908116911614158061045757506020808201516040516103eb9201611177565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012060008681526005835292909220919261043e9260010191016115b1565b6040516020818303038152906040528051906020012014155b1561051e578051600083815260056020908152604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9093169290921782558201516001909101906104c490826116a0565b50806000015173ffffffffffffffffffffffffffffffffffffffff167f14c8f513e8a6d86d2d16b0cb64976de4e72386c4f8068eca3b7354373f8fe97a8383602001516040516105159291906117ba565b60405180910390a25b50508061052a906117d3565b905061028c565b505050505050565b610541610d9e565b60006105528235602084013561082d565b905061055f600382610e21565b15610596576040517fe288638f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105a86080840160608501611367565b73ffffffffffffffffffffffffffffffffffffffff1614610713576105d36080830160608401611367565b73ffffffffffffffffffffffffffffffffffffffff163b15806106b357506106016080830160608401611367565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f884efe6100000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff91909116906301ffc9a790602401602060405180830381865afa15801561068d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106b19190611832565b155b15610713576106c86080830160608401611367565b6040517fabb5e3fd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610267565b61071e600382610e3c565b50600081815260026020526040902082906107398282611854565b505060405181907f65610e5677eedff94555572640e442f89848a109ef8593fa927ac30b2565ff0690600090a25050565b610772610d9e565b60005b8181101561082857600083838381811061079157610791611384565b60209081029290920135600081815260059093526040832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001681559093509190506107e26001830182610ff5565b50506040518181527f1e5877d7b3001d1569bf733b76c7eceda58bd6c031e5b8d0b7042308ba2e9d4f9060200160405180910390a150610821816117d3565b9050610775565b505050565b604080516020808201859052818301849052825180830384018152606090920190925280519101205b92915050565b610864610d9e565b60005b8181101561082857600083838381811061088357610883611384565b905060200281019061089591906113b3565b61089e90611498565b805190915073ffffffffffffffffffffffffffffffffffffffff166108ef576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600654604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815260008681526005909252939020825181547fffffffffffffffffffffffff00000000000000000000000000000000000000001692169190911781559151909190600182019061097290826116a0565b50905050600660008154610985906117d3565b909155508151602083015160405173ffffffffffffffffffffffffffffffffffffffff909216917fda6697b182650034bd205cdc2dbfabb06bdb3a0a83a2b45bfefa3c4881284e0b916109da918591906117ba565b60405180910390a25050806109ee906117d3565b9050610867565b6040805180820190915260008152606060208201526000828152600560209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff1683526001810180549192840191610a5290611564565b80601f0160208091040260200160405190810160405280929190818152602001828054610a7e90611564565b8015610acb5780601f10610aa057610100808354040283529160200191610acb565b820191906000526020600020905b815481529060010190602001808311610aae57829003601f168201915b5050505050815250509050919050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610267565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b604080516080808201835260008083526020808401829052838501829052606084018290528582526002808252918590208551938401865280548452600180820154928501929092529182015493949293919284019160ff1690811115610c4157610c4161124a565b6001811115610c5257610c5261124a565b815260029190910154610100900473ffffffffffffffffffffffffffffffffffffffff1660209091015292915050565b60606000610c906003610e48565b90506000815167ffffffffffffffff811115610cae57610cae6113f1565b604051908082528060200260200182016040528015610d1e57816020015b6040805160808101825260008082526020808301829052928201819052606082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181610ccc5790505b50905060005b8251811015610d83576000838281518110610d4157610d41611384565b60200260200101519050610d5481610bd8565b838381518110610d6657610d66611384565b60200260200101819052505080610d7c906117d3565b9050610d24565b5092915050565b610d92610d9e565b610d9b81610e55565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610267565b565b600081815260018301602052604081205415155b9392505050565b6000610e358383610f4a565b60606000610e3583610f99565b3373ffffffffffffffffffffffffffffffffffffffff821603610ed4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610267565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000818152600183016020526040812054610f9157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610856565b506000610856565b606081600001805480602002602001604051908101604052809291908181526020018280548015610fe957602002820191906000526020600020905b815481526020019060010190808311610fd5575b50505050509050919050565b50805461100190611564565b6000825580601f10611011575050565b601f016020900490600052602060002090810190610d9b91905b8082111561103f576000815560010161102b565b5090565b60008083601f84011261105557600080fd5b50813567ffffffffffffffff81111561106d57600080fd5b6020830191508360208260051b850101111561108857600080fd5b9250929050565b600080600080604085870312156110a557600080fd5b843567ffffffffffffffff808211156110bd57600080fd5b6110c988838901611043565b909650945060208701359150808211156110e257600080fd5b506110ef87828801611043565b95989497509550505050565b60006080828403121561110d57600080fd5b50919050565b6000815180845260005b818110156111395760208185018101518683018201520161111d565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610e356020830184611113565b6000806020838503121561119d57600080fd5b823567ffffffffffffffff8111156111b457600080fd5b6111c085828601611043565b90969095509350505050565b600080604083850312156111df57600080fd5b50508035926020909101359150565b60006020828403121561120057600080fd5b5035919050565b6020815273ffffffffffffffffffffffffffffffffffffffff8251166020820152600060208301516040808401526112426060840182611113565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b80518252602081015160208301526040810151600281106112c3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b604083015260609081015173ffffffffffffffffffffffffffffffffffffffff16910152565b608081016108568284611279565b6020808252825182820181905260009190848201906040850190845b8181101561133957611326838551611279565b9284019260809290920191600101611313565b50909695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610d9b57600080fd5b60006020828403121561137957600080fd5b8135610e3581611345565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126113e757600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611443576114436113f1565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611490576114906113f1565b604052919050565b6000604082360312156114aa57600080fd5b6114b2611420565b82356114bd81611345565b815260208381013567ffffffffffffffff808211156114db57600080fd5b9085019036601f8301126114ee57600080fd5b813581811115611500576115006113f1565b611530847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611449565b9150808252368482850101111561154657600080fd5b80848401858401376000908201840152918301919091525092915050565b600181811c9082168061157857607f821691505b60208210810361110d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020808352600084546115c581611564565b808487015260406001808416600081146115e6576001811461161e5761164c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a0101955061164c565b896000528660002060005b858110156116445781548b8201860152908301908801611629565b8a0184019650505b509398975050505050505050565b601f82111561082857600081815260208120601f850160051c810160208610156116815750805b601f850160051c820191505b818110156105315782815560010161168d565b815167ffffffffffffffff8111156116ba576116ba6113f1565b6116ce816116c88454611564565b8461165a565b602080601f83116001811461172157600084156116eb5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555610531565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561176e5788860151825594840194600190910190840161174f565b50858210156117aa57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b8281526040602082015260006112426040830184611113565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361182b577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60006020828403121561184457600080fd5b81518015158114610e3557600080fd5b81358155602082013560018201556002810160408301356002811061187857600080fd5b8154606085013561188881611345565b74ffffffffffffffffffffffffffffffffffffffff008160081b1660ff84167fffffffffffffffffffffff00000000000000000000000000000000000000000084161717845550505050505056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAlreadyDeprecated\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CapabilityAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedConfigurationContract\",\"type\":\"address\"}],\"name\":\"InvalidCapabilityConfigurationContractInterface\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeOperatorAdmin\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"lengthOne\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lengthTwo\",\"type\":\"uint256\"}],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDeprecated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"NodeOperatorRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"capability\",\"type\":\"tuple\"}],\"name\":\"addCapability\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"addNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"deprecateCapability\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilities\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityID\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"name\":\"getCapabilityID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"getNodeOperator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"isCapabilityDeprecated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint256[]\"}],\"name\":\"removeNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"updateNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611a7d80620001586000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806365c14dc71161008c5780639cb7c5f4116100665780639cb7c5f41461023c578063ae3c241c1461025c578063ddbe4f821461026f578063f2fde38b1461028457600080fd5b806365c14dc7146101ec57806379ba50971461020c5780638da5cb5b1461021457600080fd5b8063181f5a77116100c8578063181f5a771461013f5780631cdf63431461017e578063229111f514610191578063398f3773146101d957600080fd5b80630c5801e3146100ef578063117392ce146101045780631257001114610117575b600080fd5b6101026100fd36600461120e565b610297565b005b61010261011236600461127a565b6105a8565b61012a610125366004611292565b6107f3565b60405190151581526020015b60405180910390f35b604080518082018252601881527f4361706162696c697479526567697374727920312e302e30000000000000000060208201529051610136919061130f565b61010261018c366004611322565b610806565b6101cb61019f366004611364565b604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b604051908152602001610136565b6101026101e7366004611322565b6108c9565b6101ff6101fa366004611292565b610a62565b6040516101369190611386565b610102610b48565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610136565b61024f61024a366004611292565b610c45565b6040516101369190611468565b61010261026a366004611292565b610cef565b610277610dba565b6040516101369190611476565b6101026102923660046114e6565b610eff565b8281146102df576040517fab8b67c600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff16905b848110156105a057600086868381811061031757610317611503565b905060200201359050600085858481811061033457610334611503565b90506020028101906103469190611532565b61034f90611617565b805190915073ffffffffffffffffffffffffffffffffffffffff166103a0576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805173ffffffffffffffffffffffffffffffffffffffff1633148015906103dd57503373ffffffffffffffffffffffffffffffffffffffff851614155b15610414576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160008381526007602052604090205473ffffffffffffffffffffffffffffffffffffffff90811691161415806104c6575060208082015160405161045a920161130f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206000868152600783529290922091926104ad926001019101611730565b6040516020818303038152906040528051906020012014155b1561058d578051600083815260076020908152604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909316929092178255820151600190910190610533908261181f565b50806000015173ffffffffffffffffffffffffffffffffffffffff167f14c8f513e8a6d86d2d16b0cb64976de4e72386c4f8068eca3b7354373f8fe97a838360200151604051610584929190611939565b60405180910390a25b50508061059990611981565b90506102fb565b505050505050565b6105b0610f13565b6040805182356020828101919091528084013582840152825180830384018152606090920190925280519101206105e8600382610f96565b1561061f576040517fe288638f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061063160808401606085016114e6565b73ffffffffffffffffffffffffffffffffffffffff161461079c5761065c60808301606084016114e6565b73ffffffffffffffffffffffffffffffffffffffff163b158061073c575061068a60808301606084016114e6565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f884efe6100000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff91909116906301ffc9a790602401602060405180830381865afa158015610716573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073a91906119b9565b155b1561079c5761075160808301606084016114e6565b6040517fabb5e3fd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016102d6565b6107a7600382610fb1565b50600081815260026020526040902082906107c282826119db565b505060405181907f65610e5677eedff94555572640e442f89848a109ef8593fa927ac30b2565ff0690600090a25050565b6000610800600583610f96565b92915050565b61080e610f13565b60005b818110156108c457600083838381811061082d5761082d611503565b60209081029290920135600081815260079093526040832080547fffffffffffffffffffffffff000000000000000000000000000000000000000016815590935091905061087e6001830182611174565b50506040518181527f1e5877d7b3001d1569bf733b76c7eceda58bd6c031e5b8d0b7042308ba2e9d4f9060200160405180910390a1506108bd81611981565b9050610811565b505050565b6108d1610f13565b60005b818110156108c45760008383838181106108f0576108f0611503565b90506020028101906109029190611532565b61090b90611617565b805190915073ffffffffffffffffffffffffffffffffffffffff1661095c576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600854604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815260008681526007909252939020825181547fffffffffffffffffffffffff0000000000000000000000000000000000000000169216919091178155915190919060018201906109df908261181f565b509050506008600081546109f290611981565b909155508151602083015160405173ffffffffffffffffffffffffffffffffffffffff909216917fda6697b182650034bd205cdc2dbfabb06bdb3a0a83a2b45bfefa3c4881284e0b91610a4791859190611939565b60405180910390a2505080610a5b90611981565b90506108d4565b6040805180820190915260008152606060208201526000828152600760209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff1683526001810180549192840191610abf906116e3565b80601f0160208091040260200160405190810160405280929190818152602001828054610aeb906116e3565b8015610b385780601f10610b0d57610100808354040283529160200191610b38565b820191906000526020600020905b815481529060010190602001808311610b1b57829003601f168201915b5050505050815250509050919050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610bc9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016102d6565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b604080516080808201835260008083526020808401829052838501829052606084018290528582526002808252918590208551938401865280548452600180820154928501929092529182015493949293919284019160ff1690811115610cae57610cae6113c9565b6001811115610cbf57610cbf6113c9565b815260029190910154610100900473ffffffffffffffffffffffffffffffffffffffff1660209091015292915050565b610cf7610f13565b610d02600382610f96565b610d3b576040517fe181733f000000000000000000000000000000000000000000000000000000008152600481018290526024016102d6565b610d46600582610f96565b15610d80576040517f16950d1d000000000000000000000000000000000000000000000000000000008152600481018290526024016102d6565b610d8b600582610fb1565b5060405181907fdcea1b78b6ddc31592a94607d537543fcaafda6cc52d6d5cc7bbfca1422baf2190600090a250565b60606000610dc86003610fbd565b90506000610dd66005610fca565b8251610de29190611a5d565b67ffffffffffffffff811115610dfa57610dfa611570565b604051908082528060200260200182016040528015610e6a57816020015b6040805160808101825260008082526020808301829052928201819052606082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181610e185790505b5090506000805b8351811015610ef6576000848281518110610e8e57610e8e611503565b60200260200101519050610eac816005610f9690919063ffffffff16565b610ee557610eb981610c45565b848481518110610ecb57610ecb611503565b60200260200101819052508280610ee190611981565b9350505b50610eef81611981565b9050610e71565b50909392505050565b610f07610f13565b610f1081610fd4565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610f94576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016102d6565b565b600081815260018301602052604081205415155b9392505050565b6000610faa83836110c9565b60606000610faa83611118565b6000610800825490565b3373ffffffffffffffffffffffffffffffffffffffff821603611053576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016102d6565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600081815260018301602052604081205461111057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610800565b506000610800565b60608160000180548060200260200160405190810160405280929190818152602001828054801561116857602002820191906000526020600020905b815481526020019060010190808311611154575b50505050509050919050565b508054611180906116e3565b6000825580601f10611190575050565b601f016020900490600052602060002090810190610f1091905b808211156111be57600081556001016111aa565b5090565b60008083601f8401126111d457600080fd5b50813567ffffffffffffffff8111156111ec57600080fd5b6020830191508360208260051b850101111561120757600080fd5b9250929050565b6000806000806040858703121561122457600080fd5b843567ffffffffffffffff8082111561123c57600080fd5b611248888389016111c2565b9096509450602087013591508082111561126157600080fd5b5061126e878288016111c2565b95989497509550505050565b60006080828403121561128c57600080fd5b50919050565b6000602082840312156112a457600080fd5b5035919050565b6000815180845260005b818110156112d1576020818501810151868301820152016112b5565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610faa60208301846112ab565b6000806020838503121561133557600080fd5b823567ffffffffffffffff81111561134c57600080fd5b611358858286016111c2565b90969095509350505050565b6000806040838503121561137757600080fd5b50508035926020909101359150565b6020815273ffffffffffffffffffffffffffffffffffffffff8251166020820152600060208301516040808401526113c160608401826112ab565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8051825260208101516020830152604081015160028110611442577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b604083015260609081015173ffffffffffffffffffffffffffffffffffffffff16910152565b6080810161080082846113f8565b6020808252825182820181905260009190848201906040850190845b818110156114b8576114a58385516113f8565b9284019260809290920191600101611492565b50909695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f1057600080fd5b6000602082840312156114f857600080fd5b8135610faa816114c4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261156657600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156115c2576115c2611570565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561160f5761160f611570565b604052919050565b60006040823603121561162957600080fd5b61163161159f565b823561163c816114c4565b815260208381013567ffffffffffffffff8082111561165a57600080fd5b9085019036601f83011261166d57600080fd5b81358181111561167f5761167f611570565b6116af847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016115c8565b915080825236848285010111156116c557600080fd5b80848401858401376000908201840152918301919091525092915050565b600181811c908216806116f757607f821691505b60208210810361128c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000602080835260008454611744816116e3565b80848701526040600180841660008114611765576001811461179d576117cb565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a010195506117cb565b896000528660002060005b858110156117c35781548b82018601529083019088016117a8565b8a0184019650505b509398975050505050505050565b601f8211156108c457600081815260208120601f850160051c810160208610156118005750805b601f850160051c820191505b818110156105a05782815560010161180c565b815167ffffffffffffffff81111561183957611839611570565b61184d8161184784546116e3565b846117d9565b602080601f8311600181146118a0576000841561186a5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556105a0565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156118ed578886015182559484019460019091019084016118ce565b508582101561192957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b8281526040602082015260006113c160408301846112ab565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036119b2576119b2611952565b5060010190565b6000602082840312156119cb57600080fd5b81518015158114610faa57600080fd5b8135815560208201356001820155600281016040830135600281106119ff57600080fd5b81546060850135611a0f816114c4565b74ffffffffffffffffffffffffffffffffffffffff008160081b1660ff84167fffffffffffffffffffffff000000000000000000000000000000000000000000841617178455505050505050565b818103818111156108005761080061195256fea164736f6c6343000813000a", } var CapabilityRegistryABI = CapabilityRegistryMetaData.ABI @@ -271,6 +271,28 @@ func (_CapabilityRegistry *CapabilityRegistryCallerSession) GetNodeOperator(node return _CapabilityRegistry.Contract.GetNodeOperator(&_CapabilityRegistry.CallOpts, nodeOperatorId) } +func (_CapabilityRegistry *CapabilityRegistryCaller) IsCapabilityDeprecated(opts *bind.CallOpts, capabilityId [32]byte) (bool, error) { + var out []interface{} + err := _CapabilityRegistry.contract.Call(opts, &out, "isCapabilityDeprecated", capabilityId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CapabilityRegistry *CapabilityRegistrySession) IsCapabilityDeprecated(capabilityId [32]byte) (bool, error) { + return _CapabilityRegistry.Contract.IsCapabilityDeprecated(&_CapabilityRegistry.CallOpts, capabilityId) +} + +func (_CapabilityRegistry *CapabilityRegistryCallerSession) IsCapabilityDeprecated(capabilityId [32]byte) (bool, error) { + return _CapabilityRegistry.Contract.IsCapabilityDeprecated(&_CapabilityRegistry.CallOpts, capabilityId) +} + func (_CapabilityRegistry *CapabilityRegistryCaller) Owner(opts *bind.CallOpts) (common.Address, error) { var out []interface{} err := _CapabilityRegistry.contract.Call(opts, &out, "owner") @@ -351,6 +373,18 @@ func (_CapabilityRegistry *CapabilityRegistryTransactorSession) AddNodeOperators return _CapabilityRegistry.Contract.AddNodeOperators(&_CapabilityRegistry.TransactOpts, nodeOperators) } +func (_CapabilityRegistry *CapabilityRegistryTransactor) DeprecateCapability(opts *bind.TransactOpts, capabilityId [32]byte) (*types.Transaction, error) { + return _CapabilityRegistry.contract.Transact(opts, "deprecateCapability", capabilityId) +} + +func (_CapabilityRegistry *CapabilityRegistrySession) DeprecateCapability(capabilityId [32]byte) (*types.Transaction, error) { + return _CapabilityRegistry.Contract.DeprecateCapability(&_CapabilityRegistry.TransactOpts, capabilityId) +} + +func (_CapabilityRegistry *CapabilityRegistryTransactorSession) DeprecateCapability(capabilityId [32]byte) (*types.Transaction, error) { + return _CapabilityRegistry.Contract.DeprecateCapability(&_CapabilityRegistry.TransactOpts, capabilityId) +} + func (_CapabilityRegistry *CapabilityRegistryTransactor) RemoveNodeOperators(opts *bind.TransactOpts, nodeOperatorIds []*big.Int) (*types.Transaction, error) { return _CapabilityRegistry.contract.Transact(opts, "removeNodeOperators", nodeOperatorIds) } @@ -514,6 +548,133 @@ func (_CapabilityRegistry *CapabilityRegistryFilterer) ParseCapabilityAdded(log return event, nil } +type CapabilityRegistryCapabilityDeprecatedIterator struct { + Event *CapabilityRegistryCapabilityDeprecated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CapabilityRegistryCapabilityDeprecatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CapabilityRegistryCapabilityDeprecated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CapabilityRegistryCapabilityDeprecated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CapabilityRegistryCapabilityDeprecatedIterator) Error() error { + return it.fail +} + +func (it *CapabilityRegistryCapabilityDeprecatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CapabilityRegistryCapabilityDeprecated struct { + CapabilityId [32]byte + Raw types.Log +} + +func (_CapabilityRegistry *CapabilityRegistryFilterer) FilterCapabilityDeprecated(opts *bind.FilterOpts, capabilityId [][32]byte) (*CapabilityRegistryCapabilityDeprecatedIterator, error) { + + var capabilityIdRule []interface{} + for _, capabilityIdItem := range capabilityId { + capabilityIdRule = append(capabilityIdRule, capabilityIdItem) + } + + logs, sub, err := _CapabilityRegistry.contract.FilterLogs(opts, "CapabilityDeprecated", capabilityIdRule) + if err != nil { + return nil, err + } + return &CapabilityRegistryCapabilityDeprecatedIterator{contract: _CapabilityRegistry.contract, event: "CapabilityDeprecated", logs: logs, sub: sub}, nil +} + +func (_CapabilityRegistry *CapabilityRegistryFilterer) WatchCapabilityDeprecated(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryCapabilityDeprecated, capabilityId [][32]byte) (event.Subscription, error) { + + var capabilityIdRule []interface{} + for _, capabilityIdItem := range capabilityId { + capabilityIdRule = append(capabilityIdRule, capabilityIdItem) + } + + logs, sub, err := _CapabilityRegistry.contract.WatchLogs(opts, "CapabilityDeprecated", capabilityIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CapabilityRegistryCapabilityDeprecated) + if err := _CapabilityRegistry.contract.UnpackLog(event, "CapabilityDeprecated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CapabilityRegistry *CapabilityRegistryFilterer) ParseCapabilityDeprecated(log types.Log) (*CapabilityRegistryCapabilityDeprecated, error) { + event := new(CapabilityRegistryCapabilityDeprecated) + if err := _CapabilityRegistry.contract.UnpackLog(event, "CapabilityDeprecated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type CapabilityRegistryNodeOperatorAddedIterator struct { Event *CapabilityRegistryNodeOperatorAdded @@ -1165,6 +1326,8 @@ func (_CapabilityRegistry *CapabilityRegistry) ParseLog(log types.Log) (generate switch log.Topics[0] { case _CapabilityRegistry.abi.Events["CapabilityAdded"].ID: return _CapabilityRegistry.ParseCapabilityAdded(log) + case _CapabilityRegistry.abi.Events["CapabilityDeprecated"].ID: + return _CapabilityRegistry.ParseCapabilityDeprecated(log) case _CapabilityRegistry.abi.Events["NodeOperatorAdded"].ID: return _CapabilityRegistry.ParseNodeOperatorAdded(log) case _CapabilityRegistry.abi.Events["NodeOperatorRemoved"].ID: @@ -1185,6 +1348,10 @@ func (CapabilityRegistryCapabilityAdded) Topic() common.Hash { return common.HexToHash("0x65610e5677eedff94555572640e442f89848a109ef8593fa927ac30b2565ff06") } +func (CapabilityRegistryCapabilityDeprecated) Topic() common.Hash { + return common.HexToHash("0xdcea1b78b6ddc31592a94607d537543fcaafda6cc52d6d5cc7bbfca1422baf21") +} + func (CapabilityRegistryNodeOperatorAdded) Topic() common.Hash { return common.HexToHash("0xda6697b182650034bd205cdc2dbfabb06bdb3a0a83a2b45bfefa3c4881284e0b") } @@ -1218,6 +1385,8 @@ type CapabilityRegistryInterface interface { GetNodeOperator(opts *bind.CallOpts, nodeOperatorId *big.Int) (CapabilityRegistryNodeOperator, error) + IsCapabilityDeprecated(opts *bind.CallOpts, capabilityId [32]byte) (bool, error) + Owner(opts *bind.CallOpts) (common.Address, error) TypeAndVersion(opts *bind.CallOpts) (string, error) @@ -1228,6 +1397,8 @@ type CapabilityRegistryInterface interface { AddNodeOperators(opts *bind.TransactOpts, nodeOperators []CapabilityRegistryNodeOperator) (*types.Transaction, error) + DeprecateCapability(opts *bind.TransactOpts, capabilityId [32]byte) (*types.Transaction, error) + RemoveNodeOperators(opts *bind.TransactOpts, nodeOperatorIds []*big.Int) (*types.Transaction, error) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) @@ -1240,6 +1411,12 @@ type CapabilityRegistryInterface interface { ParseCapabilityAdded(log types.Log) (*CapabilityRegistryCapabilityAdded, error) + FilterCapabilityDeprecated(opts *bind.FilterOpts, capabilityId [][32]byte) (*CapabilityRegistryCapabilityDeprecatedIterator, error) + + WatchCapabilityDeprecated(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryCapabilityDeprecated, capabilityId [][32]byte) (event.Subscription, error) + + ParseCapabilityDeprecated(log types.Log) (*CapabilityRegistryCapabilityDeprecated, error) + FilterNodeOperatorAdded(opts *bind.FilterOpts, admin []common.Address) (*CapabilityRegistryNodeOperatorAddedIterator, error) WatchNodeOperatorAdded(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryNodeOperatorAdded, admin []common.Address) (event.Subscription, error) diff --git a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt index efe3e4eaf90..0dff3f2986e 100644 --- a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,4 +1,4 @@ GETH_VERSION: 1.13.8 forwarder: ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.bin b4c900aae9e022f01abbac7993d41f93912247613ac6270b0c4da4ef6f2016e3 -keystone_capability_registry: ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.abi ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.bin ae9e077854854fa066746eaa354324c7dac2a13bc38b81a66c856fddfc3b79bf +keystone_capability_registry: ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.abi ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.bin 28fb0e1c437b97271d999f3b028f7bd44558352ec83f89501aabf501fcc915f1 ocr3_capability: ../../../contracts/solc/v0.8.19/OCR3Capability/OCR3Capability.abi ../../../contracts/solc/v0.8.19/OCR3Capability/OCR3Capability.bin 9dcbdf55bd5729ba266148da3f17733eb592c871c2108ccca546618628fd9ad2 From 60a800b076ac359e78fd57c79ce6f1b9ef870e59 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Tue, 30 Apr 2024 07:40:53 -0500 Subject: [PATCH 65/77] mockery cleanup (#13019) --- .tool-versions | 2 +- common/types/mocks/subscription.go | 2 +- common/types/subscription.go | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.tool-versions b/.tool-versions index 4aa55bda3f5..9db7d9b080d 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,5 +1,5 @@ golang 1.21.7 -mockery 2.38.0 +mockery 2.42.2 nodejs 16.16.0 pnpm 8.11.0 postgres 13.3 diff --git a/common/types/mocks/subscription.go b/common/types/mocks/subscription.go index 32db6dfa769..e52fafa7ca5 100644 --- a/common/types/mocks/subscription.go +++ b/common/types/mocks/subscription.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.38.0. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/common/types/subscription.go b/common/types/subscription.go index 36d41ce1a20..e0cd0a1660d 100644 --- a/common/types/subscription.go +++ b/common/types/subscription.go @@ -1,9 +1,10 @@ package types +//go:generate mockery --quiet --name Subscription --output ./mocks/ --case=underscore + // Subscription represents an event subscription where events are // delivered on a data channel. // This is a generic interface for Subscription to represent used by clients. - type Subscription interface { // Unsubscribe cancels the sending of events to the data channel // and closes the error channel. From 5b87de0d4de8d572e1d9a2088cac7e0af7b85027 Mon Sep 17 00:00:00 2001 From: frank zhu Date: Tue, 30 Apr 2024 07:02:10 -0700 Subject: [PATCH 66/77] delete changeset workflow comment when conditions met (#13049) --- .github/workflows/changeset.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/changeset.yml b/.github/workflows/changeset.yml index 0af608624b1..c9b557a8bc9 100644 --- a/.github/workflows/changeset.yml +++ b/.github/workflows/changeset.yml @@ -60,7 +60,7 @@ jobs: - name: Make a comment uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 # v2.5.0 - if: ${{ (steps.files-changed.outputs.core == 'true' || steps.files-changed.outputs.shared == 'true') && steps.files-changed.outputs.core-changeset == 'false' }} + if: ${{ steps.files-changed.outputs.core == 'true' || steps.files-changed.outputs.shared == 'true' }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -69,10 +69,12 @@ jobs: ${{ env.TAGS }} reactions: eyes comment_tag: changeset-core + mode: ${{ steps.files-changed.outputs.core-changeset == 'false' && 'upsert' || 'delete' }} + create_if_not_exists: ${{ steps.files-changed.outputs.core-changeset == 'false' && 'true' || 'false' }} - name: Make a comment uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 # v2.5.0 - if: ${{ steps.files-changed.outputs.contracts == 'true' && steps.files-changed.outputs.contracts-changeset == 'false' }} + if: ${{ steps.files-changed.outputs.contracts == 'true' }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -80,6 +82,8 @@ jobs: I see you updated files related to `contracts`. Please run `pnpm changeset` in the `contracts` directory to add a changeset. reactions: eyes comment_tag: changeset-contracts + mode: ${{ steps.files-changed.outputs.contracts-changeset == 'false' && 'upsert' || 'delete' }} + create_if_not_exists: ${{ steps.files-changed.outputs.contracts-changeset == 'false' && 'true' || 'false' }} - name: Check for new changeset for core if: ${{ (steps.files-changed.outputs.core == 'true' || steps.files-changed.outputs.shared == 'true') && steps.files-changed.outputs.core-changeset == 'false' }} @@ -103,7 +107,7 @@ jobs: - name: Make a comment uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 # v2.5.0 - if: ${{ steps.files-changed.outputs.core-changeset == 'true' && steps.changeset-tags.outputs.has_tags == 'false' }} + if: ${{ steps.files-changed.outputs.core-changeset == 'true' }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -112,6 +116,8 @@ jobs: ${{ env.TAGS }} reactions: eyes comment_tag: changeset-core-tags + mode: ${{ steps.changeset-tags.outputs.has_tags == 'false' && 'upsert' || 'delete' }} + create_if_not_exists: ${{ steps.changeset-tags.outputs.has_tags == 'false' && 'true' || 'false' }} - name: Check for new changeset tags for core if: ${{ steps.files-changed.outputs.core-changeset == 'true' && steps.changeset-tags.outputs.has_tags == 'false' }} From 61106ec1ea6a4ab47ab0207088fa4f02bb1e3cc7 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Tue, 30 Apr 2024 09:48:04 -0500 Subject: [PATCH 67/77] context cleanup (#13047) --- common/client/poller.go | 3 +-- core/internal/testutils/pgtest/txdb.go | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/common/client/poller.go b/common/client/poller.go index b21f28fe604..ebdcbd66283 100644 --- a/common/client/poller.go +++ b/common/client/poller.go @@ -78,8 +78,7 @@ func (p *Poller[T]) pollingLoop() { return case <-ticker.C: // Set polling timeout - pollingCtx, cancelPolling := context.WithTimeout(context.Background(), p.pollingTimeout) - p.stopCh.CtxCancel(pollingCtx, cancelPolling) + pollingCtx, cancelPolling := p.stopCh.CtxCancel(context.WithTimeout(context.Background(), p.pollingTimeout)) // Execute polling function result, err := p.pollingFunc(pollingCtx) cancelPolling() diff --git a/core/internal/testutils/pgtest/txdb.go b/core/internal/testutils/pgtest/txdb.go index 38fe8390bab..da9fd6cb2d0 100644 --- a/core/internal/testutils/pgtest/txdb.go +++ b/core/internal/testutils/pgtest/txdb.go @@ -19,7 +19,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/store/dialects" ) -// TODO still need to import this for side effects // txdb is a simplified version of https://github.com/DATA-DOG/go-txdb // // The original lib has various problems and is hard to understand because it From e50d38b0bddc34aa0b97ae6bdf23c355b5619682 Mon Sep 17 00:00:00 2001 From: HenryNguyen5 <6404866+HenryNguyen5@users.noreply.github.com> Date: Tue, 30 Apr 2024 11:26:23 -0400 Subject: [PATCH 68/77] Rename tags -> labels (#12961) --- .changeset/perfect-dancers-guess.md | 5 +++++ core/services/workflows/models_yaml.go | 22 +++++++++---------- .../workflows/marshalling/workflow_2.yaml | 2 +- .../fixtures/workflows/workflow_schema.json | 4 ++-- 4 files changed, 19 insertions(+), 14 deletions(-) create mode 100644 .changeset/perfect-dancers-guess.md diff --git a/.changeset/perfect-dancers-guess.md b/.changeset/perfect-dancers-guess.md new file mode 100644 index 00000000000..6ee4099c45a --- /dev/null +++ b/.changeset/perfect-dancers-guess.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal Rename workflow tags to labels diff --git a/core/services/workflows/models_yaml.go b/core/services/workflows/models_yaml.go index 3d65e24a814..280a895f1b8 100644 --- a/core/services/workflows/models_yaml.go +++ b/core/services/workflows/models_yaml.go @@ -172,8 +172,8 @@ type stepDefinitionYaml struct { // // Eventually, we might support minor version and specific version pins. This will allow workflow authors to have flexibility when selecting the version, and node operators will be able to determine when they should update their capabilities. // - // There are two ways to specify a type - using a string as a fully qualified ID or a structured table. When using a table, tags are ordered alphanumerically and joined into a string following a - // {type}:{tag1_key}_{tag1_value}:{tag2_key}_{tag2_value}@{version} + // There are two ways to specify a type - using a string as a fully qualified ID or a structured table. When using a table, labels are ordered alphanumerically and joined into a string following a + // {name}:{label1_key}_{label1_value}:{label2_key}_{label2_value}@{version} // pattern. // // The “type” supports [a-z0-9_-:] characters followed by an @ and [semver regex] at the end. @@ -191,7 +191,7 @@ type stepDefinitionYaml struct { // type: // name: read_chain // version: 1 - // tags: + // labels: // chain: ethereum // network: mainnet // @@ -319,22 +319,22 @@ func (stepDefinitionType) JSONSchema() *jsonschema.Schema { type stepDefinitionTableType struct { Name string `json:"name"` Version string `json:"version" jsonschema:"pattern=(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$"` - Tags map[string]string `json:"tags"` + Labels map[string]string `json:"labels"` } // String returns the string representation of a stepDefinitionTableType. // // It follows the format: // -// {name}:{tag1_key}_{tag1_value}:{tag2_key}_{tag2_value}@{version} +// {name}:{label1_key}_{label1_value}:{label2_key}_{label2_value}@{version} // -// where tags are ordered alphanumerically. +// where labels are ordered alphanumerically. func (s stepDefinitionTableType) String() string { - tags := make([]string, 0, len(s.Tags)) - for k, v := range s.Tags { - tags = append(tags, fmt.Sprintf("%s_%s", k, v)) + labels := make([]string, 0, len(s.Labels)) + for k, v := range s.Labels { + labels = append(labels, fmt.Sprintf("%s_%s", k, v)) } - slices.Sort(tags) + slices.Sort(labels) - return fmt.Sprintf("%s:%s@%s", s.Name, strings.Join(tags, ":"), s.Version) + return fmt.Sprintf("%s:%s@%s", s.Name, strings.Join(labels, ":"), s.Version) } diff --git a/core/services/workflows/testdata/fixtures/workflows/marshalling/workflow_2.yaml b/core/services/workflows/testdata/fixtures/workflows/marshalling/workflow_2.yaml index f43cd291703..50a598d0bc9 100644 --- a/core/services/workflows/testdata/fixtures/workflows/marshalling/workflow_2.yaml +++ b/core/services/workflows/testdata/fixtures/workflows/marshalling/workflow_2.yaml @@ -9,7 +9,7 @@ - type: name: trigger_test version: "2" - tags: + labels: chain: ethereum aaShouldBeFirst: "true" network: mainnet diff --git a/core/services/workflows/testdata/fixtures/workflows/workflow_schema.json b/core/services/workflows/testdata/fixtures/workflows/workflow_schema.json index 2cb02c7921d..83ecd42ecb9 100644 --- a/core/services/workflows/testdata/fixtures/workflows/workflow_schema.json +++ b/core/services/workflows/testdata/fixtures/workflows/workflow_schema.json @@ -23,7 +23,7 @@ "type": "string", "pattern": "(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$" }, - "tags": { + "labels": { "additionalProperties": { "type": "string" }, @@ -35,7 +35,7 @@ "required": [ "name", "version", - "tags" + "labels" ] } ], From 2729ef76f34877a2e6e8644b2e67f3e5dfb0c2b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Friedemann=20F=C3=BCrst?= <59653747+friedemannf@users.noreply.github.com> Date: Tue, 30 Apr 2024 17:31:39 +0200 Subject: [PATCH 69/77] [SHIP-1523] Add X Layer (#12747) * Add X Layer * go mod tidy * Add ChainType for XLayer to ignore transactions with 0 gasPrice * revert switch stmt * update changeset * fix test * add BlockHistoryEstimator test for XLayer --- .changeset/sixty-readers-mix.md | 5 + common/config/chaintype.go | 4 +- .../config/toml/defaults/XLayer_Mainnet.toml | 25 +++ .../config/toml/defaults/XLayer_Sepolia.toml | 25 +++ .../evm/gas/block_history_estimator_test.go | 5 + core/chains/evm/gas/chain_specific.go | 4 +- core/config/docs/chains-evm.toml | 2 +- core/services/chainlink/config_test.go | 4 +- core/services/ocr/contract_tracker.go | 2 +- core/services/ocrcommon/block_translator.go | 2 +- docs/CONFIG.md | 172 +++++++++++++++++- 11 files changed, 241 insertions(+), 9 deletions(-) create mode 100644 .changeset/sixty-readers-mix.md create mode 100644 core/chains/evm/config/toml/defaults/XLayer_Mainnet.toml create mode 100644 core/chains/evm/config/toml/defaults/XLayer_Sepolia.toml diff --git a/.changeset/sixty-readers-mix.md b/.changeset/sixty-readers-mix.md new file mode 100644 index 00000000000..a6782a5b276 --- /dev/null +++ b/.changeset/sixty-readers-mix.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +Add support for X Layer (X1) #added diff --git a/common/config/chaintype.go b/common/config/chaintype.go index 29bab2a91e2..73c48960a13 100644 --- a/common/config/chaintype.go +++ b/common/config/chaintype.go @@ -19,6 +19,7 @@ const ( ChainScroll ChainType = "scroll" ChainWeMix ChainType = "wemix" ChainXDai ChainType = "xdai" // Deprecated: use ChainGnosis instead + ChainXLayer ChainType = "xlayer" ChainZkSync ChainType = "zksync" ) @@ -31,13 +32,14 @@ var ErrInvalidChainType = fmt.Errorf("must be one of %s or omitted", strings.Joi string(ChainOptimismBedrock), string(ChainScroll), string(ChainWeMix), + string(ChainXLayer), string(ChainZkSync), }, ", ")) // IsValid returns true if the ChainType value is known or empty. func (c ChainType) IsValid() bool { switch c { - case "", ChainArbitrum, ChainCelo, ChainGnosis, ChainKroma, ChainMetis, ChainOptimismBedrock, ChainScroll, ChainWeMix, ChainXDai, ChainZkSync: + case "", ChainArbitrum, ChainCelo, ChainGnosis, ChainKroma, ChainMetis, ChainOptimismBedrock, ChainScroll, ChainWeMix, ChainXDai, ChainXLayer, ChainZkSync: return true } return false diff --git a/core/chains/evm/config/toml/defaults/XLayer_Mainnet.toml b/core/chains/evm/config/toml/defaults/XLayer_Mainnet.toml new file mode 100644 index 00000000000..4096a4db244 --- /dev/null +++ b/core/chains/evm/config/toml/defaults/XLayer_Mainnet.toml @@ -0,0 +1,25 @@ +ChainID = '196' +ChainType = 'xlayer' +FinalityDepth = 500 +NoNewHeadsThreshold = '6m' +MinIncomingConfirmations = 1 +LogPollInterval = '30s' +RPCBlockQueryDelay = 15 +RPCDefaultBatchSize = 100 + +[OCR] +ContractConfirmations = 1 + +[Transactions] +ResendAfterThreshold = '3m' + +[GasEstimator] +PriceMin = '100 mwei' +BumpPercent = 40 +BumpMin = '100 mwei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 12 + +[HeadTracker] +HistoryDepth = 2000 diff --git a/core/chains/evm/config/toml/defaults/XLayer_Sepolia.toml b/core/chains/evm/config/toml/defaults/XLayer_Sepolia.toml new file mode 100644 index 00000000000..62e2c1e8ad0 --- /dev/null +++ b/core/chains/evm/config/toml/defaults/XLayer_Sepolia.toml @@ -0,0 +1,25 @@ +ChainID = '195' +ChainType = 'xlayer' +FinalityDepth = 500 +NoNewHeadsThreshold = '12m' +MinIncomingConfirmations = 1 +LogPollInterval = '30s' +RPCBlockQueryDelay = 15 +RPCDefaultBatchSize = 100 + +[OCR] +ContractConfirmations = 1 + +[Transactions] +ResendAfterThreshold = '3m' + +[GasEstimator] +PriceMin = '1 mwei' +BumpPercent = 40 +BumpMin = '20 mwei' + +[GasEstimator.BlockHistory] +BlockHistorySize = 12 + +[HeadTracker] +HistoryDepth = 2000 diff --git a/core/chains/evm/gas/block_history_estimator_test.go b/core/chains/evm/gas/block_history_estimator_test.go index 941b60545ba..43f42c69203 100644 --- a/core/chains/evm/gas/block_history_estimator_test.go +++ b/core/chains/evm/gas/block_history_estimator_test.go @@ -997,6 +997,11 @@ func TestBlockHistoryEstimator_Recalculate_NoEIP1559(t *testing.T) { cfg.ChainTypeF = string(config.ChainXDai) bhe.Recalculate(cltest.Head(0)) require.Equal(t, assets.NewWeiI(80), gas.GetGasPrice(bhe)) + + // And for X Layer + cfg.ChainTypeF = string(config.ChainXLayer) + bhe.Recalculate(cltest.Head(0)) + require.Equal(t, assets.NewWeiI(80), gas.GetGasPrice(bhe)) }) t.Run("handles unreasonably large gas prices (larger than a 64 bit int can hold)", func(t *testing.T) { diff --git a/core/chains/evm/gas/chain_specific.go b/core/chains/evm/gas/chain_specific.go index c64441cc142..694411f164b 100644 --- a/core/chains/evm/gas/chain_specific.go +++ b/core/chains/evm/gas/chain_specific.go @@ -9,9 +9,9 @@ import ( // chainSpecificIsUsable allows for additional logic specific to a particular // Config that determines whether a transaction should be used for gas estimation func chainSpecificIsUsable(tx evmtypes.Transaction, baseFee *assets.Wei, chainType config.ChainType, minGasPriceWei *assets.Wei) bool { - if chainType == config.ChainGnosis || chainType == config.ChainXDai { + if chainType == config.ChainGnosis || chainType == config.ChainXDai || chainType == config.ChainXLayer { // GasPrice 0 on most chains is great since it indicates cheap/free transactions. - // However, Gnosis reserves a special type of "bridge" transaction with 0 gas + // However, Gnosis and XLayer reserve a special type of "bridge" transaction with 0 gas // price that is always processed at top priority. Ordinary transactions // must be priced at least 1GWei, so we have to discard anything priced // below that (unless the contract is whitelisted). diff --git a/core/config/docs/chains-evm.toml b/core/config/docs/chains-evm.toml index 49c42bc04fb..49360caad21 100644 --- a/core/config/docs/chains-evm.toml +++ b/core/config/docs/chains-evm.toml @@ -14,7 +14,7 @@ BlockBackfillDepth = 10 # Default # BlockBackfillSkip enables skipping of very long backfills. BlockBackfillSkip = false # Default # ChainType is automatically detected from chain ID. Set this to force a certain chain type regardless of chain ID. -# Available types: `arbitrum`, `celo`, `gnosis`, `kroma`, `metis`, `optimismBedrock`, `scroll`, `wemix`, `zksync` +# Available types: `arbitrum`, `celo`, `gnosis`, `kroma`, `metis`, `optimismBedrock`, `scroll`, `wemix`, `xlayer`, `zksync` # # `xdai` has been deprecated and will be removed in v2.13.0, use `gnosis` instead. ChainType = 'arbitrum' # Example diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go index 0d40697345d..11d286fbcd5 100644 --- a/core/services/chainlink/config_test.go +++ b/core/services/chainlink/config_test.go @@ -1264,7 +1264,7 @@ func TestConfig_Validate(t *testing.T) { - 1: 6 errors: - ChainType: invalid value (Foo): must not be set with this chain id - Nodes: missing: must have at least one node - - ChainType: invalid value (Foo): must be one of arbitrum, celo, gnosis, kroma, metis, optimismBedrock, scroll, wemix, zksync or omitted + - ChainType: invalid value (Foo): must be one of arbitrum, celo, gnosis, kroma, metis, optimismBedrock, scroll, wemix, xlayer, zksync or omitted - HeadTracker.HistoryDepth: invalid value (30): must be equal to or greater than FinalityDepth - GasEstimator: 2 errors: - FeeCapDefault: invalid value (101 wei): must be equal to PriceMax (99 wei) since you are using FixedPrice estimation with gas bumping disabled in EIP1559 mode - PriceMax will be used as the FeeCap for transactions instead of FeeCapDefault @@ -1273,7 +1273,7 @@ func TestConfig_Validate(t *testing.T) { - 2: 5 errors: - ChainType: invalid value (Arbitrum): only "optimismBedrock" can be used with this chain id - Nodes: missing: must have at least one node - - ChainType: invalid value (Arbitrum): must be one of arbitrum, celo, gnosis, kroma, metis, optimismBedrock, scroll, wemix, zksync or omitted + - ChainType: invalid value (Arbitrum): must be one of arbitrum, celo, gnosis, kroma, metis, optimismBedrock, scroll, wemix, xlayer, zksync or omitted - FinalityDepth: invalid value (0): must be greater than or equal to 1 - MinIncomingConfirmations: invalid value (0): must be greater than or equal to 1 - 3.Nodes: 5 errors: diff --git a/core/services/ocr/contract_tracker.go b/core/services/ocr/contract_tracker.go index f7c7a9940b5..1d9076b8322 100644 --- a/core/services/ocr/contract_tracker.go +++ b/core/services/ocr/contract_tracker.go @@ -400,7 +400,7 @@ func (t *OCRContractTracker) LatestBlockHeight(ctx context.Context) (blockheight // care about the block height; we have no way of getting the L1 block // height anyway return 0, nil - case "", config.ChainArbitrum, config.ChainCelo, config.ChainGnosis, config.ChainKroma, config.ChainOptimismBedrock, config.ChainScroll, config.ChainWeMix, config.ChainXDai, config.ChainZkSync: + case "", config.ChainArbitrum, config.ChainCelo, config.ChainGnosis, config.ChainKroma, config.ChainOptimismBedrock, config.ChainScroll, config.ChainWeMix, config.ChainXDai, config.ChainXLayer, config.ChainZkSync: // continue } latestBlockHeight := t.getLatestBlockHeight() diff --git a/core/services/ocrcommon/block_translator.go b/core/services/ocrcommon/block_translator.go index bc7242a6019..6ef64499fa9 100644 --- a/core/services/ocrcommon/block_translator.go +++ b/core/services/ocrcommon/block_translator.go @@ -21,7 +21,7 @@ func NewBlockTranslator(cfg Config, client evmclient.Client, lggr logger.Logger) switch cfg.ChainType() { case config.ChainArbitrum: return NewArbitrumBlockTranslator(client, lggr) - case "", config.ChainCelo, config.ChainGnosis, config.ChainKroma, config.ChainMetis, config.ChainOptimismBedrock, config.ChainScroll, config.ChainWeMix, config.ChainXDai, config.ChainZkSync: + case "", config.ChainCelo, config.ChainGnosis, config.ChainKroma, config.ChainMetis, config.ChainOptimismBedrock, config.ChainScroll, config.ChainWeMix, config.ChainXDai, config.ChainXLayer, config.ChainZkSync: fallthrough default: return &l1BlockTranslator{} diff --git a/docs/CONFIG.md b/docs/CONFIG.md index f93d990413f..61ba9256d9d 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -3005,6 +3005,176 @@ GasLimit = 5400000

+
XLayer Sepolia (195)

+ +```toml +AutoCreateKey = true +BlockBackfillDepth = 10 +BlockBackfillSkip = false +ChainType = 'xlayer' +FinalityDepth = 500 +FinalityTagEnabled = false +LogBackfillBatchSize = 1000 +LogPollInterval = '30s' +LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 +BackupLogPollerBlockDelay = 100 +MinIncomingConfirmations = 1 +MinContractPayment = '0.00001 link' +NonceAutoSync = true +NoNewHeadsThreshold = '12m0s' +RPCDefaultBatchSize = 100 +RPCBlockQueryDelay = 15 + +[Transactions] +ForwardersEnabled = false +MaxInFlight = 16 +MaxQueued = 250 +ReaperInterval = '1h0m0s' +ReaperThreshold = '168h0m0s' +ResendAfterThreshold = '3m0s' + +[BalanceMonitor] +Enabled = true + +[GasEstimator] +Mode = 'BlockHistory' +PriceDefault = '20 gwei' +PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' +PriceMin = '1 mwei' +LimitDefault = 500000 +LimitMax = 500000 +LimitMultiplier = '1' +LimitTransfer = 21000 +BumpMin = '20 mwei' +BumpPercent = 40 +BumpThreshold = 3 +EIP1559DynamicFees = false +FeeCapDefault = '100 gwei' +TipCapDefault = '1 wei' +TipCapMin = '1 wei' + +[GasEstimator.BlockHistory] +BatchSize = 25 +BlockHistorySize = 12 +CheckInclusionBlocks = 12 +CheckInclusionPercentile = 90 +TransactionPercentile = 60 + +[HeadTracker] +HistoryDepth = 2000 +MaxBufferSize = 3 +SamplingInterval = '1s' + +[NodePool] +PollFailureThreshold = 5 +PollInterval = '10s' +SelectionMode = 'HighestHead' +SyncThreshold = 5 +LeaseDuration = '0s' +NodeIsSyncingEnabled = false +FinalizedBlockPollInterval = '5s' + +[OCR] +ContractConfirmations = 1 +ContractTransmitterTransmitTimeout = '10s' +DatabaseTimeout = '10s' +DeltaCOverride = '168h0m0s' +DeltaCJitterOverride = '1h0m0s' +ObservationGracePeriod = '1s' + +[OCR2] +[OCR2.Automation] +GasLimit = 5400000 +``` + +

+ +
XLayer Mainnet (196)

+ +```toml +AutoCreateKey = true +BlockBackfillDepth = 10 +BlockBackfillSkip = false +ChainType = 'xlayer' +FinalityDepth = 500 +FinalityTagEnabled = false +LogBackfillBatchSize = 1000 +LogPollInterval = '30s' +LogKeepBlocksDepth = 100000 +LogPrunePageSize = 0 +BackupLogPollerBlockDelay = 100 +MinIncomingConfirmations = 1 +MinContractPayment = '0.00001 link' +NonceAutoSync = true +NoNewHeadsThreshold = '6m0s' +RPCDefaultBatchSize = 100 +RPCBlockQueryDelay = 15 + +[Transactions] +ForwardersEnabled = false +MaxInFlight = 16 +MaxQueued = 250 +ReaperInterval = '1h0m0s' +ReaperThreshold = '168h0m0s' +ResendAfterThreshold = '3m0s' + +[BalanceMonitor] +Enabled = true + +[GasEstimator] +Mode = 'BlockHistory' +PriceDefault = '20 gwei' +PriceMax = '115792089237316195423570985008687907853269984665.640564039457584007913129639935 tether' +PriceMin = '100 mwei' +LimitDefault = 500000 +LimitMax = 500000 +LimitMultiplier = '1' +LimitTransfer = 21000 +BumpMin = '100 mwei' +BumpPercent = 40 +BumpThreshold = 3 +EIP1559DynamicFees = false +FeeCapDefault = '100 gwei' +TipCapDefault = '1 wei' +TipCapMin = '1 wei' + +[GasEstimator.BlockHistory] +BatchSize = 25 +BlockHistorySize = 12 +CheckInclusionBlocks = 12 +CheckInclusionPercentile = 90 +TransactionPercentile = 60 + +[HeadTracker] +HistoryDepth = 2000 +MaxBufferSize = 3 +SamplingInterval = '1s' + +[NodePool] +PollFailureThreshold = 5 +PollInterval = '10s' +SelectionMode = 'HighestHead' +SyncThreshold = 5 +LeaseDuration = '0s' +NodeIsSyncingEnabled = false +FinalizedBlockPollInterval = '5s' + +[OCR] +ContractConfirmations = 1 +ContractTransmitterTransmitTimeout = '10s' +DatabaseTimeout = '10s' +DeltaCOverride = '168h0m0s' +DeltaCJitterOverride = '1h0m0s' +ObservationGracePeriod = '1s' + +[OCR2] +[OCR2.Automation] +GasLimit = 5400000 +``` + +

+
Fantom Mainnet (250)

```toml @@ -6606,7 +6776,7 @@ BlockBackfillSkip enables skipping of very long backfills. ChainType = 'arbitrum' # Example ``` ChainType is automatically detected from chain ID. Set this to force a certain chain type regardless of chain ID. -Available types: `arbitrum`, `celo`, `gnosis`, `kroma`, `metis`, `optimismBedrock`, `scroll`, `wemix`, `zksync` +Available types: `arbitrum`, `celo`, `gnosis`, `kroma`, `metis`, `optimismBedrock`, `scroll`, `wemix`, `xlayer`, `zksync` `xdai` has been deprecated and will be removed in v2.13.0, use `gnosis` instead. From 55545bb1514dfcb83d103b3801ba5b8327252a1b Mon Sep 17 00:00:00 2001 From: Tate Date: Tue, 30 Apr 2024 15:58:17 -0600 Subject: [PATCH 70/77] Add job name to be required by golangci-lint action to fix metrics (#13054) --- .github/actions/golangci-lint/action.yml | 2 +- .github/workflows/ci-core.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/actions/golangci-lint/action.yml b/.github/actions/golangci-lint/action.yml index e52dd1aed7b..e667ade16eb 100644 --- a/.github/actions/golangci-lint/action.yml +++ b/.github/actions/golangci-lint/action.yml @@ -7,7 +7,7 @@ inputs: required: true name: description: Name of the lint action - default: lint + required: true go-directory: description: Go directory to run commands from default: "." diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index e1891770930..fbef1b8282c 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -64,6 +64,7 @@ jobs: if: ${{ needs.filter.outputs.changes == 'true' }} with: id: core + name: lint gc-basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} gc-host: ${{ secrets.GRAFANA_INTERNAL_HOST }} gc-org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} From ea08b5f08d84d2ff1ddfa2027660ff58a60219c3 Mon Sep 17 00:00:00 2001 From: HenryNguyen5 <6404866+HenryNguyen5@users.noreply.github.com> Date: Tue, 30 Apr 2024 21:05:34 -0400 Subject: [PATCH 71/77] Fix some txdb comment typos (#13059) --- .changeset/spotty-cooks-think.md | 5 +++++ core/internal/testutils/pgtest/txdb.go | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 .changeset/spotty-cooks-think.md diff --git a/.changeset/spotty-cooks-think.md b/.changeset/spotty-cooks-think.md new file mode 100644 index 00000000000..e645de27beb --- /dev/null +++ b/.changeset/spotty-cooks-think.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal fix txdb documentation typos diff --git a/core/internal/testutils/pgtest/txdb.go b/core/internal/testutils/pgtest/txdb.go index da9fd6cb2d0..f4640946ad4 100644 --- a/core/internal/testutils/pgtest/txdb.go +++ b/core/internal/testutils/pgtest/txdb.go @@ -74,8 +74,8 @@ var _ driver.Conn = &conn{} var _ driver.Validator = &conn{} var _ driver.SessionResetter = &conn{} -// txDriver is an sql driver which runs on single transaction -// when the Close is called, transaction is rolled back +// txDriver is an sql driver which runs on a single transaction. +// When `Close` is called, transaction is rolled back. type txDriver struct { sync.Mutex db *sql.DB @@ -110,8 +110,8 @@ func (d *txDriver) Open(dsn string) (driver.Conn, error) { return c, nil } -// deleteConn is called by connection when it is closed -// It also auto-closes the DB when the last checked out connection is closed +// deleteConn is called by a connection when it is closed via the `close` method. +// It also auto-closes the DB when the last checked out connection is closed. func (d *txDriver) deleteConn(c *conn) error { // must lock here to avoid racing with Open d.Lock() From 2805fa6c9b469d535edcd3d66c08e1d22bbaa2d0 Mon Sep 17 00:00:00 2001 From: Christopher Dimitri Sastropranoto Date: Wed, 1 May 2024 22:41:46 +0700 Subject: [PATCH 72/77] Implement addNodes and getNode (#13022) * implement add node * Fix the test * Use p2pId for node identification. * Revert if node exists * supportedCapabilityIds string[] => bytes32[] * Revert when adding node without capabilities * Verify that supported capabilities exist in the registry * Create a variable for a non-existent capability. * Undo a change * Add p2pId to the event * Remove redundant comment * Regen wrappers * Switch to using bytes32 instead of bytes for p2pId * Add a comment about allowing deprecated capabilities * Add signer address to Node * Move checks around * Regen wrappers --------- Co-authored-by: DeividasK --- .changeset/thirty-students-explain.md | 5 + contracts/.changeset/tidy-stingrays-care.md | 5 + .../src/v0.8/keystone/CapabilityRegistry.sol | 67 ++++++- .../src/v0.8/keystone/test/BaseTest.t.sol | 14 +- .../CapabilityRegistry_AddNodesTest.t.sol | 136 +++++++++++++ ...pabilityRegistry_DeprecateCapability.t.sol | 8 +- .../src/v0.8/keystone/test/Constants.t.sol | 4 + .../keystone_capability_registry.go | 179 +++++++++++++++++- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 9 files changed, 411 insertions(+), 9 deletions(-) create mode 100644 .changeset/thirty-students-explain.md create mode 100644 contracts/.changeset/tidy-stingrays-care.md create mode 100644 contracts/src/v0.8/keystone/test/CapabilityRegistry_AddNodesTest.t.sol diff --git a/.changeset/thirty-students-explain.md b/.changeset/thirty-students-explain.md new file mode 100644 index 00000000000..0408383bd03 --- /dev/null +++ b/.changeset/thirty-students-explain.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal diff --git a/contracts/.changeset/tidy-stingrays-care.md b/contracts/.changeset/tidy-stingrays-care.md new file mode 100644 index 00000000000..9d376e40c05 --- /dev/null +++ b/contracts/.changeset/tidy-stingrays-care.md @@ -0,0 +1,5 @@ +--- +"@chainlink/contracts": patch +--- + +#internal diff --git a/contracts/src/v0.8/keystone/CapabilityRegistry.sol b/contracts/src/v0.8/keystone/CapabilityRegistry.sol index 9d627c2afb5..ed3a300ac40 100644 --- a/contracts/src/v0.8/keystone/CapabilityRegistry.sol +++ b/contracts/src/v0.8/keystone/CapabilityRegistry.sol @@ -19,6 +19,21 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { string name; } + struct Node { + /// @notice The id of the node operator that manages this node + uint256 nodeOperatorId; + /// @notice This is an Ed25519 public key that is used to identify a node. + /// This key is guaranteed to be unique in the CapabilityRegistry. It is + /// used to identify a node in the the P2P network. + bytes32 p2pId; + /// @notice The signer address for application-layer message verification. + address signer; + /// @notice The list of capability IDs this node supports. This list is + /// never empty and all capabilities are guaranteed to exist in the + /// CapabilityRegistry. + bytes32[] supportedCapabilityIds; + } + // CapabilityResponseType indicates whether remote response requires // aggregation or is an already aggregated report. There are multiple // possible ways to aggregate. @@ -70,6 +85,21 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { /// admin address to the zero address error InvalidNodeOperatorAdmin(); + /// @notice This error is thrown when trying to add a node with P2P ID that + /// is empty bytes or a duplicate. + /// @param p2pId The provided P2P ID + error InvalidNodeP2PId(bytes32 p2pId); + + /// @notice This error is thrown when trying to add a node without + /// capabilities or with capabilities that do not exist. + /// @param capabilityIds The IDs of the capabilities that are being added. + error InvalidNodeCapabilities(bytes32[] capabilityIds); + + /// @notice This event is emitted when a new node is added + /// @param p2pId The P2P ID of the node + /// @param nodeOperatorId The ID of the node operator that manages this node + event NodeAdded(bytes32 p2pId, uint256 nodeOperatorId); + /// @notice This error is thrown when trying add a capability that already /// exists. error CapabilityAlreadyExists(); @@ -120,7 +150,10 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { EnumerableSet.Bytes32Set private s_deprecatedCapabilityIds; /// @notice Mapping of node operators - mapping(uint256 nodeOperatorId => NodeOperator) private s_nodeOperators; + mapping(uint256 nodeOperatorId => NodeOperator nodeOperator) private s_nodeOperators; + + /// @notice Mapping of nodes + mapping(bytes32 p2pId => Node node) private s_nodes; /// @notice The latest node operator ID /// @dev No getter for this as this is an implementation detail @@ -184,6 +217,38 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { return s_nodeOperators[nodeOperatorId]; } + /// @notice Adds nodes. Nodes can be added with deprecated capabilities to + /// avoid breaking changes when deprecating capabilities. + /// @param nodes The nodes to add + function addNodes(Node[] calldata nodes) external { + for (uint256 i; i < nodes.length; ++i) { + Node memory node = nodes[i]; + + NodeOperator memory nodeOperator = s_nodeOperators[node.nodeOperatorId]; + if (msg.sender != nodeOperator.admin) revert AccessForbidden(); + + bool nodeExists = s_nodes[node.p2pId].supportedCapabilityIds.length > 0; + if (nodeExists || bytes32(node.p2pId) == bytes32("")) revert InvalidNodeP2PId(node.p2pId); + + if (node.supportedCapabilityIds.length == 0) revert InvalidNodeCapabilities(node.supportedCapabilityIds); + + for (uint256 j; j < node.supportedCapabilityIds.length; ++j) { + if (!s_capabilityIds.contains(node.supportedCapabilityIds[j])) + revert InvalidNodeCapabilities(node.supportedCapabilityIds); + } + + s_nodes[node.p2pId] = node; + emit NodeAdded(node.p2pId, node.nodeOperatorId); + } + } + + /// @notice Gets a node's data + /// @param p2pId The P2P ID of the node to query for + /// @return Node The node data + function getNode(bytes32 p2pId) external view returns (Node memory) { + return s_nodes[p2pId]; + } + function addCapability(Capability calldata capability) external onlyOwner { bytes32 capabilityId = getCapabilityID(capability.capabilityType, capability.version); diff --git a/contracts/src/v0.8/keystone/test/BaseTest.t.sol b/contracts/src/v0.8/keystone/test/BaseTest.t.sol index a2b1b3a53eb..95c8d1e5d3d 100644 --- a/contracts/src/v0.8/keystone/test/BaseTest.t.sol +++ b/contracts/src/v0.8/keystone/test/BaseTest.t.sol @@ -11,6 +11,9 @@ contract BaseTest is Test, Constants { CapabilityConfigurationContract internal s_capabilityConfigurationContract; CapabilityRegistry.Capability internal s_basicCapability; CapabilityRegistry.Capability internal s_capabilityWithConfigurationContract; + bytes32 internal s_basicCapabilityId; + bytes32 internal s_capabilityWithConfigurationContractId; + bytes32 internal s_nonExistentCapabilityId; function setUp() public virtual { vm.startPrank(ADMIN); @@ -23,13 +26,22 @@ contract BaseTest is Test, Constants { responseType: CapabilityRegistry.CapabilityResponseType.REPORT, configurationContract: address(0) }); - s_capabilityWithConfigurationContract = CapabilityRegistry.Capability({ capabilityType: "read-ethereum-mainnet-gas-price", version: "1.0.2", responseType: CapabilityRegistry.CapabilityResponseType.OBSERVATION_IDENTICAL, configurationContract: address(s_capabilityConfigurationContract) }); + + s_basicCapabilityId = s_capabilityRegistry.getCapabilityID( + s_basicCapability.capabilityType, + s_basicCapability.version + ); + s_capabilityWithConfigurationContractId = s_capabilityRegistry.getCapabilityID( + s_capabilityWithConfigurationContract.capabilityType, + s_capabilityWithConfigurationContract.version + ); + s_nonExistentCapabilityId = s_capabilityRegistry.getCapabilityID("non-existent-capability", "1.0.0"); } function _getNodeOperators() internal view returns (CapabilityRegistry.NodeOperator[] memory) { diff --git a/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddNodesTest.t.sol b/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddNodesTest.t.sol new file mode 100644 index 00000000000..fe85c144eea --- /dev/null +++ b/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddNodesTest.t.sol @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {BaseTest} from "./BaseTest.t.sol"; +import {CapabilityRegistry} from "../CapabilityRegistry.sol"; + +contract CapabilityRegistry_AddNodesTest is BaseTest { + event NodeAdded(bytes32 p2pId, uint256 nodeOperatorId); + + uint256 private constant TEST_NODE_OPERATOR_ONE_ID = 0; + uint256 private constant TEST_NODE_OPERATOR_TWO_ID = 1; + + function setUp() public override { + BaseTest.setUp(); + changePrank(ADMIN); + s_capabilityRegistry.addNodeOperators(_getNodeOperators()); + s_capabilityRegistry.addCapability(s_basicCapability); + s_capabilityRegistry.addCapability(s_capabilityWithConfigurationContract); + } + + function test_RevertWhen_CalledByNonNodeOperatorAdmin() public { + changePrank(STRANGER); + CapabilityRegistry.Node[] memory nodes = new CapabilityRegistry.Node[](1); + + bytes32[] memory capabilityIds = new bytes32[](1); + capabilityIds[0] = s_basicCapabilityId; + + nodes[0] = CapabilityRegistry.Node({ + nodeOperatorId: TEST_NODE_OPERATOR_ONE_ID, + p2pId: P2P_ID, + signer: NODE_OPERATOR_ONE_SIGNER_ADDRESS, + supportedCapabilityIds: capabilityIds + }); + + vm.expectRevert(CapabilityRegistry.AccessForbidden.selector); + s_capabilityRegistry.addNodes(nodes); + } + + function test_RevertWhen_AddingDuplicateP2PId() public { + changePrank(NODE_OPERATOR_ONE_ADMIN); + CapabilityRegistry.Node[] memory nodes = new CapabilityRegistry.Node[](1); + + bytes32[] memory capabilityIds = new bytes32[](1); + capabilityIds[0] = s_basicCapabilityId; + + nodes[0] = CapabilityRegistry.Node({ + nodeOperatorId: TEST_NODE_OPERATOR_ONE_ID, + p2pId: P2P_ID, + signer: NODE_OPERATOR_ONE_SIGNER_ADDRESS, + supportedCapabilityIds: capabilityIds + }); + s_capabilityRegistry.addNodes(nodes); + + vm.expectRevert(abi.encodeWithSelector(CapabilityRegistry.InvalidNodeP2PId.selector, P2P_ID)); + s_capabilityRegistry.addNodes(nodes); + } + + function test_RevertWhen_P2PIDEmpty() public { + changePrank(NODE_OPERATOR_ONE_ADMIN); + CapabilityRegistry.Node[] memory nodes = new CapabilityRegistry.Node[](1); + + bytes32[] memory capabilityIds = new bytes32[](1); + capabilityIds[0] = s_basicCapabilityId; + + nodes[0] = CapabilityRegistry.Node({ + nodeOperatorId: TEST_NODE_OPERATOR_ONE_ID, + p2pId: bytes32(""), + signer: NODE_OPERATOR_ONE_SIGNER_ADDRESS, + supportedCapabilityIds: capabilityIds + }); + + vm.expectRevert(abi.encodeWithSelector(CapabilityRegistry.InvalidNodeP2PId.selector, bytes32(""))); + s_capabilityRegistry.addNodes(nodes); + } + + function test_RevertWhen_AddingNodeWithoutCapabilities() public { + changePrank(NODE_OPERATOR_ONE_ADMIN); + CapabilityRegistry.Node[] memory nodes = new CapabilityRegistry.Node[](1); + + bytes32[] memory capabilityIds = new bytes32[](0); + + nodes[0] = CapabilityRegistry.Node({ + nodeOperatorId: TEST_NODE_OPERATOR_ONE_ID, + p2pId: P2P_ID, + signer: NODE_OPERATOR_ONE_SIGNER_ADDRESS, + supportedCapabilityIds: capabilityIds + }); + vm.expectRevert(abi.encodeWithSelector(CapabilityRegistry.InvalidNodeCapabilities.selector, capabilityIds)); + s_capabilityRegistry.addNodes(nodes); + } + + function test_RevertWhen_AddingNodeWithInvalidCapability() public { + changePrank(NODE_OPERATOR_ONE_ADMIN); + CapabilityRegistry.Node[] memory nodes = new CapabilityRegistry.Node[](1); + + bytes32[] memory capabilityIds = new bytes32[](1); + capabilityIds[0] = s_nonExistentCapabilityId; + + nodes[0] = CapabilityRegistry.Node({ + nodeOperatorId: TEST_NODE_OPERATOR_ONE_ID, + p2pId: P2P_ID, + signer: NODE_OPERATOR_ONE_SIGNER_ADDRESS, + supportedCapabilityIds: capabilityIds + }); + + vm.expectRevert(abi.encodeWithSelector(CapabilityRegistry.InvalidNodeCapabilities.selector, capabilityIds)); + s_capabilityRegistry.addNodes(nodes); + } + + function test_AddsNode() public { + changePrank(NODE_OPERATOR_ONE_ADMIN); + + CapabilityRegistry.Node[] memory nodes = new CapabilityRegistry.Node[](1); + bytes32[] memory capabilityIds = new bytes32[](2); + capabilityIds[0] = s_basicCapabilityId; + capabilityIds[1] = s_capabilityWithConfigurationContractId; + + nodes[0] = CapabilityRegistry.Node({ + nodeOperatorId: TEST_NODE_OPERATOR_ONE_ID, + p2pId: P2P_ID, + signer: NODE_OPERATOR_ONE_SIGNER_ADDRESS, + supportedCapabilityIds: capabilityIds + }); + + vm.expectEmit(address(s_capabilityRegistry)); + emit NodeAdded(P2P_ID, TEST_NODE_OPERATOR_ONE_ID); + s_capabilityRegistry.addNodes(nodes); + + CapabilityRegistry.Node memory node = s_capabilityRegistry.getNode(P2P_ID); + assertEq(node.nodeOperatorId, TEST_NODE_OPERATOR_ONE_ID); + assertEq(node.p2pId, P2P_ID); + assertEq(node.supportedCapabilityIds.length, 2); + assertEq(node.supportedCapabilityIds[0], s_basicCapabilityId); + assertEq(node.supportedCapabilityIds[1], s_capabilityWithConfigurationContractId); + } +} diff --git a/contracts/src/v0.8/keystone/test/CapabilityRegistry_DeprecateCapability.t.sol b/contracts/src/v0.8/keystone/test/CapabilityRegistry_DeprecateCapability.t.sol index ceefdf431cf..2e64ab7411f 100644 --- a/contracts/src/v0.8/keystone/test/CapabilityRegistry_DeprecateCapability.t.sol +++ b/contracts/src/v0.8/keystone/test/CapabilityRegistry_DeprecateCapability.t.sol @@ -27,10 +27,10 @@ contract CapabilityRegistry_AddCapabilityTest is BaseTest { } function test_RevertWhen_CapabilityDoesNotExist() public { - bytes32 capabilityId = s_capabilityRegistry.getCapabilityID("non-existent-capability", "1.0.0"); - - vm.expectRevert(abi.encodeWithSelector(CapabilityRegistry.CapabilityDoesNotExist.selector, capabilityId)); - s_capabilityRegistry.deprecateCapability(capabilityId); + vm.expectRevert( + abi.encodeWithSelector(CapabilityRegistry.CapabilityDoesNotExist.selector, s_nonExistentCapabilityId) + ); + s_capabilityRegistry.deprecateCapability(s_nonExistentCapabilityId); } function test_RevertWhen_CapabilityAlreadyDeprecated() public { diff --git a/contracts/src/v0.8/keystone/test/Constants.t.sol b/contracts/src/v0.8/keystone/test/Constants.t.sol index 6f0b7ef43f3..0ef99f4f477 100644 --- a/contracts/src/v0.8/keystone/test/Constants.t.sol +++ b/contracts/src/v0.8/keystone/test/Constants.t.sol @@ -6,6 +6,10 @@ contract Constants { address internal STRANGER = address(2); address internal NODE_OPERATOR_ONE_ADMIN = address(3); string internal NODE_OPERATOR_ONE_NAME = "node-operator-one"; + address internal NODE_OPERATOR_ONE_SIGNER_ADDRESS = address(3333); address internal NODE_OPERATOR_TWO_ADMIN = address(4); string internal NODE_OPERATOR_TWO_NAME = "node-operator-two"; + address internal NODE_OPERATOR_TWO_SIGNER_ADDRESS = address(4444); + + bytes32 internal P2P_ID = hex"e42415859707d90ed4dc534ad730f187a17b0c368e1beec2e9b995587c4b0a05"; } diff --git a/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go b/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go index 4bac3789a33..b54a101d44e 100644 --- a/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go +++ b/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go @@ -37,14 +37,21 @@ type CapabilityRegistryCapability struct { ConfigurationContract common.Address } +type CapabilityRegistryNode struct { + NodeOperatorId *big.Int + P2pId [32]byte + Signer common.Address + SupportedCapabilityIds [][32]byte +} + type CapabilityRegistryNodeOperator struct { Admin common.Address Name string } var CapabilityRegistryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAlreadyDeprecated\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CapabilityAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedConfigurationContract\",\"type\":\"address\"}],\"name\":\"InvalidCapabilityConfigurationContractInterface\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeOperatorAdmin\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"lengthOne\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lengthTwo\",\"type\":\"uint256\"}],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDeprecated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"NodeOperatorRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"capability\",\"type\":\"tuple\"}],\"name\":\"addCapability\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"addNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"deprecateCapability\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilities\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityID\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"name\":\"getCapabilityID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"getNodeOperator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"isCapabilityDeprecated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint256[]\"}],\"name\":\"removeNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"updateNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x608060405234801561001057600080fd5b5033806000816100675760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615610097576100978161009f565b505050610148565b336001600160a01b038216036100f75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161005e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611a7d80620001586000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806365c14dc71161008c5780639cb7c5f4116100665780639cb7c5f41461023c578063ae3c241c1461025c578063ddbe4f821461026f578063f2fde38b1461028457600080fd5b806365c14dc7146101ec57806379ba50971461020c5780638da5cb5b1461021457600080fd5b8063181f5a77116100c8578063181f5a771461013f5780631cdf63431461017e578063229111f514610191578063398f3773146101d957600080fd5b80630c5801e3146100ef578063117392ce146101045780631257001114610117575b600080fd5b6101026100fd36600461120e565b610297565b005b61010261011236600461127a565b6105a8565b61012a610125366004611292565b6107f3565b60405190151581526020015b60405180910390f35b604080518082018252601881527f4361706162696c697479526567697374727920312e302e30000000000000000060208201529051610136919061130f565b61010261018c366004611322565b610806565b6101cb61019f366004611364565b604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b604051908152602001610136565b6101026101e7366004611322565b6108c9565b6101ff6101fa366004611292565b610a62565b6040516101369190611386565b610102610b48565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610136565b61024f61024a366004611292565b610c45565b6040516101369190611468565b61010261026a366004611292565b610cef565b610277610dba565b6040516101369190611476565b6101026102923660046114e6565b610eff565b8281146102df576040517fab8b67c600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff16905b848110156105a057600086868381811061031757610317611503565b905060200201359050600085858481811061033457610334611503565b90506020028101906103469190611532565b61034f90611617565b805190915073ffffffffffffffffffffffffffffffffffffffff166103a0576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805173ffffffffffffffffffffffffffffffffffffffff1633148015906103dd57503373ffffffffffffffffffffffffffffffffffffffff851614155b15610414576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160008381526007602052604090205473ffffffffffffffffffffffffffffffffffffffff90811691161415806104c6575060208082015160405161045a920161130f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206000868152600783529290922091926104ad926001019101611730565b6040516020818303038152906040528051906020012014155b1561058d578051600083815260076020908152604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909316929092178255820151600190910190610533908261181f565b50806000015173ffffffffffffffffffffffffffffffffffffffff167f14c8f513e8a6d86d2d16b0cb64976de4e72386c4f8068eca3b7354373f8fe97a838360200151604051610584929190611939565b60405180910390a25b50508061059990611981565b90506102fb565b505050505050565b6105b0610f13565b6040805182356020828101919091528084013582840152825180830384018152606090920190925280519101206105e8600382610f96565b1561061f576040517fe288638f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061063160808401606085016114e6565b73ffffffffffffffffffffffffffffffffffffffff161461079c5761065c60808301606084016114e6565b73ffffffffffffffffffffffffffffffffffffffff163b158061073c575061068a60808301606084016114e6565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f884efe6100000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff91909116906301ffc9a790602401602060405180830381865afa158015610716573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073a91906119b9565b155b1561079c5761075160808301606084016114e6565b6040517fabb5e3fd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016102d6565b6107a7600382610fb1565b50600081815260026020526040902082906107c282826119db565b505060405181907f65610e5677eedff94555572640e442f89848a109ef8593fa927ac30b2565ff0690600090a25050565b6000610800600583610f96565b92915050565b61080e610f13565b60005b818110156108c457600083838381811061082d5761082d611503565b60209081029290920135600081815260079093526040832080547fffffffffffffffffffffffff000000000000000000000000000000000000000016815590935091905061087e6001830182611174565b50506040518181527f1e5877d7b3001d1569bf733b76c7eceda58bd6c031e5b8d0b7042308ba2e9d4f9060200160405180910390a1506108bd81611981565b9050610811565b505050565b6108d1610f13565b60005b818110156108c45760008383838181106108f0576108f0611503565b90506020028101906109029190611532565b61090b90611617565b805190915073ffffffffffffffffffffffffffffffffffffffff1661095c576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600854604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815260008681526007909252939020825181547fffffffffffffffffffffffff0000000000000000000000000000000000000000169216919091178155915190919060018201906109df908261181f565b509050506008600081546109f290611981565b909155508151602083015160405173ffffffffffffffffffffffffffffffffffffffff909216917fda6697b182650034bd205cdc2dbfabb06bdb3a0a83a2b45bfefa3c4881284e0b91610a4791859190611939565b60405180910390a2505080610a5b90611981565b90506108d4565b6040805180820190915260008152606060208201526000828152600760209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff1683526001810180549192840191610abf906116e3565b80601f0160208091040260200160405190810160405280929190818152602001828054610aeb906116e3565b8015610b385780601f10610b0d57610100808354040283529160200191610b38565b820191906000526020600020905b815481529060010190602001808311610b1b57829003601f168201915b5050505050815250509050919050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610bc9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016102d6565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b604080516080808201835260008083526020808401829052838501829052606084018290528582526002808252918590208551938401865280548452600180820154928501929092529182015493949293919284019160ff1690811115610cae57610cae6113c9565b6001811115610cbf57610cbf6113c9565b815260029190910154610100900473ffffffffffffffffffffffffffffffffffffffff1660209091015292915050565b610cf7610f13565b610d02600382610f96565b610d3b576040517fe181733f000000000000000000000000000000000000000000000000000000008152600481018290526024016102d6565b610d46600582610f96565b15610d80576040517f16950d1d000000000000000000000000000000000000000000000000000000008152600481018290526024016102d6565b610d8b600582610fb1565b5060405181907fdcea1b78b6ddc31592a94607d537543fcaafda6cc52d6d5cc7bbfca1422baf2190600090a250565b60606000610dc86003610fbd565b90506000610dd66005610fca565b8251610de29190611a5d565b67ffffffffffffffff811115610dfa57610dfa611570565b604051908082528060200260200182016040528015610e6a57816020015b6040805160808101825260008082526020808301829052928201819052606082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181610e185790505b5090506000805b8351811015610ef6576000848281518110610e8e57610e8e611503565b60200260200101519050610eac816005610f9690919063ffffffff16565b610ee557610eb981610c45565b848481518110610ecb57610ecb611503565b60200260200101819052508280610ee190611981565b9350505b50610eef81611981565b9050610e71565b50909392505050565b610f07610f13565b610f1081610fd4565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610f94576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016102d6565b565b600081815260018301602052604081205415155b9392505050565b6000610faa83836110c9565b60606000610faa83611118565b6000610800825490565b3373ffffffffffffffffffffffffffffffffffffffff821603611053576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016102d6565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600081815260018301602052604081205461111057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610800565b506000610800565b60608160000180548060200260200160405190810160405280929190818152602001828054801561116857602002820191906000526020600020905b815481526020019060010190808311611154575b50505050509050919050565b508054611180906116e3565b6000825580601f10611190575050565b601f016020900490600052602060002090810190610f1091905b808211156111be57600081556001016111aa565b5090565b60008083601f8401126111d457600080fd5b50813567ffffffffffffffff8111156111ec57600080fd5b6020830191508360208260051b850101111561120757600080fd5b9250929050565b6000806000806040858703121561122457600080fd5b843567ffffffffffffffff8082111561123c57600080fd5b611248888389016111c2565b9096509450602087013591508082111561126157600080fd5b5061126e878288016111c2565b95989497509550505050565b60006080828403121561128c57600080fd5b50919050565b6000602082840312156112a457600080fd5b5035919050565b6000815180845260005b818110156112d1576020818501810151868301820152016112b5565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610faa60208301846112ab565b6000806020838503121561133557600080fd5b823567ffffffffffffffff81111561134c57600080fd5b611358858286016111c2565b90969095509350505050565b6000806040838503121561137757600080fd5b50508035926020909101359150565b6020815273ffffffffffffffffffffffffffffffffffffffff8251166020820152600060208301516040808401526113c160608401826112ab565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8051825260208101516020830152604081015160028110611442577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b604083015260609081015173ffffffffffffffffffffffffffffffffffffffff16910152565b6080810161080082846113f8565b6020808252825182820181905260009190848201906040850190845b818110156114b8576114a58385516113f8565b9284019260809290920191600101611492565b50909695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f1057600080fd5b6000602082840312156114f857600080fd5b8135610faa816114c4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc183360301811261156657600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156115c2576115c2611570565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561160f5761160f611570565b604052919050565b60006040823603121561162957600080fd5b61163161159f565b823561163c816114c4565b815260208381013567ffffffffffffffff8082111561165a57600080fd5b9085019036601f83011261166d57600080fd5b81358181111561167f5761167f611570565b6116af847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016115c8565b915080825236848285010111156116c557600080fd5b80848401858401376000908201840152918301919091525092915050565b600181811c908216806116f757607f821691505b60208210810361128c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000602080835260008454611744816116e3565b80848701526040600180841660008114611765576001811461179d576117cb565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a010195506117cb565b896000528660002060005b858110156117c35781548b82018601529083019088016117a8565b8a0184019650505b509398975050505050505050565b601f8211156108c457600081815260208120601f850160051c810160208610156118005750805b601f850160051c820191505b818110156105a05782815560010161180c565b815167ffffffffffffffff81111561183957611839611570565b61184d8161184784546116e3565b846117d9565b602080601f8311600181146118a0576000841561186a5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556105a0565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156118ed578886015182559484019460019091019084016118ce565b508582101561192957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b8281526040602082015260006113c160408301846112ab565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036119b2576119b2611952565b5060010190565b6000602082840312156119cb57600080fd5b81518015158114610faa57600080fd5b8135815560208201356001820155600281016040830135600281106119ff57600080fd5b81546060850135611a0f816114c4565b74ffffffffffffffffffffffffffffffffffffffff008160081b1660ff84167fffffffffffffffffffffff000000000000000000000000000000000000000000841617178455505050505050565b818103818111156108005761080061195256fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAlreadyDeprecated\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CapabilityAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedConfigurationContract\",\"type\":\"address\"}],\"name\":\"InvalidCapabilityConfigurationContractInterface\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"capabilityIds\",\"type\":\"bytes32[]\"}],\"name\":\"InvalidNodeCapabilities\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeOperatorAdmin\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"InvalidNodeP2PId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"lengthOne\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lengthTwo\",\"type\":\"uint256\"}],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDeprecated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"NodeAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"NodeOperatorRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"capability\",\"type\":\"tuple\"}],\"name\":\"addCapability\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"addNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"supportedCapabilityIds\",\"type\":\"bytes32[]\"}],\"internalType\":\"structCapabilityRegistry.Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"}],\"name\":\"addNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"deprecateCapability\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilities\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityID\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"name\":\"getCapabilityID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"getNode\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"supportedCapabilityIds\",\"type\":\"bytes32[]\"}],\"internalType\":\"structCapabilityRegistry.Node\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"getNodeOperator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"isCapabilityDeprecated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint256[]\"}],\"name\":\"removeNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"updateNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b503380600081620000695760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156200009c576200009c81620000a5565b50505062000150565b336001600160a01b03821603620000ff5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000060565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61214580620001606000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c806365c14dc711610097578063ae3c241c11610066578063ae3c241c14610292578063c2d483a1146102a5578063ddbe4f82146102b8578063f2fde38b146102cd57600080fd5b806365c14dc71461022257806379ba5097146102425780638da5cb5b1461024a5780639cb7c5f41461027257600080fd5b80631cdf6343116100d35780631cdf634314610194578063229111f5146101a7578063398f3773146101ef57806350c946fe1461020257600080fd5b80630c5801e314610105578063117392ce1461011a578063125700111461012d578063181f5a7714610155575b600080fd5b6101186101133660046116ec565b6102e0565b005b610118610128366004611758565b6105f1565b61014061013b366004611770565b61083c565b60405190151581526020015b60405180910390f35b604080518082018252601881527f4361706162696c697479526567697374727920312e302e3000000000000000006020820152905161014c91906117ed565b6101186101a2366004611800565b61084f565b6101e16101b5366004611842565b604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b60405190815260200161014c565b6101186101fd366004611800565b610912565b610215610210366004611770565b610aab565b60405161014c9190611864565b610235610230366004611770565b610b73565b60405161014c91906118ea565b610118610c50565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161014c565b610285610280366004611770565b610d4d565b60405161014c91906119cc565b6101186102a0366004611770565b610df7565b6101186102b3366004611800565b610ec2565b6102c061124c565b60405161014c91906119da565b6101186102db366004611a4a565b611391565b828114610328576040517fab8b67c600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff16905b848110156105e957600086868381811061036057610360611a67565b905060200201359050600085858481811061037d5761037d611a67565b905060200281019061038f9190611a96565b61039890611b9e565b805190915073ffffffffffffffffffffffffffffffffffffffff166103e9576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805173ffffffffffffffffffffffffffffffffffffffff16331480159061042657503373ffffffffffffffffffffffffffffffffffffffff851614155b1561045d576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160008381526007602052604090205473ffffffffffffffffffffffffffffffffffffffff908116911614158061050f57506020808201516040516104a392016117ed565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206000868152600783529290922091926104f6926001019101611cb7565b6040516020818303038152906040528051906020012014155b156105d6578051600083815260076020908152604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90931692909217825582015160019091019061057c9082611da6565b50806000015173ffffffffffffffffffffffffffffffffffffffff167f14c8f513e8a6d86d2d16b0cb64976de4e72386c4f8068eca3b7354373f8fe97a8383602001516040516105cd929190611ec0565b60405180910390a25b5050806105e290611f08565b9050610344565b505050505050565b6105f96113a5565b604080518235602082810191909152808401358284015282518083038401815260609092019092528051910120610631600382611428565b15610668576040517fe288638f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061067a6080840160608501611a4a565b73ffffffffffffffffffffffffffffffffffffffff16146107e5576106a56080830160608401611a4a565b73ffffffffffffffffffffffffffffffffffffffff163b158061078557506106d36080830160608401611a4a565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f884efe6100000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff91909116906301ffc9a790602401602060405180830381865afa15801561075f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107839190611f40565b155b156107e55761079a6080830160608401611a4a565b6040517fabb5e3fd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161031f565b6107f0600382611443565b506000818152600260205260409020829061080b8282611f62565b505060405181907f65610e5677eedff94555572640e442f89848a109ef8593fa927ac30b2565ff0690600090a25050565b6000610849600583611428565b92915050565b6108576113a5565b60005b8181101561090d57600083838381811061087657610876611a67565b60209081029290920135600081815260079093526040832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001681559093509190506108c76001830182611606565b50506040518181527f1e5877d7b3001d1569bf733b76c7eceda58bd6c031e5b8d0b7042308ba2e9d4f9060200160405180910390a15061090681611f08565b905061085a565b505050565b61091a6113a5565b60005b8181101561090d57600083838381811061093957610939611a67565b905060200281019061094b9190611a96565b61095490611b9e565b805190915073ffffffffffffffffffffffffffffffffffffffff166109a5576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600954604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815260008681526007909252939020825181547fffffffffffffffffffffffff000000000000000000000000000000000000000016921691909117815591519091906001820190610a289082611da6565b50905050600960008154610a3b90611f08565b909155508151602083015160405173ffffffffffffffffffffffffffffffffffffffff909216917fda6697b182650034bd205cdc2dbfabb06bdb3a0a83a2b45bfefa3c4881284e0b91610a9091859190611ec0565b60405180910390a2505080610aa490611f08565b905061091d565b6040805160808101825260008082526020820181905291810191909152606080820152600082815260086020908152604091829020825160808101845281548152600182015481840152600282015473ffffffffffffffffffffffffffffffffffffffff16818501526003820180548551818602810186019096528086529194929360608601939290830182828015610b6357602002820191906000526020600020905b815481526020019060010190808311610b4f575b5050505050815250509050919050565b6040805180820190915260008152606060208201526000828152600760209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff1683526001810180549192840191610bd090611c6a565b80601f0160208091040260200160405190810160405280929190818152602001828054610bfc90611c6a565b8015610b635780601f10610c1e57610100808354040283529160200191610b63565b820191906000526020600020905b815481529060010190602001808311610c2c57505050919092525091949350505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610cd1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161031f565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b604080516080808201835260008083526020808401829052838501829052606084018290528582526002808252918590208551938401865280548452600180820154928501929092529182015493949293919284019160ff1690811115610db657610db661192d565b6001811115610dc757610dc761192d565b815260029190910154610100900473ffffffffffffffffffffffffffffffffffffffff1660209091015292915050565b610dff6113a5565b610e0a600382611428565b610e43576040517fe181733f0000000000000000000000000000000000000000000000000000000081526004810182905260240161031f565b610e4e600582611428565b15610e88576040517f16950d1d0000000000000000000000000000000000000000000000000000000081526004810182905260240161031f565b610e93600582611443565b5060405181907fdcea1b78b6ddc31592a94607d537543fcaafda6cc52d6d5cc7bbfca1422baf2190600090a250565b60005b8181101561090d576000838383818110610ee157610ee1611a67565b9050602002810190610ef39190611fe4565b610efc90612018565b805160009081526007602090815260408083208151808301909252805473ffffffffffffffffffffffffffffffffffffffff168252600181018054959650939491939092840191610f4c90611c6a565b80601f0160208091040260200160405190810160405280929190818152602001828054610f7890611c6a565b8015610fc55780601f10610f9a57610100808354040283529160200191610fc5565b820191906000526020600020905b815481529060010190602001808311610fa857829003601f168201915b5050505050815250509050806000015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611039576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808301516000908152600890915260409020600301541515808061106157506020830151155b156110a05782602001516040517f64e2ee9200000000000000000000000000000000000000000000000000000000815260040161031f91815260200190565b8260600151516000036110e55782606001516040517f3748d4c600000000000000000000000000000000000000000000000000000000815260040161031f91906120ed565b60005b836060015151811015611172576111268460600151828151811061110e5761110e611a67565b6020026020010151600361142890919063ffffffff16565b6111625783606001516040517f3748d4c600000000000000000000000000000000000000000000000000000000815260040161031f91906120ed565b61116b81611f08565b90506110e8565b506020838101805160009081526008835260409081902086518155915160018301558501516002820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790556060850151805186936111f7926003850192910190611640565b505050602083810151845160408051928352928201527f5bfe8a52ad26ac6ee7b0cd46d2fd92be04735a31c45ef8aa3d4b7ea1b61bbc1f910160405180910390a15050508061124590611f08565b9050610ec5565b6060600061125a600361144f565b90506000611268600561145c565b82516112749190612125565b67ffffffffffffffff81111561128c5761128c611ad4565b6040519080825280602002602001820160405280156112fc57816020015b6040805160808101825260008082526020808301829052928201819052606082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816112aa5790505b5090506000805b835181101561138857600084828151811061132057611320611a67565b6020026020010151905061133e81600561142890919063ffffffff16565b6113775761134b81610d4d565b84848151811061135d5761135d611a67565b6020026020010181905250828061137390611f08565b9350505b5061138181611f08565b9050611303565b50909392505050565b6113996113a5565b6113a281611466565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611426576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161031f565b565b600081815260018301602052604081205415155b9392505050565b600061143c838361155b565b6060600061143c836115aa565b6000610849825490565b3373ffffffffffffffffffffffffffffffffffffffff8216036114e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161031f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120546115a257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610849565b506000610849565b6060816000018054806020026020016040519081016040528092919081815260200182805480156115fa57602002820191906000526020600020905b8154815260200190600101908083116115e6575b50505050509050919050565b50805461161290611c6a565b6000825580601f10611622575050565b601f0160209004906000526020600020908101906113a2919061168b565b82805482825590600052602060002090810192821561167b579160200282015b8281111561167b578251825591602001919060010190611660565b5061168792915061168b565b5090565b5b80821115611687576000815560010161168c565b60008083601f8401126116b257600080fd5b50813567ffffffffffffffff8111156116ca57600080fd5b6020830191508360208260051b85010111156116e557600080fd5b9250929050565b6000806000806040858703121561170257600080fd5b843567ffffffffffffffff8082111561171a57600080fd5b611726888389016116a0565b9096509450602087013591508082111561173f57600080fd5b5061174c878288016116a0565b95989497509550505050565b60006080828403121561176a57600080fd5b50919050565b60006020828403121561178257600080fd5b5035919050565b6000815180845260005b818110156117af57602081850181015186830182015201611793565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061143c6020830184611789565b6000806020838503121561181357600080fd5b823567ffffffffffffffff81111561182a57600080fd5b611836858286016116a0565b90969095509350505050565b6000806040838503121561185557600080fd5b50508035926020909101359150565b6000602080835260a0830184518285015281850151604085015273ffffffffffffffffffffffffffffffffffffffff6040860151166060850152606085015160808086015281815180845260c0870191508483019350600092505b808310156118df57835182529284019260019290920191908401906118bf565b509695505050505050565b6020815273ffffffffffffffffffffffffffffffffffffffff8251166020820152600060208301516040808401526119256060840182611789565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b80518252602081015160208301526040810151600281106119a6577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b604083015260609081015173ffffffffffffffffffffffffffffffffffffffff16910152565b60808101610849828461195c565b6020808252825182820181905260009190848201906040850190845b81811015611a1c57611a0983855161195c565b92840192608092909201916001016119f6565b50909695505050505050565b73ffffffffffffffffffffffffffffffffffffffff811681146113a257600080fd5b600060208284031215611a5c57600080fd5b813561143c81611a28565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112611aca57600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611b2657611b26611ad4565b60405290565b6040516080810167ffffffffffffffff81118282101715611b2657611b26611ad4565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611b9657611b96611ad4565b604052919050565b600060408236031215611bb057600080fd5b611bb8611b03565b8235611bc381611a28565b815260208381013567ffffffffffffffff80821115611be157600080fd5b9085019036601f830112611bf457600080fd5b813581811115611c0657611c06611ad4565b611c36847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611b4f565b91508082523684828501011115611c4c57600080fd5b80848401858401376000908201840152918301919091525092915050565b600181811c90821680611c7e57607f821691505b60208210810361176a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000602080835260008454611ccb81611c6a565b80848701526040600180841660008114611cec5760018114611d2457611d52565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a01019550611d52565b896000528660002060005b85811015611d4a5781548b8201860152908301908801611d2f565b8a0184019650505b509398975050505050505050565b601f82111561090d57600081815260208120601f850160051c81016020861015611d875750805b601f850160051c820191505b818110156105e957828155600101611d93565b815167ffffffffffffffff811115611dc057611dc0611ad4565b611dd481611dce8454611c6a565b84611d60565b602080601f831160018114611e275760008415611df15750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556105e9565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015611e7457888601518255948401946001909101908401611e55565b5085821015611eb057878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b8281526040602082015260006119256040830184611789565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611f3957611f39611ed9565b5060010190565b600060208284031215611f5257600080fd5b8151801515811461143c57600080fd5b813581556020820135600182015560028101604083013560028110611f8657600080fd5b81546060850135611f9681611a28565b74ffffffffffffffffffffffffffffffffffffffff008160081b1660ff84167fffffffffffffffffffffff000000000000000000000000000000000000000000841617178455505050505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112611aca57600080fd5b60006080823603121561202a57600080fd5b612032611b2c565b8235815260208084013581830152604084013561204e81611a28565b6040830152606084013567ffffffffffffffff8082111561206e57600080fd5b9085019036601f83011261208157600080fd5b81358181111561209357612093611ad4565b8060051b91506120a4848301611b4f565b81815291830184019184810190368411156120be57600080fd5b938501935b838510156120dc578435825293850193908501906120c3565b606087015250939695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611a1c57835183529284019291840191600101612109565b8181038181111561084957610849611ed956fea164736f6c6343000813000a", } var CapabilityRegistryABI = CapabilityRegistryMetaData.ABI @@ -249,6 +256,28 @@ func (_CapabilityRegistry *CapabilityRegistryCallerSession) GetCapabilityID(capa return _CapabilityRegistry.Contract.GetCapabilityID(&_CapabilityRegistry.CallOpts, capabilityType, version) } +func (_CapabilityRegistry *CapabilityRegistryCaller) GetNode(opts *bind.CallOpts, p2pId [32]byte) (CapabilityRegistryNode, error) { + var out []interface{} + err := _CapabilityRegistry.contract.Call(opts, &out, "getNode", p2pId) + + if err != nil { + return *new(CapabilityRegistryNode), err + } + + out0 := *abi.ConvertType(out[0], new(CapabilityRegistryNode)).(*CapabilityRegistryNode) + + return out0, err + +} + +func (_CapabilityRegistry *CapabilityRegistrySession) GetNode(p2pId [32]byte) (CapabilityRegistryNode, error) { + return _CapabilityRegistry.Contract.GetNode(&_CapabilityRegistry.CallOpts, p2pId) +} + +func (_CapabilityRegistry *CapabilityRegistryCallerSession) GetNode(p2pId [32]byte) (CapabilityRegistryNode, error) { + return _CapabilityRegistry.Contract.GetNode(&_CapabilityRegistry.CallOpts, p2pId) +} + func (_CapabilityRegistry *CapabilityRegistryCaller) GetNodeOperator(opts *bind.CallOpts, nodeOperatorId *big.Int) (CapabilityRegistryNodeOperator, error) { var out []interface{} err := _CapabilityRegistry.contract.Call(opts, &out, "getNodeOperator", nodeOperatorId) @@ -373,6 +402,18 @@ func (_CapabilityRegistry *CapabilityRegistryTransactorSession) AddNodeOperators return _CapabilityRegistry.Contract.AddNodeOperators(&_CapabilityRegistry.TransactOpts, nodeOperators) } +func (_CapabilityRegistry *CapabilityRegistryTransactor) AddNodes(opts *bind.TransactOpts, nodes []CapabilityRegistryNode) (*types.Transaction, error) { + return _CapabilityRegistry.contract.Transact(opts, "addNodes", nodes) +} + +func (_CapabilityRegistry *CapabilityRegistrySession) AddNodes(nodes []CapabilityRegistryNode) (*types.Transaction, error) { + return _CapabilityRegistry.Contract.AddNodes(&_CapabilityRegistry.TransactOpts, nodes) +} + +func (_CapabilityRegistry *CapabilityRegistryTransactorSession) AddNodes(nodes []CapabilityRegistryNode) (*types.Transaction, error) { + return _CapabilityRegistry.Contract.AddNodes(&_CapabilityRegistry.TransactOpts, nodes) +} + func (_CapabilityRegistry *CapabilityRegistryTransactor) DeprecateCapability(opts *bind.TransactOpts, capabilityId [32]byte) (*types.Transaction, error) { return _CapabilityRegistry.contract.Transact(opts, "deprecateCapability", capabilityId) } @@ -675,6 +716,124 @@ func (_CapabilityRegistry *CapabilityRegistryFilterer) ParseCapabilityDeprecated return event, nil } +type CapabilityRegistryNodeAddedIterator struct { + Event *CapabilityRegistryNodeAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CapabilityRegistryNodeAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CapabilityRegistryNodeAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CapabilityRegistryNodeAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CapabilityRegistryNodeAddedIterator) Error() error { + return it.fail +} + +func (it *CapabilityRegistryNodeAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CapabilityRegistryNodeAdded struct { + P2pId [32]byte + NodeOperatorId *big.Int + Raw types.Log +} + +func (_CapabilityRegistry *CapabilityRegistryFilterer) FilterNodeAdded(opts *bind.FilterOpts) (*CapabilityRegistryNodeAddedIterator, error) { + + logs, sub, err := _CapabilityRegistry.contract.FilterLogs(opts, "NodeAdded") + if err != nil { + return nil, err + } + return &CapabilityRegistryNodeAddedIterator{contract: _CapabilityRegistry.contract, event: "NodeAdded", logs: logs, sub: sub}, nil +} + +func (_CapabilityRegistry *CapabilityRegistryFilterer) WatchNodeAdded(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryNodeAdded) (event.Subscription, error) { + + logs, sub, err := _CapabilityRegistry.contract.WatchLogs(opts, "NodeAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CapabilityRegistryNodeAdded) + if err := _CapabilityRegistry.contract.UnpackLog(event, "NodeAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CapabilityRegistry *CapabilityRegistryFilterer) ParseNodeAdded(log types.Log) (*CapabilityRegistryNodeAdded, error) { + event := new(CapabilityRegistryNodeAdded) + if err := _CapabilityRegistry.contract.UnpackLog(event, "NodeAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type CapabilityRegistryNodeOperatorAddedIterator struct { Event *CapabilityRegistryNodeOperatorAdded @@ -1328,6 +1487,8 @@ func (_CapabilityRegistry *CapabilityRegistry) ParseLog(log types.Log) (generate return _CapabilityRegistry.ParseCapabilityAdded(log) case _CapabilityRegistry.abi.Events["CapabilityDeprecated"].ID: return _CapabilityRegistry.ParseCapabilityDeprecated(log) + case _CapabilityRegistry.abi.Events["NodeAdded"].ID: + return _CapabilityRegistry.ParseNodeAdded(log) case _CapabilityRegistry.abi.Events["NodeOperatorAdded"].ID: return _CapabilityRegistry.ParseNodeOperatorAdded(log) case _CapabilityRegistry.abi.Events["NodeOperatorRemoved"].ID: @@ -1352,6 +1513,10 @@ func (CapabilityRegistryCapabilityDeprecated) Topic() common.Hash { return common.HexToHash("0xdcea1b78b6ddc31592a94607d537543fcaafda6cc52d6d5cc7bbfca1422baf21") } +func (CapabilityRegistryNodeAdded) Topic() common.Hash { + return common.HexToHash("0x5bfe8a52ad26ac6ee7b0cd46d2fd92be04735a31c45ef8aa3d4b7ea1b61bbc1f") +} + func (CapabilityRegistryNodeOperatorAdded) Topic() common.Hash { return common.HexToHash("0xda6697b182650034bd205cdc2dbfabb06bdb3a0a83a2b45bfefa3c4881284e0b") } @@ -1383,6 +1548,8 @@ type CapabilityRegistryInterface interface { GetCapabilityID(opts *bind.CallOpts, capabilityType [32]byte, version [32]byte) ([32]byte, error) + GetNode(opts *bind.CallOpts, p2pId [32]byte) (CapabilityRegistryNode, error) + GetNodeOperator(opts *bind.CallOpts, nodeOperatorId *big.Int) (CapabilityRegistryNodeOperator, error) IsCapabilityDeprecated(opts *bind.CallOpts, capabilityId [32]byte) (bool, error) @@ -1397,6 +1564,8 @@ type CapabilityRegistryInterface interface { AddNodeOperators(opts *bind.TransactOpts, nodeOperators []CapabilityRegistryNodeOperator) (*types.Transaction, error) + AddNodes(opts *bind.TransactOpts, nodes []CapabilityRegistryNode) (*types.Transaction, error) + DeprecateCapability(opts *bind.TransactOpts, capabilityId [32]byte) (*types.Transaction, error) RemoveNodeOperators(opts *bind.TransactOpts, nodeOperatorIds []*big.Int) (*types.Transaction, error) @@ -1417,6 +1586,12 @@ type CapabilityRegistryInterface interface { ParseCapabilityDeprecated(log types.Log) (*CapabilityRegistryCapabilityDeprecated, error) + FilterNodeAdded(opts *bind.FilterOpts) (*CapabilityRegistryNodeAddedIterator, error) + + WatchNodeAdded(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryNodeAdded) (event.Subscription, error) + + ParseNodeAdded(log types.Log) (*CapabilityRegistryNodeAdded, error) + FilterNodeOperatorAdded(opts *bind.FilterOpts, admin []common.Address) (*CapabilityRegistryNodeOperatorAddedIterator, error) WatchNodeOperatorAdded(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryNodeOperatorAdded, admin []common.Address) (event.Subscription, error) diff --git a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 0dff3f2986e..3e0110cdee6 100644 --- a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,4 +1,4 @@ GETH_VERSION: 1.13.8 forwarder: ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.bin b4c900aae9e022f01abbac7993d41f93912247613ac6270b0c4da4ef6f2016e3 -keystone_capability_registry: ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.abi ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.bin 28fb0e1c437b97271d999f3b028f7bd44558352ec83f89501aabf501fcc915f1 +keystone_capability_registry: ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.abi ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.bin b7d748b585d7cf1cf91e268b609613f77a8390d119e03d724b49c25fd2ea75e7 ocr3_capability: ../../../contracts/solc/v0.8.19/OCR3Capability/OCR3Capability.abi ../../../contracts/solc/v0.8.19/OCR3Capability/OCR3Capability.bin 9dcbdf55bd5729ba266148da3f17733eb592c871c2108ccca546618628fd9ad2 From ded90f0837c9726ae1ffb86caa63af456d8451b4 Mon Sep 17 00:00:00 2001 From: Cedric Date: Wed, 1 May 2024 18:59:11 +0100 Subject: [PATCH 73/77] [chore] Introduce test hooks (#13066) --- core/services/workflows/engine.go | 34 ++++++++++++-------------- core/services/workflows/engine_test.go | 34 +++++++++++++++++--------- 2 files changed, 38 insertions(+), 30 deletions(-) diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go index 040e123567e..9629e845336 100644 --- a/core/services/workflows/engine.go +++ b/core/services/workflows/engine.go @@ -43,8 +43,8 @@ type Engine struct { stopCh services.StopChan newWorkerTimeout time.Duration - // Used for testing to wait for an execution to complete - xxxExecutionFinished chan string + // testing lifecycle hook to signal when an execution is finished. + onExecutionFinished func(string) // testing lifecycle hook to signal initialization status afterInit func(success bool) // Used for testing to control the number of retries @@ -511,14 +511,7 @@ func (e *Engine) finishExecution(ctx context.Context, executionID string, status return err } - // Signal that an execution has finished in a - // non-blocking fashion. This is intended for - // testing purposes only. - select { - case e.xxxExecutionFinished <- executionID: - default: - } - + e.onExecutionFinished(executionID) return nil } @@ -688,9 +681,10 @@ type Config struct { PeerID func() *p2ptypes.PeerID // For testing purposes only - maxRetries int - retryMs int - afterInit func(success bool) + maxRetries int + retryMs int + afterInit func(success bool) + onExecutionFinished func(weid string) } const ( @@ -720,6 +714,10 @@ func NewEngine(cfg Config) (engine *Engine, err error) { cfg.afterInit = func(success bool) {} } + if cfg.onExecutionFinished == nil { + cfg.onExecutionFinished = func(weid string) {} + } + // TODO: validation of the workflow spec // We'll need to check, among other things: // - that there are no step `ref` called `trigger` as this is reserved for any triggers @@ -756,11 +754,11 @@ func NewEngine(cfg Config) (engine *Engine, err error) { triggerEvents: make(chan capabilities.CapabilityResponse), stopCh: make(chan struct{}), newWorkerTimeout: cfg.NewWorkerTimeout, - // For testing purposes only - xxxExecutionFinished: make(chan string), - afterInit: cfg.afterInit, - maxRetries: cfg.maxRetries, - retryMs: cfg.retryMs, + + onExecutionFinished: cfg.onExecutionFinished, + afterInit: cfg.afterInit, + maxRetries: cfg.maxRetries, + retryMs: cfg.retryMs, } return engine, nil } diff --git a/core/services/workflows/engine_test.go b/core/services/workflows/engine_test.go index 4821b5800c7..3896f840ee8 100644 --- a/core/services/workflows/engine_test.go +++ b/core/services/workflows/engine_test.go @@ -65,10 +65,16 @@ targets: abi: "receive(report bytes)" ` +type testHooks struct { + initFailed chan struct{} + executionFinished chan string +} + // newTestEngine creates a new engine with some test defaults. -func newTestEngine(t *testing.T, reg *coreCap.Registry, spec string) (eng *Engine, initFailed chan struct{}) { +func newTestEngine(t *testing.T, reg *coreCap.Registry, spec string) (*Engine, *testHooks) { peerID := p2ptypes.PeerID{} - initFailed = make(chan struct{}) + initFailed := make(chan struct{}) + executionFinished := make(chan string, 100) cfg := Config{ Lggr: logger.TestLogger(t), Registry: reg, @@ -82,10 +88,13 @@ func newTestEngine(t *testing.T, reg *coreCap.Registry, spec string) (eng *Engin close(initFailed) } }, + onExecutionFinished: func(weid string) { + executionFinished <- weid + }, } eng, err := NewEngine(cfg) require.NoError(t, err) - return eng, initFailed + return eng, &testHooks{initFailed: initFailed, executionFinished: executionFinished} } // getExecutionId returns the execution id of the workflow that is @@ -93,13 +102,14 @@ func newTestEngine(t *testing.T, reg *coreCap.Registry, spec string) (eng *Engin // // If the engine fails to initialize, the test will fail rather // than blocking indefinitely. -func getExecutionId(t *testing.T, eng *Engine, initFailed <-chan struct{}) string { +func getExecutionId(t *testing.T, eng *Engine, hooks *testHooks) string { var eid string select { - case <-initFailed: + case <-hooks.initFailed: t.FailNow() - case eid = <-eng.xxxExecutionFinished: + case eid = <-hooks.executionFinished: } + return eid } @@ -186,13 +196,13 @@ func TestEngineWithHardcodedWorkflow(t *testing.T) { ) require.NoError(t, reg.Add(ctx, target2)) - eng, initFailed := newTestEngine(t, reg, hardcodedWorkflow) + eng, hooks := newTestEngine(t, reg, hardcodedWorkflow) err := eng.Start(ctx) require.NoError(t, err) defer eng.Close() - eid := getExecutionId(t, eng, initFailed) + eid := getExecutionId(t, eng, hooks) assert.Equal(t, cr, <-target1.response) assert.Equal(t, cr, <-target2.response) @@ -340,13 +350,13 @@ func TestEngine_ErrorsTheWorkflowIfAStepErrors(t *testing.T) { require.NoError(t, reg.Add(ctx, mockFailingConsensus())) require.NoError(t, reg.Add(ctx, mockTarget())) - eng, initFailed := newTestEngine(t, reg, simpleWorkflow) + eng, hooks := newTestEngine(t, reg, simpleWorkflow) err := eng.Start(ctx) require.NoError(t, err) defer eng.Close() - eid := getExecutionId(t, eng, initFailed) + eid := getExecutionId(t, eng, hooks) state, err := eng.executionStates.get(ctx, eid) require.NoError(t, err) @@ -439,12 +449,12 @@ func TestEngine_MultiStepDependencies(t *testing.T) { action, out := mockAction() require.NoError(t, reg.Add(ctx, action)) - eng, initFailed := newTestEngine(t, reg, multiStepWorkflow) + eng, hooks := newTestEngine(t, reg, multiStepWorkflow) err := eng.Start(ctx) require.NoError(t, err) defer eng.Close() - eid := getExecutionId(t, eng, initFailed) + eid := getExecutionId(t, eng, hooks) state, err := eng.executionStates.get(ctx, eid) require.NoError(t, err) From 3f065cfcf4ea0e67edfc46082115f4d882c18459 Mon Sep 17 00:00:00 2001 From: Sneha Agnihotri <180277+snehaagni@users.noreply.github.com> Date: Wed, 1 May 2024 11:56:14 -0700 Subject: [PATCH 74/77] chore/release 2.11.0 to develop (#13067) * Bump version and update CHANGELOG for core 2.11.0 Signed-off-by: Sneha Agnihotri * Add jfpc cache staleness alert to config and pass it into jfpc cache (#12595) * Add jfpc cache staleness alert to config and pass it into jfpc cache * Extract JuelsPerFeeCoinCache cfg into a separate struct, improve naming * Changeset * Update config validation test * Reduce changeset to minor * [BCF-3178] - Improve err handling and logs for in memory data source cache (#12907) * Fix inMemoryDataSourceCache get() warn log formatting * Fix in mem ds cache updateCache() to save runs even if some ds failed * Improve in memory data source cache Observe() logs and error messages * Add changeset * Bumping solana validator (#12832) * Bumping solana * Bumping the checksum for solana validator * Update release changelog with cherry pick commits from develop Signed-off-by: Sneha Agnihotri * Cherry pick: enable jpfc cache by default (#12973) * Draft * Check JuelsPerFeeCoinCache before checking Disable param * Add test * Update NewInMemoryDataSourceCache * Update NewInMemoryDataSourceCache * Update release changelog with cherry pick commits from develop Signed-off-by: Sneha Agnihotri * Remove duplicates Signed-off-by: Sneha Agnihotri * Finalize date on changelog for 2.11.0 Signed-off-by: Sneha Agnihotri * Remove codecov (#13020) (cherry picked from commit 2e994684de6d326ff3dc4674986a10fbf28e3511) --------- Signed-off-by: Sneha Agnihotri Co-authored-by: ilija42 <57732589+ilija42@users.noreply.github.com> Co-authored-by: Damjan Smickovski <32773226+smickovskid@users.noreply.github.com> Co-authored-by: george-dorin <120329946+george-dorin@users.noreply.github.com> Co-authored-by: HenryNguyen5 <6404866+HenryNguyen5@users.noreply.github.com> --- .changeset/beige-papayas-develop.md | 5 ----- .changeset/early-cats-check.md | 5 ----- .changeset/loud-peaches-beg.md | 5 ----- .changeset/odd-horses-fix.md | 5 ----- .changeset/sour-needles-collect.md | 5 ----- .changeset/ten-clouds-collect.md | 5 ----- CHANGELOG.md | 32 +++++++++++++++-------------- 7 files changed, 17 insertions(+), 45 deletions(-) delete mode 100644 .changeset/beige-papayas-develop.md delete mode 100644 .changeset/early-cats-check.md delete mode 100644 .changeset/loud-peaches-beg.md delete mode 100644 .changeset/odd-horses-fix.md delete mode 100644 .changeset/sour-needles-collect.md delete mode 100644 .changeset/ten-clouds-collect.md diff --git a/.changeset/beige-papayas-develop.md b/.changeset/beige-papayas-develop.md deleted file mode 100644 index 0408383bd03..00000000000 --- a/.changeset/beige-papayas-develop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal diff --git a/.changeset/early-cats-check.md b/.changeset/early-cats-check.md deleted file mode 100644 index 0408383bd03..00000000000 --- a/.changeset/early-cats-check.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal diff --git a/.changeset/loud-peaches-beg.md b/.changeset/loud-peaches-beg.md deleted file mode 100644 index cd880ae5f5c..00000000000 --- a/.changeset/loud-peaches-beg.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -support decimals #added diff --git a/.changeset/odd-horses-fix.md b/.changeset/odd-horses-fix.md deleted file mode 100644 index 290d82bebfe..00000000000 --- a/.changeset/odd-horses-fix.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -contracts work diff --git a/.changeset/sour-needles-collect.md b/.changeset/sour-needles-collect.md deleted file mode 100644 index 5d1ae86fd7c..00000000000 --- a/.changeset/sour-needles-collect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -cleanup set #bugfix diff --git a/.changeset/ten-clouds-collect.md b/.changeset/ten-clouds-collect.md deleted file mode 100644 index 0408383bd03..00000000000 --- a/.changeset/ten-clouds-collect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal diff --git a/CHANGELOG.md b/CHANGELOG.md index bb21a1a904a..336b896ce78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,13 @@ # Changelog Chainlink Core -## 2.11.0 - UNRELEASED + +## 2.11.0 - 2024-04-30 ### Minor Changes +- [#12920](https://github.com/smartcontractkit/chainlink/pull/12920) [`2d2a42876d`](https://github.com/smartcontractkit/chainlink/commit/2d2a42876de5285618c9a9de4b834d078ae8a8cc) Thanks [@ilija42](https://github.com/ilija42)! - Move JuelsPerFeeCoinCacheDuration under JuelsPerFeeCoinCache struct in config. Rename JuelsPerFeeCoinCacheDuration to updateInterval. Add stalenessAlertThreshold to JuelsPerFeeCoinCache config. + StalenessAlertThreshold cfg option has a default of 24 hours which means that it doesn't have to be set unless we want to override the duration after which a stale cache should start throwing errors. + - [#12348](https://github.com/smartcontractkit/chainlink/pull/12348) [`efead72965`](https://github.com/smartcontractkit/chainlink/commit/efead72965fec7e822a16f4d50cc0e5a27dd4640) Thanks [@reductionista](https://github.com/reductionista)! - Update config for zkevm polygon chains - [#12082](https://github.com/smartcontractkit/chainlink/pull/12082) [`608ea0a467`](https://github.com/smartcontractkit/chainlink/commit/608ea0a467ee36e15fdc654a88494ae579d778a6) Thanks [@dhaidashenko](https://github.com/dhaidashenko)! - HeadTracker now respects the `FinalityTagEnabled` config option. If the flag is enabled, HeadTracker backfills blocks up to the latest finalized block provided by the corresponding RPC call. To address potential misconfigurations, `HistoryDepth` is now calculated from the latest finalized block instead of the head. NOTE: Consumers (e.g. TXM and LogPoller) do not fully utilize Finality Tag yet. @@ -26,8 +30,6 @@ - [#12496](https://github.com/smartcontractkit/chainlink/pull/12496) [`31350477ae`](https://github.com/smartcontractkit/chainlink/commit/31350477ae51f00e035b1b8c50775e5955258ac1) Thanks [@silaslenihan](https://github.com/silaslenihan)! - Change LimitTransfer gasLimit type from uint32 to uint64 -- [#12622](https://github.com/smartcontractkit/chainlink/pull/12622) [`a2bdcf51ef`](https://github.com/smartcontractkit/chainlink/commit/a2bdcf51efc1efbbac21745b260bd130dbb1ce3d) Thanks [@HenryNguyen5](https://github.com/HenryNguyen5)! - Add table support to "type" property for step definitions - - [#12339](https://github.com/smartcontractkit/chainlink/pull/12339) [`96d2fe13b8`](https://github.com/smartcontractkit/chainlink/commit/96d2fe13b8510631bbc92ffd20a4d923b93002e6) Thanks [@dhaidashenko](https://github.com/dhaidashenko)! - Add the `pool_rpc_node_highest_finalized_block` metric that tracks the highest finalized block seen per RPC. If `FinalityTagEnabled = true`, a positive `NodePool.FinalizedBlockPollInterval` is needed to collect the metric. If the finality tag is not enabled, the metric is populated with a calculated latest finalized block based on the latest head and finality depth. - [#12473](https://github.com/smartcontractkit/chainlink/pull/12473) [`f1d1f249eb`](https://github.com/smartcontractkit/chainlink/commit/f1d1f249ebecb37da7eacbc4cc12e1eb0205f29a) Thanks [@justinkaseman](https://github.com/justinkaseman)! - Copy common transmitter methods into FunctionsContractTransmitter to enable product specific modification @@ -36,9 +38,12 @@ - [#12578](https://github.com/smartcontractkit/chainlink/pull/12578) [`ffd492295f`](https://github.com/smartcontractkit/chainlink/commit/ffd492295f03de8c3b946a003dacbded731d7899) Thanks [@RensR](https://github.com/RensR)! - Remove 0.6 and 0.7 Solidity source code - ### Patch Changes +- [#12973](https://github.com/smartcontractkit/chainlink/pull/12973) [`02d3f2fee9`](https://github.com/smartcontractkit/chainlink/commit/02d3f2fee9269b85e9500ae720d15bec6c5e0d63) Thanks [@george-dorin](https://github.com/george-dorin)! - JuelsPerFeeCoinCache is enabled by default for OCR2 jobs, added `Disable` field under [pluginConfig.JuelsPerFeeCoinCache] tag to disable this feature (e.g. Disable=true) + +- [#12920](https://github.com/smartcontractkit/chainlink/pull/12920) [`be50a8370a`](https://github.com/smartcontractkit/chainlink/commit/be50a8370a0f604fbe9612e38479ccfa5ceb1ebd) Thanks [@ilija42](https://github.com/ilija42)! - Fix in memory data source cache changes/bug that only allowed pipeline results where none of the data sources failed. #bugfix + - [#12570](https://github.com/smartcontractkit/chainlink/pull/12570) [`2d33524a35`](https://github.com/smartcontractkit/chainlink/commit/2d33524a3539e32ac32a84c4600e6cdfb8e01cf3) Thanks [@samsondav](https://github.com/samsondav)! - VerboseLogging is now turned on by default. You may disable if this results in excessive log volume. Disable like so: @@ -56,7 +61,7 @@ automatically increased to the number of mercury jobs if this exceeds the configured value. -- [#12540](https://github.com/smartcontractkit/chainlink/pull/12540) [`17c037678d`](https://github.com/smartcontractkit/chainlink/commit/17c037678d05c88f28a28a3ac760c742f549d5ec) Thanks [@RyanRHall](https://github.com/RyanRHall)! - change auto 2.3 flat fees from link to USD +- [#12540](https://github.com/smartcontractkit/chainlink/pull/12540) [`17c037678d`](https://github.com/smartcontractkit/chainlink/commit/17c037678d05c88f28a28a3ac760c742f549d5ec) Thanks [@RyanRHall](https://github.com/RyanRHall)! - Change auto 2.3 flat fees from link to USD - [#12696](https://github.com/smartcontractkit/chainlink/pull/12696) [`ee52be7cf9`](https://github.com/smartcontractkit/chainlink/commit/ee52be7cf90076677b1e96e3b294f284e798194f) Thanks [@KuphJr](https://github.com/KuphJr)! - Remove LogPoller filters for outdated Functions coordinator contracts @@ -99,7 +104,7 @@ - [#12564](https://github.com/smartcontractkit/chainlink/pull/12564) [`246762ceeb`](https://github.com/smartcontractkit/chainlink/commit/246762ceebba7923641ec00e66ae1aaf59bbcdc2) Thanks [@mateusz-sekara](https://github.com/mateusz-sekara)! - Exposing information about LogPoller finality violation via Healthy method. It's raised whenever LogPoller sees reorg deeper than the finality -- [#12575](https://github.com/smartcontractkit/chainlink/pull/12575) [`23254c4bf5`](https://github.com/smartcontractkit/chainlink/commit/23254c4bf577e84b71bda1d9a8b2c11e7b548267) Thanks [@augustbleeds](https://github.com/augustbleeds)! - update starknet relayer to fix nonce issue. introduces optional api-key for starknet toml config. +- [#12575](https://github.com/smartcontractkit/chainlink/pull/12575) [`23254c4bf5`](https://github.com/smartcontractkit/chainlink/commit/23254c4bf577e84b71bda1d9a8b2c11e7b548267) Thanks [@augustbleeds](https://github.com/augustbleeds)! - Update starknet relayer to fix nonce issue. introduces optional api-key for starknet toml config. - [#12353](https://github.com/smartcontractkit/chainlink/pull/12353) [`07c9f6cadd`](https://github.com/smartcontractkit/chainlink/commit/07c9f6cadd449989b21977af461305ded8e5b2f0) Thanks [@amit-momin](https://github.com/amit-momin)! - Fixed a race condition bug around EVM nonce management, which could cause the Node to skip a nonce and get stuck. @@ -107,11 +112,11 @@ - [#12484](https://github.com/smartcontractkit/chainlink/pull/12484) [`590cad6126`](https://github.com/smartcontractkit/chainlink/commit/590cad61269c75a6b22be1f6a73c74adfd1baa40) Thanks [@mateusz-sekara](https://github.com/mateusz-sekara)! - Making LogPoller's replay more robust by backfilling up to finalized block and processing rest in the main loop -- [#12612](https://github.com/smartcontractkit/chainlink/pull/12612) [`d44abe3769`](https://github.com/smartcontractkit/chainlink/commit/d44abe37693d6995377fa1329e433e7fba26885d) Thanks [@RensR](https://github.com/RensR)! - upgraded transmission to 0.8.19 +- [#12612](https://github.com/smartcontractkit/chainlink/pull/12612) [`d44abe3769`](https://github.com/smartcontractkit/chainlink/commit/d44abe37693d6995377fa1329e433e7fba26885d) Thanks [@RensR](https://github.com/RensR)! - Upgraded transmission to 0.8.19 - [#12444](https://github.com/smartcontractkit/chainlink/pull/12444) [`dde7fdff33`](https://github.com/smartcontractkit/chainlink/commit/dde7fdff33cfc0690844cf0a88295bef57e2a269) Thanks [@ogtownsend](https://github.com/ogtownsend)! - Updating prometheus metrics for Automation log triggers -- [#12479](https://github.com/smartcontractkit/chainlink/pull/12479) [`93762ccbd8`](https://github.com/smartcontractkit/chainlink/commit/93762ccbd868b9e227abf3220afb9ad22ba41b92) Thanks [@jinhoonbang](https://github.com/jinhoonbang)! - update solc version for vrf v2.5 coordinators +- [#12479](https://github.com/smartcontractkit/chainlink/pull/12479) [`93762ccbd8`](https://github.com/smartcontractkit/chainlink/commit/93762ccbd868b9e227abf3220afb9ad22ba41b92) Thanks [@jinhoonbang](https://github.com/jinhoonbang)! - Update solc version for vrf v2.5 coordinators - [#12337](https://github.com/smartcontractkit/chainlink/pull/12337) [`195b504a93`](https://github.com/smartcontractkit/chainlink/commit/195b504a93b1a241c1981ec21726e4b722d40b2b) Thanks [@samsondav](https://github.com/samsondav)! - Mercury jobs can now broadcast to multiple mercury servers. @@ -132,16 +137,13 @@ - [#11899](https://github.com/smartcontractkit/chainlink/pull/11899) [`67560b9f1d`](https://github.com/smartcontractkit/chainlink/commit/67560b9f1dc052712a76eeb245fba12f2daf8e8d) Thanks [@DylanTinianov](https://github.com/DylanTinianov)! - Refactor EVM ORMs to remove pg dependency -- [#12531](https://github.com/smartcontractkit/chainlink/pull/12531) [`88e010d604`](https://github.com/smartcontractkit/chainlink/commit/88e010d604682c54c4f99e0a0916f94c0d13ece6) Thanks [@jinhoonbang](https://github.com/jinhoonbang)! - increase num optimizations to 500 for vrf v2.5 coordinator - -- [#12375](https://github.com/smartcontractkit/chainlink/pull/12375) [`831aea819d`](https://github.com/smartcontractkit/chainlink/commit/831aea819dd6b3415770cc927c4857a1da4557b5) Thanks [@shileiwill](https://github.com/shileiwill)! - add liquidity pool for automation 2.3 - -- [#12412](https://github.com/smartcontractkit/chainlink/pull/12412) [`83c8688a14`](https://github.com/smartcontractkit/chainlink/commit/83c8688a14ac04111f999d132673ebaf6a364b4a) Thanks [@poopoothegorilla](https://github.com/poopoothegorilla)! - bump grafana to 1.1.1 - -- [#12248](https://github.com/smartcontractkit/chainlink/pull/12248) [`e1950769ee`](https://github.com/smartcontractkit/chainlink/commit/e1950769ee3ff2a40ca5772b9634c45f8be241cc) Thanks [@FelixFan1992](https://github.com/FelixFan1992)! - add version support for automation registry 2.\* +- [#12531](https://github.com/smartcontractkit/chainlink/pull/12531) [`88e010d604`](https://github.com/smartcontractkit/chainlink/commit/88e010d604682c54c4f99e0a0916f94c0d13ece6) Thanks [@jinhoonbang](https://github.com/jinhoonbang)! - Increase num optimizations to 500 for vrf v2.5 coordinator +- [#12375](https://github.com/smartcontractkit/chainlink/pull/12375) [`831aea819d`](https://github.com/smartcontractkit/chainlink/commit/831aea819dd6b3415770cc927c4857a1da4557b5) Thanks [@shileiwill](https://github.com/shileiwill)! - Add liquidity pool for automation 2.3 +- [#12412](https://github.com/smartcontractkit/chainlink/pull/12412) [`83c8688a14`](https://github.com/smartcontractkit/chainlink/commit/83c8688a14ac04111f999d132673ebaf6a364b4a) Thanks [@poopoothegorilla](https://github.com/poopoothegorilla)! - Bump grafana to 1.1.1 +- [#12248](https://github.com/smartcontractkit/chainlink/pull/12248) [`e1950769ee`](https://github.com/smartcontractkit/chainlink/commit/e1950769ee3ff2a40ca5772b9634c45f8be241cc) Thanks [@FelixFan1992](https://github.com/FelixFan1992)! - Add version support for automation registry 2.\* ## 2.10.0 - 2024-04-05 From 9ca4f04f97af46d64e7f17b8afedfd0f009f0d63 Mon Sep 17 00:00:00 2001 From: Sneha Agnihotri <180277+snehaagni@users.noreply.github.com> Date: Wed, 1 May 2024 15:51:18 -0700 Subject: [PATCH 75/77] Bump version and update CHANGELOG for core v2.12.0 (#13075) Signed-off-by: Sneha Agnihotri --- .changeset/beige-socks-cover.md | 5 - .changeset/brave-dots-breathe.md | 7 -- .changeset/brown-penguins-grin.md | 5 - .changeset/chilled-bikes-unite.md | 5 - .changeset/curvy-weeks-cover.md | 5 - .changeset/cyan-crabs-explode.md | 5 - .changeset/dull-dingos-remember.md | 5 - .changeset/early-paws-end.md | 5 - .changeset/empty-tomatoes-yawn.md | 5 - .changeset/fast-students-accept.md | 5 - .changeset/flat-guests-marry.md | 6 -- .changeset/forty-feet-train.md | 5 - .changeset/four-shoes-trade.md | 5 - .changeset/fresh-lizards-love.md | 5 - .changeset/fresh-moles-explode.md | 5 - .changeset/fresh-rice-learn.md | 5 - .changeset/fuzzy-pans-destroy.md | 5 - .changeset/gold-bottles-tell.md | 5 - .changeset/great-rockets-obey.md | 5 - .changeset/hot-dryers-flash.md | 5 - .changeset/hungry-ways-add.md | 6 -- .changeset/kind-deers-leave.md | 5 - .changeset/lovely-jeans-confess.md | 6 -- .changeset/lucky-ghosts-give.md | 5 - .changeset/lucky-windows-taste.md | 5 - .changeset/many-pillows-reflect.md | 5 - .changeset/new-forks-grab.md | 5 - .changeset/olive-knives-happen.md | 5 - .changeset/orange-squids-kick.md | 5 - .changeset/perfect-dancers-guess.md | 5 - .changeset/pink-schools-provide.md | 5 - .changeset/plenty-wombats-grab.md | 5 - .changeset/poor-masks-fold.md | 6 -- .changeset/poor-socks-travel.md | 5 - .changeset/pretty-flies-fold.md | 5 - .changeset/pretty-kangaroos-tell.md | 5 - .changeset/proud-toys-travel.md | 5 - .changeset/quick-fishes-heal.md | 5 - .changeset/real-numbers-taste.md | 5 - .changeset/rich-jars-flow.md | 5 - .changeset/silver-otters-play.md | 5 - .changeset/sixty-readers-mix.md | 5 - .changeset/smooth-comics-love.md | 5 - .changeset/soft-hotels-decide.md | 5 - .changeset/sour-jars-cross.md | 13 --- .changeset/spotty-cooks-think.md | 5 - .changeset/stale-terms-march.md | 7 -- .changeset/sweet-sloths-laugh.md | 5 - .changeset/swift-horses-unite.md | 5 - .changeset/tasty-lions-rhyme.md | 5 - .changeset/tender-crews-jam.md | 5 - .changeset/thirty-students-explain.md | 5 - .changeset/tidy-trees-tie.md | 5 - .changeset/tricky-bats-exist.md | 5 - .changeset/two-countries-lay.md | 5 - .changeset/warm-impalas-return.md | 5 - .changeset/weak-emus-reply.md | 5 - .changeset/witty-icons-rhyme.md | 5 - .changeset/witty-numbers-sleep.md | 5 - CHANGELOG.md | 142 ++++++++++++++++++++++++++ package.json | 2 +- 61 files changed, 143 insertions(+), 312 deletions(-) delete mode 100644 .changeset/beige-socks-cover.md delete mode 100644 .changeset/brave-dots-breathe.md delete mode 100644 .changeset/brown-penguins-grin.md delete mode 100644 .changeset/chilled-bikes-unite.md delete mode 100644 .changeset/curvy-weeks-cover.md delete mode 100644 .changeset/cyan-crabs-explode.md delete mode 100644 .changeset/dull-dingos-remember.md delete mode 100644 .changeset/early-paws-end.md delete mode 100644 .changeset/empty-tomatoes-yawn.md delete mode 100644 .changeset/fast-students-accept.md delete mode 100644 .changeset/flat-guests-marry.md delete mode 100644 .changeset/forty-feet-train.md delete mode 100644 .changeset/four-shoes-trade.md delete mode 100644 .changeset/fresh-lizards-love.md delete mode 100644 .changeset/fresh-moles-explode.md delete mode 100644 .changeset/fresh-rice-learn.md delete mode 100644 .changeset/fuzzy-pans-destroy.md delete mode 100644 .changeset/gold-bottles-tell.md delete mode 100644 .changeset/great-rockets-obey.md delete mode 100644 .changeset/hot-dryers-flash.md delete mode 100644 .changeset/hungry-ways-add.md delete mode 100644 .changeset/kind-deers-leave.md delete mode 100644 .changeset/lovely-jeans-confess.md delete mode 100644 .changeset/lucky-ghosts-give.md delete mode 100644 .changeset/lucky-windows-taste.md delete mode 100644 .changeset/many-pillows-reflect.md delete mode 100644 .changeset/new-forks-grab.md delete mode 100644 .changeset/olive-knives-happen.md delete mode 100644 .changeset/orange-squids-kick.md delete mode 100644 .changeset/perfect-dancers-guess.md delete mode 100644 .changeset/pink-schools-provide.md delete mode 100644 .changeset/plenty-wombats-grab.md delete mode 100644 .changeset/poor-masks-fold.md delete mode 100644 .changeset/poor-socks-travel.md delete mode 100644 .changeset/pretty-flies-fold.md delete mode 100644 .changeset/pretty-kangaroos-tell.md delete mode 100644 .changeset/proud-toys-travel.md delete mode 100644 .changeset/quick-fishes-heal.md delete mode 100644 .changeset/real-numbers-taste.md delete mode 100644 .changeset/rich-jars-flow.md delete mode 100644 .changeset/silver-otters-play.md delete mode 100644 .changeset/sixty-readers-mix.md delete mode 100644 .changeset/smooth-comics-love.md delete mode 100644 .changeset/soft-hotels-decide.md delete mode 100644 .changeset/sour-jars-cross.md delete mode 100644 .changeset/spotty-cooks-think.md delete mode 100644 .changeset/stale-terms-march.md delete mode 100644 .changeset/sweet-sloths-laugh.md delete mode 100644 .changeset/swift-horses-unite.md delete mode 100644 .changeset/tasty-lions-rhyme.md delete mode 100644 .changeset/tender-crews-jam.md delete mode 100644 .changeset/thirty-students-explain.md delete mode 100644 .changeset/tidy-trees-tie.md delete mode 100644 .changeset/tricky-bats-exist.md delete mode 100644 .changeset/two-countries-lay.md delete mode 100644 .changeset/warm-impalas-return.md delete mode 100644 .changeset/weak-emus-reply.md delete mode 100644 .changeset/witty-icons-rhyme.md delete mode 100644 .changeset/witty-numbers-sleep.md diff --git a/.changeset/beige-socks-cover.md b/.changeset/beige-socks-cover.md deleted file mode 100644 index 0b7c22d01e5..00000000000 --- a/.changeset/beige-socks-cover.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#internal changes to core required by change BCF3168 in common to add relayer set diff --git a/.changeset/brave-dots-breathe.md b/.changeset/brave-dots-breathe.md deleted file mode 100644 index f1ae4f4d21e..00000000000 --- a/.changeset/brave-dots-breathe.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"chainlink": minor ---- - -Added a new CLI command, `blocks find-lca,` which finds the latest block that is available in both the database and on the chain for the specified chain. -Added a new CLI command, `node remove-blocks,` which removes all blocks and logs greater than or equal to the specified block number. -#nops #added diff --git a/.changeset/brown-penguins-grin.md b/.changeset/brown-penguins-grin.md deleted file mode 100644 index 24a06a030fc..00000000000 --- a/.changeset/brown-penguins-grin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Fix in memory data source cache changes/bug that only allowed pipeline results where none of the data sources failed. #bugfix diff --git a/.changeset/chilled-bikes-unite.md b/.changeset/chilled-bikes-unite.md deleted file mode 100644 index e3e54852002..00000000000 --- a/.changeset/chilled-bikes-unite.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#internal Add script to create test database user and update docs diff --git a/.changeset/curvy-weeks-cover.md b/.changeset/curvy-weeks-cover.md deleted file mode 100644 index 0b19df8ad16..00000000000 --- a/.changeset/curvy-weeks-cover.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#wip Keystone contract wrappers updated diff --git a/.changeset/cyan-crabs-explode.md b/.changeset/cyan-crabs-explode.md deleted file mode 100644 index 5018e2d555c..00000000000 --- a/.changeset/cyan-crabs-explode.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Add support for workflow jobs to Operator UI #wip #added diff --git a/.changeset/dull-dingos-remember.md b/.changeset/dull-dingos-remember.md deleted file mode 100644 index 7c1b748cff7..00000000000 --- a/.changeset/dull-dingos-remember.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -use safe lib for approve #bugfix diff --git a/.changeset/early-paws-end.md b/.changeset/early-paws-end.md deleted file mode 100644 index 1a3edb5083f..00000000000 --- a/.changeset/early-paws-end.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -generate gethwrappers for updating node operators in capability registry #internal diff --git a/.changeset/empty-tomatoes-yawn.md b/.changeset/empty-tomatoes-yawn.md deleted file mode 100644 index 3f6e94b79a9..00000000000 --- a/.changeset/empty-tomatoes-yawn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Add a comment to Chain Reader Service constructor that specifies that anonymous events are not supported. diff --git a/.changeset/fast-students-accept.md b/.changeset/fast-students-accept.md deleted file mode 100644 index 8813f3a7812..00000000000 --- a/.changeset/fast-students-accept.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal Optimize workflow engine tests diff --git a/.changeset/flat-guests-marry.md b/.changeset/flat-guests-marry.md deleted file mode 100644 index c1eb6549a96..00000000000 --- a/.changeset/flat-guests-marry.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"chainlink": minor ---- - -#internal Gas Estimator L1Oracles to be chain specific -#removed cmd/arbgas diff --git a/.changeset/forty-feet-train.md b/.changeset/forty-feet-train.md deleted file mode 100644 index f5ea60fd061..00000000000 --- a/.changeset/forty-feet-train.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Bumping chainlink-automation version to v1.0.3 diff --git a/.changeset/four-shoes-trade.md b/.changeset/four-shoes-trade.md deleted file mode 100644 index cb5c9f4be6b..00000000000 --- a/.changeset/four-shoes-trade.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Removed AppConfig from Evm config #internal diff --git a/.changeset/fresh-lizards-love.md b/.changeset/fresh-lizards-love.md deleted file mode 100644 index 8e6e5d5cfef..00000000000 --- a/.changeset/fresh-lizards-love.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#internal Updates required to work with chainlink-common changes to support grpc streams for capabilities diff --git a/.changeset/fresh-moles-explode.md b/.changeset/fresh-moles-explode.md deleted file mode 100644 index 205002b40a0..00000000000 --- a/.changeset/fresh-moles-explode.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -core/chains/evm/logpoller: Stricter finality checks in LogPoller, to be more robust during rpc failover events #updated diff --git a/.changeset/fresh-rice-learn.md b/.changeset/fresh-rice-learn.md deleted file mode 100644 index 6425cdd4581..00000000000 --- a/.changeset/fresh-rice-learn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Moved test functions under evm package to support evm extraction #internal diff --git a/.changeset/fuzzy-pans-destroy.md b/.changeset/fuzzy-pans-destroy.md deleted file mode 100644 index 3cff19f8d8a..00000000000 --- a/.changeset/fuzzy-pans-destroy.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Use sqlutil instead of pg.Opts/Q/Queryer #internal diff --git a/.changeset/gold-bottles-tell.md b/.changeset/gold-bottles-tell.md deleted file mode 100644 index 5289f368a55..00000000000 --- a/.changeset/gold-bottles-tell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#added : Re-enable abandoned transaction tracker diff --git a/.changeset/great-rockets-obey.md b/.changeset/great-rockets-obey.md deleted file mode 100644 index b90bc810a01..00000000000 --- a/.changeset/great-rockets-obey.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#wip Keystone wrapper regenerate diff --git a/.changeset/hot-dryers-flash.md b/.changeset/hot-dryers-flash.md deleted file mode 100644 index 8423420589d..00000000000 --- a/.changeset/hot-dryers-flash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -core/services: update llo & versioning to use sqlutil #internal diff --git a/.changeset/hungry-ways-add.md b/.changeset/hungry-ways-add.md deleted file mode 100644 index 657494de605..00000000000 --- a/.changeset/hungry-ways-add.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"chainlink": patch ---- - -#bugfix -vrf fix replay number of blocks logic and add logging for job specs diff --git a/.changeset/kind-deers-leave.md b/.changeset/kind-deers-leave.md deleted file mode 100644 index ef88e78241c..00000000000 --- a/.changeset/kind-deers-leave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -bump mockery in makefile #updated diff --git a/.changeset/lovely-jeans-confess.md b/.changeset/lovely-jeans-confess.md deleted file mode 100644 index 50fc70c2c14..00000000000 --- a/.changeset/lovely-jeans-confess.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"chainlink": minor ---- - -#nops : Enable configurable client error regexes for error classification -#added : New toml configuration options for [EVM.NodePool.Errors] to pass regexes on NonceTooLow, NonceTooHigh, ReplacementTransactionUnderpriced, LimitReached, TransactionAlreadyInMempool, TerminallyUnderpriced, InsufficientEth, TxFeeExceedsCap, L2FeeTooLow, L2FeeTooHigh, L2Full, TransactionAlreadyMined, Fatal, and ServiceUnavailable. diff --git a/.changeset/lucky-ghosts-give.md b/.changeset/lucky-ghosts-give.md deleted file mode 100644 index 2ce47a6978b..00000000000 --- a/.changeset/lucky-ghosts-give.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -core/services/keystore: switch to sqlutil.DataStore #internal diff --git a/.changeset/lucky-windows-taste.md b/.changeset/lucky-windows-taste.md deleted file mode 100644 index bfcf559adb5..00000000000 --- a/.changeset/lucky-windows-taste.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Validate support for postgresql-client 16, and update docker image's bundled postgresql-client from 15 to 16. #nops #updated diff --git a/.changeset/many-pillows-reflect.md b/.changeset/many-pillows-reflect.md deleted file mode 100644 index 6de57ecc2a4..00000000000 --- a/.changeset/many-pillows-reflect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -core/services/keeper: switch to sqlutil.DataSource #internal diff --git a/.changeset/new-forks-grab.md b/.changeset/new-forks-grab.md deleted file mode 100644 index 350b5baafb0..00000000000 --- a/.changeset/new-forks-grab.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Drop unused queryTimeout config from TXM strategy #internal diff --git a/.changeset/olive-knives-happen.md b/.changeset/olive-knives-happen.md deleted file mode 100644 index 7f522c96ff1..00000000000 --- a/.changeset/olive-knives-happen.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal Generic Plugin `onchainSigningStrategy` support diff --git a/.changeset/orange-squids-kick.md b/.changeset/orange-squids-kick.md deleted file mode 100644 index a934e70063d..00000000000 --- a/.changeset/orange-squids-kick.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal Remote Trigger setup diff --git a/.changeset/perfect-dancers-guess.md b/.changeset/perfect-dancers-guess.md deleted file mode 100644 index 6ee4099c45a..00000000000 --- a/.changeset/perfect-dancers-guess.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal Rename workflow tags to labels diff --git a/.changeset/pink-schools-provide.md b/.changeset/pink-schools-provide.md deleted file mode 100644 index 6b2aa5ea0c4..00000000000 --- a/.changeset/pink-schools-provide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#bugfix Fixed an issue where the `rebroadcast-transactions` commands did not execute config validation. diff --git a/.changeset/plenty-wombats-grab.md b/.changeset/plenty-wombats-grab.md deleted file mode 100644 index 84fb96f8b80..00000000000 --- a/.changeset/plenty-wombats-grab.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#wip Regenerate Keystone wrappers diff --git a/.changeset/poor-masks-fold.md b/.changeset/poor-masks-fold.md deleted file mode 100644 index 1564aa0791f..00000000000 --- a/.changeset/poor-masks-fold.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"chainlink": minor ---- - -Move JuelsPerFeeCoinCacheDuration under JuelsPerFeeCoinCache struct in config. Rename JuelsPerFeeCoinCacheDuration to updateInterval. Add stalenessAlertThreshold to JuelsPerFeeCoinCache config. -StalenessAlertThreshold cfg option has a default of 24 hours which means that it doesn't have to be set unless we want to override the duration after which a stale cache should start throwing errors. diff --git a/.changeset/poor-socks-travel.md b/.changeset/poor-socks-travel.md deleted file mode 100644 index 88986845095..00000000000 --- a/.changeset/poor-socks-travel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -core/services/ocr2/plugins/ocr2keeper/evmregister/v21/upkeepstate: use sqlutil instead of pg.QOpts #internal diff --git a/.changeset/pretty-flies-fold.md b/.changeset/pretty-flies-fold.md deleted file mode 100644 index d67a3117e14..00000000000 --- a/.changeset/pretty-flies-fold.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -cor/services/relay/evm/mercury: switch to sqlutil.DataStore #internal diff --git a/.changeset/pretty-kangaroos-tell.md b/.changeset/pretty-kangaroos-tell.md deleted file mode 100644 index 946869b1ca0..00000000000 --- a/.changeset/pretty-kangaroos-tell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Add check for valid semvar value for changeset file #internal diff --git a/.changeset/proud-toys-travel.md b/.changeset/proud-toys-travel.md deleted file mode 100644 index e2b1f0c7269..00000000000 --- a/.changeset/proud-toys-travel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Improving LogPoller read queries by properly sorting by multiple columns #updated diff --git a/.changeset/quick-fishes-heal.md b/.changeset/quick-fishes-heal.md deleted file mode 100644 index 966e74c843a..00000000000 --- a/.changeset/quick-fishes-heal.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- -#changed -Added prefix `RPCClient returned error ({RPC_NAME})` to RPC errors to simplify filtering of RPC related issues. diff --git a/.changeset/real-numbers-taste.md b/.changeset/real-numbers-taste.md deleted file mode 100644 index d9f545444c2..00000000000 --- a/.changeset/real-numbers-taste.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -core/services/functions: switch to sqlutil.DataStore #internal diff --git a/.changeset/rich-jars-flow.md b/.changeset/rich-jars-flow.md deleted file mode 100644 index cb72503fe0d..00000000000 --- a/.changeset/rich-jars-flow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Narrowing topic, data_word indexes by adding (evm_chain_id, address, event_sig) to the index definition #db_update diff --git a/.changeset/silver-otters-play.md b/.changeset/silver-otters-play.md deleted file mode 100644 index 433011b5c76..00000000000 --- a/.changeset/silver-otters-play.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Validate user email before asking for a password in the chainlink CLI. diff --git a/.changeset/sixty-readers-mix.md b/.changeset/sixty-readers-mix.md deleted file mode 100644 index a6782a5b276..00000000000 --- a/.changeset/sixty-readers-mix.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Add support for X Layer (X1) #added diff --git a/.changeset/smooth-comics-love.md b/.changeset/smooth-comics-love.md deleted file mode 100644 index 6d41284978d..00000000000 --- a/.changeset/smooth-comics-love.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -update keystone gethwrapper with remove operator function #internal diff --git a/.changeset/soft-hotels-decide.md b/.changeset/soft-hotels-decide.md deleted file mode 100644 index 75b4cadd4e5..00000000000 --- a/.changeset/soft-hotels-decide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -switch more EVM components to use sqlutil.DataStore #internal diff --git a/.changeset/sour-jars-cross.md b/.changeset/sour-jars-cross.md deleted file mode 100644 index b904e8e3dd0..00000000000 --- a/.changeset/sour-jars-cross.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -"chainlink": patch ---- - -#added - -Add configurability to mercury transmitter - -```toml -[Mercury.Transmitter] -TransmitQueueMaxSize = 10_000 # Default -TransmitTimeout = "5s" # Default -``` diff --git a/.changeset/spotty-cooks-think.md b/.changeset/spotty-cooks-think.md deleted file mode 100644 index e645de27beb..00000000000 --- a/.changeset/spotty-cooks-think.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal fix txdb documentation typos diff --git a/.changeset/stale-terms-march.md b/.changeset/stale-terms-march.md deleted file mode 100644 index 72ba417eac3..00000000000 --- a/.changeset/stale-terms-march.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"chainlink": patch ---- - -Bump libocr => fd3cab206b2ca3b7ff207996b95673b2d6303ec4 - -#internal diff --git a/.changeset/sweet-sloths-laugh.md b/.changeset/sweet-sloths-laugh.md deleted file mode 100644 index cbc72913ec9..00000000000 --- a/.changeset/sweet-sloths-laugh.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -core/sessions: switch to sqlutil.DataSource #internal diff --git a/.changeset/swift-horses-unite.md b/.changeset/swift-horses-unite.md deleted file mode 100644 index d9d426efe6d..00000000000 --- a/.changeset/swift-horses-unite.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -core/bridges: use sqlutil.DataSource #internal diff --git a/.changeset/tasty-lions-rhyme.md b/.changeset/tasty-lions-rhyme.md deleted file mode 100644 index b80f1337bce..00000000000 --- a/.changeset/tasty-lions-rhyme.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -add getters #internal diff --git a/.changeset/tender-crews-jam.md b/.changeset/tender-crews-jam.md deleted file mode 100644 index 41b4f0a7633..00000000000 --- a/.changeset/tender-crews-jam.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -vrfv2plus - account for num words in coordinator gas overhead in v2plus wrapper diff --git a/.changeset/thirty-students-explain.md b/.changeset/thirty-students-explain.md deleted file mode 100644 index 0408383bd03..00000000000 --- a/.changeset/thirty-students-explain.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#internal diff --git a/.changeset/tidy-trees-tie.md b/.changeset/tidy-trees-tie.md deleted file mode 100644 index 7ff415e9de4..00000000000 --- a/.changeset/tidy-trees-tie.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#changed Updating the log trigger log provider's readMaxBatchSize to 56 diff --git a/.changeset/tricky-bats-exist.md b/.changeset/tricky-bats-exist.md deleted file mode 100644 index 3c748353859..00000000000 --- a/.changeset/tricky-bats-exist.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -minor fixes #bugfix diff --git a/.changeset/two-countries-lay.md b/.changeset/two-countries-lay.md deleted file mode 100644 index f3d78e6a2e6..00000000000 --- a/.changeset/two-countries-lay.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -update keystone gethwrapper #internal diff --git a/.changeset/warm-impalas-return.md b/.changeset/warm-impalas-return.md deleted file mode 100644 index 167d831692c..00000000000 --- a/.changeset/warm-impalas-return.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#added JuelsPerFeeCoinCache is enabled by default for OCR2 jobs, added `Disable` field under [pluginConfig.JuelsPerFeeCoinCache] tag to disable this feature (e.g. Disable=true) diff --git a/.changeset/weak-emus-reply.md b/.changeset/weak-emus-reply.md deleted file mode 100644 index ef0c1fe4dae..00000000000 --- a/.changeset/weak-emus-reply.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -#internal Updated FindTxesWithAttemptsAndReceiptsByIdsAndState method signature to accept int64 for tx ID instead of big.Int diff --git a/.changeset/witty-icons-rhyme.md b/.changeset/witty-icons-rhyme.md deleted file mode 100644 index 25d9cf3b1d3..00000000000 --- a/.changeset/witty-icons-rhyme.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -offchain settlement fix #bugfix diff --git a/.changeset/witty-numbers-sleep.md b/.changeset/witty-numbers-sleep.md deleted file mode 100644 index d42664d9f76..00000000000 --- a/.changeset/witty-numbers-sleep.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -Support for retention in LogPoller's filters registered by ContractTransmitter #changed diff --git a/CHANGELOG.md b/CHANGELOG.md index 336b896ce78..314626a0bd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,145 @@ # Changelog Chainlink Core +## 2.12.0 - UNRELEASED + +### Minor Changes + +- [#13000](https://github.com/smartcontractkit/chainlink/pull/13000) [`1b994043b0`](https://github.com/smartcontractkit/chainlink/commit/1b994043b00cad9e0c900b6d12173dd1008480a5) Thanks [@ettec](https://github.com/ettec)! - #internal changes to core required by change BCF3168 in common to add relayer set + +- [#12867](https://github.com/smartcontractkit/chainlink/pull/12867) [`27d9413286`](https://github.com/smartcontractkit/chainlink/commit/27d941328655e0cde608c1eff47de736c11e2e58) Thanks [@dhaidashenko](https://github.com/dhaidashenko)! - Added a new CLI command, `blocks find-lca,` which finds the latest block that is available in both the database and on the chain for the specified chain. + Added a new CLI command, `node remove-blocks,` which removes all blocks and logs greater than or equal to the specified block number. + #nops #added + +- [#12914](https://github.com/smartcontractkit/chainlink/pull/12914) [`28df745115`](https://github.com/smartcontractkit/chainlink/commit/28df74511568df989944ee92cfd625a5d22a2840) Thanks [@krehermann](https://github.com/krehermann)! - #internal Add script to create test database user and update docs + +- [#12837](https://github.com/smartcontractkit/chainlink/pull/12837) [`f7982fa718`](https://github.com/smartcontractkit/chainlink/commit/f7982fa718cd9dc6563019acd8dfc5a40475df9e) Thanks [@cedric-cordenier](https://github.com/cedric-cordenier)! - Add support for workflow jobs to Operator UI #wip #added + +- [#12686](https://github.com/smartcontractkit/chainlink/pull/12686) [`2e768c150b`](https://github.com/smartcontractkit/chainlink/commit/2e768c150b44eb3ac8e41e7bafdd46911be57397) Thanks [@nolag](https://github.com/nolag)! - Add a comment to Chain Reader Service constructor that specifies that anonymous events are not supported. + +- [#12650](https://github.com/smartcontractkit/chainlink/pull/12650) [`6991af26d9`](https://github.com/smartcontractkit/chainlink/commit/6991af26d9fa0e048b72a05f4f9c13f2306c0328) Thanks [@silaslenihan](https://github.com/silaslenihan)! - #internal Gas Estimator L1Oracles to be chain specific + #removed cmd/arbgas + +- [#12857](https://github.com/smartcontractkit/chainlink/pull/12857) [`d90229e7a7`](https://github.com/smartcontractkit/chainlink/commit/d90229e7a7011f8dc1c331dffb0ad1eeaddba46f) Thanks [@ettec](https://github.com/ettec)! - #internal Updates required to work with chainlink-common changes to support grpc streams for capabilities + +- [#12605](https://github.com/smartcontractkit/chainlink/pull/12605) [`1d9dd466e2`](https://github.com/smartcontractkit/chainlink/commit/1d9dd466e2933b7558949554b882f29f63d90b9f) Thanks [@reductionista](https://github.com/reductionista)! - core/chains/evm/logpoller: Stricter finality checks in LogPoller, to be more robust during rpc failover events #updated + +- [#12968](https://github.com/smartcontractkit/chainlink/pull/12968) [`c97781582b`](https://github.com/smartcontractkit/chainlink/commit/c97781582bbe0333332b985fb10a06edeaafa524) Thanks [@dimriou](https://github.com/dimriou)! - Moved test functions under evm package to support evm extraction #internal + +- [#12456](https://github.com/smartcontractkit/chainlink/pull/12456) [`78dd3e026a`](https://github.com/smartcontractkit/chainlink/commit/78dd3e026a81cb656b99ac62ce552369573ca736) Thanks [@jmank88](https://github.com/jmank88)! - Use sqlutil instead of pg.Opts/Q/Queryer #internal + +- [#12533](https://github.com/smartcontractkit/chainlink/pull/12533) [`ccb8cd85fe`](https://github.com/smartcontractkit/chainlink/commit/ccb8cd85fef8e3bbe3fb5580277a7bd7f477e6bb) Thanks [@DylanTinianov](https://github.com/DylanTinianov)! - #added : Re-enable abandoned transaction tracker + +- [#12760](https://github.com/smartcontractkit/chainlink/pull/12760) [`3f4573479c`](https://github.com/smartcontractkit/chainlink/commit/3f4573479c32dedf44f04261f9d5d4905f2542c7) Thanks [@DylanTinianov](https://github.com/DylanTinianov)! - #nops : Enable configurable client error regexes for error classification + #added : New toml configuration options for [EVM.NodePool.Errors] to pass regexes on NonceTooLow, NonceTooHigh, ReplacementTransactionUnderpriced, LimitReached, TransactionAlreadyInMempool, TerminallyUnderpriced, InsufficientEth, TxFeeExceedsCap, L2FeeTooLow, L2FeeTooHigh, L2Full, TransactionAlreadyMined, Fatal, and ServiceUnavailable. + +- [#12595](https://github.com/smartcontractkit/chainlink/pull/12595) [`e6d4814bda`](https://github.com/smartcontractkit/chainlink/commit/e6d4814bda908f1c0582b914d5aa803cecf333be) Thanks [@ilija42](https://github.com/ilija42)! - Move JuelsPerFeeCoinCacheDuration under JuelsPerFeeCoinCache struct in config. Rename JuelsPerFeeCoinCacheDuration to updateInterval. Add stalenessAlertThreshold to JuelsPerFeeCoinCache config. + StalenessAlertThreshold cfg option has a default of 24 hours which means that it doesn't have to be set unless we want to override the duration after which a stale cache should start throwing errors. + +- [#12767](https://github.com/smartcontractkit/chainlink/pull/12767) [`8db5ccfb39`](https://github.com/smartcontractkit/chainlink/commit/8db5ccfb39f86c9817fcad28292dbe6500821810) Thanks [@pavel-raykov](https://github.com/pavel-raykov)! - Validate user email before asking for a password in the chainlink CLI. + +- [#12851](https://github.com/smartcontractkit/chainlink/pull/12851) [`40064f0dfe`](https://github.com/smartcontractkit/chainlink/commit/40064f0dfecda6e404993dff056e7a666cca7d26) Thanks [@amit-momin](https://github.com/amit-momin)! - #internal Updated FindTxesWithAttemptsAndReceiptsByIdsAndState method signature to accept int64 for tx ID instead of big.Int + +### Patch Changes + +- [#12907](https://github.com/smartcontractkit/chainlink/pull/12907) [`f0439ec840`](https://github.com/smartcontractkit/chainlink/commit/f0439ec8408b39456a74c37df9a264782ed4725c) Thanks [@ilija42](https://github.com/ilija42)! - Fix in memory data source cache changes/bug that only allowed pipeline results where none of the data sources failed. #bugfix + +- [#12996](https://github.com/smartcontractkit/chainlink/pull/12996) [`0a37c0ed53`](https://github.com/smartcontractkit/chainlink/commit/0a37c0ed5346df509b545c88278c026cb2adf375) Thanks [@DeividasK](https://github.com/DeividasK)! - #wip Keystone contract wrappers updated + +- [#12923](https://github.com/smartcontractkit/chainlink/pull/12923) [`274a988985`](https://github.com/smartcontractkit/chainlink/commit/274a988985e0530676bdfedbdb35dec4cb9fe8b2) Thanks [@shileiwill](https://github.com/shileiwill)! - use safe lib for approve #bugfix + +- [#12991](https://github.com/smartcontractkit/chainlink/pull/12991) [`929312681f`](https://github.com/smartcontractkit/chainlink/commit/929312681fb27529915912e8bd6e4000559ea77f) Thanks [@cds95](https://github.com/cds95)! - generate gethwrappers for updating node operators in capability registry #internal + +- [#12959](https://github.com/smartcontractkit/chainlink/pull/12959) [`e482c79822`](https://github.com/smartcontractkit/chainlink/commit/e482c7982278e232acaaa4b3e9a79165faa35d1c) Thanks [@HenryNguyen5](https://github.com/HenryNguyen5)! - #internal Optimize workflow engine tests + +- [#12754](https://github.com/smartcontractkit/chainlink/pull/12754) [`4d9875ecba`](https://github.com/smartcontractkit/chainlink/commit/4d9875ecba9c7f672a9320d43cdb3d24a529f2ee) Thanks [@amirylm](https://github.com/amirylm)! - Bumping chainlink-automation version to v1.0.3 + +- [#12636](https://github.com/smartcontractkit/chainlink/pull/12636) [`bdc076c139`](https://github.com/smartcontractkit/chainlink/commit/bdc076c1395259298f520d741a3a1b397c3e0037) Thanks [@dimriou](https://github.com/dimriou)! - Removed AppConfig from Evm config #internal + +- [#12880](https://github.com/smartcontractkit/chainlink/pull/12880) [`8337fc821b`](https://github.com/smartcontractkit/chainlink/commit/8337fc821baf8011c6c73203482db85f5a44d7ae) Thanks [@DeividasK](https://github.com/DeividasK)! - #wip Keystone wrapper regenerate + +- [#12807](https://github.com/smartcontractkit/chainlink/pull/12807) [`dd41ee6c1f`](https://github.com/smartcontractkit/chainlink/commit/dd41ee6c1fb79333bfec4e8ef795a859e09e72c8) Thanks [@jmank88](https://github.com/jmank88)! - core/services: update llo & versioning to use sqlutil #internal + +- [#12887](https://github.com/smartcontractkit/chainlink/pull/12887) [`e87b83cd78`](https://github.com/smartcontractkit/chainlink/commit/e87b83cd78595c09061c199916c4bb9145e719b7) Thanks [@jinhoonbang](https://github.com/jinhoonbang)! - #bugfix + vrf fix replay number of blocks logic and add logging for job specs + +- [#12848](https://github.com/smartcontractkit/chainlink/pull/12848) [`91698020fb`](https://github.com/smartcontractkit/chainlink/commit/91698020fb695545eeb4befb2d73e36cc3ded0ab) Thanks [@poopoothegorilla](https://github.com/poopoothegorilla)! - bump mockery in makefile #updated + +- [#12810](https://github.com/smartcontractkit/chainlink/pull/12810) [`1fce16e735`](https://github.com/smartcontractkit/chainlink/commit/1fce16e735e417553c00680a3fcae2e081353095) Thanks [@jmank88](https://github.com/jmank88)! - core/services/keystore: switch to sqlutil.DataStore #internal + +- [#11936](https://github.com/smartcontractkit/chainlink/pull/11936) [`2b38bd8738`](https://github.com/smartcontractkit/chainlink/commit/2b38bd8738b4edf16e9913c90720820bc2b8dbd1) Thanks [@erikburt](https://github.com/erikburt)! - Validate support for postgresql-client 16, and update docker image's bundled postgresql-client from 15 to 16. #nops #updated + +- [#12820](https://github.com/smartcontractkit/chainlink/pull/12820) [`e523aa0bc7`](https://github.com/smartcontractkit/chainlink/commit/e523aa0bc7752fbf11dfbb842c8a411d345f30e7) Thanks [@jmank88](https://github.com/jmank88)! - core/services/keeper: switch to sqlutil.DataSource #internal + +- [#12859](https://github.com/smartcontractkit/chainlink/pull/12859) [`44c9b40e0a`](https://github.com/smartcontractkit/chainlink/commit/44c9b40e0a77be0609c33d06c3101d8a7163c3e7) Thanks [@dimriou](https://github.com/dimriou)! - Drop unused queryTimeout config from TXM strategy #internal + +- [#12909](https://github.com/smartcontractkit/chainlink/pull/12909) [`fa5b22773e`](https://github.com/smartcontractkit/chainlink/commit/fa5b22773e52744d3abab1a05cd12ecc2e103d88) Thanks [@vyzaldysanchez](https://github.com/vyzaldysanchez)! - #internal Generic Plugin `onchainSigningStrategy` support + +- [#12845](https://github.com/smartcontractkit/chainlink/pull/12845) [`63abd08cd5`](https://github.com/smartcontractkit/chainlink/commit/63abd08cd55b6dc31e74c6d3e50597eb8400eeb4) Thanks [@bolekk](https://github.com/bolekk)! - #internal Remote Trigger setup + +- [#12961](https://github.com/smartcontractkit/chainlink/pull/12961) [`e50d38b0bd`](https://github.com/smartcontractkit/chainlink/commit/e50d38b0bddc34aa0b97ae6bdf23c355b5619682) Thanks [@HenryNguyen5](https://github.com/HenryNguyen5)! - #internal Rename workflow tags to labels + +- [#12997](https://github.com/smartcontractkit/chainlink/pull/12997) [`8c8994e242`](https://github.com/smartcontractkit/chainlink/commit/8c8994e24284236645509b4c49152e6270ce0e35) Thanks [@george-dorin](https://github.com/george-dorin)! - #bugfix Fixed an issue where the `rebroadcast-transactions` commands did not execute config validation. + +- [#12888](https://github.com/smartcontractkit/chainlink/pull/12888) [`7c059b2c26`](https://github.com/smartcontractkit/chainlink/commit/7c059b2c26ed6d99a40403b4f690c0f3e08154b4) Thanks [@DeividasK](https://github.com/DeividasK)! - #wip Regenerate Keystone wrappers + +- [#12806](https://github.com/smartcontractkit/chainlink/pull/12806) [`9964dc82e5`](https://github.com/smartcontractkit/chainlink/commit/9964dc82e591f8653adb06f0b149a16e0b6cea40) Thanks [@jmank88](https://github.com/jmank88)! - core/services/ocr2/plugins/ocr2keeper/evmregister/v21/upkeepstate: use sqlutil instead of pg.QOpts #internal + +- [#12818](https://github.com/smartcontractkit/chainlink/pull/12818) [`6a0b4a9b09`](https://github.com/smartcontractkit/chainlink/commit/6a0b4a9b099663e3aed202f48f363afc4d111293) Thanks [@jmank88](https://github.com/jmank88)! - cor/services/relay/evm/mercury: switch to sqlutil.DataStore #internal + +- [#12947](https://github.com/smartcontractkit/chainlink/pull/12947) [`758ffd6da0`](https://github.com/smartcontractkit/chainlink/commit/758ffd6da097adac1f49ceded5e0998cdcb98a29) Thanks [@momentmaker](https://github.com/momentmaker)! - Add check for valid semvar value for changeset file #internal + +- [#13026](https://github.com/smartcontractkit/chainlink/pull/13026) [`e21be2a890`](https://github.com/smartcontractkit/chainlink/commit/e21be2a890a50bd3cbac60c450e3c2d68ddefbd3) Thanks [@mateusz-sekara](https://github.com/mateusz-sekara)! - Improving LogPoller read queries by properly sorting by multiple columns #updated + +- [#12638](https://github.com/smartcontractkit/chainlink/pull/12638) [`bcf7653486`](https://github.com/smartcontractkit/chainlink/commit/bcf76534862b32503f4192e38b7e1cb4dd7e312d) Thanks [@dhaidashenko](https://github.com/dhaidashenko)! - #changed + Added prefix `RPCClient returned error ({RPC_NAME})` to RPC errors to simplify filtering of RPC related issues. + +- [#12811](https://github.com/smartcontractkit/chainlink/pull/12811) [`6b0a7afe23`](https://github.com/smartcontractkit/chainlink/commit/6b0a7afe235399790c066dd725c437403a47a73e) Thanks [@jmank88](https://github.com/jmank88)! - core/services/functions: switch to sqlutil.DataStore #internal + +- [#12786](https://github.com/smartcontractkit/chainlink/pull/12786) [`fbb705c4f1`](https://github.com/smartcontractkit/chainlink/commit/fbb705c4f1338c6e0919d728adee827ec1e2007a) Thanks [@mateusz-sekara](https://github.com/mateusz-sekara)! - Narrowing topic, data_word indexes by adding (evm_chain_id, address, event_sig) to the index definition #db_update + +- [#12747](https://github.com/smartcontractkit/chainlink/pull/12747) [`2729ef76f3`](https://github.com/smartcontractkit/chainlink/commit/2729ef76f34877a2e6e8644b2e67f3e5dfb0c2b6) Thanks [@friedemannf](https://github.com/friedemannf)! - Add support for X Layer (X1) #added + +- [#12979](https://github.com/smartcontractkit/chainlink/pull/12979) [`0c4c24ad8c`](https://github.com/smartcontractkit/chainlink/commit/0c4c24ad8c95e505cd2a29be711cc40e612658b0) Thanks [@cds95](https://github.com/cds95)! - update keystone gethwrapper with remove operator function #internal + +- [#12856](https://github.com/smartcontractkit/chainlink/pull/12856) [`0ec92765cc`](https://github.com/smartcontractkit/chainlink/commit/0ec92765ccd419973f4eab5b0cc38df212f4ad21) Thanks [@jmank88](https://github.com/jmank88)! - switch more EVM components to use sqlutil.DataStore #internal + +- [#12680](https://github.com/smartcontractkit/chainlink/pull/12680) [`f55d8be495`](https://github.com/smartcontractkit/chainlink/commit/f55d8be495a83c97ac5439672563400e12ec2ee7) Thanks [@samsondav](https://github.com/samsondav)! - #added + + Add configurability to mercury transmitter + + ```toml + [Mercury.Transmitter] + TransmitQueueMaxSize = 10_000 # Default + TransmitTimeout = "5s" # Default + ``` + +- [#13059](https://github.com/smartcontractkit/chainlink/pull/13059) [`ea08b5f08d`](https://github.com/smartcontractkit/chainlink/commit/ea08b5f08d84d2ff1ddfa2027660ff58a60219c3) Thanks [@HenryNguyen5](https://github.com/HenryNguyen5)! - #internal fix txdb documentation typos + +- [#12902](https://github.com/smartcontractkit/chainlink/pull/12902) [`d1845e22d3`](https://github.com/smartcontractkit/chainlink/commit/d1845e22d3b057d9d736bc05c30f0db34c84a7e4) Thanks [@samsondav](https://github.com/samsondav)! - Bump libocr => fd3cab206b2ca3b7ff207996b95673b2d6303ec4 + + #internal + +- [#12809](https://github.com/smartcontractkit/chainlink/pull/12809) [`0af4acafbd`](https://github.com/smartcontractkit/chainlink/commit/0af4acafbdf243feea8507e421016933b0e538ca) Thanks [@jmank88](https://github.com/jmank88)! - core/sessions: switch to sqlutil.DataSource #internal + +- [#12808](https://github.com/smartcontractkit/chainlink/pull/12808) [`601c79f891`](https://github.com/smartcontractkit/chainlink/commit/601c79f89120dc0d98db63a528c79644ebb38132) Thanks [@jmank88](https://github.com/jmank88)! - core/bridges: use sqlutil.DataSource #internal + +- [#12903](https://github.com/smartcontractkit/chainlink/pull/12903) [`a293dfe797`](https://github.com/smartcontractkit/chainlink/commit/a293dfe7975b035a71eff7a6197e3ce5a25f1887) Thanks [@shileiwill](https://github.com/shileiwill)! - add getters #internal + +- [#12669](https://github.com/smartcontractkit/chainlink/pull/12669) [`3134ce8868`](https://github.com/smartcontractkit/chainlink/commit/3134ce8868ccc22bd4ae670c8b0bfda5fa78a332) Thanks [@leeyikjiun](https://github.com/leeyikjiun)! - vrfv2plus - account for num words in coordinator gas overhead in v2plus wrapper + +- [#13022](https://github.com/smartcontractkit/chainlink/pull/13022) [`2805fa6c9b`](https://github.com/smartcontractkit/chainlink/commit/2805fa6c9b469d535edcd3d66c08e1d22bbaa2d0) Thanks [@cds95](https://github.com/cds95)! - #internal + +- [#12951](https://github.com/smartcontractkit/chainlink/pull/12951) [`c98ea6413d`](https://github.com/smartcontractkit/chainlink/commit/c98ea6413dcdc02a7d0c82b9b36d3fce97dac94b) Thanks [@ogtownsend](https://github.com/ogtownsend)! - #changed Updating the log trigger log provider's readMaxBatchSize to 56 + +- [#12944](https://github.com/smartcontractkit/chainlink/pull/12944) [`167782c680`](https://github.com/smartcontractkit/chainlink/commit/167782c680b92b1e99ae3e9d1a8b87fd595dd644) Thanks [@shileiwill](https://github.com/shileiwill)! - minor fixes #bugfix + +- [#12906](https://github.com/smartcontractkit/chainlink/pull/12906) [`365c38be8b`](https://github.com/smartcontractkit/chainlink/commit/365c38be8b589d5ffa0b21755dcb40e2e4205652) Thanks [@cds95](https://github.com/cds95)! - update keystone gethwrapper #internal + +- [#12966](https://github.com/smartcontractkit/chainlink/pull/12966) [`ac7d3409ed`](https://github.com/smartcontractkit/chainlink/commit/ac7d3409ed9bc98af970ca75c3b92e41e4fb01cf) Thanks [@george-dorin](https://github.com/george-dorin)! - #added JuelsPerFeeCoinCache is enabled by default for OCR2 jobs, added `Disable` field under [pluginConfig.JuelsPerFeeCoinCache] tag to disable this feature (e.g. Disable=true) + +- [#12916](https://github.com/smartcontractkit/chainlink/pull/12916) [`7ec1d5b7ab`](https://github.com/smartcontractkit/chainlink/commit/7ec1d5b7abb51e100f7a6a48662e33703a589ecb) Thanks [@shileiwill](https://github.com/shileiwill)! - offchain settlement fix #bugfix + +- [#12998](https://github.com/smartcontractkit/chainlink/pull/12998) [`d50936ce38`](https://github.com/smartcontractkit/chainlink/commit/d50936ce3824d7ad6026f630172e9764a34cc08b) Thanks [@mateusz-sekara](https://github.com/mateusz-sekara)! - Support for retention in LogPoller's filters registered by ContractTransmitter #changed ## 2.11.0 - 2024-04-30 @@ -215,6 +355,7 @@ `mercury_transmit_queue_push_error_count` Nops should consider alerting on these. - Mercury now implements a local cache for fetching prices for fees, which ought to reduce latency and load on the mercury server, as well as increasing performance. It is enabled by default and can be configured with the following new config variables: + ``` [Mercury] @@ -239,6 +380,7 @@ # mercury server before retrying. Setting this to zero will wait indefinitely. LatestReportDeadline = "5s" # Default ``` + - New prom metrics for the mercury cache: `mercury_cache_fetch_failure_count` `mercury_cache_hit_count` diff --git a/package.json b/package.json index 759f8aaea4d..c903ac23165 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chainlink", - "version": "2.11.0", + "version": "2.12.0", "description": "node of the decentralized oracle network, bridging on and off-chain computation", "main": "index.js", "scripts": { From 9bd03c99930b504029bbb3eed4ecd1d00509cd49 Mon Sep 17 00:00:00 2001 From: HenryNguyen5 <6404866+HenryNguyen5@users.noreply.github.com> Date: Wed, 1 May 2024 23:20:12 -0400 Subject: [PATCH 76/77] Run short tests once on CI (#13077) --- .github/workflows/ci-core.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index fbef1b8282c..1d7b58820b0 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -112,7 +112,7 @@ jobs: if: ${{ needs.filter.outputs.changes == 'true' }} uses: ./.github/actions/setup-go - name: Run short tests - if: ${{ needs.filter.outputs.changes == 'true' }} + if: ${{ needs.filter.outputs.changes == 'true' && matrix.type.cmd == 'go_core_tests' }} run: go test -short ./... - name: Setup Solana if: ${{ needs.filter.outputs.changes == 'true' }} From 841fe61daa90b980f1e1622d2f7bd8f850b55462 Mon Sep 17 00:00:00 2001 From: HenryNguyen5 <6404866+HenryNguyen5@users.noreply.github.com> Date: Thu, 2 May 2024 00:38:00 -0400 Subject: [PATCH 77/77] Rename type -> id (#13008) --- .changeset/bright-queens-joke.md | 5 + contracts/.changeset/old-seas-doubt.md | 5 + .../src/v0.8/keystone/CapabilityRegistry.sol | 116 +++++++++------- .../src/v0.8/keystone/test/BaseTest.t.sol | 18 +-- ...CapabilityRegistry_AddCapabilityTest.t.sol | 17 ++- .../CapabilityRegistry_AddNodesTest.t.sol | 46 +++---- ...pabilityRegistry_DeprecateCapability.t.sol | 40 +++--- .../CapabilityRegistry_GetCapabilities.t.sol | 12 +- .../CapabilityRegistry_GetCapabilityIds.t.sol | 4 +- .../keystone_capability_registry.go | 126 +++++++++--------- ...rapper-dependency-versions-do-not-edit.txt | 2 +- core/services/workflows/engine.go | 10 +- core/services/workflows/engine_test.go | 22 +-- core/services/workflows/models.go | 5 +- core/services/workflows/models_test.go | 58 ++++---- core/services/workflows/models_yaml.go | 72 +++++----- core/services/workflows/models_yaml_test.go | 2 +- .../workflows/marshalling/workflow_1.yaml | 6 +- .../workflows/marshalling/workflow_2.yaml | 6 +- .../marshalling/workflow_2_spec.json | 8 +- .../workflows/references/failing_1.yaml | 6 +- .../workflows/references/passing_1.yaml | 6 +- .../workflows/versioning/failing_1.yaml | 6 +- .../workflows/versioning/failing_2.yaml | 6 +- .../workflows/versioning/passing_1.yaml | 6 +- .../fixtures/workflows/workflow_schema.json | 16 +-- core/web/jobs_controller_test.go | 8 +- 27 files changed, 333 insertions(+), 301 deletions(-) create mode 100644 .changeset/bright-queens-joke.md create mode 100644 contracts/.changeset/old-seas-doubt.md diff --git a/.changeset/bright-queens-joke.md b/.changeset/bright-queens-joke.md new file mode 100644 index 00000000000..a9dc2c8eb6d --- /dev/null +++ b/.changeset/bright-queens-joke.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#internal Keystone - rename type -> id diff --git a/contracts/.changeset/old-seas-doubt.md b/contracts/.changeset/old-seas-doubt.md new file mode 100644 index 00000000000..d559b3f5641 --- /dev/null +++ b/contracts/.changeset/old-seas-doubt.md @@ -0,0 +1,5 @@ +--- +"@chainlink/contracts": patch +--- + +#internal Keystone - rename type to id diff --git a/contracts/src/v0.8/keystone/CapabilityRegistry.sol b/contracts/src/v0.8/keystone/CapabilityRegistry.sol index ed3a300ac40..9e0a67434fc 100644 --- a/contracts/src/v0.8/keystone/CapabilityRegistry.sol +++ b/contracts/src/v0.8/keystone/CapabilityRegistry.sol @@ -28,10 +28,10 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { bytes32 p2pId; /// @notice The signer address for application-layer message verification. address signer; - /// @notice The list of capability IDs this node supports. This list is + /// @notice The list of hashed capability IDs this node supports. This list is /// never empty and all capabilities are guaranteed to exist in the /// CapabilityRegistry. - bytes32[] supportedCapabilityIds; + bytes32[] supportedHashedCapabilityIds; } // CapabilityResponseType indicates whether remote response requires @@ -45,10 +45,16 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { } struct Capability { - // Capability type, e.g. "data-streams-reports" + // The `labelledName` is a partially qualified ID for the capability. + // + // Given the following capability ID: {name}:{label1_key}_{label1_value}:{label2_key}_{label2_value}@{version} + // Then we denote the `labelledName` as the `{name}:{label1_key}_{label1_value}:{label2_key}_{label2_value}` portion of the ID. + // + // Ex. id = "data-streams-reports:chain:ethereum@1.0.0" + // labelledName = "data-streams-reports:chain:ethereum" + // // bytes32(string); validation regex: ^[a-z0-9_\-:]{1,32}$ - // Not "type" because that's a reserved keyword in Solidity. - bytes32 capabilityType; + bytes32 labelledName; // Semver, e.g., "1.2.3" // bytes32(string); must be valid Semver + max 32 characters. bytes32 version; @@ -92,8 +98,8 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { /// @notice This error is thrown when trying to add a node without /// capabilities or with capabilities that do not exist. - /// @param capabilityIds The IDs of the capabilities that are being added. - error InvalidNodeCapabilities(bytes32[] capabilityIds); + /// @param hashedCapabilityIds The IDs of the capabilities that are being added. + error InvalidNodeCapabilities(bytes32[] hashedCapabilityIds); /// @notice This event is emitted when a new node is added /// @param p2pId The P2P ID of the node @@ -104,15 +110,15 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { /// exists. error CapabilityAlreadyExists(); - /// @notice This error is thrown when a capability with the provided ID is + /// @notice This error is thrown when a capability with the provided hashed ID is /// not found. - /// @param capabilityId The ID used for the lookup. - error CapabilityDoesNotExist(bytes32 capabilityId); + /// @param hashedCapabilityId The hashed ID used for the lookup. + error CapabilityDoesNotExist(bytes32 hashedCapabilityId); /// @notice This error is thrown when trying to deprecate a capability that /// is already deprecated. - /// @param capabilityId The ID of the capability that is already deprecated. - error CapabilityAlreadyDeprecated(bytes32 capabilityId); + /// @param hashedCapabilityId The hashed ID of the capability that is already deprecated. + error CapabilityAlreadyDeprecated(bytes32 hashedCapabilityId); /// @notice This error is thrown when trying to add a capability with a /// configuration contract that does not implement the required interface. @@ -138,16 +144,22 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { event NodeOperatorUpdated(uint256 nodeOperatorId, address indexed admin, string name); /// @notice This event is emitted when a new capability is added - /// @param capabilityId The ID of the newly added capability - event CapabilityAdded(bytes32 indexed capabilityId); + /// @param hashedCapabilityId The hashed ID of the newly added capability + event CapabilityAdded(bytes32 indexed hashedCapabilityId); /// @notice This event is emitted when a capability is deprecated - /// @param capabilityId The ID of the deprecated capability - event CapabilityDeprecated(bytes32 indexed capabilityId); + /// @param hashedCapabilityId The hashed ID of the deprecated capability + event CapabilityDeprecated(bytes32 indexed hashedCapabilityId); mapping(bytes32 => Capability) private s_capabilities; - EnumerableSet.Bytes32Set private s_capabilityIds; - EnumerableSet.Bytes32Set private s_deprecatedCapabilityIds; + /// @notice Set of hashed capability IDs. + /// A hashed ID is created by the function `getHashedCapabilityId`. + EnumerableSet.Bytes32Set private s_hashedCapabilityIds; + /// @notice Set of deprecated hashed capability IDs, + /// A hashed ID is created by the function `getHashedCapabilityId`. + /// + /// Deprecated capabilities are skipped by the `getCapabilities` function. + EnumerableSet.Bytes32Set private s_deprecatedHashedCapabilityIds; /// @notice Mapping of node operators mapping(uint256 nodeOperatorId => NodeOperator nodeOperator) private s_nodeOperators; @@ -227,14 +239,15 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { NodeOperator memory nodeOperator = s_nodeOperators[node.nodeOperatorId]; if (msg.sender != nodeOperator.admin) revert AccessForbidden(); - bool nodeExists = s_nodes[node.p2pId].supportedCapabilityIds.length > 0; + bool nodeExists = s_nodes[node.p2pId].supportedHashedCapabilityIds.length > 0; if (nodeExists || bytes32(node.p2pId) == bytes32("")) revert InvalidNodeP2PId(node.p2pId); - if (node.supportedCapabilityIds.length == 0) revert InvalidNodeCapabilities(node.supportedCapabilityIds); + if (node.supportedHashedCapabilityIds.length == 0) + revert InvalidNodeCapabilities(node.supportedHashedCapabilityIds); - for (uint256 j; j < node.supportedCapabilityIds.length; ++j) { - if (!s_capabilityIds.contains(node.supportedCapabilityIds[j])) - revert InvalidNodeCapabilities(node.supportedCapabilityIds); + for (uint256 j; j < node.supportedHashedCapabilityIds.length; ++j) { + if (!s_hashedCapabilityIds.contains(node.supportedHashedCapabilityIds[j])) + revert InvalidNodeCapabilities(node.supportedHashedCapabilityIds); } s_nodes[node.p2pId] = node; @@ -250,9 +263,8 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { } function addCapability(Capability calldata capability) external onlyOwner { - bytes32 capabilityId = getCapabilityID(capability.capabilityType, capability.version); - - if (s_capabilityIds.contains(capabilityId)) revert CapabilityAlreadyExists(); + bytes32 hashedId = getHashedCapabilityId(capability.labelledName, capability.version); + if (s_hashedCapabilityIds.contains(hashedId)) revert CapabilityAlreadyExists(); if (capability.configurationContract != address(0)) { if ( @@ -263,24 +275,26 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { ) revert InvalidCapabilityConfigurationContractInterface(capability.configurationContract); } - s_capabilityIds.add(capabilityId); - s_capabilities[capabilityId] = capability; + s_hashedCapabilityIds.add(hashedId); + s_capabilities[hashedId] = capability; - emit CapabilityAdded(capabilityId); + emit CapabilityAdded(hashedId); } /// @notice Deprecates a capability by adding it to the deprecated list - /// @param capabilityId The ID of the capability to deprecate - function deprecateCapability(bytes32 capabilityId) external onlyOwner { - if (!s_capabilityIds.contains(capabilityId)) revert CapabilityDoesNotExist(capabilityId); - if (s_deprecatedCapabilityIds.contains(capabilityId)) revert CapabilityAlreadyDeprecated(capabilityId); - - s_deprecatedCapabilityIds.add(capabilityId); - emit CapabilityDeprecated(capabilityId); + /// @param hashedCapabilityId The ID of the capability to deprecate + function deprecateCapability(bytes32 hashedCapabilityId) external onlyOwner { + if (!s_hashedCapabilityIds.contains(hashedCapabilityId)) revert CapabilityDoesNotExist(hashedCapabilityId); + if (s_deprecatedHashedCapabilityIds.contains(hashedCapabilityId)) + revert CapabilityAlreadyDeprecated(hashedCapabilityId); + + s_deprecatedHashedCapabilityIds.add(hashedCapabilityId); + emit CapabilityDeprecated(hashedCapabilityId); } - function getCapability(bytes32 capabilityID) public view returns (Capability memory) { - return s_capabilities[capabilityID]; + /// @notice This function returns a Capability by its hashed ID. Use `getHashedCapabilityId` to get the hashed ID. + function getCapability(bytes32 hashedId) public view returns (Capability memory) { + return s_capabilities[hashedId]; } /// @notice Returns all capabilities. This operation will copy capabilities @@ -288,21 +302,23 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { /// used by view accessors that are queried without any gas fees. /// @return Capability[] An array of capabilities function getCapabilities() external view returns (Capability[] memory) { - bytes32[] memory capabilityIds = s_capabilityIds.values(); + bytes32[] memory hashedCapabilityIds = s_hashedCapabilityIds.values(); // Solidity does not support dynamic arrays in memory, so we create a // fixed-size array and copy the capabilities into it. - Capability[] memory capabilities = new Capability[](capabilityIds.length - s_deprecatedCapabilityIds.length()); + Capability[] memory capabilities = new Capability[]( + hashedCapabilityIds.length - s_deprecatedHashedCapabilityIds.length() + ); // We need to keep track of the new index because we are skipping // deprecated capabilities. uint256 newIndex; - for (uint256 i; i < capabilityIds.length; ++i) { - bytes32 capabilityId = capabilityIds[i]; + for (uint256 i; i < hashedCapabilityIds.length; ++i) { + bytes32 hashedCapabilityId = hashedCapabilityIds[i]; - if (!s_deprecatedCapabilityIds.contains(capabilityId)) { - capabilities[newIndex] = getCapability(capabilityId); + if (!s_deprecatedHashedCapabilityIds.contains(hashedCapabilityId)) { + capabilities[newIndex] = getCapability(hashedCapabilityId); newIndex++; } } @@ -310,16 +326,16 @@ contract CapabilityRegistry is OwnerIsCreator, TypeAndVersionInterface { return capabilities; } - /// @notice This functions returns a Capability ID packed into a bytes32 for cheaper access + /// @notice This functions returns a capability id that has been hashed to fit into a bytes32 for cheaper access /// @return bytes32 A unique identifier for the capability - function getCapabilityID(bytes32 capabilityType, bytes32 version) public pure returns (bytes32) { - return keccak256(abi.encodePacked(capabilityType, version)); + function getHashedCapabilityId(bytes32 labelledName, bytes32 version) public pure returns (bytes32) { + return keccak256(abi.encodePacked(labelledName, version)); } /// @notice Returns whether a capability is deprecated - /// @param capabilityId The ID of the capability to check + /// @param hashedCapabilityId The hashed ID of the capability to check /// @return bool True if the capability is deprecated, false otherwise - function isCapabilityDeprecated(bytes32 capabilityId) external view returns (bool) { - return s_deprecatedCapabilityIds.contains(capabilityId); + function isCapabilityDeprecated(bytes32 hashedCapabilityId) external view returns (bool) { + return s_deprecatedHashedCapabilityIds.contains(hashedCapabilityId); } } diff --git a/contracts/src/v0.8/keystone/test/BaseTest.t.sol b/contracts/src/v0.8/keystone/test/BaseTest.t.sol index 95c8d1e5d3d..b4d12f7ba73 100644 --- a/contracts/src/v0.8/keystone/test/BaseTest.t.sol +++ b/contracts/src/v0.8/keystone/test/BaseTest.t.sol @@ -11,9 +11,9 @@ contract BaseTest is Test, Constants { CapabilityConfigurationContract internal s_capabilityConfigurationContract; CapabilityRegistry.Capability internal s_basicCapability; CapabilityRegistry.Capability internal s_capabilityWithConfigurationContract; - bytes32 internal s_basicCapabilityId; + bytes32 internal s_basicHashedCapabilityId; bytes32 internal s_capabilityWithConfigurationContractId; - bytes32 internal s_nonExistentCapabilityId; + bytes32 internal s_nonExistentHashedCapabilityId; function setUp() public virtual { vm.startPrank(ADMIN); @@ -21,27 +21,27 @@ contract BaseTest is Test, Constants { s_capabilityConfigurationContract = new CapabilityConfigurationContract(); s_basicCapability = CapabilityRegistry.Capability({ - capabilityType: "data-streams-reports", + labelledName: "data-streams-reports", version: "1.0.0", responseType: CapabilityRegistry.CapabilityResponseType.REPORT, configurationContract: address(0) }); s_capabilityWithConfigurationContract = CapabilityRegistry.Capability({ - capabilityType: "read-ethereum-mainnet-gas-price", + labelledName: "read-ethereum-mainnet-gas-price", version: "1.0.2", responseType: CapabilityRegistry.CapabilityResponseType.OBSERVATION_IDENTICAL, configurationContract: address(s_capabilityConfigurationContract) }); - s_basicCapabilityId = s_capabilityRegistry.getCapabilityID( - s_basicCapability.capabilityType, + s_basicHashedCapabilityId = s_capabilityRegistry.getHashedCapabilityId( + s_basicCapability.labelledName, s_basicCapability.version ); - s_capabilityWithConfigurationContractId = s_capabilityRegistry.getCapabilityID( - s_capabilityWithConfigurationContract.capabilityType, + s_capabilityWithConfigurationContractId = s_capabilityRegistry.getHashedCapabilityId( + s_capabilityWithConfigurationContract.labelledName, s_capabilityWithConfigurationContract.version ); - s_nonExistentCapabilityId = s_capabilityRegistry.getCapabilityID("non-existent-capability", "1.0.0"); + s_nonExistentHashedCapabilityId = s_capabilityRegistry.getHashedCapabilityId("non-existent-capability", "1.0.0"); } function _getNodeOperators() internal view returns (CapabilityRegistry.NodeOperator[] memory) { diff --git a/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddCapabilityTest.t.sol b/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddCapabilityTest.t.sol index cf1bc6c8d73..dbcc0ae1712 100644 --- a/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddCapabilityTest.t.sol +++ b/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddCapabilityTest.t.sol @@ -47,10 +47,13 @@ contract CapabilityRegistry_AddCapabilityTest is BaseTest { function test_AddCapability_NoConfigurationContract() public { s_capabilityRegistry.addCapability(s_basicCapability); - bytes32 capabilityId = s_capabilityRegistry.getCapabilityID(bytes32("data-streams-reports"), bytes32("1.0.0")); - CapabilityRegistry.Capability memory storedCapability = s_capabilityRegistry.getCapability(capabilityId); + bytes32 hashedCapabilityId = s_capabilityRegistry.getHashedCapabilityId( + bytes32("data-streams-reports"), + bytes32("1.0.0") + ); + CapabilityRegistry.Capability memory storedCapability = s_capabilityRegistry.getCapability(hashedCapabilityId); - assertEq(storedCapability.capabilityType, s_basicCapability.capabilityType); + assertEq(storedCapability.labelledName, s_basicCapability.labelledName); assertEq(storedCapability.version, s_basicCapability.version); assertEq(uint256(storedCapability.responseType), uint256(s_basicCapability.responseType)); assertEq(storedCapability.configurationContract, s_basicCapability.configurationContract); @@ -59,13 +62,13 @@ contract CapabilityRegistry_AddCapabilityTest is BaseTest { function test_AddCapability_WithConfiguration() public { s_capabilityRegistry.addCapability(s_capabilityWithConfigurationContract); - bytes32 capabilityId = s_capabilityRegistry.getCapabilityID( - bytes32(s_capabilityWithConfigurationContract.capabilityType), + bytes32 hashedCapabilityId = s_capabilityRegistry.getHashedCapabilityId( + bytes32(s_capabilityWithConfigurationContract.labelledName), bytes32(s_capabilityWithConfigurationContract.version) ); - CapabilityRegistry.Capability memory storedCapability = s_capabilityRegistry.getCapability(capabilityId); + CapabilityRegistry.Capability memory storedCapability = s_capabilityRegistry.getCapability(hashedCapabilityId); - assertEq(storedCapability.capabilityType, s_capabilityWithConfigurationContract.capabilityType); + assertEq(storedCapability.labelledName, s_capabilityWithConfigurationContract.labelledName); assertEq(storedCapability.version, s_capabilityWithConfigurationContract.version); assertEq(uint256(storedCapability.responseType), uint256(s_capabilityWithConfigurationContract.responseType)); assertEq(storedCapability.configurationContract, s_capabilityWithConfigurationContract.configurationContract); diff --git a/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddNodesTest.t.sol b/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddNodesTest.t.sol index fe85c144eea..e179cc5cea6 100644 --- a/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddNodesTest.t.sol +++ b/contracts/src/v0.8/keystone/test/CapabilityRegistry_AddNodesTest.t.sol @@ -22,14 +22,14 @@ contract CapabilityRegistry_AddNodesTest is BaseTest { changePrank(STRANGER); CapabilityRegistry.Node[] memory nodes = new CapabilityRegistry.Node[](1); - bytes32[] memory capabilityIds = new bytes32[](1); - capabilityIds[0] = s_basicCapabilityId; + bytes32[] memory hashedCapabilityIds = new bytes32[](1); + hashedCapabilityIds[0] = s_basicHashedCapabilityId; nodes[0] = CapabilityRegistry.Node({ nodeOperatorId: TEST_NODE_OPERATOR_ONE_ID, p2pId: P2P_ID, signer: NODE_OPERATOR_ONE_SIGNER_ADDRESS, - supportedCapabilityIds: capabilityIds + supportedHashedCapabilityIds: hashedCapabilityIds }); vm.expectRevert(CapabilityRegistry.AccessForbidden.selector); @@ -40,14 +40,14 @@ contract CapabilityRegistry_AddNodesTest is BaseTest { changePrank(NODE_OPERATOR_ONE_ADMIN); CapabilityRegistry.Node[] memory nodes = new CapabilityRegistry.Node[](1); - bytes32[] memory capabilityIds = new bytes32[](1); - capabilityIds[0] = s_basicCapabilityId; + bytes32[] memory hashedCapabilityIds = new bytes32[](1); + hashedCapabilityIds[0] = s_basicHashedCapabilityId; nodes[0] = CapabilityRegistry.Node({ nodeOperatorId: TEST_NODE_OPERATOR_ONE_ID, p2pId: P2P_ID, signer: NODE_OPERATOR_ONE_SIGNER_ADDRESS, - supportedCapabilityIds: capabilityIds + supportedHashedCapabilityIds: hashedCapabilityIds }); s_capabilityRegistry.addNodes(nodes); @@ -59,14 +59,14 @@ contract CapabilityRegistry_AddNodesTest is BaseTest { changePrank(NODE_OPERATOR_ONE_ADMIN); CapabilityRegistry.Node[] memory nodes = new CapabilityRegistry.Node[](1); - bytes32[] memory capabilityIds = new bytes32[](1); - capabilityIds[0] = s_basicCapabilityId; + bytes32[] memory hashedCapabilityIds = new bytes32[](1); + hashedCapabilityIds[0] = s_basicHashedCapabilityId; nodes[0] = CapabilityRegistry.Node({ nodeOperatorId: TEST_NODE_OPERATOR_ONE_ID, p2pId: bytes32(""), signer: NODE_OPERATOR_ONE_SIGNER_ADDRESS, - supportedCapabilityIds: capabilityIds + supportedHashedCapabilityIds: hashedCapabilityIds }); vm.expectRevert(abi.encodeWithSelector(CapabilityRegistry.InvalidNodeP2PId.selector, bytes32(""))); @@ -77,15 +77,15 @@ contract CapabilityRegistry_AddNodesTest is BaseTest { changePrank(NODE_OPERATOR_ONE_ADMIN); CapabilityRegistry.Node[] memory nodes = new CapabilityRegistry.Node[](1); - bytes32[] memory capabilityIds = new bytes32[](0); + bytes32[] memory hashedCapabilityIds = new bytes32[](0); nodes[0] = CapabilityRegistry.Node({ nodeOperatorId: TEST_NODE_OPERATOR_ONE_ID, p2pId: P2P_ID, signer: NODE_OPERATOR_ONE_SIGNER_ADDRESS, - supportedCapabilityIds: capabilityIds + supportedHashedCapabilityIds: hashedCapabilityIds }); - vm.expectRevert(abi.encodeWithSelector(CapabilityRegistry.InvalidNodeCapabilities.selector, capabilityIds)); + vm.expectRevert(abi.encodeWithSelector(CapabilityRegistry.InvalidNodeCapabilities.selector, hashedCapabilityIds)); s_capabilityRegistry.addNodes(nodes); } @@ -93,17 +93,17 @@ contract CapabilityRegistry_AddNodesTest is BaseTest { changePrank(NODE_OPERATOR_ONE_ADMIN); CapabilityRegistry.Node[] memory nodes = new CapabilityRegistry.Node[](1); - bytes32[] memory capabilityIds = new bytes32[](1); - capabilityIds[0] = s_nonExistentCapabilityId; + bytes32[] memory hashedCapabilityIds = new bytes32[](1); + hashedCapabilityIds[0] = s_nonExistentHashedCapabilityId; nodes[0] = CapabilityRegistry.Node({ nodeOperatorId: TEST_NODE_OPERATOR_ONE_ID, p2pId: P2P_ID, signer: NODE_OPERATOR_ONE_SIGNER_ADDRESS, - supportedCapabilityIds: capabilityIds + supportedHashedCapabilityIds: hashedCapabilityIds }); - vm.expectRevert(abi.encodeWithSelector(CapabilityRegistry.InvalidNodeCapabilities.selector, capabilityIds)); + vm.expectRevert(abi.encodeWithSelector(CapabilityRegistry.InvalidNodeCapabilities.selector, hashedCapabilityIds)); s_capabilityRegistry.addNodes(nodes); } @@ -111,15 +111,15 @@ contract CapabilityRegistry_AddNodesTest is BaseTest { changePrank(NODE_OPERATOR_ONE_ADMIN); CapabilityRegistry.Node[] memory nodes = new CapabilityRegistry.Node[](1); - bytes32[] memory capabilityIds = new bytes32[](2); - capabilityIds[0] = s_basicCapabilityId; - capabilityIds[1] = s_capabilityWithConfigurationContractId; + bytes32[] memory hashedCapabilityIds = new bytes32[](2); + hashedCapabilityIds[0] = s_basicHashedCapabilityId; + hashedCapabilityIds[1] = s_capabilityWithConfigurationContractId; nodes[0] = CapabilityRegistry.Node({ nodeOperatorId: TEST_NODE_OPERATOR_ONE_ID, p2pId: P2P_ID, signer: NODE_OPERATOR_ONE_SIGNER_ADDRESS, - supportedCapabilityIds: capabilityIds + supportedHashedCapabilityIds: hashedCapabilityIds }); vm.expectEmit(address(s_capabilityRegistry)); @@ -129,8 +129,8 @@ contract CapabilityRegistry_AddNodesTest is BaseTest { CapabilityRegistry.Node memory node = s_capabilityRegistry.getNode(P2P_ID); assertEq(node.nodeOperatorId, TEST_NODE_OPERATOR_ONE_ID); assertEq(node.p2pId, P2P_ID); - assertEq(node.supportedCapabilityIds.length, 2); - assertEq(node.supportedCapabilityIds[0], s_basicCapabilityId); - assertEq(node.supportedCapabilityIds[1], s_capabilityWithConfigurationContractId); + assertEq(node.supportedHashedCapabilityIds.length, 2); + assertEq(node.supportedHashedCapabilityIds[0], s_basicHashedCapabilityId); + assertEq(node.supportedHashedCapabilityIds[1], s_capabilityWithConfigurationContractId); } } diff --git a/contracts/src/v0.8/keystone/test/CapabilityRegistry_DeprecateCapability.t.sol b/contracts/src/v0.8/keystone/test/CapabilityRegistry_DeprecateCapability.t.sol index 2e64ab7411f..b2f67339767 100644 --- a/contracts/src/v0.8/keystone/test/CapabilityRegistry_DeprecateCapability.t.sol +++ b/contracts/src/v0.8/keystone/test/CapabilityRegistry_DeprecateCapability.t.sol @@ -6,7 +6,7 @@ import {BaseTest} from "./BaseTest.t.sol"; import {CapabilityRegistry} from "../CapabilityRegistry.sol"; contract CapabilityRegistry_AddCapabilityTest is BaseTest { - event CapabilityDeprecated(bytes32 indexed capabilityId); + event CapabilityDeprecated(bytes32 indexed hashedCapabilityId); function setUp() public override { BaseTest.setUp(); @@ -17,53 +17,55 @@ contract CapabilityRegistry_AddCapabilityTest is BaseTest { function test_RevertWhen_CalledByNonAdmin() public { changePrank(STRANGER); - bytes32 capabilityId = s_capabilityRegistry.getCapabilityID( - s_basicCapability.capabilityType, + bytes32 hashedCapabilityId = s_capabilityRegistry.getHashedCapabilityId( + s_basicCapability.labelledName, s_basicCapability.version ); vm.expectRevert("Only callable by owner"); - s_capabilityRegistry.deprecateCapability(capabilityId); + s_capabilityRegistry.deprecateCapability(hashedCapabilityId); } function test_RevertWhen_CapabilityDoesNotExist() public { vm.expectRevert( - abi.encodeWithSelector(CapabilityRegistry.CapabilityDoesNotExist.selector, s_nonExistentCapabilityId) + abi.encodeWithSelector(CapabilityRegistry.CapabilityDoesNotExist.selector, s_nonExistentHashedCapabilityId) ); - s_capabilityRegistry.deprecateCapability(s_nonExistentCapabilityId); + s_capabilityRegistry.deprecateCapability(s_nonExistentHashedCapabilityId); } function test_RevertWhen_CapabilityAlreadyDeprecated() public { - bytes32 capabilityId = s_capabilityRegistry.getCapabilityID( - s_basicCapability.capabilityType, + bytes32 hashedCapabilityId = s_capabilityRegistry.getHashedCapabilityId( + s_basicCapability.labelledName, s_basicCapability.version ); - s_capabilityRegistry.deprecateCapability(capabilityId); + s_capabilityRegistry.deprecateCapability(hashedCapabilityId); - vm.expectRevert(abi.encodeWithSelector(CapabilityRegistry.CapabilityAlreadyDeprecated.selector, capabilityId)); - s_capabilityRegistry.deprecateCapability(capabilityId); + vm.expectRevert( + abi.encodeWithSelector(CapabilityRegistry.CapabilityAlreadyDeprecated.selector, hashedCapabilityId) + ); + s_capabilityRegistry.deprecateCapability(hashedCapabilityId); } function test_DeprecatesCapability() public { - bytes32 capabilityId = s_capabilityRegistry.getCapabilityID( - s_basicCapability.capabilityType, + bytes32 hashedCapabilityId = s_capabilityRegistry.getHashedCapabilityId( + s_basicCapability.labelledName, s_basicCapability.version ); - s_capabilityRegistry.deprecateCapability(capabilityId); + s_capabilityRegistry.deprecateCapability(hashedCapabilityId); - assertEq(s_capabilityRegistry.isCapabilityDeprecated(capabilityId), true); + assertEq(s_capabilityRegistry.isCapabilityDeprecated(hashedCapabilityId), true); } function test_EmitsEvent() public { - bytes32 capabilityId = s_capabilityRegistry.getCapabilityID( - s_basicCapability.capabilityType, + bytes32 hashedCapabilityId = s_capabilityRegistry.getHashedCapabilityId( + s_basicCapability.labelledName, s_basicCapability.version ); vm.expectEmit(address(s_capabilityRegistry)); - emit CapabilityDeprecated(capabilityId); - s_capabilityRegistry.deprecateCapability(capabilityId); + emit CapabilityDeprecated(hashedCapabilityId); + s_capabilityRegistry.deprecateCapability(hashedCapabilityId); } } diff --git a/contracts/src/v0.8/keystone/test/CapabilityRegistry_GetCapabilities.t.sol b/contracts/src/v0.8/keystone/test/CapabilityRegistry_GetCapabilities.t.sol index b14397ba4ef..010fb619ba8 100644 --- a/contracts/src/v0.8/keystone/test/CapabilityRegistry_GetCapabilities.t.sol +++ b/contracts/src/v0.8/keystone/test/CapabilityRegistry_GetCapabilities.t.sol @@ -17,12 +17,12 @@ contract CapabilityRegistry_GetCapabilitiesTest is BaseTest { assertEq(capabilities.length, 2); - assertEq(capabilities[0].capabilityType, "data-streams-reports"); + assertEq(capabilities[0].labelledName, "data-streams-reports"); assertEq(capabilities[0].version, "1.0.0"); assertEq(uint256(capabilities[0].responseType), uint256(CapabilityRegistry.CapabilityResponseType.REPORT)); assertEq(capabilities[0].configurationContract, address(0)); - assertEq(capabilities[1].capabilityType, "read-ethereum-mainnet-gas-price"); + assertEq(capabilities[1].labelledName, "read-ethereum-mainnet-gas-price"); assertEq(capabilities[1].version, "1.0.2"); assertEq( uint256(capabilities[1].responseType), @@ -32,16 +32,16 @@ contract CapabilityRegistry_GetCapabilitiesTest is BaseTest { } function test_ExcludesDeprecatedCapabilities() public { - bytes32 capabilityId = s_capabilityRegistry.getCapabilityID( - s_basicCapability.capabilityType, + bytes32 hashedCapabilityId = s_capabilityRegistry.getHashedCapabilityId( + s_basicCapability.labelledName, s_basicCapability.version ); - s_capabilityRegistry.deprecateCapability(capabilityId); + s_capabilityRegistry.deprecateCapability(hashedCapabilityId); CapabilityRegistry.Capability[] memory capabilities = s_capabilityRegistry.getCapabilities(); assertEq(capabilities.length, 1); - assertEq(capabilities[0].capabilityType, "read-ethereum-mainnet-gas-price"); + assertEq(capabilities[0].labelledName, "read-ethereum-mainnet-gas-price"); assertEq(capabilities[0].version, "1.0.2"); assertEq( uint256(capabilities[0].responseType), diff --git a/contracts/src/v0.8/keystone/test/CapabilityRegistry_GetCapabilityIds.t.sol b/contracts/src/v0.8/keystone/test/CapabilityRegistry_GetCapabilityIds.t.sol index de7810b4c15..b3dc333f5c3 100644 --- a/contracts/src/v0.8/keystone/test/CapabilityRegistry_GetCapabilityIds.t.sol +++ b/contracts/src/v0.8/keystone/test/CapabilityRegistry_GetCapabilityIds.t.sol @@ -13,12 +13,12 @@ contract CapabilityRegistry_GetCapabilitiesTest is BaseTest { assertEq(capabilities.length, 2); - assertEq(capabilities[0].capabilityType, "data-streams-reports"); + assertEq(capabilities[0].labelledName, "data-streams-reports"); assertEq(capabilities[0].version, "1.0.0"); assertEq(uint256(capabilities[0].responseType), uint256(CapabilityRegistry.CapabilityResponseType.REPORT)); assertEq(capabilities[0].configurationContract, address(0)); - assertEq(capabilities[1].capabilityType, "read-ethereum-mainnet-gas-price"); + assertEq(capabilities[1].labelledName, "read-ethereum-mainnet-gas-price"); assertEq(capabilities[1].version, "1.0.2"); assertEq( uint256(capabilities[1].responseType), diff --git a/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go b/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go index b54a101d44e..8ea5e29d99c 100644 --- a/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go +++ b/core/gethwrappers/keystone/generated/keystone_capability_registry/keystone_capability_registry.go @@ -31,17 +31,17 @@ var ( ) type CapabilityRegistryCapability struct { - CapabilityType [32]byte + LabelledName [32]byte Version [32]byte ResponseType uint8 ConfigurationContract common.Address } type CapabilityRegistryNode struct { - NodeOperatorId *big.Int - P2pId [32]byte - Signer common.Address - SupportedCapabilityIds [][32]byte + NodeOperatorId *big.Int + P2pId [32]byte + Signer common.Address + SupportedHashedCapabilityIds [][32]byte } type CapabilityRegistryNodeOperator struct { @@ -50,8 +50,8 @@ type CapabilityRegistryNodeOperator struct { } var CapabilityRegistryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAlreadyDeprecated\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CapabilityAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedConfigurationContract\",\"type\":\"address\"}],\"name\":\"InvalidCapabilityConfigurationContractInterface\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"capabilityIds\",\"type\":\"bytes32[]\"}],\"name\":\"InvalidNodeCapabilities\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeOperatorAdmin\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"InvalidNodeP2PId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"lengthOne\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lengthTwo\",\"type\":\"uint256\"}],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDeprecated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"NodeAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"NodeOperatorRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"capability\",\"type\":\"tuple\"}],\"name\":\"addCapability\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"addNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"supportedCapabilityIds\",\"type\":\"bytes32[]\"}],\"internalType\":\"structCapabilityRegistry.Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"}],\"name\":\"addNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"deprecateCapability\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilities\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityID\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityType\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"name\":\"getCapabilityID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"getNode\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"supportedCapabilityIds\",\"type\":\"bytes32[]\"}],\"internalType\":\"structCapabilityRegistry.Node\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"getNodeOperator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"capabilityId\",\"type\":\"bytes32\"}],\"name\":\"isCapabilityDeprecated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint256[]\"}],\"name\":\"removeNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"updateNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b503380600081620000695760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156200009c576200009c81620000a5565b50505062000150565b336001600160a01b03821603620000ff5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000060565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61214580620001606000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c806365c14dc711610097578063ae3c241c11610066578063ae3c241c14610292578063c2d483a1146102a5578063ddbe4f82146102b8578063f2fde38b146102cd57600080fd5b806365c14dc71461022257806379ba5097146102425780638da5cb5b1461024a5780639cb7c5f41461027257600080fd5b80631cdf6343116100d35780631cdf634314610194578063229111f5146101a7578063398f3773146101ef57806350c946fe1461020257600080fd5b80630c5801e314610105578063117392ce1461011a578063125700111461012d578063181f5a7714610155575b600080fd5b6101186101133660046116ec565b6102e0565b005b610118610128366004611758565b6105f1565b61014061013b366004611770565b61083c565b60405190151581526020015b60405180910390f35b604080518082018252601881527f4361706162696c697479526567697374727920312e302e3000000000000000006020820152905161014c91906117ed565b6101186101a2366004611800565b61084f565b6101e16101b5366004611842565b604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b60405190815260200161014c565b6101186101fd366004611800565b610912565b610215610210366004611770565b610aab565b60405161014c9190611864565b610235610230366004611770565b610b73565b60405161014c91906118ea565b610118610c50565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161014c565b610285610280366004611770565b610d4d565b60405161014c91906119cc565b6101186102a0366004611770565b610df7565b6101186102b3366004611800565b610ec2565b6102c061124c565b60405161014c91906119da565b6101186102db366004611a4a565b611391565b828114610328576040517fab8b67c600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff16905b848110156105e957600086868381811061036057610360611a67565b905060200201359050600085858481811061037d5761037d611a67565b905060200281019061038f9190611a96565b61039890611b9e565b805190915073ffffffffffffffffffffffffffffffffffffffff166103e9576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805173ffffffffffffffffffffffffffffffffffffffff16331480159061042657503373ffffffffffffffffffffffffffffffffffffffff851614155b1561045d576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160008381526007602052604090205473ffffffffffffffffffffffffffffffffffffffff908116911614158061050f57506020808201516040516104a392016117ed565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206000868152600783529290922091926104f6926001019101611cb7565b6040516020818303038152906040528051906020012014155b156105d6578051600083815260076020908152604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90931692909217825582015160019091019061057c9082611da6565b50806000015173ffffffffffffffffffffffffffffffffffffffff167f14c8f513e8a6d86d2d16b0cb64976de4e72386c4f8068eca3b7354373f8fe97a8383602001516040516105cd929190611ec0565b60405180910390a25b5050806105e290611f08565b9050610344565b505050505050565b6105f96113a5565b604080518235602082810191909152808401358284015282518083038401815260609092019092528051910120610631600382611428565b15610668576040517fe288638f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061067a6080840160608501611a4a565b73ffffffffffffffffffffffffffffffffffffffff16146107e5576106a56080830160608401611a4a565b73ffffffffffffffffffffffffffffffffffffffff163b158061078557506106d36080830160608401611a4a565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f884efe6100000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff91909116906301ffc9a790602401602060405180830381865afa15801561075f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107839190611f40565b155b156107e55761079a6080830160608401611a4a565b6040517fabb5e3fd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161031f565b6107f0600382611443565b506000818152600260205260409020829061080b8282611f62565b505060405181907f65610e5677eedff94555572640e442f89848a109ef8593fa927ac30b2565ff0690600090a25050565b6000610849600583611428565b92915050565b6108576113a5565b60005b8181101561090d57600083838381811061087657610876611a67565b60209081029290920135600081815260079093526040832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001681559093509190506108c76001830182611606565b50506040518181527f1e5877d7b3001d1569bf733b76c7eceda58bd6c031e5b8d0b7042308ba2e9d4f9060200160405180910390a15061090681611f08565b905061085a565b505050565b61091a6113a5565b60005b8181101561090d57600083838381811061093957610939611a67565b905060200281019061094b9190611a96565b61095490611b9e565b805190915073ffffffffffffffffffffffffffffffffffffffff166109a5576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600954604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815260008681526007909252939020825181547fffffffffffffffffffffffff000000000000000000000000000000000000000016921691909117815591519091906001820190610a289082611da6565b50905050600960008154610a3b90611f08565b909155508151602083015160405173ffffffffffffffffffffffffffffffffffffffff909216917fda6697b182650034bd205cdc2dbfabb06bdb3a0a83a2b45bfefa3c4881284e0b91610a9091859190611ec0565b60405180910390a2505080610aa490611f08565b905061091d565b6040805160808101825260008082526020820181905291810191909152606080820152600082815260086020908152604091829020825160808101845281548152600182015481840152600282015473ffffffffffffffffffffffffffffffffffffffff16818501526003820180548551818602810186019096528086529194929360608601939290830182828015610b6357602002820191906000526020600020905b815481526020019060010190808311610b4f575b5050505050815250509050919050565b6040805180820190915260008152606060208201526000828152600760209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff1683526001810180549192840191610bd090611c6a565b80601f0160208091040260200160405190810160405280929190818152602001828054610bfc90611c6a565b8015610b635780601f10610c1e57610100808354040283529160200191610b63565b820191906000526020600020905b815481529060010190602001808311610c2c57505050919092525091949350505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610cd1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161031f565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b604080516080808201835260008083526020808401829052838501829052606084018290528582526002808252918590208551938401865280548452600180820154928501929092529182015493949293919284019160ff1690811115610db657610db661192d565b6001811115610dc757610dc761192d565b815260029190910154610100900473ffffffffffffffffffffffffffffffffffffffff1660209091015292915050565b610dff6113a5565b610e0a600382611428565b610e43576040517fe181733f0000000000000000000000000000000000000000000000000000000081526004810182905260240161031f565b610e4e600582611428565b15610e88576040517f16950d1d0000000000000000000000000000000000000000000000000000000081526004810182905260240161031f565b610e93600582611443565b5060405181907fdcea1b78b6ddc31592a94607d537543fcaafda6cc52d6d5cc7bbfca1422baf2190600090a250565b60005b8181101561090d576000838383818110610ee157610ee1611a67565b9050602002810190610ef39190611fe4565b610efc90612018565b805160009081526007602090815260408083208151808301909252805473ffffffffffffffffffffffffffffffffffffffff168252600181018054959650939491939092840191610f4c90611c6a565b80601f0160208091040260200160405190810160405280929190818152602001828054610f7890611c6a565b8015610fc55780601f10610f9a57610100808354040283529160200191610fc5565b820191906000526020600020905b815481529060010190602001808311610fa857829003601f168201915b5050505050815250509050806000015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611039576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808301516000908152600890915260409020600301541515808061106157506020830151155b156110a05782602001516040517f64e2ee9200000000000000000000000000000000000000000000000000000000815260040161031f91815260200190565b8260600151516000036110e55782606001516040517f3748d4c600000000000000000000000000000000000000000000000000000000815260040161031f91906120ed565b60005b836060015151811015611172576111268460600151828151811061110e5761110e611a67565b6020026020010151600361142890919063ffffffff16565b6111625783606001516040517f3748d4c600000000000000000000000000000000000000000000000000000000815260040161031f91906120ed565b61116b81611f08565b90506110e8565b506020838101805160009081526008835260409081902086518155915160018301558501516002820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790556060850151805186936111f7926003850192910190611640565b505050602083810151845160408051928352928201527f5bfe8a52ad26ac6ee7b0cd46d2fd92be04735a31c45ef8aa3d4b7ea1b61bbc1f910160405180910390a15050508061124590611f08565b9050610ec5565b6060600061125a600361144f565b90506000611268600561145c565b82516112749190612125565b67ffffffffffffffff81111561128c5761128c611ad4565b6040519080825280602002602001820160405280156112fc57816020015b6040805160808101825260008082526020808301829052928201819052606082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816112aa5790505b5090506000805b835181101561138857600084828151811061132057611320611a67565b6020026020010151905061133e81600561142890919063ffffffff16565b6113775761134b81610d4d565b84848151811061135d5761135d611a67565b6020026020010181905250828061137390611f08565b9350505b5061138181611f08565b9050611303565b50909392505050565b6113996113a5565b6113a281611466565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611426576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161031f565b565b600081815260018301602052604081205415155b9392505050565b600061143c838361155b565b6060600061143c836115aa565b6000610849825490565b3373ffffffffffffffffffffffffffffffffffffffff8216036114e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161031f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120546115a257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610849565b506000610849565b6060816000018054806020026020016040519081016040528092919081815260200182805480156115fa57602002820191906000526020600020905b8154815260200190600101908083116115e6575b50505050509050919050565b50805461161290611c6a565b6000825580601f10611622575050565b601f0160209004906000526020600020908101906113a2919061168b565b82805482825590600052602060002090810192821561167b579160200282015b8281111561167b578251825591602001919060010190611660565b5061168792915061168b565b5090565b5b80821115611687576000815560010161168c565b60008083601f8401126116b257600080fd5b50813567ffffffffffffffff8111156116ca57600080fd5b6020830191508360208260051b85010111156116e557600080fd5b9250929050565b6000806000806040858703121561170257600080fd5b843567ffffffffffffffff8082111561171a57600080fd5b611726888389016116a0565b9096509450602087013591508082111561173f57600080fd5b5061174c878288016116a0565b95989497509550505050565b60006080828403121561176a57600080fd5b50919050565b60006020828403121561178257600080fd5b5035919050565b6000815180845260005b818110156117af57602081850181015186830182015201611793565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061143c6020830184611789565b6000806020838503121561181357600080fd5b823567ffffffffffffffff81111561182a57600080fd5b611836858286016116a0565b90969095509350505050565b6000806040838503121561185557600080fd5b50508035926020909101359150565b6000602080835260a0830184518285015281850151604085015273ffffffffffffffffffffffffffffffffffffffff6040860151166060850152606085015160808086015281815180845260c0870191508483019350600092505b808310156118df57835182529284019260019290920191908401906118bf565b509695505050505050565b6020815273ffffffffffffffffffffffffffffffffffffffff8251166020820152600060208301516040808401526119256060840182611789565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b80518252602081015160208301526040810151600281106119a6577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b604083015260609081015173ffffffffffffffffffffffffffffffffffffffff16910152565b60808101610849828461195c565b6020808252825182820181905260009190848201906040850190845b81811015611a1c57611a0983855161195c565b92840192608092909201916001016119f6565b50909695505050505050565b73ffffffffffffffffffffffffffffffffffffffff811681146113a257600080fd5b600060208284031215611a5c57600080fd5b813561143c81611a28565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112611aca57600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611b2657611b26611ad4565b60405290565b6040516080810167ffffffffffffffff81118282101715611b2657611b26611ad4565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611b9657611b96611ad4565b604052919050565b600060408236031215611bb057600080fd5b611bb8611b03565b8235611bc381611a28565b815260208381013567ffffffffffffffff80821115611be157600080fd5b9085019036601f830112611bf457600080fd5b813581811115611c0657611c06611ad4565b611c36847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611b4f565b91508082523684828501011115611c4c57600080fd5b80848401858401376000908201840152918301919091525092915050565b600181811c90821680611c7e57607f821691505b60208210810361176a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000602080835260008454611ccb81611c6a565b80848701526040600180841660008114611cec5760018114611d2457611d52565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a01019550611d52565b896000528660002060005b85811015611d4a5781548b8201860152908301908801611d2f565b8a0184019650505b509398975050505050505050565b601f82111561090d57600081815260208120601f850160051c81016020861015611d875750805b601f850160051c820191505b818110156105e957828155600101611d93565b815167ffffffffffffffff811115611dc057611dc0611ad4565b611dd481611dce8454611c6a565b84611d60565b602080601f831160018114611e275760008415611df15750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556105e9565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015611e7457888601518255948401946001909101908401611e55565b5085821015611eb057878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b8281526040602082015260006119256040830184611789565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611f3957611f39611ed9565b5060010190565b600060208284031215611f5257600080fd5b8151801515811461143c57600080fd5b813581556020820135600182015560028101604083013560028110611f8657600080fd5b81546060850135611f9681611a28565b74ffffffffffffffffffffffffffffffffffffffff008160081b1660ff84167fffffffffffffffffffffff000000000000000000000000000000000000000000841617178455505050505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112611aca57600080fd5b60006080823603121561202a57600080fd5b612032611b2c565b8235815260208084013581830152604084013561204e81611a28565b6040830152606084013567ffffffffffffffff8082111561206e57600080fd5b9085019036601f83011261208157600080fd5b81358181111561209357612093611ad4565b8060051b91506120a4848301611b4f565b81815291830184019184810190368411156120be57600080fd5b938501935b838510156120dc578435825293850193908501906120c3565b606087015250939695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611a1c57835183529284019291840191600101612109565b8181038181111561084957610849611ed956fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAlreadyDeprecated\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CapabilityAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedConfigurationContract\",\"type\":\"address\"}],\"name\":\"InvalidCapabilityConfigurationContractInterface\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"name\":\"InvalidNodeCapabilities\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNodeOperatorAdmin\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"InvalidNodeP2PId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"lengthOne\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lengthTwo\",\"type\":\"uint256\"}],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"CapabilityDeprecated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"NodeAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"NodeOperatorRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NodeOperatorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"labelledName\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"capability\",\"type\":\"tuple\"}],\"name\":\"addCapability\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"addNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"supportedHashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"internalType\":\"structCapabilityRegistry.Node[]\",\"name\":\"nodes\",\"type\":\"tuple[]\"}],\"name\":\"addNodes\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"deprecateCapability\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCapabilities\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"labelledName\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedId\",\"type\":\"bytes32\"}],\"name\":\"getCapability\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"labelledName\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"enumCapabilityRegistry.CapabilityResponseType\",\"name\":\"responseType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"configurationContract\",\"type\":\"address\"}],\"internalType\":\"structCapabilityRegistry.Capability\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"labelledName\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"}],\"name\":\"getHashedCapabilityId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"}],\"name\":\"getNode\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"p2pId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"supportedHashedCapabilityIds\",\"type\":\"bytes32[]\"}],\"internalType\":\"structCapabilityRegistry.Node\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nodeOperatorId\",\"type\":\"uint256\"}],\"name\":\"getNodeOperator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hashedCapabilityId\",\"type\":\"bytes32\"}],\"name\":\"isCapabilityDeprecated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint256[]\"}],\"name\":\"removeNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"nodeOperatorIds\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"internalType\":\"structCapabilityRegistry.NodeOperator[]\",\"name\":\"nodeOperators\",\"type\":\"tuple[]\"}],\"name\":\"updateNodeOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b503380600081620000695760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156200009c576200009c81620000a5565b50505062000150565b336001600160a01b03821603620000ff5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000060565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61214580620001606000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c806365c14dc711610097578063ae3c241c11610066578063ae3c241c14610292578063c2d483a1146102a5578063ddbe4f82146102b8578063f2fde38b146102cd57600080fd5b806365c14dc71461022257806379ba5097146102425780638da5cb5b1461024a5780639cb7c5f41461027257600080fd5b80631cdf6343116100d35780631cdf63431461019457806336b402fb146101a7578063398f3773146101ef57806350c946fe1461020257600080fd5b80630c5801e314610105578063117392ce1461011a578063125700111461012d578063181f5a7714610155575b600080fd5b6101186101133660046116ec565b6102e0565b005b610118610128366004611758565b6105f1565b61014061013b366004611770565b61083c565b60405190151581526020015b60405180910390f35b604080518082018252601881527f4361706162696c697479526567697374727920312e302e3000000000000000006020820152905161014c91906117ed565b6101186101a2366004611800565b61084f565b6101e16101b5366004611842565b604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b60405190815260200161014c565b6101186101fd366004611800565b610912565b610215610210366004611770565b610aab565b60405161014c9190611864565b610235610230366004611770565b610b73565b60405161014c91906118ea565b610118610c50565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161014c565b610285610280366004611770565b610d4d565b60405161014c91906119cc565b6101186102a0366004611770565b610df7565b6101186102b3366004611800565b610ec2565b6102c061124c565b60405161014c91906119da565b6101186102db366004611a4a565b611391565b828114610328576040517fab8b67c600000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff16905b848110156105e957600086868381811061036057610360611a67565b905060200201359050600085858481811061037d5761037d611a67565b905060200281019061038f9190611a96565b61039890611b9e565b805190915073ffffffffffffffffffffffffffffffffffffffff166103e9576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805173ffffffffffffffffffffffffffffffffffffffff16331480159061042657503373ffffffffffffffffffffffffffffffffffffffff851614155b1561045d576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160008381526007602052604090205473ffffffffffffffffffffffffffffffffffffffff908116911614158061050f57506020808201516040516104a392016117ed565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206000868152600783529290922091926104f6926001019101611cb7565b6040516020818303038152906040528051906020012014155b156105d6578051600083815260076020908152604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90931692909217825582015160019091019061057c9082611da6565b50806000015173ffffffffffffffffffffffffffffffffffffffff167f14c8f513e8a6d86d2d16b0cb64976de4e72386c4f8068eca3b7354373f8fe97a8383602001516040516105cd929190611ec0565b60405180910390a25b5050806105e290611f08565b9050610344565b505050505050565b6105f96113a5565b604080518235602082810191909152808401358284015282518083038401815260609092019092528051910120610631600382611428565b15610668576040517fe288638f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061067a6080840160608501611a4a565b73ffffffffffffffffffffffffffffffffffffffff16146107e5576106a56080830160608401611a4a565b73ffffffffffffffffffffffffffffffffffffffff163b158061078557506106d36080830160608401611a4a565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f884efe6100000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff91909116906301ffc9a790602401602060405180830381865afa15801561075f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107839190611f40565b155b156107e55761079a6080830160608401611a4a565b6040517fabb5e3fd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161031f565b6107f0600382611443565b506000818152600260205260409020829061080b8282611f62565b505060405181907f65610e5677eedff94555572640e442f89848a109ef8593fa927ac30b2565ff0690600090a25050565b6000610849600583611428565b92915050565b6108576113a5565b60005b8181101561090d57600083838381811061087657610876611a67565b60209081029290920135600081815260079093526040832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001681559093509190506108c76001830182611606565b50506040518181527f1e5877d7b3001d1569bf733b76c7eceda58bd6c031e5b8d0b7042308ba2e9d4f9060200160405180910390a15061090681611f08565b905061085a565b505050565b61091a6113a5565b60005b8181101561090d57600083838381811061093957610939611a67565b905060200281019061094b9190611a96565b61095490611b9e565b805190915073ffffffffffffffffffffffffffffffffffffffff166109a5576040517feeacd93900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600954604080518082018252835173ffffffffffffffffffffffffffffffffffffffff908116825260208086015181840190815260008681526007909252939020825181547fffffffffffffffffffffffff000000000000000000000000000000000000000016921691909117815591519091906001820190610a289082611da6565b50905050600960008154610a3b90611f08565b909155508151602083015160405173ffffffffffffffffffffffffffffffffffffffff909216917fda6697b182650034bd205cdc2dbfabb06bdb3a0a83a2b45bfefa3c4881284e0b91610a9091859190611ec0565b60405180910390a2505080610aa490611f08565b905061091d565b6040805160808101825260008082526020820181905291810191909152606080820152600082815260086020908152604091829020825160808101845281548152600182015481840152600282015473ffffffffffffffffffffffffffffffffffffffff16818501526003820180548551818602810186019096528086529194929360608601939290830182828015610b6357602002820191906000526020600020905b815481526020019060010190808311610b4f575b5050505050815250509050919050565b6040805180820190915260008152606060208201526000828152600760209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff1683526001810180549192840191610bd090611c6a565b80601f0160208091040260200160405190810160405280929190818152602001828054610bfc90611c6a565b8015610b635780601f10610c1e57610100808354040283529160200191610b63565b820191906000526020600020905b815481529060010190602001808311610c2c57505050919092525091949350505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610cd1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161031f565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b604080516080808201835260008083526020808401829052838501829052606084018290528582526002808252918590208551938401865280548452600180820154928501929092529182015493949293919284019160ff1690811115610db657610db661192d565b6001811115610dc757610dc761192d565b815260029190910154610100900473ffffffffffffffffffffffffffffffffffffffff1660209091015292915050565b610dff6113a5565b610e0a600382611428565b610e43576040517fe181733f0000000000000000000000000000000000000000000000000000000081526004810182905260240161031f565b610e4e600582611428565b15610e88576040517f16950d1d0000000000000000000000000000000000000000000000000000000081526004810182905260240161031f565b610e93600582611443565b5060405181907fdcea1b78b6ddc31592a94607d537543fcaafda6cc52d6d5cc7bbfca1422baf2190600090a250565b60005b8181101561090d576000838383818110610ee157610ee1611a67565b9050602002810190610ef39190611fe4565b610efc90612018565b805160009081526007602090815260408083208151808301909252805473ffffffffffffffffffffffffffffffffffffffff168252600181018054959650939491939092840191610f4c90611c6a565b80601f0160208091040260200160405190810160405280929190818152602001828054610f7890611c6a565b8015610fc55780601f10610f9a57610100808354040283529160200191610fc5565b820191906000526020600020905b815481529060010190602001808311610fa857829003601f168201915b5050505050815250509050806000015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611039576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808301516000908152600890915260409020600301541515808061106157506020830151155b156110a05782602001516040517f64e2ee9200000000000000000000000000000000000000000000000000000000815260040161031f91815260200190565b8260600151516000036110e55782606001516040517f3748d4c600000000000000000000000000000000000000000000000000000000815260040161031f91906120ed565b60005b836060015151811015611172576111268460600151828151811061110e5761110e611a67565b6020026020010151600361142890919063ffffffff16565b6111625783606001516040517f3748d4c600000000000000000000000000000000000000000000000000000000815260040161031f91906120ed565b61116b81611f08565b90506110e8565b506020838101805160009081526008835260409081902086518155915160018301558501516002820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790556060850151805186936111f7926003850192910190611640565b505050602083810151845160408051928352928201527f5bfe8a52ad26ac6ee7b0cd46d2fd92be04735a31c45ef8aa3d4b7ea1b61bbc1f910160405180910390a15050508061124590611f08565b9050610ec5565b6060600061125a600361144f565b90506000611268600561145c565b82516112749190612125565b67ffffffffffffffff81111561128c5761128c611ad4565b6040519080825280602002602001820160405280156112fc57816020015b6040805160808101825260008082526020808301829052928201819052606082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092019101816112aa5790505b5090506000805b835181101561138857600084828151811061132057611320611a67565b6020026020010151905061133e81600561142890919063ffffffff16565b6113775761134b81610d4d565b84848151811061135d5761135d611a67565b6020026020010181905250828061137390611f08565b9350505b5061138181611f08565b9050611303565b50909392505050565b6113996113a5565b6113a281611466565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611426576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161031f565b565b600081815260018301602052604081205415155b9392505050565b600061143c838361155b565b6060600061143c836115aa565b6000610849825490565b3373ffffffffffffffffffffffffffffffffffffffff8216036114e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161031f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008181526001830160205260408120546115a257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610849565b506000610849565b6060816000018054806020026020016040519081016040528092919081815260200182805480156115fa57602002820191906000526020600020905b8154815260200190600101908083116115e6575b50505050509050919050565b50805461161290611c6a565b6000825580601f10611622575050565b601f0160209004906000526020600020908101906113a2919061168b565b82805482825590600052602060002090810192821561167b579160200282015b8281111561167b578251825591602001919060010190611660565b5061168792915061168b565b5090565b5b80821115611687576000815560010161168c565b60008083601f8401126116b257600080fd5b50813567ffffffffffffffff8111156116ca57600080fd5b6020830191508360208260051b85010111156116e557600080fd5b9250929050565b6000806000806040858703121561170257600080fd5b843567ffffffffffffffff8082111561171a57600080fd5b611726888389016116a0565b9096509450602087013591508082111561173f57600080fd5b5061174c878288016116a0565b95989497509550505050565b60006080828403121561176a57600080fd5b50919050565b60006020828403121561178257600080fd5b5035919050565b6000815180845260005b818110156117af57602081850181015186830182015201611793565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061143c6020830184611789565b6000806020838503121561181357600080fd5b823567ffffffffffffffff81111561182a57600080fd5b611836858286016116a0565b90969095509350505050565b6000806040838503121561185557600080fd5b50508035926020909101359150565b6000602080835260a0830184518285015281850151604085015273ffffffffffffffffffffffffffffffffffffffff6040860151166060850152606085015160808086015281815180845260c0870191508483019350600092505b808310156118df57835182529284019260019290920191908401906118bf565b509695505050505050565b6020815273ffffffffffffffffffffffffffffffffffffffff8251166020820152600060208301516040808401526119256060840182611789565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b80518252602081015160208301526040810151600281106119a6577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b604083015260609081015173ffffffffffffffffffffffffffffffffffffffff16910152565b60808101610849828461195c565b6020808252825182820181905260009190848201906040850190845b81811015611a1c57611a0983855161195c565b92840192608092909201916001016119f6565b50909695505050505050565b73ffffffffffffffffffffffffffffffffffffffff811681146113a257600080fd5b600060208284031215611a5c57600080fd5b813561143c81611a28565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112611aca57600080fd5b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715611b2657611b26611ad4565b60405290565b6040516080810167ffffffffffffffff81118282101715611b2657611b26611ad4565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611b9657611b96611ad4565b604052919050565b600060408236031215611bb057600080fd5b611bb8611b03565b8235611bc381611a28565b815260208381013567ffffffffffffffff80821115611be157600080fd5b9085019036601f830112611bf457600080fd5b813581811115611c0657611c06611ad4565b611c36847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611b4f565b91508082523684828501011115611c4c57600080fd5b80848401858401376000908201840152918301919091525092915050565b600181811c90821680611c7e57607f821691505b60208210810361176a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000602080835260008454611ccb81611c6a565b80848701526040600180841660008114611cec5760018114611d2457611d52565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838a01528284151560051b8a01019550611d52565b896000528660002060005b85811015611d4a5781548b8201860152908301908801611d2f565b8a0184019650505b509398975050505050505050565b601f82111561090d57600081815260208120601f850160051c81016020861015611d875750805b601f850160051c820191505b818110156105e957828155600101611d93565b815167ffffffffffffffff811115611dc057611dc0611ad4565b611dd481611dce8454611c6a565b84611d60565b602080601f831160018114611e275760008415611df15750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556105e9565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015611e7457888601518255948401946001909101908401611e55565b5085821015611eb057878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b8281526040602082015260006119256040830184611789565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611f3957611f39611ed9565b5060010190565b600060208284031215611f5257600080fd5b8151801515811461143c57600080fd5b813581556020820135600182015560028101604083013560028110611f8657600080fd5b81546060850135611f9681611a28565b74ffffffffffffffffffffffffffffffffffffffff008160081b1660ff84167fffffffffffffffffffffff000000000000000000000000000000000000000000841617178455505050505050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112611aca57600080fd5b60006080823603121561202a57600080fd5b612032611b2c565b8235815260208084013581830152604084013561204e81611a28565b6040830152606084013567ffffffffffffffff8082111561206e57600080fd5b9085019036601f83011261208157600080fd5b81358181111561209357612093611ad4565b8060051b91506120a4848301611b4f565b81815291830184019184810190368411156120be57600080fd5b938501935b838510156120dc578435825293850193908501906120c3565b606087015250939695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611a1c57835183529284019291840191600101612109565b8181038181111561084957610849611ed956fea164736f6c6343000813000a", } var CapabilityRegistryABI = CapabilityRegistryMetaData.ABI @@ -212,9 +212,9 @@ func (_CapabilityRegistry *CapabilityRegistryCallerSession) GetCapabilities() ([ return _CapabilityRegistry.Contract.GetCapabilities(&_CapabilityRegistry.CallOpts) } -func (_CapabilityRegistry *CapabilityRegistryCaller) GetCapability(opts *bind.CallOpts, capabilityID [32]byte) (CapabilityRegistryCapability, error) { +func (_CapabilityRegistry *CapabilityRegistryCaller) GetCapability(opts *bind.CallOpts, hashedId [32]byte) (CapabilityRegistryCapability, error) { var out []interface{} - err := _CapabilityRegistry.contract.Call(opts, &out, "getCapability", capabilityID) + err := _CapabilityRegistry.contract.Call(opts, &out, "getCapability", hashedId) if err != nil { return *new(CapabilityRegistryCapability), err @@ -226,17 +226,17 @@ func (_CapabilityRegistry *CapabilityRegistryCaller) GetCapability(opts *bind.Ca } -func (_CapabilityRegistry *CapabilityRegistrySession) GetCapability(capabilityID [32]byte) (CapabilityRegistryCapability, error) { - return _CapabilityRegistry.Contract.GetCapability(&_CapabilityRegistry.CallOpts, capabilityID) +func (_CapabilityRegistry *CapabilityRegistrySession) GetCapability(hashedId [32]byte) (CapabilityRegistryCapability, error) { + return _CapabilityRegistry.Contract.GetCapability(&_CapabilityRegistry.CallOpts, hashedId) } -func (_CapabilityRegistry *CapabilityRegistryCallerSession) GetCapability(capabilityID [32]byte) (CapabilityRegistryCapability, error) { - return _CapabilityRegistry.Contract.GetCapability(&_CapabilityRegistry.CallOpts, capabilityID) +func (_CapabilityRegistry *CapabilityRegistryCallerSession) GetCapability(hashedId [32]byte) (CapabilityRegistryCapability, error) { + return _CapabilityRegistry.Contract.GetCapability(&_CapabilityRegistry.CallOpts, hashedId) } -func (_CapabilityRegistry *CapabilityRegistryCaller) GetCapabilityID(opts *bind.CallOpts, capabilityType [32]byte, version [32]byte) ([32]byte, error) { +func (_CapabilityRegistry *CapabilityRegistryCaller) GetHashedCapabilityId(opts *bind.CallOpts, labelledName [32]byte, version [32]byte) ([32]byte, error) { var out []interface{} - err := _CapabilityRegistry.contract.Call(opts, &out, "getCapabilityID", capabilityType, version) + err := _CapabilityRegistry.contract.Call(opts, &out, "getHashedCapabilityId", labelledName, version) if err != nil { return *new([32]byte), err @@ -248,12 +248,12 @@ func (_CapabilityRegistry *CapabilityRegistryCaller) GetCapabilityID(opts *bind. } -func (_CapabilityRegistry *CapabilityRegistrySession) GetCapabilityID(capabilityType [32]byte, version [32]byte) ([32]byte, error) { - return _CapabilityRegistry.Contract.GetCapabilityID(&_CapabilityRegistry.CallOpts, capabilityType, version) +func (_CapabilityRegistry *CapabilityRegistrySession) GetHashedCapabilityId(labelledName [32]byte, version [32]byte) ([32]byte, error) { + return _CapabilityRegistry.Contract.GetHashedCapabilityId(&_CapabilityRegistry.CallOpts, labelledName, version) } -func (_CapabilityRegistry *CapabilityRegistryCallerSession) GetCapabilityID(capabilityType [32]byte, version [32]byte) ([32]byte, error) { - return _CapabilityRegistry.Contract.GetCapabilityID(&_CapabilityRegistry.CallOpts, capabilityType, version) +func (_CapabilityRegistry *CapabilityRegistryCallerSession) GetHashedCapabilityId(labelledName [32]byte, version [32]byte) ([32]byte, error) { + return _CapabilityRegistry.Contract.GetHashedCapabilityId(&_CapabilityRegistry.CallOpts, labelledName, version) } func (_CapabilityRegistry *CapabilityRegistryCaller) GetNode(opts *bind.CallOpts, p2pId [32]byte) (CapabilityRegistryNode, error) { @@ -300,9 +300,9 @@ func (_CapabilityRegistry *CapabilityRegistryCallerSession) GetNodeOperator(node return _CapabilityRegistry.Contract.GetNodeOperator(&_CapabilityRegistry.CallOpts, nodeOperatorId) } -func (_CapabilityRegistry *CapabilityRegistryCaller) IsCapabilityDeprecated(opts *bind.CallOpts, capabilityId [32]byte) (bool, error) { +func (_CapabilityRegistry *CapabilityRegistryCaller) IsCapabilityDeprecated(opts *bind.CallOpts, hashedCapabilityId [32]byte) (bool, error) { var out []interface{} - err := _CapabilityRegistry.contract.Call(opts, &out, "isCapabilityDeprecated", capabilityId) + err := _CapabilityRegistry.contract.Call(opts, &out, "isCapabilityDeprecated", hashedCapabilityId) if err != nil { return *new(bool), err @@ -314,12 +314,12 @@ func (_CapabilityRegistry *CapabilityRegistryCaller) IsCapabilityDeprecated(opts } -func (_CapabilityRegistry *CapabilityRegistrySession) IsCapabilityDeprecated(capabilityId [32]byte) (bool, error) { - return _CapabilityRegistry.Contract.IsCapabilityDeprecated(&_CapabilityRegistry.CallOpts, capabilityId) +func (_CapabilityRegistry *CapabilityRegistrySession) IsCapabilityDeprecated(hashedCapabilityId [32]byte) (bool, error) { + return _CapabilityRegistry.Contract.IsCapabilityDeprecated(&_CapabilityRegistry.CallOpts, hashedCapabilityId) } -func (_CapabilityRegistry *CapabilityRegistryCallerSession) IsCapabilityDeprecated(capabilityId [32]byte) (bool, error) { - return _CapabilityRegistry.Contract.IsCapabilityDeprecated(&_CapabilityRegistry.CallOpts, capabilityId) +func (_CapabilityRegistry *CapabilityRegistryCallerSession) IsCapabilityDeprecated(hashedCapabilityId [32]byte) (bool, error) { + return _CapabilityRegistry.Contract.IsCapabilityDeprecated(&_CapabilityRegistry.CallOpts, hashedCapabilityId) } func (_CapabilityRegistry *CapabilityRegistryCaller) Owner(opts *bind.CallOpts) (common.Address, error) { @@ -414,16 +414,16 @@ func (_CapabilityRegistry *CapabilityRegistryTransactorSession) AddNodes(nodes [ return _CapabilityRegistry.Contract.AddNodes(&_CapabilityRegistry.TransactOpts, nodes) } -func (_CapabilityRegistry *CapabilityRegistryTransactor) DeprecateCapability(opts *bind.TransactOpts, capabilityId [32]byte) (*types.Transaction, error) { - return _CapabilityRegistry.contract.Transact(opts, "deprecateCapability", capabilityId) +func (_CapabilityRegistry *CapabilityRegistryTransactor) DeprecateCapability(opts *bind.TransactOpts, hashedCapabilityId [32]byte) (*types.Transaction, error) { + return _CapabilityRegistry.contract.Transact(opts, "deprecateCapability", hashedCapabilityId) } -func (_CapabilityRegistry *CapabilityRegistrySession) DeprecateCapability(capabilityId [32]byte) (*types.Transaction, error) { - return _CapabilityRegistry.Contract.DeprecateCapability(&_CapabilityRegistry.TransactOpts, capabilityId) +func (_CapabilityRegistry *CapabilityRegistrySession) DeprecateCapability(hashedCapabilityId [32]byte) (*types.Transaction, error) { + return _CapabilityRegistry.Contract.DeprecateCapability(&_CapabilityRegistry.TransactOpts, hashedCapabilityId) } -func (_CapabilityRegistry *CapabilityRegistryTransactorSession) DeprecateCapability(capabilityId [32]byte) (*types.Transaction, error) { - return _CapabilityRegistry.Contract.DeprecateCapability(&_CapabilityRegistry.TransactOpts, capabilityId) +func (_CapabilityRegistry *CapabilityRegistryTransactorSession) DeprecateCapability(hashedCapabilityId [32]byte) (*types.Transaction, error) { + return _CapabilityRegistry.Contract.DeprecateCapability(&_CapabilityRegistry.TransactOpts, hashedCapabilityId) } func (_CapabilityRegistry *CapabilityRegistryTransactor) RemoveNodeOperators(opts *bind.TransactOpts, nodeOperatorIds []*big.Int) (*types.Transaction, error) { @@ -523,32 +523,32 @@ func (it *CapabilityRegistryCapabilityAddedIterator) Close() error { } type CapabilityRegistryCapabilityAdded struct { - CapabilityId [32]byte - Raw types.Log + HashedCapabilityId [32]byte + Raw types.Log } -func (_CapabilityRegistry *CapabilityRegistryFilterer) FilterCapabilityAdded(opts *bind.FilterOpts, capabilityId [][32]byte) (*CapabilityRegistryCapabilityAddedIterator, error) { +func (_CapabilityRegistry *CapabilityRegistryFilterer) FilterCapabilityAdded(opts *bind.FilterOpts, hashedCapabilityId [][32]byte) (*CapabilityRegistryCapabilityAddedIterator, error) { - var capabilityIdRule []interface{} - for _, capabilityIdItem := range capabilityId { - capabilityIdRule = append(capabilityIdRule, capabilityIdItem) + var hashedCapabilityIdRule []interface{} + for _, hashedCapabilityIdItem := range hashedCapabilityId { + hashedCapabilityIdRule = append(hashedCapabilityIdRule, hashedCapabilityIdItem) } - logs, sub, err := _CapabilityRegistry.contract.FilterLogs(opts, "CapabilityAdded", capabilityIdRule) + logs, sub, err := _CapabilityRegistry.contract.FilterLogs(opts, "CapabilityAdded", hashedCapabilityIdRule) if err != nil { return nil, err } return &CapabilityRegistryCapabilityAddedIterator{contract: _CapabilityRegistry.contract, event: "CapabilityAdded", logs: logs, sub: sub}, nil } -func (_CapabilityRegistry *CapabilityRegistryFilterer) WatchCapabilityAdded(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryCapabilityAdded, capabilityId [][32]byte) (event.Subscription, error) { +func (_CapabilityRegistry *CapabilityRegistryFilterer) WatchCapabilityAdded(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryCapabilityAdded, hashedCapabilityId [][32]byte) (event.Subscription, error) { - var capabilityIdRule []interface{} - for _, capabilityIdItem := range capabilityId { - capabilityIdRule = append(capabilityIdRule, capabilityIdItem) + var hashedCapabilityIdRule []interface{} + for _, hashedCapabilityIdItem := range hashedCapabilityId { + hashedCapabilityIdRule = append(hashedCapabilityIdRule, hashedCapabilityIdItem) } - logs, sub, err := _CapabilityRegistry.contract.WatchLogs(opts, "CapabilityAdded", capabilityIdRule) + logs, sub, err := _CapabilityRegistry.contract.WatchLogs(opts, "CapabilityAdded", hashedCapabilityIdRule) if err != nil { return nil, err } @@ -650,32 +650,32 @@ func (it *CapabilityRegistryCapabilityDeprecatedIterator) Close() error { } type CapabilityRegistryCapabilityDeprecated struct { - CapabilityId [32]byte - Raw types.Log + HashedCapabilityId [32]byte + Raw types.Log } -func (_CapabilityRegistry *CapabilityRegistryFilterer) FilterCapabilityDeprecated(opts *bind.FilterOpts, capabilityId [][32]byte) (*CapabilityRegistryCapabilityDeprecatedIterator, error) { +func (_CapabilityRegistry *CapabilityRegistryFilterer) FilterCapabilityDeprecated(opts *bind.FilterOpts, hashedCapabilityId [][32]byte) (*CapabilityRegistryCapabilityDeprecatedIterator, error) { - var capabilityIdRule []interface{} - for _, capabilityIdItem := range capabilityId { - capabilityIdRule = append(capabilityIdRule, capabilityIdItem) + var hashedCapabilityIdRule []interface{} + for _, hashedCapabilityIdItem := range hashedCapabilityId { + hashedCapabilityIdRule = append(hashedCapabilityIdRule, hashedCapabilityIdItem) } - logs, sub, err := _CapabilityRegistry.contract.FilterLogs(opts, "CapabilityDeprecated", capabilityIdRule) + logs, sub, err := _CapabilityRegistry.contract.FilterLogs(opts, "CapabilityDeprecated", hashedCapabilityIdRule) if err != nil { return nil, err } return &CapabilityRegistryCapabilityDeprecatedIterator{contract: _CapabilityRegistry.contract, event: "CapabilityDeprecated", logs: logs, sub: sub}, nil } -func (_CapabilityRegistry *CapabilityRegistryFilterer) WatchCapabilityDeprecated(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryCapabilityDeprecated, capabilityId [][32]byte) (event.Subscription, error) { +func (_CapabilityRegistry *CapabilityRegistryFilterer) WatchCapabilityDeprecated(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryCapabilityDeprecated, hashedCapabilityId [][32]byte) (event.Subscription, error) { - var capabilityIdRule []interface{} - for _, capabilityIdItem := range capabilityId { - capabilityIdRule = append(capabilityIdRule, capabilityIdItem) + var hashedCapabilityIdRule []interface{} + for _, hashedCapabilityIdItem := range hashedCapabilityId { + hashedCapabilityIdRule = append(hashedCapabilityIdRule, hashedCapabilityIdItem) } - logs, sub, err := _CapabilityRegistry.contract.WatchLogs(opts, "CapabilityDeprecated", capabilityIdRule) + logs, sub, err := _CapabilityRegistry.contract.WatchLogs(opts, "CapabilityDeprecated", hashedCapabilityIdRule) if err != nil { return nil, err } @@ -1544,15 +1544,15 @@ func (_CapabilityRegistry *CapabilityRegistry) Address() common.Address { type CapabilityRegistryInterface interface { GetCapabilities(opts *bind.CallOpts) ([]CapabilityRegistryCapability, error) - GetCapability(opts *bind.CallOpts, capabilityID [32]byte) (CapabilityRegistryCapability, error) + GetCapability(opts *bind.CallOpts, hashedId [32]byte) (CapabilityRegistryCapability, error) - GetCapabilityID(opts *bind.CallOpts, capabilityType [32]byte, version [32]byte) ([32]byte, error) + GetHashedCapabilityId(opts *bind.CallOpts, labelledName [32]byte, version [32]byte) ([32]byte, error) GetNode(opts *bind.CallOpts, p2pId [32]byte) (CapabilityRegistryNode, error) GetNodeOperator(opts *bind.CallOpts, nodeOperatorId *big.Int) (CapabilityRegistryNodeOperator, error) - IsCapabilityDeprecated(opts *bind.CallOpts, capabilityId [32]byte) (bool, error) + IsCapabilityDeprecated(opts *bind.CallOpts, hashedCapabilityId [32]byte) (bool, error) Owner(opts *bind.CallOpts) (common.Address, error) @@ -1566,7 +1566,7 @@ type CapabilityRegistryInterface interface { AddNodes(opts *bind.TransactOpts, nodes []CapabilityRegistryNode) (*types.Transaction, error) - DeprecateCapability(opts *bind.TransactOpts, capabilityId [32]byte) (*types.Transaction, error) + DeprecateCapability(opts *bind.TransactOpts, hashedCapabilityId [32]byte) (*types.Transaction, error) RemoveNodeOperators(opts *bind.TransactOpts, nodeOperatorIds []*big.Int) (*types.Transaction, error) @@ -1574,15 +1574,15 @@ type CapabilityRegistryInterface interface { UpdateNodeOperators(opts *bind.TransactOpts, nodeOperatorIds []*big.Int, nodeOperators []CapabilityRegistryNodeOperator) (*types.Transaction, error) - FilterCapabilityAdded(opts *bind.FilterOpts, capabilityId [][32]byte) (*CapabilityRegistryCapabilityAddedIterator, error) + FilterCapabilityAdded(opts *bind.FilterOpts, hashedCapabilityId [][32]byte) (*CapabilityRegistryCapabilityAddedIterator, error) - WatchCapabilityAdded(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryCapabilityAdded, capabilityId [][32]byte) (event.Subscription, error) + WatchCapabilityAdded(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryCapabilityAdded, hashedCapabilityId [][32]byte) (event.Subscription, error) ParseCapabilityAdded(log types.Log) (*CapabilityRegistryCapabilityAdded, error) - FilterCapabilityDeprecated(opts *bind.FilterOpts, capabilityId [][32]byte) (*CapabilityRegistryCapabilityDeprecatedIterator, error) + FilterCapabilityDeprecated(opts *bind.FilterOpts, hashedCapabilityId [][32]byte) (*CapabilityRegistryCapabilityDeprecatedIterator, error) - WatchCapabilityDeprecated(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryCapabilityDeprecated, capabilityId [][32]byte) (event.Subscription, error) + WatchCapabilityDeprecated(opts *bind.WatchOpts, sink chan<- *CapabilityRegistryCapabilityDeprecated, hashedCapabilityId [][32]byte) (event.Subscription, error) ParseCapabilityDeprecated(log types.Log) (*CapabilityRegistryCapabilityDeprecated, error) diff --git a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 3e0110cdee6..182c8da3f7e 100644 --- a/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/keystone/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,4 +1,4 @@ GETH_VERSION: 1.13.8 forwarder: ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.abi ../../../contracts/solc/v0.8.19/KeystoneForwarder/KeystoneForwarder.bin b4c900aae9e022f01abbac7993d41f93912247613ac6270b0c4da4ef6f2016e3 -keystone_capability_registry: ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.abi ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.bin b7d748b585d7cf1cf91e268b609613f77a8390d119e03d724b49c25fd2ea75e7 +keystone_capability_registry: ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.abi ../../../contracts/solc/v0.8.19/CapabilityRegistry/CapabilityRegistry.bin aeb366351d69f320c610419a3e09a991bd6ea75690778835eb8f6421d1277f44 ocr3_capability: ../../../contracts/solc/v0.8.19/OCR3Capability/OCR3Capability.abi ../../../contracts/solc/v0.8.19/OCR3Capability/OCR3Capability.bin 9dcbdf55bd5729ba266148da3f17733eb592c871c2108ccca546618628fd9ad2 diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go index 9629e845336..e405102e123 100644 --- a/core/services/workflows/engine.go +++ b/core/services/workflows/engine.go @@ -78,7 +78,7 @@ func (e *Engine) resolveWorkflowCapabilities(ctx context.Context) error { // triggersInitialized := true for _, t := range e.workflow.triggers { - tg, err := e.registry.GetTrigger(ctx, t.Type) + tg, err := e.registry.GetTrigger(ctx, t.ID) if err != nil { e.logger.Errorf("failed to get trigger capability: %s", err) // we don't immediately return here, since we want to retry all triggers @@ -123,16 +123,16 @@ func (e *Engine) initializeCapability(ctx context.Context, s *step) error { return nil } - cp, err := e.registry.Get(ctx, s.Type) + cp, err := e.registry.Get(ctx, s.ID) if err != nil { - return fmt.Errorf("failed to get capability with ref %s: %s", s.Type, err) + return fmt.Errorf("failed to get capability with ref %s: %s", s.ID, err) } // We configure actions, consensus and targets here, and // they all satisfy the `CallbackCapability` interface cc, ok := cp.(capabilities.CallbackCapability) if !ok { - return fmt.Errorf("could not coerce capability %s to CallbackCapability", s.Type) + return fmt.Errorf("could not coerce capability %s to CallbackCapability", s.ID) } if s.config == nil { @@ -275,7 +275,7 @@ func (e *Engine) registerTrigger(ctx context.Context, t *triggerCapability) erro } eventsCh, err := t.trigger.RegisterTrigger(ctx, triggerRegRequest) if err != nil { - return fmt.Errorf("failed to instantiate trigger %s, %s", t.Type, err) + return fmt.Errorf("failed to instantiate trigger %s, %s", t.ID, err) } go func() { diff --git a/core/services/workflows/engine_test.go b/core/services/workflows/engine_test.go index 3896f840ee8..ff4c5682129 100644 --- a/core/services/workflows/engine_test.go +++ b/core/services/workflows/engine_test.go @@ -19,7 +19,7 @@ import ( const hardcodedWorkflow = ` triggers: - - type: "mercury-trigger" + - id: "mercury-trigger" config: feedIds: - "0x1111111111111111111100000000000000000000000000000000000000000000" @@ -27,7 +27,7 @@ triggers: - "0x3333333333333333333300000000000000000000000000000000000000000000" consensus: - - type: "offchain_reporting" + - id: "offchain_reporting" ref: "evm_median" inputs: observations: @@ -49,14 +49,14 @@ consensus: abi: "mercury_reports bytes[]" targets: - - type: "write_polygon-testnet-mumbai" + - id: "write_polygon-testnet-mumbai" inputs: report: "$(evm_median.outputs.report)" config: address: "0x3F3554832c636721F1fD1822Ccca0354576741Ef" params: ["$(report)"] abi: "receive(report bytes)" - - type: "write_ethereum-testnet-sepolia" + - id: "write_ethereum-testnet-sepolia" inputs: report: "$(evm_median.outputs.report)" config: @@ -215,7 +215,7 @@ func TestEngineWithHardcodedWorkflow(t *testing.T) { const ( simpleWorkflow = ` triggers: - - type: "mercury-trigger" + - id: "mercury-trigger" config: feedlist: - "0x1111111111111111111100000000000000000000000000000000000000000000" # ETHUSD @@ -223,7 +223,7 @@ triggers: - "0x3333333333333333333300000000000000000000000000000000000000000000" # BTCUSD consensus: - - type: "offchain_reporting" + - id: "offchain_reporting" ref: "evm_median" inputs: observations: @@ -245,7 +245,7 @@ consensus: abi: "mercury_reports bytes[]" targets: - - type: "write_polygon-testnet-mumbai" + - id: "write_polygon-testnet-mumbai" inputs: report: "$(evm_median.outputs.report)" config: @@ -368,7 +368,7 @@ func TestEngine_ErrorsTheWorkflowIfAStepErrors(t *testing.T) { const ( multiStepWorkflow = ` triggers: - - type: "mercury-trigger" + - id: "mercury-trigger" config: feedlist: - "0x1111111111111111111100000000000000000000000000000000000000000000" # ETHUSD @@ -376,14 +376,14 @@ triggers: - "0x3333333333333333333300000000000000000000000000000000000000000000" # BTCUSD actions: - - type: "read_chain_action" + - id: "read_chain_action" ref: "read_chain_action" inputs: action: - "$(trigger.outputs)" consensus: - - type: "offchain_reporting" + - id: "offchain_reporting" ref: "evm_median" inputs: observations: @@ -406,7 +406,7 @@ consensus: abi: "mercury_reports bytes[]" targets: - - type: "write_polygon-testnet-mumbai" + - id: "write_polygon-testnet-mumbai" inputs: report: "$(evm_median.outputs.report)" config: diff --git a/core/services/workflows/models.go b/core/services/workflows/models.go index 92abf36d2c0..cd167403089 100644 --- a/core/services/workflows/models.go +++ b/core/services/workflows/models.go @@ -19,8 +19,7 @@ type stepRequest struct { // // Within the workflow spec, they are called "Capability Properties". type stepDefinition struct { - // TODO: Rename this, type here refers to the capability ID, not its type. - Type string `json:"type" jsonschema:"required"` + ID string `json:"id" jsonschema:"required"` Ref string `json:"ref,omitempty" jsonschema:"pattern=^[a-z0-9_]+$"` Inputs map[string]any `json:"inputs,omitempty"` Config map[string]any `json:"config" jsonschema:"required"` @@ -160,7 +159,7 @@ func Parse(yamlWorkflow string) (*workflow, error) { // To handle this, we default the `Ref` to the type, but ideally we // should find a better long-term way to handle this. if s.Ref == "" { - s.Ref = s.Type + s.Ref = s.ID } innerErr := g.AddVertex(&step{stepDefinition: s}) diff --git a/core/services/workflows/models_test.go b/core/services/workflows/models_test.go index 232e91eaaa8..0964b13d277 100644 --- a/core/services/workflows/models_test.go +++ b/core/services/workflows/models_test.go @@ -19,23 +19,23 @@ func TestParse_Graph(t *testing.T) { name: "basic example", yaml: ` triggers: - - type: "a-trigger" + - id: "a-trigger" actions: - - type: "an-action" + - id: "an-action" ref: "an-action" inputs: trigger_output: $(trigger.outputs) consensus: - - type: "a-consensus" + - id: "a-consensus" ref: "a-consensus" inputs: trigger_output: $(trigger.outputs) an-action_output: $(an-action.outputs) targets: - - type: "a-target" + - id: "a-target" ref: "a-target" inputs: consensus_output: $(a-consensus.outputs) @@ -58,28 +58,28 @@ targets: name: "circular relationship", yaml: ` triggers: - - type: "a-trigger" + - id: "a-trigger" actions: - - type: "an-action" + - id: "an-action" ref: "an-action" inputs: trigger_output: $(trigger.outputs) output: $(a-second-action.outputs) - - type: "a-second-action" + - id: "a-second-action" ref: "a-second-action" inputs: output: $(an-action.outputs) consensus: - - type: "a-consensus" + - id: "a-consensus" ref: "a-consensus" inputs: trigger_output: $(trigger.outputs) an-action_output: $(an-action.outputs) targets: - - type: "a-target" + - id: "a-target" ref: "a-target" inputs: consensus_output: $(a-consensus.outputs) @@ -90,32 +90,32 @@ targets: name: "indirect circular relationship", yaml: ` triggers: - - type: "a-trigger" + - id: "a-trigger" actions: - - type: "an-action" + - id: "an-action" ref: "an-action" inputs: trigger_output: $(trigger.outputs) action_output: $(a-third-action.outputs) - - type: "a-second-action" + - id: "a-second-action" ref: "a-second-action" inputs: output: $(an-action.outputs) - - type: "a-third-action" + - id: "a-third-action" ref: "a-third-action" inputs: output: $(a-second-action.outputs) consensus: - - type: "a-consensus" + - id: "a-consensus" ref: "a-consensus" inputs: trigger_output: $(trigger.outputs) an-action_output: $(an-action.outputs) targets: - - type: "a-target" + - id: "a-target" ref: "a-target" inputs: consensus_output: $(a-consensus.outputs) @@ -126,23 +126,23 @@ targets: name: "relationship doesn't exist", yaml: ` triggers: - - type: "a-trigger" + - id: "a-trigger" actions: - - type: "an-action" + - id: "an-action" ref: "an-action" inputs: trigger_output: $(trigger.outputs) action_output: $(missing-action.outputs) consensus: - - type: "a-consensus" + - id: "a-consensus" ref: "a-consensus" inputs: an-action_output: $(an-action.outputs) targets: - - type: "a-target" + - id: "a-target" ref: "a-target" inputs: consensus_output: $(a-consensus.outputs) @@ -153,23 +153,23 @@ targets: name: "two trigger nodes", yaml: ` triggers: - - type: "a-trigger" - - type: "a-second-trigger" + - id: "a-trigger" + - id: "a-second-trigger" actions: - - type: "an-action" + - id: "an-action" ref: "an-action" inputs: trigger_output: $(trigger.outputs) consensus: - - type: "a-consensus" + - id: "a-consensus" ref: "a-consensus" inputs: an-action_output: $(an-action.outputs) targets: - - type: "a-target" + - id: "a-target" ref: "a-target" inputs: consensus_output: $(a-consensus.outputs) @@ -191,21 +191,21 @@ targets: name: "non-trigger step with no dependent refs", yaml: ` triggers: - - type: "a-trigger" - - type: "a-second-trigger" + - id: "a-trigger" + - id: "a-second-trigger" actions: - - type: "an-action" + - id: "an-action" ref: "an-action" inputs: hello: "world" consensus: - - type: "a-consensus" + - id: "a-consensus" ref: "a-consensus" inputs: trigger_output: $(trigger.outputs) action_output: $(an-action.outputs) targets: - - type: "a-target" + - id: "a-target" ref: "a-target" inputs: consensus_output: $(a-consensus.outputs) diff --git a/core/services/workflows/models_yaml.go b/core/services/workflows/models_yaml.go index 280a895f1b8..5ed7941f84a 100644 --- a/core/services/workflows/models_yaml.go +++ b/core/services/workflows/models_yaml.go @@ -166,17 +166,19 @@ func (m mapping) MarshalJSON() ([]byte, error) { // It allows for multiple ways of defining a step, which we later // convert to a single representation, `stepDefinition`. type stepDefinitionYaml struct { - // A universally unique name for a capability will be defined under the “type” property. The uniqueness will, eventually, be enforced in the Capability Registry . Semver must be used to specify the version of the Capability at the end of the type field. Capability versions must be immutable. + // A universally unique name for a capability will be defined under the “id” property. The uniqueness will, eventually, be enforced in the Capability Registry. + // + // Semver must be used to specify the version of the Capability at the end of the id field. Capability versions must be immutable. // // Initially, we will require major versions. This will ease upgrades early on while we develop the infrastructure. // // Eventually, we might support minor version and specific version pins. This will allow workflow authors to have flexibility when selecting the version, and node operators will be able to determine when they should update their capabilities. // - // There are two ways to specify a type - using a string as a fully qualified ID or a structured table. When using a table, labels are ordered alphanumerically and joined into a string following a + // There are two ways to specify an id - using a string as a fully qualified ID or a structured table. When using a table, labels are ordered alphanumerically and joined into a string following a // {name}:{label1_key}_{label1_value}:{label2_key}_{label2_value}@{version} // pattern. // - // The “type” supports [a-z0-9_-:] characters followed by an @ and [semver regex] at the end. + // The “id” supports [a-z0-9_-:] characters followed by an @ and [semver regex] at the end. // // Validation must throw an error if: // @@ -184,11 +186,11 @@ type stepDefinitionYaml struct { // (For Keystone only.) More specific than a major version is specified. // // Example (string) - // type: read_chain:chain_ethereum:network_mainnet@1 + // id: read_chain:chain_ethereum:network_mainnet@1 // // Example (table) // - // type: + // id: // name: read_chain // version: 1 // labels: @@ -196,7 +198,7 @@ type stepDefinitionYaml struct { // network: mainnet // // [semver regex]: https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string - Type stepDefinitionType `json:"type" jsonschema:"required"` + ID stepDefinitionID `json:"id" jsonschema:"required"` // Actions and Consensus capabilities have a required “ref” property that must be unique within a Workflow file (not universally) This property enables referencing outputs and is required because Actions and Consensus always need to be referenced in the following phases. Triggers can optionally specify if they need to be referenced. // @@ -213,7 +215,7 @@ type stepDefinitionYaml struct { // Capabilities can specify an additional optional ”inputs” property. It allows specifying a dependency on the result of one or more other capabilities. These are always runtime values that cannot be provided upfront. It takes a map of the argument name internal to the capability and an explicit reference to the values. // - // References are specified using the [type].[ref].[path_to_value] pattern. + // References are specified using the [id].[ref].[path_to_value] pattern. // // The interpolation of “inputs” is allowed // @@ -231,7 +233,7 @@ type stepDefinitionYaml struct { // // Example // targets: - // - type: write_polygon_mainnet@1 + // - id: write_polygon_mainnet@1 // inputs: // report: // - consensus.evm_median.outputs.report @@ -248,66 +250,66 @@ type stepDefinitionYaml struct { func (s stepDefinitionYaml) toStepDefinition() stepDefinition { return stepDefinition{ Ref: s.Ref, - Type: s.Type.String(), + ID: s.ID.String(), Inputs: s.Inputs, Config: s.Config, } } -// stepDefinitionType represents both the string and table representations of the "type" field in a stepDefinition. -type stepDefinitionType struct { - typeStr string - typeTable *stepDefinitionTableType +// stepDefinitionID represents both the string and table representations of the "id" field in a stepDefinition. +type stepDefinitionID struct { + idStr string + idTable *stepDefinitionTableID } -func (s stepDefinitionType) String() string { - if s.typeStr != "" { - return s.typeStr +func (s stepDefinitionID) String() string { + if s.idStr != "" { + return s.idStr } - return s.typeTable.String() + return s.idTable.String() } -func (s *stepDefinitionType) UnmarshalJSON(data []byte) error { +func (s *stepDefinitionID) UnmarshalJSON(data []byte) error { // Unmarshal the JSON data into a map to determine if it's a string or a table var m string err := json.Unmarshal(data, &m) if err == nil { - s.typeStr = m + s.idStr = m return nil } - // If the JSON data is a table, unmarshal it into a stepDefinitionTableType - var table stepDefinitionTableType + // If the JSON data is a table, unmarshal it into a stepDefinitionTableID + var table stepDefinitionTableID err = json.Unmarshal(data, &table) if err != nil { return err } - s.typeTable = &table + s.idTable = &table return nil } -func (s *stepDefinitionType) MarshalJSON() ([]byte, error) { - if s.typeStr != "" { - return json.Marshal(s.typeStr) +func (s *stepDefinitionID) MarshalJSON() ([]byte, error) { + if s.idStr != "" { + return json.Marshal(s.idStr) } - return json.Marshal(s.typeTable) + return json.Marshal(s.idTable) } -// JSONSchema returns the JSON schema for a stepDefinitionType. +// JSONSchema returns the JSON schema for a stepDefinitionID. // // The schema is a oneOf schema that allows either a string or a table. -func (stepDefinitionType) JSONSchema() *jsonschema.Schema { +func (stepDefinitionID) JSONSchema() *jsonschema.Schema { reflector := jsonschema.Reflector{DoNotReference: true, ExpandedStruct: true} - tableSchema := reflector.Reflect(&stepDefinitionTableType{}) + tableSchema := reflector.Reflect(&stepDefinitionTableID{}) stringSchema := &jsonschema.Schema{ - Type: "string", + ID: "string", Pattern: "^[a-z0-9_\\-:]+@(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$", } return &jsonschema.Schema{ - Title: "type", + Title: "id", OneOf: []*jsonschema.Schema{ stringSchema, tableSchema, @@ -315,21 +317,21 @@ func (stepDefinitionType) JSONSchema() *jsonschema.Schema { } } -// stepDefinitionTableType is the structured representation of a stepDefinitionType. -type stepDefinitionTableType struct { +// stepDefinitionTableID is the structured representation of a stepDefinitionID. +type stepDefinitionTableID struct { Name string `json:"name"` Version string `json:"version" jsonschema:"pattern=(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$"` Labels map[string]string `json:"labels"` } -// String returns the string representation of a stepDefinitionTableType. +// String returns the string representation of a stepDefinitionTableID. // // It follows the format: // // {name}:{label1_key}_{label1_value}:{label2_key}_{label2_value}@{version} // // where labels are ordered alphanumerically. -func (s stepDefinitionTableType) String() string { +func (s stepDefinitionTableID) String() string { labels := make([]string, 0, len(s.Labels)) for k, v := range s.Labels { labels = append(labels, fmt.Sprintf("%s_%s", k, v)) diff --git a/core/services/workflows/models_yaml_test.go b/core/services/workflows/models_yaml_test.go index 2732f1b44c7..efcdaf6f332 100644 --- a/core/services/workflows/models_yaml_test.go +++ b/core/services/workflows/models_yaml_test.go @@ -116,7 +116,7 @@ func TestWorkflowSpecMarshalling(t *testing.T) { } }) - t.Run("Table and string capability type", func(t *testing.T) { + t.Run("Table and string capability id", func(t *testing.T) { workflowBytes := fixtureReader("workflow_2") spec := workflowSpecYaml{} diff --git a/core/services/workflows/testdata/fixtures/workflows/marshalling/workflow_1.yaml b/core/services/workflows/testdata/fixtures/workflows/marshalling/workflow_1.yaml index cbd33f4a90e..9a9870af875 100644 --- a/core/services/workflows/testdata/fixtures/workflows/marshalling/workflow_1.yaml +++ b/core/services/workflows/testdata/fixtures/workflows/marshalling/workflow_1.yaml @@ -1,5 +1,5 @@ triggers: - - type: mercury-trigger@1 + - id: mercury-trigger@1 ref: report_data config: boolean_coercion: @@ -54,7 +54,7 @@ # no actions consensus: - - type: offchain_reporting@1 + - id: offchain_reporting@1 inputs: observations: - triggers.report_data.outputs @@ -76,7 +76,7 @@ abi: "mercury_reports bytes[]" targets: - - type: write_polygon_mainnet@1 + - id: write_polygon_mainnet@1 inputs: report: - consensus.evm_median.outputs.report diff --git a/core/services/workflows/testdata/fixtures/workflows/marshalling/workflow_2.yaml b/core/services/workflows/testdata/fixtures/workflows/marshalling/workflow_2.yaml index 50a598d0bc9..be40a91daa0 100644 --- a/core/services/workflows/testdata/fixtures/workflows/marshalling/workflow_2.yaml +++ b/core/services/workflows/testdata/fixtures/workflows/marshalling/workflow_2.yaml @@ -1,12 +1,12 @@ triggers: - - type: on_mercury_report@1 + - id: on_mercury_report@1 ref: report_data config: {} # no actions consensus: - - type: + - id: name: trigger_test version: "2" labels: @@ -19,7 +19,7 @@ - triggers.report_data.outputs targets: - - type: write_polygon_mainnet@1 + - id: write_polygon_mainnet@1 config: {} inputs: report: diff --git a/core/services/workflows/testdata/fixtures/workflows/marshalling/workflow_2_spec.json b/core/services/workflows/testdata/fixtures/workflows/marshalling/workflow_2_spec.json index f4024e24267..000fa469218 100644 --- a/core/services/workflows/testdata/fixtures/workflows/marshalling/workflow_2_spec.json +++ b/core/services/workflows/testdata/fixtures/workflows/marshalling/workflow_2_spec.json @@ -1,14 +1,14 @@ { "triggers": [ { - "type": "on_mercury_report@1", + "id": "on_mercury_report@1", "ref": "report_data", "config": {} } ], "consensus": [ { - "type": "trigger_test:aaShouldBeFirst_true:chain_ethereum:network_mainnet@2", + "id": "trigger_test:aaShouldBeFirst_true:chain_ethereum:network_mainnet@2", "inputs": { "observations": [ "triggers.report_data.outputs" @@ -19,7 +19,7 @@ ], "targets": [ { - "type": "write_polygon_mainnet@1", + "id": "write_polygon_mainnet@1", "inputs": { "report": [ "consensus.evm_median.outputs.report" @@ -28,4 +28,4 @@ "config": {} } ] -} +} \ No newline at end of file diff --git a/core/services/workflows/testdata/fixtures/workflows/references/failing_1.yaml b/core/services/workflows/testdata/fixtures/workflows/references/failing_1.yaml index 67d6890c47b..b3c984e9892 100644 --- a/core/services/workflows/testdata/fixtures/workflows/references/failing_1.yaml +++ b/core/services/workflows/testdata/fixtures/workflows/references/failing_1.yaml @@ -1,14 +1,14 @@ triggers: -- type: trigger_test@1 +- id: trigger_test@1 config: {} consensus: - - type: offchain_reporting@1 + - id: offchain_reporting@1 ref: offchain_reporting=1 config: {} targets: - - type: write_polygon_mainnet@1 + - id: write_polygon_mainnet@1 ref: write_polygon_mainnet_1 config: {} diff --git a/core/services/workflows/testdata/fixtures/workflows/references/passing_1.yaml b/core/services/workflows/testdata/fixtures/workflows/references/passing_1.yaml index f8c7d20136e..cb2f424e981 100644 --- a/core/services/workflows/testdata/fixtures/workflows/references/passing_1.yaml +++ b/core/services/workflows/testdata/fixtures/workflows/references/passing_1.yaml @@ -1,14 +1,14 @@ triggers: -- type: trigger_test@1 +- id: trigger_test@1 config: {} consensus: - - type: offchain_reporting@1 + - id: offchain_reporting@1 ref: offchain_reporting_1 config: {} targets: - - type: write_polygon_mainnet@1 + - id: write_polygon_mainnet@1 ref: write_polygon_mainnet_1 config: {} diff --git a/core/services/workflows/testdata/fixtures/workflows/versioning/failing_1.yaml b/core/services/workflows/testdata/fixtures/workflows/versioning/failing_1.yaml index b45676388c5..2e41eeb9898 100644 --- a/core/services/workflows/testdata/fixtures/workflows/versioning/failing_1.yaml +++ b/core/services/workflows/testdata/fixtures/workflows/versioning/failing_1.yaml @@ -1,15 +1,15 @@ # Should fail since version is more specific than major triggers: - - type: trigger_test@1.0 + - id: trigger_test@1.0 config: {} consensus: - - type: offchain_reporting@1 + - id: offchain_reporting@1 ref: offchain_reporting_1 config: {} targets: - - type: write_polygon_mainnet@1 + - id: write_polygon_mainnet@1 ref: write_polygon_mainnet_1 config: {} diff --git a/core/services/workflows/testdata/fixtures/workflows/versioning/failing_2.yaml b/core/services/workflows/testdata/fixtures/workflows/versioning/failing_2.yaml index c2a1872b4cf..36cd5b68b6b 100644 --- a/core/services/workflows/testdata/fixtures/workflows/versioning/failing_2.yaml +++ b/core/services/workflows/testdata/fixtures/workflows/versioning/failing_2.yaml @@ -1,16 +1,16 @@ # Should fail since version is more specific than major triggers: - - type: trigger_test@1.0.0 + - id: trigger_test@1.0.0 config: {} consensus: - - type: offchain_reporting@1 + - id: offchain_reporting@1 ref: offchain_reporting_1 config: {} targets: - - type: write_polygon_mainnet@1 + - id: write_polygon_mainnet@1 ref: write_polygon_mainnet_1 config: {} diff --git a/core/services/workflows/testdata/fixtures/workflows/versioning/passing_1.yaml b/core/services/workflows/testdata/fixtures/workflows/versioning/passing_1.yaml index 83bdcc610ef..4579c2899b9 100644 --- a/core/services/workflows/testdata/fixtures/workflows/versioning/passing_1.yaml +++ b/core/services/workflows/testdata/fixtures/workflows/versioning/passing_1.yaml @@ -1,14 +1,14 @@ triggers: - - type: trigger_test@1 + - id: trigger_test@1 config: {} consensus: - - type: offchain_reporting@1-beta.1 + - id: offchain_reporting@1-beta.1 ref: offchain_reporting_1 config: {} targets: - - type: write_polygon_mainnet@1-alpha+sha246er3 + - id: write_polygon_mainnet@1-alpha+sha246er3 ref: write_polygon_mainnet_1 config: {} diff --git a/core/services/workflows/testdata/fixtures/workflows/workflow_schema.json b/core/services/workflows/testdata/fixtures/workflows/workflow_schema.json index 83ecd42ecb9..7f257f7798d 100644 --- a/core/services/workflows/testdata/fixtures/workflows/workflow_schema.json +++ b/core/services/workflows/testdata/fixtures/workflows/workflow_schema.json @@ -6,15 +6,15 @@ "mapping": { "type": "object" }, - "stepDefinitionType": { + "stepDefinitionID": { "oneOf": [ { - "type": "string", + "$id": "string", "pattern": "^[a-z0-9_\\-:]+@(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$" }, { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/smartcontractkit/chainlink/v2/core/services/workflows/step-definition-table-type", + "$id": "https://github.com/smartcontractkit/chainlink/v2/core/services/workflows/step-definition-table-id", "properties": { "name": { "type": "string" @@ -39,12 +39,12 @@ ] } ], - "title": "type" + "title": "id" }, "stepDefinitionYaml": { "properties": { - "type": { - "$ref": "#/$defs/stepDefinitionType" + "id": { + "$ref": "#/$defs/stepDefinitionID" }, "ref": { "type": "string", @@ -60,7 +60,7 @@ "additionalProperties": false, "type": "object", "required": [ - "type", + "id", "config" ] }, @@ -100,4 +100,4 @@ ] } } -} +} \ No newline at end of file diff --git a/core/web/jobs_controller_test.go b/core/web/jobs_controller_test.go index bade8fe293b..0146038d91b 100644 --- a/core/web/jobs_controller_test.go +++ b/core/web/jobs_controller_test.go @@ -397,7 +397,7 @@ func TestJobController_Create_HappyPath(t *testing.T) { owner := "00000000000000000000000000000000000000aa" workflow := ` triggers: - - type: "mercury-trigger" + - id: "mercury-trigger" config: feedIds: - "0x1111111111111111111100000000000000000000000000000000000000000000" @@ -405,7 +405,7 @@ triggers: - "0x3333333333333333333300000000000000000000000000000000000000000000" consensus: - - type: "offchain_reporting" + - id: "offchain_reporting" ref: "evm_median" inputs: observations: @@ -427,14 +427,14 @@ consensus: abi: "mercury_reports bytes[]" targets: - - type: "write_polygon-testnet-mumbai" + - id: "write_polygon-testnet-mumbai" inputs: report: "$(evm_median.outputs.report)" config: address: "0x3F3554832c636721F1fD1822Ccca0354576741Ef" params: ["$(report)"] abi: "receive(report bytes)" - - type: "write_ethereum-testnet-sepolia" + - id: "write_ethereum-testnet-sepolia" inputs: report: "$(evm_median.outputs.report)" config: