diff --git a/core/services/chainlink/mocks/relayer_chain_interoperators.go b/core/services/chainlink/mocks/relayer_chain_interoperators.go index 74dc9dc1d45..4c552551008 100644 --- a/core/services/chainlink/mocks/relayer_chain_interoperators.go +++ b/core/services/chainlink/mocks/relayer_chain_interoperators.go @@ -19,6 +19,7 @@ import ( // FakeRelayerChainInteroperators is a fake chainlink.RelayerChainInteroperators. // This exists because mockery generation doesn't understand how to produce an alias instead of the underlying type (which is not exported in this case). type FakeRelayerChainInteroperators struct { + Relayers []loop.Relayer EVMChains legacyevm.LegacyChainContainer Nodes []types.NodeStatus NodesErr error @@ -45,7 +46,7 @@ func (f *FakeRelayerChainInteroperators) Get(id relay.ID) (loop.Relayer, error) } func (f *FakeRelayerChainInteroperators) Slice() []loop.Relayer { - panic("unimplemented") + return f.Relayers } func (f *FakeRelayerChainInteroperators) LegacyCosmosChains() chainlink.LegacyCosmosContainer { diff --git a/core/web/loader/chain.go b/core/web/loader/chain.go index a12fef3d590..34ca4bd5f82 100644 --- a/core/web/loader/chain.go +++ b/core/web/loader/chain.go @@ -2,9 +2,11 @@ package loader import ( "context" + "slices" "github.com/graph-gophers/dataloader" + "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" @@ -14,7 +16,7 @@ type chainBatcher struct { app chainlink.Application } -func (b *chainBatcher) loadByIDs(_ context.Context, keys dataloader.Keys) []*dataloader.Result { +func (b *chainBatcher) 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 @@ -24,13 +26,20 @@ func (b *chainBatcher) loadByIDs(_ context.Context, keys dataloader.Keys) []*dat keyOrder[key.String()] = ix } - // Fetch the chains - cs, _, err := b.app.EVMORM().Chains(chainIDs...) - if err != nil { - return []*dataloader.Result{{Data: nil, Error: err}} + var cs []types.ChainStatus + relayers := b.app.GetRelayers().Slice() + + for _, r := range relayers { + s, err := r.GetChainStatus(ctx) + if err != nil { + return []*dataloader.Result{{Data: nil, Error: err}} + } + + if slices.Contains(chainIDs, s.ID) { + cs = append(cs, s) + } } - // Construct the output array of dataloader results results := make([]*dataloader.Result, len(keys)) for _, c := range cs { ix, ok := keyOrder[c.ID] diff --git a/core/web/loader/loader_test.go b/core/web/loader/loader_test.go index a039834997e..b17c96ee206 100644 --- a/core/web/loader/loader_test.go +++ b/core/web/loader/loader_test.go @@ -11,23 +11,24 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/loop" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" - "github.com/smartcontractkit/chainlink/v2/core/chains" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" evmtxmgrmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr/mocks" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + evmutils "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" + ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" coremocks "github.com/smartcontractkit/chainlink/v2/core/internal/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" chainlinkmocks "github.com/smartcontractkit/chainlink/v2/core/services/chainlink/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/feeds" feedsMocks "github.com/smartcontractkit/chainlink/v2/core/services/feeds/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/job" jobORMMocks "github.com/smartcontractkit/chainlink/v2/core/services/job/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" + testutils2 "github.com/smartcontractkit/chainlink/v2/core/web/testutils" ) func TestLoader_Chains(t *testing.T) { @@ -40,21 +41,33 @@ func TestLoader_Chains(t *testing.T) { chain := toml.EVMConfig{ChainID: one, Chain: toml.Defaults(one)} two := ubig.NewI(2) chain2 := toml.EVMConfig{ChainID: two, Chain: toml.Defaults(two)} - evmORM := evmtest.NewTestConfigs(&chain, &chain2) - app.On("EVMORM").Return(evmORM) + config1, err := chain.TOMLString() + require.NoError(t, err) + config2, err := chain2.TOMLString() + require.NoError(t, err) - batcher := chainBatcher{app} + app.On("GetRelayers").Return(&chainlinkmocks.FakeRelayerChainInteroperators{Relayers: []loop.Relayer{ + testutils2.MockRelayer{ChainStatus: commontypes.ChainStatus{ + ID: "1", + Enabled: true, + Config: config1, + }}, testutils2.MockRelayer{ChainStatus: commontypes.ChainStatus{ + ID: "2", + Enabled: true, + Config: config2, + }}, + }}) + batcher := chainBatcher{app} keys := dataloader.NewKeysFromStrings([]string{"2", "1", "3"}) results := batcher.loadByIDs(ctx, keys) assert.Len(t, results, 3) - config2, err := chain2.TOMLString() + require.NoError(t, err) want2 := commontypes.ChainStatus{ID: "2", Enabled: true, Config: config2} assert.Equal(t, want2, results[0].Data.(commontypes.ChainStatus)) - config1, err := chain.TOMLString() - require.NoError(t, err) + want1 := commontypes.ChainStatus{ID: "1", Enabled: true, Config: config1} assert.Equal(t, want1, results[1].Data.(commontypes.ChainStatus)) assert.Nil(t, results[2].Data) @@ -367,7 +380,7 @@ func TestLoader_loadByEthTransactionID(t *testing.T) { ctx := InjectDataloader(testutils.Context(t), app) ethTxID := int64(3) - ethTxHash := utils.NewHash() + ethTxHash := evmutils.NewHash() receipt := txmgr.Receipt{ ID: int64(1), diff --git a/core/web/resolver/chain_test.go b/core/web/resolver/chain_test.go index 700963cd4da..b7a4b7c8386 100644 --- a/core/web/resolver/chain_test.go +++ b/core/web/resolver/chain_test.go @@ -8,8 +8,12 @@ import ( "github.com/pelletier/go-toml/v2" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/loop" + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" evmtoml "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" + chainlinkmocks "github.com/smartcontractkit/chainlink/v2/core/services/chainlink/mocks" + "github.com/smartcontractkit/chainlink/v2/core/web/testutils" ) func TestResolver_Chains(t *testing.T) { @@ -70,13 +74,24 @@ ResendAfterThreshold = '1h0m0s' name: "success", authenticated: true, before: func(f *gqlTestFramework) { - f.App.On("EVMORM").Return(f.Mocks.evmORM) - f.Mocks.evmORM.PutChains(evmtoml.EVMConfig{ + chainConf := evmtoml.EVMConfig{ ChainID: &chainID, Enabled: chain.Enabled, Chain: chain.Chain, - }) + } + + chainConfToml, err2 := chainConf.TOMLString() + require.NoError(t, err2) + + f.App.On("GetRelayers").Return(&chainlinkmocks.FakeRelayerChainInteroperators{Relayers: []loop.Relayer{ + testutils.MockRelayer{ChainStatus: commontypes.ChainStatus{ + ID: chainID.String(), + Enabled: *chain.Enabled, + Config: chainConfToml, + }}, + }}) + }, query: query, result: fmt.Sprintf(` @@ -93,6 +108,25 @@ ResendAfterThreshold = '1h0m0s' } }`, configTOMLEscaped), }, + unauthorizedTestCase(GQLTestCase{query: query}, "chains"), + { + name: "no chains", + authenticated: true, + before: func(f *gqlTestFramework) { + f.App.On("GetRelayers").Return(&chainlinkmocks.FakeRelayerChainInteroperators{Relayers: []loop.Relayer{}}) + + }, + query: query, + result: ` + { + "chains": { + "results": [], + "metadata": { + "total": 0 + } + } + }`, + }, } RunGQLTests(t, testCases) diff --git a/core/web/resolver/eth_key_test.go b/core/web/resolver/eth_key_test.go index 1874e4c68e0..f574c885ff9 100644 --- a/core/web/resolver/eth_key_test.go +++ b/core/web/resolver/eth_key_test.go @@ -10,6 +10,8 @@ import ( "github.com/stretchr/testify/mock" commonassets "github.com/smartcontractkit/chainlink-common/pkg/assets" + "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config" mocks2 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/mocks" @@ -17,6 +19,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" + "github.com/smartcontractkit/chainlink/v2/core/web/testutils" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" @@ -102,10 +105,18 @@ func TestResolver_ETHKeys(t *testing.T) { f.Mocks.chain.On("BalanceMonitor").Return(f.Mocks.balM) f.Mocks.chain.On("Config").Return(f.Mocks.scfg) f.Mocks.relayerChainInterops.EVMChains = legacyEVMChains + f.Mocks.relayerChainInterops.Relayers = []loop.Relayer{ + testutils.MockRelayer{ + ChainStatus: types.ChainStatus{ + ID: "12", + Enabled: true, + }, + NodeStatuses: nil, + }, + } f.Mocks.evmORM.PutChains(toml.EVMConfig{ChainID: &chainID}) f.Mocks.keystore.On("Eth").Return(f.Mocks.ethKs) f.App.On("GetKeyStore").Return(f.Mocks.keystore) - f.App.On("EVMORM").Return(f.Mocks.evmORM) f.App.On("GetRelayers").Return(f.Mocks.relayerChainInterops) f.Mocks.scfg.On("EVM").Return(&evmMockConfig) @@ -152,9 +163,17 @@ func TestResolver_ETHKeys(t *testing.T) { f.Mocks.ethKs.On("GetAll").Return(keys, nil) f.Mocks.relayerChainInterops.EVMChains = f.Mocks.legacyEVMChains f.Mocks.evmORM.PutChains(toml.EVMConfig{ChainID: &chainID}) + f.Mocks.relayerChainInterops.Relayers = []loop.Relayer{ + testutils.MockRelayer{ + ChainStatus: types.ChainStatus{ + ID: "12", + Enabled: true, + }, + NodeStatuses: nil, + }, + } f.Mocks.keystore.On("Eth").Return(f.Mocks.ethKs) f.App.On("GetKeyStore").Return(f.Mocks.keystore) - f.App.On("EVMORM").Return(f.Mocks.evmORM) f.App.On("GetRelayers").Return(f.Mocks.relayerChainInterops) }, query: query, @@ -304,6 +323,15 @@ func TestResolver_ETHKeys(t *testing.T) { f.Mocks.ethClient.On("LINKBalance", mock.Anything, address, linkAddr).Return(commonassets.NewLinkFromJuels(12), gError) f.Mocks.legacyEVMChains.On("Get", states[0].EVMChainID.String()).Return(f.Mocks.chain, nil) f.Mocks.relayerChainInterops.EVMChains = f.Mocks.legacyEVMChains + f.Mocks.relayerChainInterops.Relayers = []loop.Relayer{ + testutils.MockRelayer{ + ChainStatus: types.ChainStatus{ + ID: "12", + Enabled: true, + }, + NodeStatuses: nil, + }, + } f.Mocks.chain.On("Client").Return(f.Mocks.ethClient) f.Mocks.balM.On("GetEthBalance", address).Return(assets.NewEth(1)) f.Mocks.chain.On("BalanceMonitor").Return(f.Mocks.balM) @@ -311,7 +339,6 @@ func TestResolver_ETHKeys(t *testing.T) { f.Mocks.chain.On("Config").Return(f.Mocks.scfg) f.Mocks.evmORM.PutChains(toml.EVMConfig{ChainID: &chainID}) f.App.On("GetRelayers").Return(f.Mocks.relayerChainInterops) - f.App.On("EVMORM").Return(f.Mocks.evmORM) f.Mocks.scfg.On("EVM").Return(&evmMockConfig) }, query: query, @@ -361,9 +388,17 @@ func TestResolver_ETHKeys(t *testing.T) { f.Mocks.legacyEVMChains.On("Get", states[0].EVMChainID.String()).Return(f.Mocks.chain, nil) f.Mocks.relayerChainInterops.EVMChains = f.Mocks.legacyEVMChains f.Mocks.evmORM.PutChains(toml.EVMConfig{ChainID: &chainID}) + f.Mocks.relayerChainInterops.Relayers = []loop.Relayer{ + testutils.MockRelayer{ + ChainStatus: types.ChainStatus{ + ID: "12", + Enabled: true, + }, + NodeStatuses: nil, + }, + } f.Mocks.keystore.On("Eth").Return(f.Mocks.ethKs) f.App.On("GetKeyStore").Return(f.Mocks.keystore) - f.App.On("EVMORM").Return(f.Mocks.evmORM) f.App.On("GetRelayers").Return(f.Mocks.relayerChainInterops) f.Mocks.scfg.On("EVM").Return(&evmMockConfig) }, diff --git a/core/web/resolver/eth_transaction_test.go b/core/web/resolver/eth_transaction_test.go index 238aa9d1679..5c50d60539e 100644 --- a/core/web/resolver/eth_transaction_test.go +++ b/core/web/resolver/eth_transaction_test.go @@ -9,6 +9,8 @@ import ( "github.com/ethereum/go-ethereum/common" gqlerrors "github.com/graph-gophers/graphql-go/errors" + "github.com/smartcontractkit/chainlink-common/pkg/loop" + "github.com/smartcontractkit/chainlink-common/pkg/types" txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" @@ -16,6 +18,8 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ubig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" + chainlinkmocks "github.com/smartcontractkit/chainlink/v2/core/services/chainlink/mocks" + "github.com/smartcontractkit/chainlink/v2/core/web/testutils" ) func TestResolver_EthTransaction(t *testing.T) { @@ -85,7 +89,15 @@ func TestResolver_EthTransaction(t *testing.T) { }, nil) f.App.On("TxmStorageService").Return(f.Mocks.txmStore) f.Mocks.evmORM.PutChains(toml.EVMConfig{ChainID: &chainID}) - f.App.On("EVMORM").Return(f.Mocks.evmORM) + f.App.On("GetRelayers").Return(&chainlinkmocks.FakeRelayerChainInteroperators{ + Relayers: []loop.Relayer{ + testutils.MockRelayer{ChainStatus: types.ChainStatus{ + ID: "22", + Enabled: true, + Config: "", + }}, + }, + }) }, query: query, variables: variables, @@ -142,7 +154,15 @@ func TestResolver_EthTransaction(t *testing.T) { }, nil) f.App.On("TxmStorageService").Return(f.Mocks.txmStore) f.Mocks.evmORM.PutChains(toml.EVMConfig{ChainID: &chainID}) - f.App.On("EVMORM").Return(f.Mocks.evmORM) + f.App.On("GetRelayers").Return(&chainlinkmocks.FakeRelayerChainInteroperators{ + Relayers: []loop.Relayer{ + testutils.MockRelayer{ChainStatus: types.ChainStatus{ + ID: "22", + Enabled: true, + Config: "", + }}, + }, + }) }, query: query, variables: variables, diff --git a/core/web/resolver/node_test.go b/core/web/resolver/node_test.go index 7f4e69ac4ae..62e964a6820 100644 --- a/core/web/resolver/node_test.go +++ b/core/web/resolver/node_test.go @@ -6,19 +6,16 @@ import ( gqlerrors "github.com/graph-gophers/graphql-go/errors" "github.com/pkg/errors" - 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/v2/core/chains/evm/config/toml" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" - "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + chainlinkmocks "github.com/smartcontractkit/chainlink/v2/core/services/chainlink/mocks" + "github.com/smartcontractkit/chainlink/v2/core/web/testutils" ) func TestResolver_Nodes(t *testing.T) { t.Parallel() var ( - chainID = *big.NewI(1) - query = ` query GetNodes { nodes { @@ -43,16 +40,24 @@ func TestResolver_Nodes(t *testing.T) { name: "success", authenticated: true, before: func(f *gqlTestFramework) { - f.App.On("GetRelayers").Return(chainlink.RelayerChainInteroperators(f.Mocks.relayerChainInterops)) - f.Mocks.relayerChainInterops.Nodes = []types.NodeStatus{ - { - Name: "node-name", - ChainID: chainID.String(), - Config: `Name = 'node-name'`, + f.App.On("GetRelayers").Return(&chainlinkmocks.FakeRelayerChainInteroperators{ + Nodes: []types.NodeStatus{ + { + ChainID: "1", + Name: "node-name", + Config: "Name='node-name'\nOrder=11\nHTTPURL='http://some-url'\nWSURL='ws://some-url'", + State: "alive", + }, }, - } - f.App.On("EVMORM").Return(f.Mocks.evmORM) - f.Mocks.evmORM.PutChains(toml.EVMConfig{ChainID: &chainID}) + Relayers: []loop.Relayer{ + testutils.MockRelayer{ChainStatus: types.ChainStatus{ + ID: "1", + Enabled: true, + Config: "", + }}, + }, + }) + }, query: query, result: ` @@ -113,21 +118,20 @@ func Test_NodeQuery(t *testing.T) { } }` - var name = "node-name" - testCases := []GQLTestCase{ unauthorizedTestCase(GQLTestCase{query: query}, "node"), { name: "success", authenticated: true, before: func(f *gqlTestFramework) { - f.App.On("EVMORM").Return(f.Mocks.evmORM) - f.Mocks.evmORM.PutChains(toml.EVMConfig{Nodes: []*toml.Node{{ - Name: &name, - WSURL: commonconfig.MustParseURL("ws://some-url"), - HTTPURL: commonconfig.MustParseURL("http://some-url"), - Order: ptr(int32(11)), - }}}) + f.App.On("GetRelayers").Return(&chainlinkmocks.FakeRelayerChainInteroperators{Relayers: []loop.Relayer{ + testutils.MockRelayer{NodeStatuses: []types.NodeStatus{ + { + Name: "node-name", + Config: "Name='node-name'\nOrder=11\nHTTPURL='http://some-url'\nWSURL='ws://some-url'", + }, + }}, + }}) }, query: query, result: ` @@ -144,7 +148,7 @@ func Test_NodeQuery(t *testing.T) { name: "not found error", authenticated: true, before: func(f *gqlTestFramework) { - f.App.On("EVMORM").Return(f.Mocks.evmORM) + f.App.On("GetRelayers").Return(&chainlinkmocks.FakeRelayerChainInteroperators{Relayers: []loop.Relayer{}}) }, query: query, result: ` @@ -159,5 +163,3 @@ func Test_NodeQuery(t *testing.T) { RunGQLTests(t, testCases) } - -func ptr[T any](t T) *T { return &t } diff --git a/core/web/resolver/query.go b/core/web/resolver/query.go index da15b7f7c26..ccc9da2ab91 100644 --- a/core/web/resolver/query.go +++ b/core/web/resolver/query.go @@ -95,10 +95,21 @@ func (r *Resolver) Chains(ctx context.Context, args struct { offset := pageOffset(args.Offset) limit := pageLimit(args.Limit) - chains, count, err := r.App.EVMORM().Chains() - if err != nil { - return nil, err + var chains []types.ChainStatus + for _, rel := range r.App.GetRelayers().Slice() { + status, err := rel.GetChainStatus(ctx) + if err != nil { + return nil, err + } + chains = append(chains, status) + } + count := len(chains) + + if count == 0 { + //No chains are configured, return an empty ChainsPayload, so we don't break the UI + return NewChainsPayload(nil, 0), nil } + // bound the chain results if offset >= len(chains) { return nil, fmt.Errorf("offset %d out of range", offset) @@ -238,25 +249,25 @@ func (r *Resolver) Node(ctx context.Context, args struct{ ID graphql.ID }) (*Nod r.App.GetLogger().Debug("resolver Node args %v", args) name := string(args.ID) r.App.GetLogger().Debug("resolver Node name %s", name) - node, err := r.App.EVMORM().NodeStatus(name) - if err != nil { - r.App.GetLogger().Errorw("resolver getting node status", "err", err) - if errors.Is(err, chains.ErrNotFound) { - npr, warn := NewNodePayloadResolver(nil, err) - if warn != nil { - r.App.GetLogger().Warnw("Error creating NodePayloadResolver", "name", name, "err", warn) + for _, relayer := range r.App.GetRelayers().Slice() { + statuses, _, _, err := relayer.ListNodeStatuses(ctx, 0, "") + if err != nil { + return nil, err + } + for i, s := range statuses { + if s.Name == name { + npr, err2 := NewNodePayloadResolver(&statuses[i], nil) + if err2 != nil { + return nil, err2 + } + return npr, nil } - return npr, nil } - return nil, err } - npr, warn := NewNodePayloadResolver(&node, nil) - if warn != nil { - r.App.GetLogger().Warnw("Error creating NodePayloadResolver", "name", name, "err", warn) - } - return npr, nil + r.App.GetLogger().Errorw("resolver getting node status", "err", chains.ErrNotFound) + return NewNodePayloadResolver(nil, chains.ErrNotFound) } func (r *Resolver) P2PKeys(ctx context.Context) (*P2PKeysPayloadResolver, error) { diff --git a/core/web/testutils/mock_relayer.go b/core/web/testutils/mock_relayer.go new file mode 100644 index 00000000000..d1972f52626 --- /dev/null +++ b/core/web/testutils/mock_relayer.go @@ -0,0 +1,53 @@ +package testutils + +import ( + "context" + "math/big" + + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" +) + +type MockRelayer struct { + ChainStatus commontypes.ChainStatus + NodeStatuses []commontypes.NodeStatus +} + +func (m MockRelayer) Name() string { + panic("not implemented") +} + +func (m MockRelayer) Start(ctx context.Context) error { + panic("not implemented") +} + +func (m MockRelayer) Close() error { + panic("not implemented") +} + +func (m MockRelayer) Ready() error { + panic("not implemented") +} + +func (m MockRelayer) HealthReport() map[string]error { + panic("not implemented") +} + +func (m MockRelayer) GetChainStatus(ctx context.Context) (commontypes.ChainStatus, error) { + return m.ChainStatus, nil +} + +func (m MockRelayer) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) (stats []commontypes.NodeStatus, nextPageToken string, total int, err error) { + return m.NodeStatuses, "", len(m.NodeStatuses), nil +} + +func (m MockRelayer) Transact(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error { + panic("not implemented") +} + +func (m MockRelayer) NewConfigProvider(ctx context.Context, args commontypes.RelayArgs) (commontypes.ConfigProvider, error) { + panic("not implemented") +} + +func (m MockRelayer) NewPluginProvider(ctx context.Context, args commontypes.RelayArgs, args2 commontypes.PluginArgs) (commontypes.PluginProvider, error) { + panic("not implemented") +}