From f62858b47abee4a6a088b09a0de0ed1ac2c60230 Mon Sep 17 00:00:00 2001 From: kevinssgh Date: Wed, 10 Apr 2024 12:18:02 -0400 Subject: [PATCH] fix some runtime issues --- cmd/zetaclientd/start_utils.go | 37 ++++++++++- zetaclient/evm/evm_client.go | 2 +- zetaclient/evm/evm_rpc_fallback.go | 2 +- zetaclient/evm/evm_signer.go | 3 +- zetaclient/evm/evm_signer_test.go | 20 ++++-- zetaclient/evm/inbounds_test.go | 51 ++++++++------- zetaclient/testutils/stub/evm_json_rpc.go | 75 ----------------------- zetaclient/testutils/stub/evm_rpc.go | 42 ++++++++++++- 8 files changed, 117 insertions(+), 115 deletions(-) delete mode 100644 zetaclient/testutils/stub/evm_json_rpc.go diff --git a/cmd/zetaclientd/start_utils.go b/cmd/zetaclientd/start_utils.go index 947789d4a9..a23496e22a 100644 --- a/cmd/zetaclientd/start_utils.go +++ b/cmd/zetaclientd/start_utils.go @@ -55,7 +55,28 @@ func validatePeer(seedPeer string) error { // // other fields can be added. func maskCfg(cfg config.Config) string { - maskedCfg := cfg + //Perform deep copy to avoid modifying original config + maskedCfg := config.Config{ + Peer: cfg.Peer, + PublicIP: cfg.PublicIP, + LogFormat: cfg.LogFormat, + LogLevel: cfg.LogLevel, + LogSampler: cfg.LogSampler, + PreParamsPath: cfg.PreParamsPath, + ZetaCoreHome: cfg.ZetaCoreHome, + ChainID: cfg.ChainID, + ZetaCoreURL: cfg.ZetaCoreURL, + AuthzGranter: cfg.AuthzGranter, + AuthzHotkey: cfg.AuthzHotkey, + P2PDiagnostic: cfg.P2PDiagnostic, + ConfigUpdateTicker: cfg.ConfigUpdateTicker, + P2PDiagnosticTicker: cfg.P2PDiagnosticTicker, + TssPath: cfg.TssPath, + TestTssKeysign: cfg.TestTssKeysign, + KeyringBackend: cfg.KeyringBackend, + HsmMode: cfg.HsmMode, + HsmHotKey: cfg.HsmHotKey, + } maskedCfg.BitcoinConfig = config.BTCConfig{ RPCUsername: cfg.BitcoinConfig.RPCUsername, @@ -63,11 +84,22 @@ func maskCfg(cfg config.Config) string { RPCHost: cfg.BitcoinConfig.RPCHost, RPCParams: cfg.BitcoinConfig.RPCParams, } + + restrictedAddresses := make([]string, len(cfg.ComplianceConfig.RestrictedAddresses)) + copy(restrictedAddresses, cfg.ComplianceConfig.RestrictedAddresses) + maskedCfg.ComplianceConfig = config.ComplianceConfig{ + LogPath: cfg.ComplianceConfig.LogPath, + RestrictedAddresses: restrictedAddresses, + } + maskedCfg.EVMChainConfigs = map[int64]config.EVMConfig{} for key, val := range cfg.EVMChainConfigs { + endpoints := make([]string, len(val.Endpoint)) + copy(endpoints, val.Endpoint) + maskedCfg.EVMChainConfigs[key] = config.EVMConfig{ Chain: val.Chain, - Endpoint: val.Endpoint, + Endpoint: endpoints, } } @@ -84,7 +116,6 @@ func maskCfg(cfg config.Config) string { chain.Endpoint[i] = endpointURL.Hostname() } } - maskedCfg.BitcoinConfig.RPCUsername = "" maskedCfg.BitcoinConfig.RPCPassword = "" diff --git a/zetaclient/evm/evm_client.go b/zetaclient/evm/evm_client.go index 7bf2c57437..9c50158d8b 100644 --- a/zetaclient/evm/evm_client.go +++ b/zetaclient/evm/evm_client.go @@ -172,7 +172,7 @@ func (ob *ChainClient) WithLogger(logger zerolog.Logger) { } } -func (ob *ChainClient) WithEvmClient(client *EthClientFallback) { +func (ob *ChainClient) WithEvmClient(client interfaces.EthClientFallback) { ob.Mu.Lock() defer ob.Mu.Unlock() ob.evmClient = client diff --git a/zetaclient/evm/evm_rpc_fallback.go b/zetaclient/evm/evm_rpc_fallback.go index dd4fe0738f..827b90cd92 100644 --- a/zetaclient/evm/evm_rpc_fallback.go +++ b/zetaclient/evm/evm_rpc_fallback.go @@ -343,7 +343,7 @@ func (e *EthClientFallback) TransactionSender(ctx context.Context, tx *ethtypes. func (e *EthClientFallback) ChainID(ctx context.Context) (res *big.Int, err error) { for i := 0; i < e.ethClients.Length(); i++ { if client := e.ethClients.First(); client != nil { - rpcClient := client.(ethclient.Client) + rpcClient := client.(*ethclient.Client) res, err = rpcClient.ChainID(ctx) } if err != nil { diff --git a/zetaclient/evm/evm_signer.go b/zetaclient/evm/evm_signer.go index eb87449a8d..f9071357fe 100644 --- a/zetaclient/evm/evm_signer.go +++ b/zetaclient/evm/evm_signer.go @@ -655,7 +655,8 @@ func (signer *Signer) EvmSigner() ethtypes.Signer { // getEVMRPC is a helper function to set up the client and signer, also initializes a mock client for unit tests func getEVMRPC(cfg config.EVMConfig, logger clientcommon.ClientLogger) (interfaces.EthClientFallback, ethtypes.Signer, error) { - if cfg.Endpoint[0] == stub.EVMRPCEnabled { + // Test RPC setup + if len(cfg.Endpoint) > 0 && cfg.Endpoint[0] == stub.EVMRPCEnabled { chainID := big.NewInt(chains.BscMainnetChain().ChainId) ethSigner := ethtypes.NewLondonSigner(chainID) client := &stub.MockEvmClient{} diff --git a/zetaclient/evm/evm_signer_test.go b/zetaclient/evm/evm_signer_test.go index eace105ff2..2501cd7de6 100644 --- a/zetaclient/evm/evm_signer_test.go +++ b/zetaclient/evm/evm_signer_test.go @@ -34,9 +34,13 @@ func getNewEvmSigner() (*Signer, error) { logger := common.ClientLogger{} ts := &metrics.TelemetryServer{} cfg := config.NewConfig() + evmCfg := config.EVMConfig{ + Chain: chains.BscMainnetChain(), + Endpoint: []string{stub.EVMRPCEnabled}, + } + cfg.EVMChainConfigs[chains.BscMainnetChain().ChainId] = evmCfg return NewEVMSigner( - chains.BscMainnetChain(), - stub.EVMRPCEnabled, + evmCfg, stub.NewTSSMainnet(), config.GetConnectorABI(), config.GetERC20CustodyABI(), @@ -53,7 +57,7 @@ func getNewEvmChainClient() (*ChainClient, error) { cfg := config.NewConfig() tss := stub.NewTSSMainnet() - evmcfg := config.EVMConfig{Chain: chains.BscMainnetChain(), Endpoint: "http://localhost:8545"} + evmcfg := config.EVMConfig{Chain: chains.BscMainnetChain(), Endpoint: []string{"http://localhost:8545"}} cfg.EVMChainConfigs[chains.BscMainnetChain().ChainId] = evmcfg coreCTX := corecontext.NewZetaCoreContext(cfg) appCTX := appcontext.NewAppContext(coreCTX, cfg) @@ -309,7 +313,15 @@ func TestSigner_BroadcastOutTx(t *testing.T) { func TestSigner_getEVMRPC(t *testing.T) { t.Run("getEVMRPC error dialing", func(t *testing.T) { - client, signer, err := getEVMRPC("invalidEndpoint") + evmCfg := config.EVMConfig{ + Chain: chains.BscMainnetChain(), + Endpoint: []string{"invalidEndpoint"}, + } + clientLogger := common.ClientLogger{ + Std: zerolog.Logger{}, + Compliance: zerolog.Logger{}, + } + client, signer, err := getEVMRPC(evmCfg, clientLogger) require.Nil(t, client) require.Nil(t, signer) require.Error(t, err) diff --git a/zetaclient/evm/inbounds_test.go b/zetaclient/evm/inbounds_test.go index e24c66b4d5..0690faf55b 100644 --- a/zetaclient/evm/inbounds_test.go +++ b/zetaclient/evm/inbounds_test.go @@ -25,8 +25,7 @@ import ( // MockEVMClient creates a mock ChainClient with custom chain, TSS, params etc func MockEVMClient( chain chains.Chain, - evmClient interfaces.EVMRPCClient, - evmJSONRPC interfaces.EVMJSONRPCClient, + evmClient interfaces.EthClientFallback, zetClient interfaces.ZetaCoreBridger, tss interfaces.TSSSigner, lastBlock uint64, @@ -37,7 +36,6 @@ func MockEVMClient( } client.WithChain(chain) client.WithEvmClient(evmClient) - client.WithEvmJSONRPC(evmJSONRPC) if zetClient != nil { client.WithZetaClient(zetClient) } else { @@ -65,7 +63,7 @@ func TestEVM_CheckAndVoteInboundTokenZeta(t *testing.T) { require.NoError(t, evm.ValidateEvmTransaction(tx)) lastBlock := receipt.BlockNumber.Uint64() + confirmation - ob := MockEVMClient(chain, nil, nil, nil, stub.NewTSSMainnet(), lastBlock, chainParam) + ob := MockEVMClient(chain, nil, nil, stub.NewTSSMainnet(), lastBlock, chainParam) ballot, err := ob.CheckAndVoteInboundTokenZeta(tx, receipt, false) require.NoError(t, err) require.Equal(t, cctx.InboundTxParams.InboundTxBallotIndex, ballot) @@ -75,7 +73,7 @@ func TestEVM_CheckAndVoteInboundTokenZeta(t *testing.T) { require.NoError(t, evm.ValidateEvmTransaction(tx)) lastBlock := receipt.BlockNumber.Uint64() + confirmation - 1 - ob := MockEVMClient(chain, nil, nil, nil, stub.NewTSSMainnet(), lastBlock, chainParam) + ob := MockEVMClient(chain, nil, nil, stub.NewTSSMainnet(), lastBlock, chainParam) _, err := ob.CheckAndVoteInboundTokenZeta(tx, receipt, false) require.ErrorContains(t, err, "not been confirmed") }) @@ -85,7 +83,7 @@ func TestEVM_CheckAndVoteInboundTokenZeta(t *testing.T) { require.NoError(t, evm.ValidateEvmTransaction(tx)) lastBlock := receipt.BlockNumber.Uint64() + confirmation - ob := MockEVMClient(chain, nil, nil, nil, stub.NewTSSMainnet(), lastBlock, chainParam) + ob := MockEVMClient(chain, nil, nil, stub.NewTSSMainnet(), lastBlock, chainParam) ballot, err := ob.CheckAndVoteInboundTokenZeta(tx, receipt, true) require.NoError(t, err) require.Equal(t, "", ballot) @@ -96,7 +94,7 @@ func TestEVM_CheckAndVoteInboundTokenZeta(t *testing.T) { lastBlock := receipt.BlockNumber.Uint64() + confirmation chainID = 56 // use BSC chain connector - ob := MockEVMClient(chain, nil, nil, nil, stub.NewTSSMainnet(), lastBlock, stub.MockChainParams(chainID, confirmation)) + ob := MockEVMClient(chain, nil, nil, stub.NewTSSMainnet(), lastBlock, stub.MockChainParams(chainID, confirmation)) _, err := ob.CheckAndVoteInboundTokenZeta(tx, receipt, true) require.ErrorContains(t, err, "emitter address mismatch") }) @@ -116,7 +114,7 @@ func TestEVM_CheckAndVoteInboundTokenERC20(t *testing.T) { require.NoError(t, evm.ValidateEvmTransaction(tx)) lastBlock := receipt.BlockNumber.Uint64() + confirmation - ob := MockEVMClient(chain, nil, nil, nil, stub.NewTSSMainnet(), lastBlock, chainParam) + ob := MockEVMClient(chain, nil, nil, stub.NewTSSMainnet(), lastBlock, chainParam) ballot, err := ob.CheckAndVoteInboundTokenERC20(tx, receipt, false) require.NoError(t, err) require.Equal(t, cctx.InboundTxParams.InboundTxBallotIndex, ballot) @@ -126,7 +124,7 @@ func TestEVM_CheckAndVoteInboundTokenERC20(t *testing.T) { require.NoError(t, evm.ValidateEvmTransaction(tx)) lastBlock := receipt.BlockNumber.Uint64() + confirmation - 1 - ob := MockEVMClient(chain, nil, nil, nil, stub.NewTSSMainnet(), lastBlock, chainParam) + ob := MockEVMClient(chain, nil, nil, stub.NewTSSMainnet(), lastBlock, chainParam) _, err := ob.CheckAndVoteInboundTokenERC20(tx, receipt, false) require.ErrorContains(t, err, "not been confirmed") }) @@ -136,7 +134,7 @@ func TestEVM_CheckAndVoteInboundTokenERC20(t *testing.T) { require.NoError(t, evm.ValidateEvmTransaction(tx)) lastBlock := receipt.BlockNumber.Uint64() + confirmation - ob := MockEVMClient(chain, nil, nil, nil, stub.NewTSSMainnet(), lastBlock, chainParam) + ob := MockEVMClient(chain, nil, nil, stub.NewTSSMainnet(), lastBlock, chainParam) ballot, err := ob.CheckAndVoteInboundTokenERC20(tx, receipt, true) require.NoError(t, err) require.Equal(t, "", ballot) @@ -147,7 +145,7 @@ func TestEVM_CheckAndVoteInboundTokenERC20(t *testing.T) { lastBlock := receipt.BlockNumber.Uint64() + confirmation chainID = 56 // use BSC chain ERC20 custody - ob := MockEVMClient(chain, nil, nil, nil, stub.NewTSSMainnet(), lastBlock, stub.MockChainParams(chainID, confirmation)) + ob := MockEVMClient(chain, nil, nil, stub.NewTSSMainnet(), lastBlock, stub.MockChainParams(chainID, confirmation)) _, err := ob.CheckAndVoteInboundTokenERC20(tx, receipt, true) require.ErrorContains(t, err, "emitter address mismatch") }) @@ -167,7 +165,7 @@ func TestEVM_CheckAndVoteInboundTokenGas(t *testing.T) { require.NoError(t, evm.ValidateEvmTransaction(tx)) lastBlock := receipt.BlockNumber.Uint64() + confirmation - ob := MockEVMClient(chain, nil, nil, nil, stub.NewTSSMainnet(), lastBlock, chainParam) + ob := MockEVMClient(chain, nil, nil, stub.NewTSSMainnet(), lastBlock, chainParam) ballot, err := ob.CheckAndVoteInboundTokenGas(tx, receipt, false) require.NoError(t, err) require.Equal(t, cctx.InboundTxParams.InboundTxBallotIndex, ballot) @@ -177,7 +175,7 @@ func TestEVM_CheckAndVoteInboundTokenGas(t *testing.T) { require.NoError(t, evm.ValidateEvmTransaction(tx)) lastBlock := receipt.BlockNumber.Uint64() + confirmation - 1 - ob := MockEVMClient(chain, nil, nil, nil, stub.NewTSSMainnet(), lastBlock, chainParam) + ob := MockEVMClient(chain, nil, nil, stub.NewTSSMainnet(), lastBlock, chainParam) _, err := ob.CheckAndVoteInboundTokenGas(tx, receipt, false) require.ErrorContains(t, err, "not been confirmed") }) @@ -187,7 +185,7 @@ func TestEVM_CheckAndVoteInboundTokenGas(t *testing.T) { require.NoError(t, evm.ValidateEvmTransaction(tx)) lastBlock := receipt.BlockNumber.Uint64() + confirmation - ob := MockEVMClient(chain, nil, nil, nil, stub.NewTSSMainnet(), lastBlock, chainParam) + ob := MockEVMClient(chain, nil, nil, stub.NewTSSMainnet(), lastBlock, chainParam) ballot, err := ob.CheckAndVoteInboundTokenGas(tx, receipt, false) require.ErrorContains(t, err, "not TSS address") require.Equal(t, "", ballot) @@ -198,7 +196,7 @@ func TestEVM_CheckAndVoteInboundTokenGas(t *testing.T) { require.NoError(t, evm.ValidateEvmTransaction(tx)) lastBlock := receipt.BlockNumber.Uint64() + confirmation - ob := MockEVMClient(chain, nil, nil, nil, stub.NewTSSMainnet(), lastBlock, chainParam) + ob := MockEVMClient(chain, nil, nil, stub.NewTSSMainnet(), lastBlock, chainParam) ballot, err := ob.CheckAndVoteInboundTokenGas(tx, receipt, false) require.ErrorContains(t, err, "not a successful tx") require.Equal(t, "", ballot) @@ -209,7 +207,7 @@ func TestEVM_CheckAndVoteInboundTokenGas(t *testing.T) { require.NoError(t, evm.ValidateEvmTransaction(tx)) lastBlock := receipt.BlockNumber.Uint64() + confirmation - ob := MockEVMClient(chain, nil, nil, nil, stub.NewTSSMainnet(), lastBlock, chainParam) + ob := MockEVMClient(chain, nil, nil, stub.NewTSSMainnet(), lastBlock, chainParam) ballot, err := ob.CheckAndVoteInboundTokenGas(tx, receipt, false) require.NoError(t, err) require.Equal(t, "", ballot) @@ -226,7 +224,7 @@ func TestEVM_BuildInboundVoteMsgForZetaSentEvent(t *testing.T) { cctx := testutils.LoadEVMIntxCctx(t, chainID, intxHash, coin.CoinType_Zeta) // parse ZetaSent event - ob := MockEVMClient(chain, nil, nil, nil, nil, 1, stub.MockChainParams(1, 1)) + ob := MockEVMClient(chain, nil, nil, nil, 1, stub.MockChainParams(1, 1)) connector := stub.MockConnectorNonEth(chainID) event := testutils.ParseReceiptZetaSent(receipt, connector) @@ -273,7 +271,7 @@ func TestEVM_BuildInboundVoteMsgForDepositedEvent(t *testing.T) { cctx := testutils.LoadEVMIntxCctx(t, chainID, intxHash, coin.CoinType_ERC20) // parse Deposited event - ob := MockEVMClient(chain, nil, nil, nil, nil, 1, stub.MockChainParams(1, 1)) + ob := MockEVMClient(chain, nil, nil, nil, 1, stub.MockChainParams(1, 1)) custody := stub.MockERC20Custody(chainID) event := testutils.ParseReceiptERC20Deposited(receipt, custody) sender := ethcommon.HexToAddress(tx.From) @@ -325,7 +323,7 @@ func TestEVM_BuildInboundVoteMsgForTokenSentToTSS(t *testing.T) { require.NoError(t, evm.ValidateEvmTransaction(txDonation)) // create test compliance config - ob := MockEVMClient(chain, nil, nil, nil, nil, 1, stub.MockChainParams(1, 1)) + ob := MockEVMClient(chain, nil, nil, nil, 1, stub.MockChainParams(1, 1)) cfg := config.Config{ ComplianceConfig: config.ComplianceConfig{}, } @@ -377,38 +375,37 @@ func TestEVM_ObserveTSSReceiveInBlock(t *testing.T) { // create mock client evmClient := stub.NewMockEvmClient() - evmJSONRPC := stub.NewMockJSONRPCClient() zetaClient := stub.NewMockZetaCoreBridge() tss := stub.NewTSSMainnet() lastBlock := receipt.BlockNumber.Uint64() + confirmation t.Run("should observe TSS receive in block", func(t *testing.T) { - ob := MockEVMClient(chain, evmClient, evmJSONRPC, zetaClient, tss, lastBlock, chainParam) + ob := MockEVMClient(chain, evmClient, zetaClient, tss, lastBlock, chainParam) // feed archived block and receipt - evmJSONRPC.WithBlock(block) + evmClient.WithBlock(block) evmClient.WithReceipt(receipt) err := ob.ObserveTSSReceiveInBlock(blockNumber) require.NoError(t, err) }) t.Run("should not observe on error getting block", func(t *testing.T) { - ob := MockEVMClient(chain, evmClient, evmJSONRPC, zetaClient, tss, lastBlock, chainParam) + ob := MockEVMClient(chain, evmClient, zetaClient, tss, lastBlock, chainParam) err := ob.ObserveTSSReceiveInBlock(blockNumber) // error getting block is expected because the mock JSONRPC contains no block require.ErrorContains(t, err, "error getting block") }) t.Run("should not observe on error getting receipt", func(t *testing.T) { - ob := MockEVMClient(chain, evmClient, evmJSONRPC, zetaClient, tss, lastBlock, chainParam) - evmJSONRPC.WithBlock(block) + ob := MockEVMClient(chain, evmClient, zetaClient, tss, lastBlock, chainParam) + evmClient.WithBlock(block) err := ob.ObserveTSSReceiveInBlock(blockNumber) // error getting block is expected because the mock evmClient contains no receipt require.ErrorContains(t, err, "error getting receipt") }) t.Run("should not observe on error posting vote", func(t *testing.T) { - ob := MockEVMClient(chain, evmClient, evmJSONRPC, zetaClient, tss, lastBlock, chainParam) + ob := MockEVMClient(chain, evmClient, zetaClient, tss, lastBlock, chainParam) // feed archived block and pause zeta bridge - evmJSONRPC.WithBlock(block) + evmClient.WithBlock(block) evmClient.WithReceipt(receipt) zetaClient.Pause() err := ob.ObserveTSSReceiveInBlock(blockNumber) diff --git a/zetaclient/testutils/stub/evm_json_rpc.go b/zetaclient/testutils/stub/evm_json_rpc.go deleted file mode 100644 index cd80966660..0000000000 --- a/zetaclient/testutils/stub/evm_json_rpc.go +++ /dev/null @@ -1,75 +0,0 @@ -package stub - -import ( - "errors" - - "github.com/onrik/ethrpc" - "github.com/zeta-chain/zetacore/zetaclient/interfaces" -) - -// EvmClient interface -var _ interfaces.EVMJSONRPCClient = &MockJSONRPCClient{} - -// MockJSONRPCClient is a mock implementation of the EVMJSONRPCClient interface -type MockJSONRPCClient struct { - Blocks []*ethrpc.Block - Transactions []*ethrpc.Transaction -} - -// NewMockJSONRPCClient creates a new mock JSON RPC client -func NewMockJSONRPCClient() *MockJSONRPCClient { - client := &MockJSONRPCClient{} - return client.Reset() -} - -// EthGetBlockByNumber returns a pre-loaded block or nil -func (e *MockJSONRPCClient) EthGetBlockByNumber(_ int, _ bool) (*ethrpc.Block, error) { - // pop a block from the list - if len(e.Blocks) > 0 { - block := e.Blocks[len(e.Blocks)-1] - e.Blocks = e.Blocks[:len(e.Blocks)-1] - return block, nil - } - return nil, errors.New("no block found") -} - -// EthGetTransactionByHash returns a pre-loaded transaction or nil -func (e *MockJSONRPCClient) EthGetTransactionByHash(_ string) (*ethrpc.Transaction, error) { - // pop a transaction from the list - if len(e.Transactions) > 0 { - tx := e.Transactions[len(e.Transactions)-1] - e.Transactions = e.Transactions[:len(e.Transactions)-1] - return tx, nil - } - return nil, errors.New("no transaction found") -} - -// Reset clears the mock data -func (e *MockJSONRPCClient) Reset() *MockJSONRPCClient { - e.Blocks = []*ethrpc.Block{} - e.Transactions = []*ethrpc.Transaction{} - return e -} - -// ---------------------------------------------------------------------------- -// Feed data to the mock JSON RPC client for testing -// ---------------------------------------------------------------------------- -func (e *MockJSONRPCClient) WithBlock(block *ethrpc.Block) *MockJSONRPCClient { - e.Blocks = append(e.Blocks, block) - return e -} - -func (e *MockJSONRPCClient) WithBlocks(blocks []*ethrpc.Block) *MockJSONRPCClient { - e.Blocks = append(e.Blocks, blocks...) - return e -} - -func (e *MockJSONRPCClient) WithTransaction(tx *ethrpc.Transaction) *MockJSONRPCClient { - e.Transactions = append(e.Transactions, tx) - return e -} - -func (e *MockJSONRPCClient) WithTransactions(txs []*ethrpc.Transaction) *MockJSONRPCClient { - e.Transactions = append(e.Transactions, txs...) - return e -} diff --git a/zetaclient/testutils/stub/evm_rpc.go b/zetaclient/testutils/stub/evm_rpc.go index 52afaa204e..c36d91fcd4 100644 --- a/zetaclient/testutils/stub/evm_rpc.go +++ b/zetaclient/testutils/stub/evm_rpc.go @@ -32,15 +32,29 @@ func (s subscription) Err() <-chan error { var _ interfaces.EthClientFallback = &MockEvmClient{} type MockEvmClient struct { - Receipts []*ethtypes.Receipt + Receipts []*ethtypes.Receipt + Blocks []*ethrpc.Block + Transactions []*ethrpc.Transaction } func (e *MockEvmClient) EthGetBlockByNumber(_ int, _ bool) (*ethrpc.Block, error) { - return nil, nil + // pop a block from the list + if len(e.Blocks) > 0 { + block := e.Blocks[len(e.Blocks)-1] + e.Blocks = e.Blocks[:len(e.Blocks)-1] + return block, nil + } + return nil, errors.New("no block found") } func (e *MockEvmClient) EthGetTransactionByHash(_ string) (*ethrpc.Transaction, error) { - return nil, nil + // pop a transaction from the list + if len(e.Transactions) > 0 { + tx := e.Transactions[len(e.Transactions)-1] + e.Transactions = e.Transactions[:len(e.Transactions)-1] + return tx, nil + } + return nil, errors.New("no transaction found") } func NewMockEvmClient() *MockEvmClient { @@ -122,6 +136,8 @@ func (e *MockEvmClient) TransactionSender(_ context.Context, _ *ethtypes.Transac func (e *MockEvmClient) Reset() *MockEvmClient { e.Receipts = []*ethtypes.Receipt{} + e.Blocks = []*ethrpc.Block{} + e.Transactions = []*ethrpc.Transaction{} return e } @@ -137,3 +153,23 @@ func (e *MockEvmClient) WithReceipts(receipts []*ethtypes.Receipt) *MockEvmClien e.Receipts = append(e.Receipts, receipts...) return e } + +func (e *MockEvmClient) WithBlock(block *ethrpc.Block) *MockEvmClient { + e.Blocks = append(e.Blocks, block) + return e +} + +func (e *MockEvmClient) WithBlocks(blocks []*ethrpc.Block) *MockEvmClient { + e.Blocks = append(e.Blocks, blocks...) + return e +} + +func (e *MockEvmClient) WithTransaction(tx *ethrpc.Transaction) *MockEvmClient { + e.Transactions = append(e.Transactions, tx) + return e +} + +func (e *MockEvmClient) WithTransactions(txs []*ethrpc.Transaction) *MockEvmClient { + e.Transactions = append(e.Transactions, txs...) + return e +}