diff --git a/CHANGELOG.md b/CHANGELOG.md index 26d1f96b6..49d5d9dfe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -120,6 +120,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#2030](https://github.com/NibiruChain/nibiru/pull/2030) - refactor(eth/rpc): Delete unused code and improve logging in the eth and debug namespaces - [#2031](https://github.com/NibiruChain/nibiru/pull/2031) - fix(evm): debug calls with custom tracer and tracer options - [#2039](https://github.com/NibiruChain/nibiru/pull/2039) - refactor(rpc-backend): remove unnecessary interface code +- [#2039](https://github.com/NibiruChain/nibiru/pull/2039) - refactor(rpc-backend): Remove mocks from eth/rpc/backend, partially completing [nibiru#2037](https://github.com/NibiruChain/nibiru/issue/2037). #### Dapp modules: perp, spot, oracle, etc diff --git a/eth/rpc/backend/account_info_test.go b/eth/rpc/backend/account_info_test.go index 15650c0f4..f0dcea536 100644 --- a/eth/rpc/backend/account_info_test.go +++ b/eth/rpc/backend/account_info_test.go @@ -1,412 +1 @@ -package backend - -import ( - "fmt" - "math/big" - - tmrpcclient "github.com/cometbft/cometbft/rpc/client" - sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "google.golang.org/grpc/metadata" - - "github.com/NibiruChain/nibiru/v2/eth/rpc" - "github.com/NibiruChain/nibiru/v2/eth/rpc/backend/mocks" - "github.com/NibiruChain/nibiru/v2/x/evm" - evmtest "github.com/NibiruChain/nibiru/v2/x/evm/evmtest" -) - -func (s *BackendSuite) TestGetCode() { - blockNr := rpc.NewBlockNumber(big.NewInt(1)) - contractCode := []byte( - "0xef616c92f3cfc9e92dc270d6acff9cea213cecc7020a76ee4395af09bdceb4837a1ebdb5735e11e7d3adb6104e0c3ac55180b4ddf5e54d022cc5e8837f6a4f971b", - ) - - testCases := []struct { - name string - addr common.Address - blockNrOrHash rpc.BlockNumberOrHash - registerMock func(common.Address) - expPass bool - expCode hexutil.Bytes - }{ - { - "fail - BlockHash and BlockNumber are both nil ", - evmtest.NewEthPrivAcc().EthAddr, - rpc.BlockNumberOrHash{}, - func(addr common.Address) {}, - false, - nil, - }, - { - "fail - query client errors on getting Code", - evmtest.NewEthPrivAcc().EthAddr, - rpc.BlockNumberOrHash{BlockNumber: &blockNr}, - func(addr common.Address) { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterCodeError(queryClient, addr) - }, - false, - nil, - }, - { - "pass", - evmtest.NewEthPrivAcc().EthAddr, - rpc.BlockNumberOrHash{BlockNumber: &blockNr}, - func(addr common.Address) { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterCode(queryClient, addr, contractCode) - }, - true, - contractCode, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() // reset - tc.registerMock(tc.addr) - - code, err := s.backend.GetCode(tc.addr, tc.blockNrOrHash) - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(tc.expCode, code) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestGetProof() { - blockNrInvalid := rpc.NewBlockNumber(big.NewInt(1)) - blockNr := rpc.NewBlockNumber(big.NewInt(4)) - address1 := evmtest.NewEthPrivAcc().EthAddr - - testCases := []struct { - name string - addr common.Address - storageKeys []string - blockNrOrHash rpc.BlockNumberOrHash - registerMock func(rpc.BlockNumber, common.Address) - expPass bool - expAccRes *rpc.AccountResult - }{ - { - "fail - BlockNumeber = 1 (invalidBlockNumber)", - address1, - []string{}, - rpc.BlockNumberOrHash{BlockNumber: &blockNrInvalid}, - func(bn rpc.BlockNumber, addr common.Address) { - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlock(client, bn.Int64(), nil) - s.Require().NoError(err) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterAccount(queryClient, addr, blockNrInvalid.Int64()) - }, - false, - &rpc.AccountResult{}, - }, - { - "fail - Block doesn't exist", - address1, - []string{}, - rpc.BlockNumberOrHash{BlockNumber: &blockNrInvalid}, - func(bn rpc.BlockNumber, addr common.Address) { - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockError(client, bn.Int64()) - }, - false, - &rpc.AccountResult{}, - }, - { - "pass", - address1, - []string{"0x0"}, - rpc.BlockNumberOrHash{BlockNumber: &blockNr}, - func(bn rpc.BlockNumber, addr common.Address) { - s.backend.ctx = rpc.NewContextWithHeight(bn.Int64()) - - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlock(client, bn.Int64(), nil) - s.Require().NoError(err) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterAccount(queryClient, addr, bn.Int64()) - - // Use the IAVL height if a valid tendermint height is passed in. - iavlHeight := bn.Int64() - RegisterABCIQueryWithOptions( - client, - bn.Int64(), - "store/evm/key", - evm.StateKey(address1, common.HexToHash("0x0").Bytes()), - tmrpcclient.ABCIQueryOptions{Height: iavlHeight, Prove: true}, - ) - RegisterABCIQueryWithOptions( - client, - bn.Int64(), - "store/acc/key", - authtypes.AddressStoreKey(sdk.AccAddress(address1.Bytes())), - tmrpcclient.ABCIQueryOptions{Height: iavlHeight, Prove: true}, - ) - }, - true, - &rpc.AccountResult{ - Address: address1, - AccountProof: []string{""}, - Balance: (*hexutil.Big)(big.NewInt(0)), - CodeHash: common.HexToHash(""), - Nonce: 0x0, - StorageHash: common.Hash{}, - StorageProof: []rpc.StorageResult{ - { - Key: "0x0", - Value: (*hexutil.Big)(big.NewInt(2)), - Proof: []string{""}, - }, - }, - }, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() - tc.registerMock(*tc.blockNrOrHash.BlockNumber, tc.addr) - - accRes, err := s.backend.GetProof(tc.addr, tc.storageKeys, tc.blockNrOrHash) - - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(tc.expAccRes, accRes) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestGetStorageAt() { - blockNr := rpc.NewBlockNumber(big.NewInt(1)) - - testCases := []struct { - name string - addr common.Address - key string - blockNrOrHash rpc.BlockNumberOrHash - registerMock func(common.Address, string, string) - expPass bool - expStorage hexutil.Bytes - }{ - { - "fail - BlockHash and BlockNumber are both nil", - evmtest.NewEthPrivAcc().EthAddr, - "0x0", - rpc.BlockNumberOrHash{}, - func(addr common.Address, key string, storage string) {}, - false, - nil, - }, - { - "fail - query client errors on getting Storage", - evmtest.NewEthPrivAcc().EthAddr, - "0x0", - rpc.BlockNumberOrHash{BlockNumber: &blockNr}, - func(addr common.Address, key string, storage string) { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterStorageAtError(queryClient, addr, key) - }, - false, - nil, - }, - { - "pass", - evmtest.NewEthPrivAcc().EthAddr, - "0x0", - rpc.BlockNumberOrHash{BlockNumber: &blockNr}, - func(addr common.Address, key string, storage string) { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterStorageAt(queryClient, addr, key, storage) - }, - true, - hexutil.Bytes{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() - tc.registerMock(tc.addr, tc.key, tc.expStorage.String()) - - storage, err := s.backend.GetStorageAt(tc.addr, tc.key, tc.blockNrOrHash) - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(tc.expStorage, storage) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestGetEvmGasBalance() { - blockNr := rpc.NewBlockNumber(big.NewInt(1)) - - testCases := []struct { - name string - addr common.Address - blockNrOrHash rpc.BlockNumberOrHash - registerMock func(rpc.BlockNumber, common.Address) - expPass bool - expBalance *hexutil.Big - }{ - { - "fail - BlockHash and BlockNumber are both nil", - evmtest.NewEthPrivAcc().EthAddr, - rpc.BlockNumberOrHash{}, - func(bn rpc.BlockNumber, addr common.Address) { - }, - false, - nil, - }, - { - "fail - tendermint client failed to get block", - evmtest.NewEthPrivAcc().EthAddr, - rpc.BlockNumberOrHash{BlockNumber: &blockNr}, - func(bn rpc.BlockNumber, addr common.Address) { - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockError(client, bn.Int64()) - }, - false, - nil, - }, - { - "fail - query client failed to get balance", - evmtest.NewEthPrivAcc().EthAddr, - rpc.BlockNumberOrHash{BlockNumber: &blockNr}, - func(bn rpc.BlockNumber, addr common.Address) { - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlock(client, bn.Int64(), nil) - s.Require().NoError(err) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBalanceError(queryClient, addr, bn.Int64()) - }, - false, - nil, - }, - { - "fail - invalid balance", - evmtest.NewEthPrivAcc().EthAddr, - rpc.BlockNumberOrHash{BlockNumber: &blockNr}, - func(bn rpc.BlockNumber, addr common.Address) { - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlock(client, bn.Int64(), nil) - s.Require().NoError(err) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBalanceInvalid(queryClient, addr, bn.Int64()) - }, - false, - nil, - }, - { - "fail - pruned node state", - evmtest.NewEthPrivAcc().EthAddr, - rpc.BlockNumberOrHash{BlockNumber: &blockNr}, - func(bn rpc.BlockNumber, addr common.Address) { - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlock(client, bn.Int64(), nil) - s.Require().NoError(err) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBalanceNegative(queryClient, addr, bn.Int64()) - }, - false, - nil, - }, - { - "pass", - evmtest.NewEthPrivAcc().EthAddr, - rpc.BlockNumberOrHash{BlockNumber: &blockNr}, - func(bn rpc.BlockNumber, addr common.Address) { - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlock(client, bn.Int64(), nil) - s.Require().NoError(err) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBalance(queryClient, addr, bn.Int64()) - }, - true, - (*hexutil.Big)(big.NewInt(1)), - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() - - // avoid nil pointer reference - if tc.blockNrOrHash.BlockNumber != nil { - tc.registerMock(*tc.blockNrOrHash.BlockNumber, tc.addr) - } - - balance, err := s.backend.GetBalance(tc.addr, tc.blockNrOrHash) - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(tc.expBalance, balance) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestGetTransactionCount() { - testCases := []struct { - name string - accExists bool - blockNum rpc.BlockNumber - registerMock func(common.Address, rpc.BlockNumber) - expPass bool - expTxCount hexutil.Uint64 - }{ - { - "pass - account doesn't exist", - false, - rpc.NewBlockNumber(big.NewInt(1)), - func(addr common.Address, bn rpc.BlockNumber) { - var header metadata.MD - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterParams(queryClient, &header, 1) - }, - true, - hexutil.Uint64(0), - }, - { - "fail - block height is in the future", - false, - rpc.NewBlockNumber(big.NewInt(10000)), - func(addr common.Address, bn rpc.BlockNumber) { - var header metadata.MD - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterParams(queryClient, &header, 1) - }, - false, - hexutil.Uint64(0), - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() - - addr := evmtest.NewEthPrivAcc().EthAddr - if tc.accExists { - addr = common.BytesToAddress(s.acc.Bytes()) - } - - tc.registerMock(addr, tc.blockNum) - - txCount, err := s.backend.GetTransactionCount(addr, tc.blockNum) - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(tc.expTxCount, *txCount) - } else { - s.Require().Error(err) - } - }) - } -} +package backend_test diff --git a/eth/rpc/backend/backend.go b/eth/rpc/backend/backend.go index 9f3ad79ba..2f569125f 100644 --- a/eth/rpc/backend/backend.go +++ b/eth/rpc/backend/backend.go @@ -60,7 +60,7 @@ func NewBackend( } // CosmosBackend: Currently unused. Backend functionality for the shared -// "cosmos" RPC namespace. Implements [BackendI] in combination with [EVMBackend]. +// "cosmos" RPC namespace. Implements [BackendI] in combination with [Backend]. // TODO: feat(eth): Implement the cosmos JSON-RPC defined by Wallet Connect V2: // https://docs.walletconnect.com/2.0/json-rpc/cosmos. type CosmosBackend interface { diff --git a/eth/rpc/backend/backend_suite_test.go b/eth/rpc/backend/backend_suite_test.go index e019c2fcc..1914bf865 100644 --- a/eth/rpc/backend/backend_suite_test.go +++ b/eth/rpc/backend/backend_suite_test.go @@ -1,203 +1,110 @@ -package backend +package backend_test import ( - "bufio" "math/big" - "os" - "path/filepath" "testing" - dbm "github.com/cometbft/cometbft-db" + "crypto/ecdsa" - tmrpctypes "github.com/cometbft/cometbft/rpc/core/types" - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - "github.com/cosmos/cosmos-sdk/server" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/ethereum/go-ethereum/common" + gethcommon "github.com/ethereum/go-ethereum/common" gethcore "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" "github.com/stretchr/testify/suite" - "github.com/NibiruChain/nibiru/v2/app" - "github.com/NibiruChain/nibiru/v2/eth" - "github.com/NibiruChain/nibiru/v2/eth/crypto/hd" - "github.com/NibiruChain/nibiru/v2/eth/encoding" - "github.com/NibiruChain/nibiru/v2/eth/indexer" + "github.com/NibiruChain/nibiru/v2/x/evm/evmtest" + "github.com/NibiruChain/nibiru/v2/eth/rpc" - "github.com/NibiruChain/nibiru/v2/eth/rpc/backend/mocks" "github.com/NibiruChain/nibiru/v2/x/evm" - evmtest "github.com/NibiruChain/nibiru/v2/x/evm/evmtest" + + "github.com/NibiruChain/nibiru/v2/app" + "github.com/NibiruChain/nibiru/v2/app/appconst" + "github.com/NibiruChain/nibiru/v2/eth" + "github.com/NibiruChain/nibiru/v2/eth/rpc/backend" + + "github.com/NibiruChain/nibiru/v2/x/common/testutil/genesis" + "github.com/NibiruChain/nibiru/v2/x/common/testutil/testapp" + "github.com/NibiruChain/nibiru/v2/x/common/testutil/testnetwork" ) +var recipient = evmtest.NewEthPrivAcc().EthAddr +var amountToSend = evm.NativeToWei(big.NewInt(1)) +var transferTxBlockNumber rpc.BlockNumber +var transferTxHash gethcommon.Hash + type BackendSuite struct { suite.Suite - - backend *Backend - from common.Address - acc sdk.AccAddress - signer keyring.Signer + cfg testnetwork.Config + network *testnetwork.Network + node *testnetwork.Validator + fundedAccPrivateKey *ecdsa.PrivateKey + fundedAccEthAddr gethcommon.Address + fundedAccNibiAddr sdk.AccAddress + backend *backend.Backend + ethChainID *big.Int } func TestBackendSuite(t *testing.T) { suite.Run(t, new(BackendSuite)) } -const ChainID = eth.EIP155ChainID_Testnet - -// SetupTest is executed before every BackendTestSuite test -func (s *BackendSuite) SetupTest() { - ctx := server.NewDefaultContext() - ctx.Viper.Set("telemetry.global-labels", []interface{}{}) - - baseDir := s.T().TempDir() - nodeDirName := "node" - clientDir := filepath.Join(baseDir, nodeDirName, "nibirucli") - keyRing, err := s.generateTestKeyring(clientDir) - if err != nil { - panic(err) - } - - // Create Account with set sequence - s.acc = sdk.AccAddress(evmtest.NewEthPrivAcc().EthAddr.Bytes()) - accounts := map[string]client.TestAccount{} - accounts[s.acc.String()] = client.TestAccount{ - Address: s.acc, - Num: uint64(1), - Seq: uint64(1), - } - - ethAcc := evmtest.NewEthPrivAcc() - from, priv := ethAcc.EthAddr, ethAcc.PrivKey - s.from = from - s.signer = evmtest.NewSigner(priv) - s.Require().NoError(err) - - encCfg := encoding.MakeConfig(app.ModuleBasics) - evm.RegisterInterfaces(encCfg.InterfaceRegistry) - eth.RegisterInterfaces(encCfg.InterfaceRegistry) - clientCtx := client.Context{}.WithChainID(ChainID). - WithHeight(1). - WithTxConfig(encCfg.TxConfig). - WithKeyringDir(clientDir). - WithKeyring(keyRing). - WithAccountRetriever(client.TestAccountRetriever{Accounts: accounts}) - - allowUnprotectedTxs := false - idxer := indexer.NewKVIndexer(dbm.NewMemDB(), ctx.Logger, clientCtx) - - s.backend = NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, idxer) - s.backend.cfg.JSONRPC.GasCap = 0 - s.backend.cfg.JSONRPC.EVMTimeout = 0 - s.backend.queryClient.QueryClient = mocks.NewEVMQueryClient(s.T()) - s.backend.clientCtx.Client = mocks.NewClient(s.T()) - s.backend.ctx = rpc.NewContextWithHeight(1) - - s.backend.clientCtx.Codec = encCfg.Codec -} +func (s *BackendSuite) SetupSuite() { + testapp.EnsureNibiruPrefix() -// buildEthereumTx returns an example legacy Ethereum transaction -func (s *BackendSuite) buildEthereumTx() (*evm.MsgEthereumTx, []byte) { - ethTxParams := evm.EvmTxArgs{ - ChainID: s.backend.chainID, - Nonce: uint64(0), - To: &common.Address{}, - Amount: big.NewInt(0), - GasLimit: 100000, - GasPrice: big.NewInt(1), - } - msgEthereumTx := evm.NewTx(ðTxParams) - - // A valid msg should have empty `From` - msgEthereumTx.From = s.from.Hex() - - txBuilder := s.backend.clientCtx.TxConfig.NewTxBuilder() - err := txBuilder.SetMsgs(msgEthereumTx) + genState := genesis.NewTestGenesisState(app.MakeEncodingConfig()) + homeDir := s.T().TempDir() + s.cfg = testnetwork.BuildNetworkConfig(genState) + network, err := testnetwork.New(s.T(), homeDir, s.cfg) s.Require().NoError(err) + s.network = network + s.node = network.Validators[0] + s.ethChainID = appconst.GetEthChainID(s.node.ClientCtx.ChainID) + s.backend = s.node.EthRpcBackend - bz, err := s.backend.clientCtx.TxConfig.TxEncoder()(txBuilder.GetTx()) - s.Require().NoError(err) - return msgEthereumTx, bz -} + testAccPrivateKey, _ := crypto.GenerateKey() + s.fundedAccPrivateKey = testAccPrivateKey + s.fundedAccEthAddr = crypto.PubkeyToAddress(testAccPrivateKey.PublicKey) + s.fundedAccNibiAddr = eth.EthAddrToNibiruAddr(s.fundedAccEthAddr) -// buildFormattedBlock returns a formatted block for testing -func (s *BackendSuite) buildFormattedBlock( - blockRes *tmrpctypes.ResultBlockResults, - resBlock *tmrpctypes.ResultBlock, - fullTx bool, - tx *evm.MsgEthereumTx, - validator sdk.AccAddress, - baseFee *big.Int, -) map[string]interface{} { - header := resBlock.Block.Header - gasLimit := int64(^uint32(0)) // for `MaxGas = -1` (DefaultConsensusParams) - gasUsed := new(big.Int).SetUint64(uint64(blockRes.TxsResults[0].GasUsed)) - - root := common.Hash{}.Bytes() - receipt := gethcore.NewReceipt(root, false, gasUsed.Uint64()) - bloom := gethcore.CreateBloom(gethcore.Receipts{receipt}) - - ethRPCTxs := []interface{}{} - if tx != nil { - if fullTx { - rpcTx, err := rpc.NewRPCTxFromEthTx( - tx.AsTransaction(), - common.BytesToHash(header.Hash()), - uint64(header.Height), - uint64(0), - baseFee, - s.backend.chainID, - ) - s.Require().NoError(err) - ethRPCTxs = []interface{}{rpcTx} - } else { - ethRPCTxs = []interface{}{common.HexToHash(tx.Hash)} - } - } - - return rpc.FormatBlock( - header, - resBlock.Block.Size(), - gasLimit, - gasUsed, - ethRPCTxs, - bloom, - common.BytesToAddress(validator.Bytes()), - baseFee, - ) -} + funds := sdk.NewCoins(sdk.NewInt64Coin(eth.EthBaseDenom, 100_000_000)) -func (s *BackendSuite) generateTestKeyring(clientDir string) (keyring.Keyring, error) { - buf := bufio.NewReader(os.Stdin) - encCfg := encoding.MakeConfig(app.ModuleBasics) - return keyring.New( - sdk.KeyringServiceName(), // appName - keyring.BackendTest, // backend - clientDir, // rootDir - buf, // userInput - encCfg.Codec, // codec - []keyring.Option{hd.EthSecp256k1Option()}..., + txResp, err := testnetwork.FillWalletFromValidator( + s.fundedAccNibiAddr, funds, s.node, eth.EthBaseDenom, ) -} + s.Require().NoError(err, txResp.TxHash) + s.NoError(s.network.WaitForNextBlock()) -func (s *BackendSuite) signAndEncodeEthTx(msgEthereumTx *evm.MsgEthereumTx) []byte { - ethAcc := evmtest.NewEthPrivAcc() - from, priv := ethAcc.EthAddr, ethAcc.PrivKey - signer := evmtest.NewSigner(priv) - - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterParamsWithoutHeader(queryClient, 1) + // Send 1 Transfer TX and use the results in the tests + transferTxBlockNumber, transferTxHash = s.sendNibiViaEthTransfer(recipient, amountToSend) +} - ethSigner := gethcore.LatestSigner(s.backend.ChainConfig()) - msgEthereumTx.From = from.String() - err := msgEthereumTx.Sign(ethSigner, signer) +// SendNibiViaEthTransfer sends nibi using the eth rpc backend +func (s *BackendSuite) sendNibiViaEthTransfer( + to gethcommon.Address, + amount *big.Int, +) (rpc.BlockNumber, gethcommon.Hash) { + block, err := s.backend.BlockNumber() s.Require().NoError(err) - - tx, err := msgEthereumTx.BuildTx(s.backend.clientCtx.TxConfig.NewTxBuilder(), eth.EthBaseDenom) + s.NoError(err) + + signer := gethcore.LatestSignerForChainID(s.ethChainID) + gasPrice := evm.NativeToWei(big.NewInt(1)) + tx, err := gethcore.SignNewTx( + s.fundedAccPrivateKey, + signer, + &gethcore.LegacyTx{ + To: &to, + Value: amount, + Gas: params.TxGas, + GasPrice: gasPrice, + }) s.Require().NoError(err) - - txEncoder := s.backend.clientCtx.TxConfig.TxEncoder() - txBz, err := txEncoder(tx) + txBz, err := tx.MarshalBinary() + s.Require().NoError(err) + txHash, err := s.backend.SendRawTransaction(txBz) s.Require().NoError(err) + s.Require().NoError(s.network.WaitForNextBlock()) - return txBz + return rpc.NewBlockNumber(big.NewInt(int64(block) + 1)), txHash } diff --git a/eth/rpc/backend/blocks_test.go b/eth/rpc/backend/blocks_test.go index 2cefc8748..8d04c814f 100644 --- a/eth/rpc/backend/blocks_test.go +++ b/eth/rpc/backend/blocks_test.go @@ -1,1630 +1,39 @@ -package backend +package backend_test import ( - "fmt" + "context" "math/big" - "cosmossdk.io/math" - "github.com/cosmos/gogoproto/proto" - - "github.com/cometbft/cometbft/abci/types" - cmtrpc "github.com/cometbft/cometbft/rpc/core/types" - cmt "github.com/cometbft/cometbft/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - gethcore "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/trie" - "google.golang.org/grpc/metadata" "github.com/NibiruChain/nibiru/v2/eth/rpc" - "github.com/NibiruChain/nibiru/v2/eth/rpc/backend/mocks" - "github.com/NibiruChain/nibiru/v2/x/evm" - evmtest "github.com/NibiruChain/nibiru/v2/x/evm/evmtest" ) func (s *BackendSuite) TestBlockNumber() { - testCases := []struct { - name string - registerMock func() - wantBlockNum hexutil.Uint64 - wantPass bool - }{ - { - name: "fail - invalid block header height", - registerMock: func() { - var header metadata.MD - height := int64(1) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterParamsInvalidHeight(queryClient, &header, height) - }, - wantBlockNum: 0x0, - wantPass: false, - }, - { - name: "fail - invalid block header", - registerMock: func() { - var header metadata.MD - height := int64(1) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterParamsInvalidHeader(queryClient, &header, height) - }, - wantBlockNum: 0x0, - wantPass: false, - }, - { - name: "pass - app state header height 1", - registerMock: func() { - var header metadata.MD - height := int64(1) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterParams(queryClient, &header, height) - }, - wantBlockNum: 0x1, - wantPass: true, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock() - - blockNumber, err := s.backend.BlockNumber() - - if tc.wantPass { - s.Require().NoError(err) - s.Require().Equal(tc.wantBlockNum, blockNumber) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestGetBlockByNumber() { - var ( - blockRes *cmtrpc.ResultBlockResults - resBlock *cmtrpc.ResultBlock + blockHeight, err := s.backend.BlockNumber() + s.Require().NoError(err) + blockHeightU64, err := hexutil.DecodeUint64(blockHeight.String()) + s.NoError(err) + s.Greater(blockHeightU64, uint64(1)) + + latestHeight, _ := s.network.LatestHeight() + wantFullTx := true + resp, err := s.backend.GetBlockByNumber( + rpc.NewBlockNumber(big.NewInt(latestHeight)), + wantFullTx, ) - msgEthereumTx, bz := s.buildEthereumTx() - - testCases := []struct { - name string - blockNumber rpc.BlockNumber - fullTx bool - baseFee *big.Int - validator sdk.AccAddress - ethTx *evm.MsgEthereumTx - ethTxBz []byte - registerMock func(rpc.BlockNumber, math.Int, sdk.AccAddress, []byte) - wantNoop bool - wantPass bool - }{ - { - name: "pass - tendermint block not found", - blockNumber: rpc.BlockNumber(1), - fullTx: true, - baseFee: math.NewInt(1).BigInt(), - validator: sdk.AccAddress(evmtest.NewEthPrivAcc().EthAddr.Bytes()), - ethTx: nil, - ethTxBz: nil, - registerMock: func(blockNum rpc.BlockNumber, _ math.Int, _ sdk.AccAddress, _ []byte) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockError(client, height) - }, - wantNoop: true, - wantPass: true, - }, - { - name: "pass - block not found (e.g. request block height that is greater than current one)", - blockNumber: rpc.BlockNumber(1), - fullTx: true, - baseFee: math.NewInt(1).BigInt(), - validator: sdk.AccAddress(evmtest.NewEthPrivAcc().EthAddr.Bytes()), - ethTx: nil, - ethTxBz: nil, - registerMock: func(blockNum rpc.BlockNumber, baseFee math.Int, validator sdk.AccAddress, txBz []byte) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - resBlock, _ = RegisterBlockNotFound(client, height) - }, - wantNoop: true, - wantPass: true, - }, - { - name: "pass - block results error", - blockNumber: rpc.BlockNumber(1), - fullTx: true, - baseFee: math.NewInt(1).BigInt(), - validator: sdk.AccAddress(evmtest.NewEthPrivAcc().EthAddr.Bytes()), - ethTx: nil, - ethTxBz: nil, - registerMock: func(blockNum rpc.BlockNumber, baseFee math.Int, validator sdk.AccAddress, txBz []byte) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - resBlock, _ = RegisterBlock(client, height, txBz) - RegisterBlockResultsError(client, blockNum.Int64()) - }, - wantNoop: true, - wantPass: true, - }, - { - name: "pass - without tx", - blockNumber: rpc.BlockNumber(1), - fullTx: true, - baseFee: math.NewInt(1).BigInt(), - validator: sdk.AccAddress(evmtest.NewEthPrivAcc().EthAddr.Bytes()), - ethTx: nil, - ethTxBz: nil, - registerMock: func(blockNum rpc.BlockNumber, baseFee math.Int, validator sdk.AccAddress, txBz []byte) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - resBlock, _ = RegisterBlock(client, height, txBz) - blockRes, _ = RegisterBlockResults(client, blockNum.Int64()) - RegisterConsensusParams(client, height) - - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBaseFee(queryClient, baseFee) - RegisterValidatorAccount(queryClient, validator) - }, - wantNoop: false, - wantPass: true, - }, - { - name: "pass - with tx", - blockNumber: rpc.BlockNumber(1), - fullTx: true, - baseFee: math.NewInt(1).BigInt(), - validator: sdk.AccAddress(evmtest.NewEthPrivAcc().EthAddr.Bytes()), - ethTx: msgEthereumTx, - ethTxBz: bz, - registerMock: func(blockNum rpc.BlockNumber, baseFee math.Int, validator sdk.AccAddress, txBz []byte) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - resBlock, _ = RegisterBlock(client, height, txBz) - blockRes, _ = RegisterBlockResults(client, blockNum.Int64()) - RegisterConsensusParams(client, height) + s.Require().NoError(err, resp) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBaseFee(queryClient, baseFee) - RegisterValidatorAccount(queryClient, validator) - }, - wantNoop: false, - wantPass: true, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock(tc.blockNumber, math.NewIntFromBigInt(tc.baseFee), tc.validator, tc.ethTxBz) - - block, err := s.backend.GetBlockByNumber(tc.blockNumber, tc.fullTx) - - if tc.wantPass { - if tc.wantNoop { - s.Require().Nil(block) - } else { - expBlock := s.buildFormattedBlock( - blockRes, - resBlock, - tc.fullTx, - tc.ethTx, - tc.validator, - tc.baseFee, - ) - s.Require().Equal(expBlock, block) - } - s.Require().NoError(err) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestGetBlockByHash() { - var ( - blockRes *cmtrpc.ResultBlockResults - resBlock *cmtrpc.ResultBlock + // TODO: test backend.GetBlockByHash + // s.backend.GetBlockByHash() + block, err := s.node.RPCClient.Block( + context.Background(), + &latestHeight, ) - msgEthereumTx, bz := s.buildEthereumTx() - - block := cmt.MakeBlock(1, []cmt.Tx{bz}, nil, nil) - - testCases := []struct { - name string - hash common.Hash - fullTx bool - baseFee *big.Int - validator sdk.AccAddress - tx *evm.MsgEthereumTx - txBz []byte - registerMock func( - common.Hash, math.Int, sdk.AccAddress, []byte) - wantNoop bool - wantPass bool - }{ - { - name: "fail - tendermint failed to get block", - hash: common.BytesToHash(block.Hash()), - fullTx: true, - baseFee: math.NewInt(1).BigInt(), - validator: sdk.AccAddress(evmtest.NewEthPrivAcc().EthAddr.Bytes()), - tx: nil, - txBz: nil, - registerMock: func(hash common.Hash, baseFee math.Int, validator sdk.AccAddress, txBz []byte) { - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockByHashError(client, hash, txBz) - }, - wantNoop: false, - wantPass: false, - }, - { - name: "noop - tendermint blockres not found", - hash: common.BytesToHash(block.Hash()), - fullTx: true, - baseFee: math.NewInt(1).BigInt(), - validator: sdk.AccAddress(evmtest.NewEthPrivAcc().EthAddr.Bytes()), - tx: nil, - txBz: nil, - registerMock: func(hash common.Hash, baseFee math.Int, validator sdk.AccAddress, txBz []byte) { - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockByHashNotFound(client, hash, txBz) - }, - wantNoop: true, - wantPass: true, - }, - { - name: "noop - tendermint failed to fetch block result", - hash: common.BytesToHash(block.Hash()), - fullTx: true, - baseFee: math.NewInt(1).BigInt(), - validator: sdk.AccAddress(evmtest.NewEthPrivAcc().EthAddr.Bytes()), - tx: nil, - txBz: nil, - registerMock: func(hash common.Hash, baseFee math.Int, validator sdk.AccAddress, txBz []byte) { - height := int64(1) - client := s.backend.clientCtx.Client.(*mocks.Client) - resBlock, _ = RegisterBlockByHash(client, hash, txBz) - - RegisterBlockResultsError(client, height) - }, - wantNoop: true, - wantPass: true, - }, - { - name: "pass - without tx", - hash: common.BytesToHash(block.Hash()), - fullTx: true, - baseFee: math.NewInt(1).BigInt(), - validator: sdk.AccAddress(evmtest.NewEthPrivAcc().EthAddr.Bytes()), - tx: nil, - txBz: nil, - registerMock: func(hash common.Hash, baseFee math.Int, validator sdk.AccAddress, txBz []byte) { - height := int64(1) - client := s.backend.clientCtx.Client.(*mocks.Client) - resBlock, _ = RegisterBlockByHash(client, hash, txBz) - - blockRes, _ = RegisterBlockResults(client, height) - RegisterConsensusParams(client, height) - - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBaseFee(queryClient, baseFee) - RegisterValidatorAccount(queryClient, validator) - }, - wantNoop: false, - wantPass: true, - }, - { - name: "pass - with tx", - hash: common.BytesToHash(block.Hash()), - fullTx: true, - baseFee: math.NewInt(1).BigInt(), - validator: sdk.AccAddress(evmtest.NewEthPrivAcc().EthAddr.Bytes()), - tx: msgEthereumTx, - txBz: bz, - registerMock: func(hash common.Hash, baseFee math.Int, validator sdk.AccAddress, txBz []byte) { - height := int64(1) - client := s.backend.clientCtx.Client.(*mocks.Client) - resBlock, _ = RegisterBlockByHash(client, hash, txBz) - - blockRes, _ = RegisterBlockResults(client, height) - RegisterConsensusParams(client, height) - - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBaseFee(queryClient, baseFee) - RegisterValidatorAccount(queryClient, validator) - }, - wantNoop: false, - wantPass: true, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock(tc.hash, math.NewIntFromBigInt(tc.baseFee), tc.validator, tc.txBz) - - block, err := s.backend.GetBlockByHash(tc.hash, tc.fullTx) - - if tc.wantPass { - if tc.wantNoop { - s.Require().Nil(block) - } else { - expBlock := s.buildFormattedBlock( - blockRes, - resBlock, - tc.fullTx, - tc.tx, - tc.validator, - tc.baseFee, - ) - s.Require().Equal(expBlock, block) - } - s.Require().NoError(err) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestGetBlockTransactionCountByHash() { - _, bz := s.buildEthereumTx() - block := cmt.MakeBlock(1, []cmt.Tx{bz}, nil, nil) - emptyBlock := cmt.MakeBlock(1, []cmt.Tx{}, nil, nil) - - testCases := []struct { - name string - hash common.Hash - registerMock func(common.Hash) - wantCount hexutil.Uint - wantPass bool - }{ - { - name: "fail - block not found", - hash: common.BytesToHash(emptyBlock.Hash()), - registerMock: func(hash common.Hash) { - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockByHashError(client, hash, nil) - }, - wantCount: hexutil.Uint(0), - wantPass: false, - }, - { - name: "fail - tendermint client failed to get block result", - hash: common.BytesToHash(emptyBlock.Hash()), - registerMock: func(hash common.Hash) { - height := int64(1) - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlockByHash(client, hash, nil) - s.Require().NoError(err) - RegisterBlockResultsError(client, height) - }, - wantCount: hexutil.Uint(0), - wantPass: false, - }, - { - name: "pass - block without tx", - hash: common.BytesToHash(emptyBlock.Hash()), - registerMock: func(hash common.Hash) { - height := int64(1) - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlockByHash(client, hash, nil) - s.Require().NoError(err) - _, err = RegisterBlockResults(client, height) - s.Require().NoError(err) - }, - wantCount: hexutil.Uint(0), - wantPass: true, - }, - { - name: "pass - block with tx", - hash: common.BytesToHash(block.Hash()), - registerMock: func(hash common.Hash) { - height := int64(1) - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlockByHash(client, hash, bz) - s.Require().NoError(err) - _, err = RegisterBlockResults(client, height) - s.Require().NoError(err) - }, - wantCount: hexutil.Uint(1), - wantPass: true, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() // reset test and queries - - tc.registerMock(tc.hash) - count := s.backend.GetBlockTransactionCountByHash(tc.hash) - if tc.wantPass { - s.Require().Equal(tc.wantCount, *count) - } else { - s.Require().Nil(count) - } - }) - } -} - -func (s *BackendSuite) TestGetBlockTransactionCountByNumber() { - _, bz := s.buildEthereumTx() - block := cmt.MakeBlock(1, []cmt.Tx{bz}, nil, nil) - emptyBlock := cmt.MakeBlock(1, []cmt.Tx{}, nil, nil) - - testCases := []struct { - name string - blockNum rpc.BlockNumber - registerMock func(rpc.BlockNumber) - wantCount hexutil.Uint - wantPass bool - }{ - { - name: "fail - block not found", - blockNum: rpc.BlockNumber(emptyBlock.Height), - registerMock: func(blockNum rpc.BlockNumber) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockError(client, height) - }, - wantCount: hexutil.Uint(0), - wantPass: false, - }, - { - name: "fail - tendermint client failed to get block result", - blockNum: rpc.BlockNumber(emptyBlock.Height), - registerMock: func(blockNum rpc.BlockNumber) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlock(client, height, nil) - s.Require().NoError(err) - RegisterBlockResultsError(client, height) - }, - wantCount: hexutil.Uint(0), - wantPass: false, - }, - { - name: "pass - block without tx", - blockNum: rpc.BlockNumber(emptyBlock.Height), - registerMock: func(blockNum rpc.BlockNumber) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlock(client, height, nil) - s.Require().NoError(err) - _, err = RegisterBlockResults(client, height) - s.Require().NoError(err) - }, - wantCount: hexutil.Uint(0), - wantPass: true, - }, - { - name: "pass - block with tx", - blockNum: rpc.BlockNumber(block.Height), - registerMock: func(blockNum rpc.BlockNumber) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlock(client, height, bz) - s.Require().NoError(err) - _, err = RegisterBlockResults(client, height) - s.Require().NoError(err) - }, - wantCount: hexutil.Uint(1), - wantPass: true, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() // reset test and queries - - tc.registerMock(tc.blockNum) - count := s.backend.GetBlockTransactionCountByNumber(tc.blockNum) - if tc.wantPass { - s.Require().Equal(tc.wantCount, *count) - } else { - s.Require().Nil(count) - } - }) - } -} - -func (s *BackendSuite) TestTendermintBlockByNumber() { - var expResultBlock *cmtrpc.ResultBlock - - testCases := []struct { - name string - blockNumber rpc.BlockNumber - registerMock func(rpc.BlockNumber) - wantBlockFound bool - wantPass bool - }{ - { - name: "fail - client error", - blockNumber: rpc.BlockNumber(1), - registerMock: func(blockNum rpc.BlockNumber) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockError(client, height) - }, - wantBlockFound: false, - wantPass: false, - }, - { - name: "noop - block not found", - blockNumber: rpc.BlockNumber(1), - registerMock: func(blockNum rpc.BlockNumber) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlockNotFound(client, height) - s.Require().NoError(err) - }, - wantBlockFound: false, - wantPass: true, - }, - { - name: "fail - blockNum < 0 with app state height error", - blockNumber: rpc.BlockNumber(-1), - registerMock: func(_ rpc.BlockNumber) { - var header metadata.MD - appHeight := int64(1) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterParamsError(queryClient, &header, appHeight) - }, - wantBlockFound: false, - wantPass: false, - }, - { - name: "pass - blockNum < 0 with app state height >= 1", - blockNumber: rpc.BlockNumber(-1), - registerMock: func(blockNum rpc.BlockNumber) { - var header metadata.MD - appHeight := int64(1) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterParams(queryClient, &header, appHeight) - - tmHeight := appHeight - client := s.backend.clientCtx.Client.(*mocks.Client) - expResultBlock, _ = RegisterBlock(client, tmHeight, nil) - }, - wantBlockFound: true, - wantPass: true, - }, - { - name: "pass - blockNum = 0 (defaults to blockNum = 1 due to a difference between tendermint heights and geth heights)", - blockNumber: rpc.BlockNumber(0), - registerMock: func(blockNum rpc.BlockNumber) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - expResultBlock, _ = RegisterBlock(client, height, nil) - }, - wantBlockFound: true, - wantPass: true, - }, - { - name: "pass - blockNum = 1", - blockNumber: rpc.BlockNumber(1), - registerMock: func(blockNum rpc.BlockNumber) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - expResultBlock, _ = RegisterBlock(client, height, nil) - }, - wantBlockFound: true, - wantPass: true, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() // reset test and queries - - tc.registerMock(tc.blockNumber) - resultBlock, err := s.backend.TendermintBlockByNumber(tc.blockNumber) - - if tc.wantPass { - s.Require().NoError(err) - - if !tc.wantBlockFound { - s.Require().Nil(resultBlock) - } else { - s.Require().Equal(expResultBlock, resultBlock) - s.Require().Equal(expResultBlock.Block.Header.Height, resultBlock.Block.Header.Height) - } - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestTendermintBlockResultByNumber() { - var expBlockRes *cmtrpc.ResultBlockResults - - testCases := []struct { - name string - blockNumber int64 - registerMock func(int64) - wantPass bool - }{ - { - name: "fail", - blockNumber: 1, - registerMock: func(blockNum int64) { - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockResultsError(client, blockNum) - }, - wantPass: false, - }, - { - name: "pass", - blockNumber: 1, - registerMock: func(blockNum int64) { - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlockResults(client, blockNum) - s.Require().NoError(err) - expBlockRes = &cmtrpc.ResultBlockResults{ - Height: blockNum, - TxsResults: []*types.ResponseDeliverTx{{Code: 0, GasUsed: 0}}, - } - }, - wantPass: true, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock(tc.blockNumber) - - blockRes, err := s.backend.TendermintBlockResultByNumber(&tc.blockNumber) //#nosec G601 -- fine for tests - - if tc.wantPass { - s.Require().NoError(err) - s.Require().Equal(expBlockRes, blockRes) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestBlockNumberFromTendermint() { - var resBlock *cmtrpc.ResultBlock - - _, bz := s.buildEthereumTx() - block := cmt.MakeBlock(1, []cmt.Tx{bz}, nil, nil) - blockNum := rpc.NewBlockNumber(big.NewInt(block.Height)) - blockHash := common.BytesToHash(block.Hash()) - - testCases := []struct { - name string - blockNum *rpc.BlockNumber - hash *common.Hash - registerMock func(*common.Hash) - wantPass bool - }{ - { - "error - without blockHash or blockNum", - nil, - nil, - func(hash *common.Hash) {}, - false, - }, - { - "error - with blockHash, tendermint client failed to get block", - nil, - &blockHash, - func(hash *common.Hash) { - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockByHashError(client, *hash, bz) - }, - false, - }, - { - "pass - with blockHash", - nil, - &blockHash, - func(hash *common.Hash) { - client := s.backend.clientCtx.Client.(*mocks.Client) - resBlock, _ = RegisterBlockByHash(client, *hash, bz) - }, - true, - }, - { - "pass - without blockHash & with blockNumber", - &blockNum, - nil, - func(hash *common.Hash) {}, - true, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() // reset test and queries - - blockNrOrHash := rpc.BlockNumberOrHash{ - BlockNumber: tc.blockNum, - BlockHash: tc.hash, - } - - tc.registerMock(tc.hash) - blockNum, err := s.backend.BlockNumberFromTendermint(blockNrOrHash) - - if tc.wantPass { - s.Require().NoError(err) - if tc.hash == nil { - s.Require().Equal(*tc.blockNum, blockNum) - } else { - expHeight := rpc.NewBlockNumber(big.NewInt(resBlock.Block.Height)) - s.Require().Equal(expHeight, blockNum) - } - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestBlockNumberFromTendermintByHash() { - var resBlock *cmtrpc.ResultBlock - - _, bz := s.buildEthereumTx() - block := cmt.MakeBlock(1, []cmt.Tx{bz}, nil, nil) - emptyBlock := cmt.MakeBlock(1, []cmt.Tx{}, nil, nil) - - testCases := []struct { - name string - hash common.Hash - registerMock func(common.Hash) - wantPass bool - }{ - { - "fail - tendermint client failed to get block", - common.BytesToHash(block.Hash()), - func(hash common.Hash) { - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockByHashError(client, hash, bz) - }, - false, - }, - { - "pass - block without tx", - common.BytesToHash(emptyBlock.Hash()), - func(hash common.Hash) { - client := s.backend.clientCtx.Client.(*mocks.Client) - resBlock, _ = RegisterBlockByHash(client, hash, bz) - }, - true, - }, - { - "pass - block with tx", - common.BytesToHash(block.Hash()), - func(hash common.Hash) { - client := s.backend.clientCtx.Client.(*mocks.Client) - resBlock, _ = RegisterBlockByHash(client, hash, bz) - }, - true, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() // reset test and queries - - tc.registerMock(tc.hash) - blockNum, err := s.backend.BlockNumberFromTendermintByHash(tc.hash) - if tc.wantPass { - expHeight := big.NewInt(resBlock.Block.Height) - s.Require().NoError(err) - s.Require().Equal(expHeight, blockNum) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestBlockBloom() { - testCases := []struct { - name string - blockRes *cmtrpc.ResultBlockResults - wantBlockBloom gethcore.Bloom - wantPass bool - }{ - { - "fail - empty block result", - &cmtrpc.ResultBlockResults{}, - gethcore.Bloom{}, - false, - }, - { - "fail - non block bloom event type", - &cmtrpc.ResultBlockResults{ - EndBlockEvents: []types.Event{{Type: evm.EventTypeEthereumTx}}, - }, - gethcore.Bloom{}, - false, - }, - { - "fail - nonblock bloom attribute key", - &cmtrpc.ResultBlockResults{ - EndBlockEvents: []types.Event{ - { - Type: proto.MessageName((*evm.EventBlockBloom)(nil)), - Attributes: []types.EventAttribute{ - {Key: evm.AttributeKeyEthereumTxHash}, - }, - }, - }, - }, - gethcore.Bloom{}, - false, - }, - { - "pass - block bloom attribute key", - &cmtrpc.ResultBlockResults{ - EndBlockEvents: []types.Event{ - { - Type: proto.MessageName((*evm.EventBlockBloom)(nil)), - Attributes: []types.EventAttribute{ - {Key: evm.AttributeKeyEthereumBloom}, - }, - }, - }, - }, - gethcore.Bloom{}, - true, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - blockBloom, err := s.backend.BlockBloom(tc.blockRes) - - if tc.wantPass { - s.Require().NoError(err) - s.Require().Equal(tc.wantBlockBloom, blockBloom) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestGetEthBlockFromTendermint() { - msgEthereumTx, bz := s.buildEthereumTx() - emptyBlock := cmt.MakeBlock(1, []cmt.Tx{}, nil, nil) - - testCases := []struct { - name string - baseFee *big.Int - validator sdk.AccAddress - height int64 - resBlock *cmtrpc.ResultBlock - blockRes *cmtrpc.ResultBlockResults - fullTx bool - registerMock func(math.Int, sdk.AccAddress, int64) - wantTxs bool - wantPass bool - }{ - { - name: "pass - block without tx", - baseFee: math.NewInt(1).BigInt(), - validator: sdk.AccAddress(common.Address{}.Bytes()), - height: int64(1), - resBlock: &cmtrpc.ResultBlock{Block: emptyBlock}, - blockRes: &cmtrpc.ResultBlockResults{ - Height: 1, - TxsResults: []*types.ResponseDeliverTx{{Code: 0, GasUsed: 0}}, - }, - fullTx: false, - registerMock: func(baseFee math.Int, validator sdk.AccAddress, height int64) { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBaseFee(queryClient, baseFee) - RegisterValidatorAccount(queryClient, validator) - - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterConsensusParams(client, height) - }, - wantTxs: false, - wantPass: true, - }, - { - name: "pass - block with tx - with BaseFee error", - baseFee: nil, - validator: sdk.AccAddress(evmtest.NewEthPrivAcc().EthAddr.Bytes()), - height: int64(1), - resBlock: &cmtrpc.ResultBlock{ - Block: cmt.MakeBlock(1, []cmt.Tx{bz}, nil, nil), - }, - blockRes: &cmtrpc.ResultBlockResults{ - Height: 1, - TxsResults: []*types.ResponseDeliverTx{{Code: 0, GasUsed: 0}}, - }, - fullTx: true, - registerMock: func(baseFee math.Int, validator sdk.AccAddress, height int64) { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBaseFeeError(queryClient) - RegisterValidatorAccount(queryClient, validator) - - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterConsensusParams(client, height) - }, - wantTxs: true, - wantPass: true, - }, - { - name: "pass - block with tx - with ValidatorAccount error", - baseFee: math.NewInt(1).BigInt(), - validator: sdk.AccAddress(common.Address{}.Bytes()), - height: int64(1), - resBlock: &cmtrpc.ResultBlock{ - Block: cmt.MakeBlock(1, []cmt.Tx{bz}, nil, nil), - }, - blockRes: &cmtrpc.ResultBlockResults{ - Height: 1, - TxsResults: []*types.ResponseDeliverTx{{Code: 0, GasUsed: 0}}, - }, - fullTx: true, - registerMock: func(baseFee math.Int, validator sdk.AccAddress, height int64) { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBaseFee(queryClient, baseFee) - RegisterValidatorAccountError(queryClient) - - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterConsensusParams(client, height) - }, - wantTxs: true, - wantPass: true, - }, - { - name: "pass - block with tx - with ConsensusParams error - BlockMaxGas defaults to max uint32", - baseFee: math.NewInt(1).BigInt(), - validator: sdk.AccAddress(evmtest.NewEthPrivAcc().EthAddr.Bytes()), - height: int64(1), - resBlock: &cmtrpc.ResultBlock{ - Block: cmt.MakeBlock(1, []cmt.Tx{bz}, nil, nil), - }, - blockRes: &cmtrpc.ResultBlockResults{ - Height: 1, - TxsResults: []*types.ResponseDeliverTx{{Code: 0, GasUsed: 0}}, - }, - fullTx: true, - registerMock: func(baseFee math.Int, validator sdk.AccAddress, height int64) { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBaseFee(queryClient, baseFee) - RegisterValidatorAccount(queryClient, validator) - - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterConsensusParamsError(client, height) - }, - wantTxs: true, - wantPass: true, - }, - { - name: "pass - block with tx - with ShouldIgnoreGasUsed - empty txs", - baseFee: math.NewInt(1).BigInt(), - validator: sdk.AccAddress(evmtest.NewEthPrivAcc().EthAddr.Bytes()), - height: int64(1), - resBlock: &cmtrpc.ResultBlock{ - Block: cmt.MakeBlock(1, []cmt.Tx{bz}, nil, nil), - }, - blockRes: &cmtrpc.ResultBlockResults{ - Height: 1, - TxsResults: []*types.ResponseDeliverTx{ - { - Code: 11, - GasUsed: 0, - Log: "no block gas left to run tx: out of gas", - }, - }, - }, - fullTx: true, - registerMock: func(baseFee math.Int, validator sdk.AccAddress, height int64) { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBaseFee(queryClient, baseFee) - RegisterValidatorAccount(queryClient, validator) - - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterConsensusParams(client, height) - }, - wantTxs: false, - wantPass: true, - }, - { - name: "pass - block with tx - non fullTx", - baseFee: math.NewInt(1).BigInt(), - validator: sdk.AccAddress(evmtest.NewEthPrivAcc().EthAddr.Bytes()), - height: int64(1), - resBlock: &cmtrpc.ResultBlock{ - Block: cmt.MakeBlock(1, []cmt.Tx{bz}, nil, nil), - }, - blockRes: &cmtrpc.ResultBlockResults{ - Height: 1, - TxsResults: []*types.ResponseDeliverTx{{Code: 0, GasUsed: 0}}, - }, - fullTx: false, - registerMock: func(baseFee math.Int, validator sdk.AccAddress, height int64) { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBaseFee(queryClient, baseFee) - RegisterValidatorAccount(queryClient, validator) - - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterConsensusParams(client, height) - }, - wantTxs: true, - wantPass: true, - }, - { - name: "pass - block with tx", - baseFee: math.NewInt(1).BigInt(), - validator: sdk.AccAddress(evmtest.NewEthPrivAcc().EthAddr.Bytes()), - height: int64(1), - resBlock: &cmtrpc.ResultBlock{ - Block: cmt.MakeBlock(1, []cmt.Tx{bz}, nil, nil), - }, - blockRes: &cmtrpc.ResultBlockResults{ - Height: 1, - TxsResults: []*types.ResponseDeliverTx{{Code: 0, GasUsed: 0}}, - }, - fullTx: true, - registerMock: func(baseFee math.Int, validator sdk.AccAddress, height int64) { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBaseFee(queryClient, baseFee) - RegisterValidatorAccount(queryClient, validator) - - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterConsensusParams(client, height) - }, - wantTxs: true, - wantPass: true, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock(math.NewIntFromBigInt(tc.baseFee), tc.validator, tc.height) - - block, err := s.backend.RPCBlockFromTendermintBlock(tc.resBlock, tc.blockRes, tc.fullTx) - - var expBlock map[string]interface{} - header := tc.resBlock.Block.Header - gasLimit := int64(^uint32(0)) // for `MaxGas = -1` (DefaultConsensusParams) - gasUsed := new(big.Int).SetUint64(uint64(tc.blockRes.TxsResults[0].GasUsed)) - - root := common.Hash{}.Bytes() - receipt := gethcore.NewReceipt(root, false, gasUsed.Uint64()) - bloom := gethcore.CreateBloom(gethcore.Receipts{receipt}) - - ethRPCTxs := []interface{}{} - - if tc.wantTxs { - if tc.fullTx { - rpcTx, err := rpc.NewRPCTxFromEthTx( - msgEthereumTx.AsTransaction(), - common.BytesToHash(header.Hash()), - uint64(header.Height), - uint64(0), - tc.baseFee, - s.backend.chainID, - ) - s.Require().NoError(err) - ethRPCTxs = []interface{}{rpcTx} - } else { - ethRPCTxs = []interface{}{common.HexToHash(msgEthereumTx.Hash)} - } - } - - expBlock = rpc.FormatBlock( - header, - tc.resBlock.Block.Size(), - gasLimit, - gasUsed, - ethRPCTxs, - bloom, - common.BytesToAddress(tc.validator.Bytes()), - tc.baseFee, - ) - - if tc.wantPass { - s.Require().Equal(expBlock, block) - s.Require().NoError(err) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestEthMsgsFromTendermintBlock() { - msgEthereumTx, bz := s.buildEthereumTx() - - testCases := []struct { - name string - resBlock *cmtrpc.ResultBlock - blockRes *cmtrpc.ResultBlockResults - wantMsgs []*evm.MsgEthereumTx - }{ - { - "tx in not included in block - unsuccessful tx without ExceedBlockGasLimit error", - &cmtrpc.ResultBlock{ - Block: cmt.MakeBlock(1, []cmt.Tx{bz}, nil, nil), - }, - &cmtrpc.ResultBlockResults{ - TxsResults: []*types.ResponseDeliverTx{ - { - Code: 1, - }, - }, - }, - []*evm.MsgEthereumTx(nil), - }, - { - "tx included in block - unsuccessful tx with ExceedBlockGasLimit error", - &cmtrpc.ResultBlock{ - Block: cmt.MakeBlock(1, []cmt.Tx{bz}, nil, nil), - }, - &cmtrpc.ResultBlockResults{ - TxsResults: []*types.ResponseDeliverTx{ - { - Code: 1, - Log: rpc.ErrExceedBlockGasLimit, - }, - }, - }, - []*evm.MsgEthereumTx{msgEthereumTx}, - }, - { - "pass", - &cmtrpc.ResultBlock{ - Block: cmt.MakeBlock(1, []cmt.Tx{bz}, nil, nil), - }, - &cmtrpc.ResultBlockResults{ - TxsResults: []*types.ResponseDeliverTx{ - { - Code: 0, - Log: rpc.ErrExceedBlockGasLimit, - }, - }, - }, - []*evm.MsgEthereumTx{msgEthereumTx}, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() // reset test and queries - - msgs := s.backend.EthMsgsFromTendermintBlock(tc.resBlock, tc.blockRes) - s.Require().Equal(tc.wantMsgs, msgs) - }) - } -} - -func (s *BackendSuite) TestHeaderByNumber() { - var expResultBlock *cmtrpc.ResultBlock - - _, bz := s.buildEthereumTx() - - testCases := []struct { - name string - blockNumber rpc.BlockNumber - baseFee *big.Int - registerMock func(rpc.BlockNumber, math.Int) - wantPass bool - }{ - { - name: "fail - tendermint client failed to get block", - blockNumber: rpc.BlockNumber(1), - baseFee: math.NewInt(1).BigInt(), - registerMock: func(blockNum rpc.BlockNumber, baseFee math.Int) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockError(client, height) - }, - wantPass: false, - }, - { - name: "fail - block not found for height", - blockNumber: rpc.BlockNumber(1), - baseFee: math.NewInt(1).BigInt(), - registerMock: func(blockNum rpc.BlockNumber, baseFee math.Int) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlockNotFound(client, height) - s.Require().NoError(err) - }, - wantPass: false, - }, - { - name: "fail - block not found for height", - blockNumber: rpc.BlockNumber(1), - baseFee: math.NewInt(1).BigInt(), - registerMock: func(blockNum rpc.BlockNumber, baseFee math.Int) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlock(client, height, nil) - s.Require().NoError(err) - RegisterBlockResultsError(client, height) - }, - wantPass: false, - }, - { - name: "pass - without Base Fee, failed to fetch from prunned block", - blockNumber: rpc.BlockNumber(1), - baseFee: nil, - registerMock: func(blockNum rpc.BlockNumber, baseFee math.Int) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - expResultBlock, _ = RegisterBlock(client, height, nil) - _, err := RegisterBlockResults(client, height) - s.Require().NoError(err) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBaseFeeError(queryClient) - }, - wantPass: true, - }, - { - name: "pass - blockNum = 1, without tx", - blockNumber: rpc.BlockNumber(1), - baseFee: math.NewInt(1).BigInt(), - registerMock: func(blockNum rpc.BlockNumber, baseFee math.Int) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - expResultBlock, _ = RegisterBlock(client, height, nil) - _, err := RegisterBlockResults(client, height) - s.Require().NoError(err) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBaseFee(queryClient, baseFee) - }, - wantPass: true, - }, - { - name: "pass - blockNum = 1, with tx", - blockNumber: rpc.BlockNumber(1), - baseFee: math.NewInt(1).BigInt(), - registerMock: func(blockNum rpc.BlockNumber, baseFee math.Int) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - expResultBlock, _ = RegisterBlock(client, height, bz) - _, err := RegisterBlockResults(client, height) - s.Require().NoError(err) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBaseFee(queryClient, baseFee) - }, - wantPass: true, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() // reset test and queries - - tc.registerMock(tc.blockNumber, math.NewIntFromBigInt(tc.baseFee)) - header, err := s.backend.HeaderByNumber(tc.blockNumber) - - if tc.wantPass { - expHeader := rpc.EthHeaderFromTendermint(expResultBlock.Block.Header, gethcore.Bloom{}, tc.baseFee) - s.Require().NoError(err) - s.Require().Equal(expHeader, header) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestHeaderByHash() { - var expResultBlock *cmtrpc.ResultBlock - - _, bz := s.buildEthereumTx() - block := cmt.MakeBlock(1, []cmt.Tx{bz}, nil, nil) - emptyBlock := cmt.MakeBlock(1, []cmt.Tx{}, nil, nil) - - testCases := []struct { - name string - hash common.Hash - baseFee *big.Int - registerMock func(common.Hash, math.Int) - wantPass bool - }{ - { - name: "fail - tendermint client failed to get block", - hash: common.BytesToHash(block.Hash()), - baseFee: math.NewInt(1).BigInt(), - registerMock: func(hash common.Hash, baseFee math.Int) { - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockByHashError(client, hash, bz) - }, - wantPass: false, - }, - { - name: "fail - block not found for height", - hash: common.BytesToHash(block.Hash()), - baseFee: math.NewInt(1).BigInt(), - registerMock: func(hash common.Hash, baseFee math.Int) { - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockByHashNotFound(client, hash, bz) - }, - wantPass: false, - }, - { - name: "fail - block not found for height", - hash: common.BytesToHash(block.Hash()), - baseFee: math.NewInt(1).BigInt(), - registerMock: func(hash common.Hash, baseFee math.Int) { - height := int64(1) - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlockByHash(client, hash, bz) - s.Require().NoError(err) - RegisterBlockResultsError(client, height) - }, - wantPass: false, - }, - { - name: "pass - without Base Fee, failed to fetch from prunned block", - hash: common.BytesToHash(block.Hash()), - baseFee: nil, - registerMock: func(hash common.Hash, baseFee math.Int) { - height := int64(1) - client := s.backend.clientCtx.Client.(*mocks.Client) - expResultBlock, _ = RegisterBlockByHash(client, hash, bz) - _, err := RegisterBlockResults(client, height) - s.Require().NoError(err) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBaseFeeError(queryClient) - }, - wantPass: true, - }, - { - name: "pass - blockNum = 1, without tx", - hash: common.BytesToHash(emptyBlock.Hash()), - baseFee: math.NewInt(1).BigInt(), - registerMock: func(hash common.Hash, baseFee math.Int) { - height := int64(1) - client := s.backend.clientCtx.Client.(*mocks.Client) - expResultBlock, _ = RegisterBlockByHash(client, hash, nil) - _, err := RegisterBlockResults(client, height) - s.Require().NoError(err) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBaseFee(queryClient, baseFee) - }, - wantPass: true, - }, - { - name: "pass - with tx", - hash: common.BytesToHash(block.Hash()), - baseFee: math.NewInt(1).BigInt(), - registerMock: func(hash common.Hash, baseFee math.Int) { - height := int64(1) - client := s.backend.clientCtx.Client.(*mocks.Client) - expResultBlock, _ = RegisterBlockByHash(client, hash, bz) - _, err := RegisterBlockResults(client, height) - s.Require().NoError(err) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBaseFee(queryClient, baseFee) - }, - wantPass: true, - }, - } - - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() // reset test and queries - - tc.registerMock(tc.hash, math.NewIntFromBigInt(tc.baseFee)) - header, err := s.backend.HeaderByHash(tc.hash) - - if tc.wantPass { - expHeader := rpc.EthHeaderFromTendermint(expResultBlock.Block.Header, gethcore.Bloom{}, tc.baseFee) - s.Require().NoError(err) - s.Require().Equal(expHeader, header) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestEthBlockByNumber() { - msgEthereumTx, bz := s.buildEthereumTx() - emptyBlock := cmt.MakeBlock(1, []cmt.Tx{}, nil, nil) - - testCases := []struct { - name string - blockNumber rpc.BlockNumber - registerMock func(rpc.BlockNumber) - expEthBlock *gethcore.Block - wantPass bool - }{ - { - name: "fail - tendermint client failed to get block", - blockNumber: rpc.BlockNumber(1), - registerMock: func(blockNum rpc.BlockNumber) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockError(client, height) - }, - expEthBlock: nil, - wantPass: false, - }, - { - name: "fail - block result not found for height", - blockNumber: rpc.BlockNumber(1), - registerMock: func(blockNum rpc.BlockNumber) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlock(client, height, nil) - s.Require().NoError(err) - RegisterBlockResultsError(client, blockNum.Int64()) - }, - expEthBlock: nil, - wantPass: false, - }, - { - name: "pass - block without tx", - blockNumber: rpc.BlockNumber(1), - registerMock: func(blockNum rpc.BlockNumber) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlock(client, height, nil) - s.Require().NoError(err) - _, err = RegisterBlockResults(client, blockNum.Int64()) - s.Require().NoError(err) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - baseFee := math.NewInt(1) - RegisterBaseFee(queryClient, baseFee) - }, - expEthBlock: gethcore.NewBlock( - rpc.EthHeaderFromTendermint( - emptyBlock.Header, - gethcore.Bloom{}, - math.NewInt(1).BigInt(), - ), - []*gethcore.Transaction{}, - nil, - nil, - nil, - ), - wantPass: true, - }, - { - name: "pass - block with tx", - blockNumber: rpc.BlockNumber(1), - registerMock: func(blockNum rpc.BlockNumber) { - height := blockNum.Int64() - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlock(client, height, bz) - s.Require().NoError(err) - _, err = RegisterBlockResults(client, blockNum.Int64()) - s.Require().NoError(err) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - baseFee := math.NewInt(1) - RegisterBaseFee(queryClient, baseFee) - }, - expEthBlock: gethcore.NewBlock( - rpc.EthHeaderFromTendermint( - emptyBlock.Header, - gethcore.Bloom{}, - math.NewInt(1).BigInt(), - ), - []*gethcore.Transaction{msgEthereumTx.AsTransaction()}, - nil, - nil, - trie.NewStackTrie(nil), - ), - wantPass: true, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock(tc.blockNumber) - - ethBlock, err := s.backend.EthBlockByNumber(tc.blockNumber) - - if tc.wantPass { - s.Require().NoError(err) - s.Require().Equal(tc.expEthBlock.Header(), ethBlock.Header()) - s.Require().Equal(tc.expEthBlock.Uncles(), ethBlock.Uncles()) - s.Require().Equal(tc.expEthBlock.ReceiptHash(), ethBlock.ReceiptHash()) - for i, tx := range tc.expEthBlock.Transactions() { - s.Require().Equal(tx.Data(), ethBlock.Transactions()[i].Data()) - } - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestEthBlockFromTendermintBlock() { - msgEthereumTx, bz := s.buildEthereumTx() - emptyBlock := cmt.MakeBlock(1, []cmt.Tx{}, nil, nil) - - testCases := []struct { - name string - baseFee *big.Int - resBlock *cmtrpc.ResultBlock - blockRes *cmtrpc.ResultBlockResults - registerMock func(math.Int, int64) - expEthBlock *gethcore.Block - wantPass bool - }{ - { - name: "pass - block without tx", - baseFee: math.NewInt(1).BigInt(), - resBlock: &cmtrpc.ResultBlock{ - Block: emptyBlock, - }, - blockRes: &cmtrpc.ResultBlockResults{ - Height: 1, - TxsResults: []*types.ResponseDeliverTx{{Code: 0, GasUsed: 0}}, - }, - registerMock: func(baseFee math.Int, blockNum int64) { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBaseFee(queryClient, baseFee) - }, - expEthBlock: gethcore.NewBlock( - rpc.EthHeaderFromTendermint( - emptyBlock.Header, - gethcore.Bloom{}, - math.NewInt(1).BigInt(), - ), - []*gethcore.Transaction{}, - nil, - nil, - nil, - ), - wantPass: true, - }, - { - name: "pass - block with tx", - baseFee: math.NewInt(1).BigInt(), - resBlock: &cmtrpc.ResultBlock{ - Block: cmt.MakeBlock(1, []cmt.Tx{bz}, nil, nil), - }, - blockRes: &cmtrpc.ResultBlockResults{ - Height: 1, - TxsResults: []*types.ResponseDeliverTx{{Code: 0, GasUsed: 0}}, - EndBlockEvents: []types.Event{ - { - Type: evm.EventTypeBlockBloom, - Attributes: []types.EventAttribute{ - {Key: evm.AttributeKeyEthereumBloom}, - }, - }, - }, - }, - registerMock: func(baseFee math.Int, blockNum int64) { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBaseFee(queryClient, baseFee) - }, - expEthBlock: gethcore.NewBlock( - rpc.EthHeaderFromTendermint( - emptyBlock.Header, - gethcore.Bloom{}, - math.NewInt(1).BigInt(), - ), - []*gethcore.Transaction{msgEthereumTx.AsTransaction()}, - nil, - nil, - trie.NewStackTrie(nil), - ), - wantPass: true, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock(math.NewIntFromBigInt(tc.baseFee), tc.blockRes.Height) - - ethBlock, err := s.backend.EthBlockFromTendermintBlock(tc.resBlock, tc.blockRes) - - if tc.wantPass { - s.Require().NoError(err) - s.Require().Equal(tc.expEthBlock.Header(), ethBlock.Header()) - s.Require().Equal(tc.expEthBlock.Uncles(), ethBlock.Uncles()) - s.Require().Equal(tc.expEthBlock.ReceiptHash(), ethBlock.ReceiptHash()) - for i, tx := range tc.expEthBlock.Transactions() { - s.Require().Equal(tx.Data(), ethBlock.Transactions()[i].Data()) - } - } else { - s.Require().Error(err) - } - }) - } + s.NoError(err, block) + blockResults, err := s.node.RPCClient.BlockResults( + context.Background(), + &latestHeight, + ) + s.NoError(err, blockResults) } diff --git a/eth/rpc/backend/call_tx_test.go b/eth/rpc/backend/call_tx_test.go index 879438d51..f0dcea536 100644 --- a/eth/rpc/backend/call_tx_test.go +++ b/eth/rpc/backend/call_tx_test.go @@ -1,502 +1 @@ -package backend - -import ( - "encoding/json" - "fmt" - "math/big" - - "cosmossdk.io/math" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - gethcore "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/rlp" - "google.golang.org/grpc/metadata" - - "github.com/NibiruChain/nibiru/v2/eth/rpc" - "github.com/NibiruChain/nibiru/v2/eth/rpc/backend/mocks" - "github.com/NibiruChain/nibiru/v2/x/evm" - evmtest "github.com/NibiruChain/nibiru/v2/x/evm/evmtest" -) - -func (s *BackendSuite) TestResend() { - txNonce := (hexutil.Uint64)(1) - baseFee := math.NewInt(1) - gasPrice := new(hexutil.Big) - toAddr := evmtest.NewEthPrivAcc().EthAddr - chainID := (*hexutil.Big)(s.backend.chainID) - callArgs := evm.JsonTxArgs{ - From: nil, - To: &toAddr, - Gas: nil, - GasPrice: nil, - MaxFeePerGas: gasPrice, - MaxPriorityFeePerGas: gasPrice, - Value: gasPrice, - Nonce: &txNonce, - Input: nil, - Data: nil, - AccessList: nil, - ChainID: chainID, - } - - testCases := []struct { - name string - registerMock func() - args evm.JsonTxArgs - gasPrice *hexutil.Big - gasLimit *hexutil.Uint64 - expHash common.Hash - expPass bool - }{ - { - "fail - Missing transaction nonce", - func() {}, - evm.JsonTxArgs{ - Nonce: nil, - }, - nil, - nil, - common.Hash{}, - false, - }, - { - "pass - Can't set Tx defaults BaseFee disabled", - func() { - var header metadata.MD - client := s.backend.clientCtx.Client.(*mocks.Client) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterParams(queryClient, &header, 1) - _, err := RegisterBlock(client, 1, nil) - s.Require().NoError(err) - _, err = RegisterBlockResults(client, 1) - s.Require().NoError(err) - RegisterBaseFeeDisabled(queryClient) - }, - evm.JsonTxArgs{ - Nonce: &txNonce, - ChainID: callArgs.ChainID, - }, - nil, - nil, - common.Hash{}, - true, - }, - { - "pass - Can't set Tx defaults", - func() { - var header metadata.MD - client := s.backend.clientCtx.Client.(*mocks.Client) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterParams(queryClient, &header, 1) - _, err := RegisterBlock(client, 1, nil) - s.Require().NoError(err) - _, err = RegisterBlockResults(client, 1) - s.Require().NoError(err) - RegisterBaseFee(queryClient, baseFee) - }, - evm.JsonTxArgs{ - Nonce: &txNonce, - }, - nil, - nil, - common.Hash{}, - true, - }, - { - "pass - MaxFeePerGas is nil", - func() { - var header metadata.MD - client := s.backend.clientCtx.Client.(*mocks.Client) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterParams(queryClient, &header, 1) - _, err := RegisterBlock(client, 1, nil) - s.Require().NoError(err) - _, err = RegisterBlockResults(client, 1) - s.Require().NoError(err) - RegisterBaseFeeDisabled(queryClient) - }, - evm.JsonTxArgs{ - Nonce: &txNonce, - MaxPriorityFeePerGas: nil, - GasPrice: nil, - MaxFeePerGas: nil, - }, - nil, - nil, - common.Hash{}, - true, - }, - { - "fail - GasPrice and (MaxFeePerGas or MaxPriorityPerGas specified)", - func() {}, - evm.JsonTxArgs{ - Nonce: &txNonce, - MaxPriorityFeePerGas: nil, - GasPrice: gasPrice, - MaxFeePerGas: gasPrice, - }, - nil, - nil, - common.Hash{}, - false, - }, - { - "fail - Block error", - func() { - var header metadata.MD - client := s.backend.clientCtx.Client.(*mocks.Client) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterParams(queryClient, &header, 1) - RegisterBlockError(client, 1) - }, - evm.JsonTxArgs{ - Nonce: &txNonce, - }, - nil, - nil, - common.Hash{}, - false, - }, - { - "pass - MaxFeePerGas is nil", - func() { - var header metadata.MD - client := s.backend.clientCtx.Client.(*mocks.Client) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterParams(queryClient, &header, 1) - _, err := RegisterBlock(client, 1, nil) - s.Require().NoError(err) - _, err = RegisterBlockResults(client, 1) - s.Require().NoError(err) - RegisterBaseFee(queryClient, baseFee) - }, - evm.JsonTxArgs{ - Nonce: &txNonce, - GasPrice: nil, - MaxPriorityFeePerGas: gasPrice, - MaxFeePerGas: gasPrice, - ChainID: callArgs.ChainID, - }, - nil, - nil, - common.Hash{}, - true, - }, - { - "pass - Chain Id is nil", - func() { - var header metadata.MD - client := s.backend.clientCtx.Client.(*mocks.Client) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterParams(queryClient, &header, 1) - _, err := RegisterBlock(client, 1, nil) - s.Require().NoError(err) - _, err = RegisterBlockResults(client, 1) - s.Require().NoError(err) - RegisterBaseFee(queryClient, baseFee) - }, - evm.JsonTxArgs{ - Nonce: &txNonce, - MaxPriorityFeePerGas: gasPrice, - ChainID: nil, - }, - nil, - nil, - common.Hash{}, - true, - }, - { - "fail - Pending transactions error", - func() { - var header metadata.MD - client := s.backend.clientCtx.Client.(*mocks.Client) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - _, err := RegisterBlock(client, 1, nil) - s.Require().NoError(err) - _, err = RegisterBlockResults(client, 1) - s.Require().NoError(err) - RegisterBaseFee(queryClient, baseFee) - RegisterEstimateGas(queryClient, callArgs) - RegisterParams(queryClient, &header, 1) - RegisterParamsWithoutHeader(queryClient, 1) - RegisterUnconfirmedTxsError(client, nil) - }, - evm.JsonTxArgs{ - Nonce: &txNonce, - To: &toAddr, - MaxFeePerGas: gasPrice, - MaxPriorityFeePerGas: gasPrice, - Value: gasPrice, - Gas: nil, - ChainID: callArgs.ChainID, - }, - gasPrice, - nil, - common.Hash{}, - false, - }, - { - "fail - Not Ethereum txs", - func() { - var header metadata.MD - client := s.backend.clientCtx.Client.(*mocks.Client) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - _, err := RegisterBlock(client, 1, nil) - s.Require().NoError(err) - _, err = RegisterBlockResults(client, 1) - s.Require().NoError(err) - RegisterBaseFee(queryClient, baseFee) - RegisterEstimateGas(queryClient, callArgs) - RegisterParams(queryClient, &header, 1) - RegisterParamsWithoutHeader(queryClient, 1) - RegisterUnconfirmedTxsEmpty(client, nil) - }, - evm.JsonTxArgs{ - Nonce: &txNonce, - To: &toAddr, - MaxFeePerGas: gasPrice, - MaxPriorityFeePerGas: gasPrice, - Value: gasPrice, - Gas: nil, - ChainID: callArgs.ChainID, - }, - gasPrice, - nil, - common.Hash{}, - false, - }, - } - - for _, tc := range testCases { - s.Run(fmt.Sprintf("case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock() - - hash, err := s.backend.Resend(tc.args, tc.gasPrice, tc.gasLimit) - - if tc.expPass { - s.Require().Equal(tc.expHash, hash) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestSendRawTransaction() { - ethTx, bz := s.buildEthereumTx() - - // Sign the ethTx - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterParamsWithoutHeader(queryClient, 1) - ethSigner := gethcore.LatestSigner(s.backend.ChainConfig()) - err := ethTx.Sign(ethSigner, s.signer) - s.Require().NoError(err) - - rlpEncodedBz, _ := rlp.EncodeToBytes(ethTx.AsTransaction()) - cosmosTx, _ := ethTx.BuildTx(s.backend.clientCtx.TxConfig.NewTxBuilder(), evm.DefaultEVMDenom) - txBytes, _ := s.backend.clientCtx.TxConfig.TxEncoder()(cosmosTx) - - testCases := []struct { - name string - registerMock func() - rawTx []byte - expHash common.Hash - expPass bool - }{ - { - "sad - empty bytes", - func() {}, - []byte{}, - common.Hash{}, - false, - }, - { - "sad - no RLP encoded bytes", - func() {}, - bz, - common.Hash{}, - false, - }, - { - "sad - unprotected transactions", - func() { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - s.backend.allowUnprotectedTxs = false - RegisterParamsWithoutHeaderError(queryClient, 1) - }, - rlpEncodedBz, - common.Hash{}, - false, - }, - { - "sad - failed to get evm params", - func() { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - s.backend.allowUnprotectedTxs = true - RegisterParamsWithoutHeaderError(queryClient, 1) - }, - rlpEncodedBz, - common.Hash{}, - false, - }, - { - "sad - failed to broadcast transaction", - func() { - client := s.backend.clientCtx.Client.(*mocks.Client) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - s.backend.allowUnprotectedTxs = true - RegisterParamsWithoutHeader(queryClient, 1) - RegisterBroadcastTxError(client, txBytes) - }, - rlpEncodedBz, - common.HexToHash(ethTx.Hash), - false, - }, - { - "pass - Gets the correct transaction hash of the eth transaction", - func() { - client := s.backend.clientCtx.Client.(*mocks.Client) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - s.backend.allowUnprotectedTxs = true - RegisterParamsWithoutHeader(queryClient, 1) - RegisterBroadcastTx(client, txBytes) - }, - rlpEncodedBz, - common.HexToHash(ethTx.Hash), - true, - }, - } - - for _, tc := range testCases { - s.Run(fmt.Sprintf("case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock() - - hash, err := s.backend.SendRawTransaction(tc.rawTx) - - if tc.expPass { - s.Require().Equal(tc.expHash, hash) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestDoCall() { - _, bz := s.buildEthereumTx() - gasPrice := (*hexutil.Big)(big.NewInt(1)) - toAddr := evmtest.NewEthPrivAcc().EthAddr - chainID := (*hexutil.Big)(s.backend.chainID) - callArgs := evm.JsonTxArgs{ - From: nil, - To: &toAddr, - Gas: nil, - GasPrice: nil, - MaxFeePerGas: gasPrice, - MaxPriorityFeePerGas: gasPrice, - Value: gasPrice, - Input: nil, - Data: nil, - AccessList: nil, - ChainID: chainID, - } - argsBz, err := json.Marshal(callArgs) - s.Require().NoError(err) - - testCases := []struct { - name string - registerMock func() - blockNum rpc.BlockNumber - callArgs evm.JsonTxArgs - expEthTx *evm.MsgEthereumTxResponse - expPass bool - }{ - { - "fail - Invalid request", - func() { - client := s.backend.clientCtx.Client.(*mocks.Client) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - _, err := RegisterBlock(client, 1, bz) - s.Require().NoError(err) - RegisterEthCallError(queryClient, &evm.EthCallRequest{Args: argsBz, ChainId: s.backend.chainID.Int64()}) - }, - rpc.BlockNumber(1), - callArgs, - &evm.MsgEthereumTxResponse{}, - false, - }, - { - "pass - Returned transaction response", - func() { - client := s.backend.clientCtx.Client.(*mocks.Client) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - _, err := RegisterBlock(client, 1, bz) - s.Require().NoError(err) - RegisterEthCall(queryClient, &evm.EthCallRequest{Args: argsBz, ChainId: s.backend.chainID.Int64()}) - }, - rpc.BlockNumber(1), - callArgs, - &evm.MsgEthereumTxResponse{}, - true, - }, - } - - for _, tc := range testCases { - s.Run(fmt.Sprintf("case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock() - - msgEthTx, err := s.backend.DoCall(tc.callArgs, tc.blockNum) - - if tc.expPass { - s.Require().Equal(tc.expEthTx, msgEthTx) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestGasPrice() { - defaultGasPrice := (*hexutil.Big)(big.NewInt(1)) - - testCases := []struct { - name string - registerMock func() - expGas *hexutil.Big - expPass bool - }{ - { - "pass - get the default gas price", - func() { - var header metadata.MD - client := s.backend.clientCtx.Client.(*mocks.Client) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterParams(queryClient, &header, 1) - _, err := RegisterBlock(client, 1, nil) - s.Require().NoError(err) - _, err = RegisterBlockResults(client, 1) - s.Require().NoError(err) - RegisterBaseFee(queryClient, math.NewInt(1)) - }, - defaultGasPrice, - true, - }, - } - - for _, tc := range testCases { - s.Run(fmt.Sprintf("case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock() - - gasPrice, err := s.backend.GasPrice() - if tc.expPass { - s.Require().Equal(tc.expGas, gasPrice) - } else { - s.Require().Error(err) - } - }) - } -} +package backend_test diff --git a/eth/rpc/backend/chain_info_test.go b/eth/rpc/backend/chain_info_test.go index b97783103..f0dcea536 100644 --- a/eth/rpc/backend/chain_info_test.go +++ b/eth/rpc/backend/chain_info_test.go @@ -1,294 +1 @@ -package backend - -import ( - "fmt" - "math/big" - - sdkmath "cosmossdk.io/math" - "github.com/ethereum/go-ethereum/common/hexutil" - ethrpc "github.com/ethereum/go-ethereum/rpc" - - "google.golang.org/grpc/metadata" - - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/cometbft/cometbft/abci/types" - tmrpctypes "github.com/cometbft/cometbft/rpc/core/types" - - "github.com/NibiruChain/nibiru/v2/eth" - "github.com/NibiruChain/nibiru/v2/eth/rpc" - "github.com/NibiruChain/nibiru/v2/eth/rpc/backend/mocks" - "github.com/NibiruChain/nibiru/v2/x/evm" - evmtest "github.com/NibiruChain/nibiru/v2/x/evm/evmtest" -) - -func (s *BackendSuite) TestBaseFee() { - baseFee := sdkmath.NewInt(1) - - testCases := []struct { - name string - blockRes *tmrpctypes.ResultBlockResults - registerMock func() - expBaseFee *big.Int - expPass bool - }{ - // TODO: test(eth): Test base fee query after it's enabled. - // { - // "fail - grpc BaseFee error", - // &tmrpctypes.ResultBlockResults{Height: 1}, - // func() { - // queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - // RegisterBaseFeeError(queryClient) - // }, - // nil, - // false, - // }, - { - name: "pass - grpc BaseFee error - with non feemarket block event", - blockRes: &tmrpctypes.ResultBlockResults{ - Height: 1, - BeginBlockEvents: []types.Event{ - { - Type: evm.EventTypeBlockBloom, - }, - }, - }, - registerMock: func() { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBaseFeeDisabled(queryClient) - }, - expBaseFee: nil, - expPass: true, - }, - { - name: "pass - base fee not enabled", - blockRes: &tmrpctypes.ResultBlockResults{Height: 1}, - registerMock: func() { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBaseFeeDisabled(queryClient) - }, - expBaseFee: nil, - expPass: true, - }, - { - "pass", - &tmrpctypes.ResultBlockResults{Height: 1}, - func() { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterBaseFee(queryClient, baseFee) - }, - baseFee.BigInt(), - true, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock() - - baseFee, err := s.backend.BaseFee(tc.blockRes) - - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(tc.expBaseFee, baseFee) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestChainId() { - expChainIDNumber, err := eth.ParseEthChainID(eth.EIP155ChainID_Testnet) - s.Require().NoError(err) - expChainID := (*hexutil.Big)(expChainIDNumber) - testCases := []struct { - name string - registerMock func() - expChainID *hexutil.Big - expPass bool - }{ - { - "pass - block is at or past the EIP-155 replay-protection fork block, return chainID from config ", - func() { - var header metadata.MD - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterParamsInvalidHeight(queryClient, &header, int64(1)) - }, - expChainID, - true, - }, - } - - for _, tc := range testCases { - s.Run(fmt.Sprintf("case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock() - - chainID, err := s.backend.ChainID() - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(tc.expChainID, chainID) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestSuggestGasTipCap() { - testCases := []struct { - name string - registerMock func() - baseFee *big.Int - expGasTipCap *big.Int - expPass bool - }{ - { - "pass - Feemarket not enabled ", - func() {}, - nil, - big.NewInt(0), - true, - }, - { - "pass - Gets the suggest gas tip cap ", - func() {}, - nil, - big.NewInt(0), - true, - }, - } - - for _, tc := range testCases { - s.Run(fmt.Sprintf("case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock() - - maxDelta, err := s.backend.SuggestGasTipCap(tc.baseFee) - - if tc.expPass { - s.Require().Equal(tc.expGasTipCap, maxDelta) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestFeeHistory() { - testCases := []struct { - name string - registerMock func(validator sdk.AccAddress) - userBlockCount ethrpc.DecimalOrHex - latestBlock ethrpc.BlockNumber - expFeeHistory *rpc.FeeHistoryResult - validator sdk.AccAddress - expPass bool - }{ - { - "fail - can't get params ", - func(validator sdk.AccAddress) { - var header metadata.MD - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - s.backend.cfg.JSONRPC.FeeHistoryCap = 0 - RegisterParamsError(queryClient, &header, ethrpc.BlockNumber(1).Int64()) - }, - 1, - -1, - nil, - nil, - false, - }, - { - "fail - user block count higher than max block count ", - func(validator sdk.AccAddress) { - var header metadata.MD - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - s.backend.cfg.JSONRPC.FeeHistoryCap = 0 - RegisterParams(queryClient, &header, ethrpc.BlockNumber(1).Int64()) - }, - 1, - -1, - nil, - nil, - false, - }, - { - "fail - Tendermint block fetching error ", - func(validator sdk.AccAddress) { - client := s.backend.clientCtx.Client.(*mocks.Client) - s.backend.cfg.JSONRPC.FeeHistoryCap = 2 - RegisterBlockError(client, ethrpc.BlockNumber(1).Int64()) - }, - 1, - 1, - nil, - nil, - false, - }, - { - "fail - Eth block fetching error", - func(validator sdk.AccAddress) { - client := s.backend.clientCtx.Client.(*mocks.Client) - s.backend.cfg.JSONRPC.FeeHistoryCap = 2 - _, err := RegisterBlock(client, ethrpc.BlockNumber(1).Int64(), nil) - s.Require().NoError(err) - RegisterBlockResultsError(client, 1) - }, - 1, - 1, - nil, - nil, - true, - }, - { - name: "pass - Valid FeeHistoryResults object", - registerMock: func(validator sdk.AccAddress) { - baseFee := sdkmath.NewInt(1) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - client := s.backend.clientCtx.Client.(*mocks.Client) - s.backend.cfg.JSONRPC.FeeHistoryCap = 2 - blockHeight := int64(1) - _, err := RegisterBlock(client, blockHeight, nil) - s.Require().NoError(err) - - _, err = RegisterBlockResults(client, blockHeight) - s.Require().NoError(err) - - RegisterBaseFee(queryClient, baseFee) - RegisterValidatorAccount(queryClient, validator) - RegisterConsensusParams(client, blockHeight) - - header := new(metadata.MD) - RegisterParams(queryClient, header, blockHeight) - RegisterParamsWithoutHeader(queryClient, blockHeight) - }, - userBlockCount: 1, - latestBlock: 1, - expFeeHistory: &rpc.FeeHistoryResult{ - OldestBlock: (*hexutil.Big)(big.NewInt(1)), - BaseFee: []*hexutil.Big{(*hexutil.Big)(big.NewInt(1)), (*hexutil.Big)(big.NewInt(1))}, - GasUsedRatio: []float64{0}, - Reward: [][]*hexutil.Big{{(*hexutil.Big)(big.NewInt(0)), (*hexutil.Big)(big.NewInt(0)), (*hexutil.Big)(big.NewInt(0)), (*hexutil.Big)(big.NewInt(0))}}, - }, - validator: sdk.AccAddress(evmtest.NewEthPrivAcc().EthAddr.Bytes()), - expPass: true, - }, - } - - for _, tc := range testCases { - s.Run(fmt.Sprintf("case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock(tc.validator) - - feeHistory, err := s.backend.FeeHistory(tc.userBlockCount, tc.latestBlock, []float64{25, 50, 75, 100}) - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(feeHistory, tc.expFeeHistory) - } else { - s.Require().Error(err) - } - }) - } -} +package backend_test diff --git a/eth/rpc/backend/client_test.go b/eth/rpc/backend/client_test.go index 53a34e799..f0dcea536 100644 --- a/eth/rpc/backend/client_test.go +++ b/eth/rpc/backend/client_test.go @@ -1,259 +1 @@ -package backend - -import ( - "context" - "testing" - - errortypes "github.com/cosmos/cosmos-sdk/types/errors" - - abci "github.com/cometbft/cometbft/abci/types" - "github.com/cometbft/cometbft/libs/bytes" - tmrpcclient "github.com/cometbft/cometbft/rpc/client" - tmrpctypes "github.com/cometbft/cometbft/rpc/core/types" - "github.com/cometbft/cometbft/types" - "github.com/ethereum/go-ethereum/common" - mock "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - - "github.com/NibiruChain/nibiru/v2/eth/rpc" - "github.com/NibiruChain/nibiru/v2/eth/rpc/backend/mocks" - "github.com/NibiruChain/nibiru/v2/x/evm" -) - -// Client defines a mocked object that implements the Tendermint JSON-RPC Client -// interface. It allows for performing Client queries without having to run a -// Tendermint RPC Client server. -// -// To use a mock method it has to be registered in a given test. -var _ tmrpcclient.Client = &mocks.Client{} - -// Tx Search -func RegisterTxSearch(client *mocks.Client, query string, txBz []byte) { - resulTxs := []*tmrpctypes.ResultTx{{Tx: txBz}} - client.On("TxSearch", rpc.NewContextWithHeight(1), query, false, (*int)(nil), (*int)(nil), ""). - Return(&tmrpctypes.ResultTxSearch{Txs: resulTxs, TotalCount: 1}, nil) -} - -func RegisterTxSearchEmpty(client *mocks.Client, query string) { - client.On("TxSearch", rpc.NewContextWithHeight(1), query, false, (*int)(nil), (*int)(nil), ""). - Return(&tmrpctypes.ResultTxSearch{}, nil) -} - -// Broadcast Tx -func RegisterBroadcastTx(client *mocks.Client, tx types.Tx) { - client.On("BroadcastTxSync", context.Background(), tx). - Return(&tmrpctypes.ResultBroadcastTx{}, nil) -} - -func RegisterBroadcastTxError(client *mocks.Client, tx types.Tx) { - client.On("BroadcastTxSync", context.Background(), tx). - Return(nil, errortypes.ErrInvalidRequest) -} - -// Unconfirmed Transactions -func RegisterUnconfirmedTxs(client *mocks.Client, limit *int, txs []types.Tx) { - client.On("UnconfirmedTxs", rpc.NewContextWithHeight(1), limit). - Return(&tmrpctypes.ResultUnconfirmedTxs{Txs: txs}, nil) -} - -func RegisterUnconfirmedTxsEmpty(client *mocks.Client, limit *int) { - client.On("UnconfirmedTxs", rpc.NewContextWithHeight(1), limit). - Return(&tmrpctypes.ResultUnconfirmedTxs{ - Txs: make([]types.Tx, 2), - }, nil) -} - -func RegisterUnconfirmedTxsError(client *mocks.Client, limit *int) { - client.On("UnconfirmedTxs", rpc.NewContextWithHeight(1), limit). - Return(nil, errortypes.ErrInvalidRequest) -} - -// Status -func RegisterStatus(client *mocks.Client) { - client.On("Status", rpc.NewContextWithHeight(1)). - Return(&tmrpctypes.ResultStatus{}, nil) -} - -func RegisterStatusError(client *mocks.Client) { - client.On("Status", rpc.NewContextWithHeight(1)). - Return(nil, errortypes.ErrInvalidRequest) -} - -// Block -func RegisterBlockMultipleTxs( - client *mocks.Client, - height int64, - txs []types.Tx, -) (*tmrpctypes.ResultBlock, error) { - block := types.MakeBlock(height, txs, nil, nil) - block.ChainID = ChainID - resBlock := &tmrpctypes.ResultBlock{Block: block} - client.On("Block", rpc.NewContextWithHeight(height), mock.AnythingOfType("*int64")).Return(resBlock, nil) - return resBlock, nil -} - -func RegisterBlock( - client *mocks.Client, - height int64, - tx []byte, -) (*tmrpctypes.ResultBlock, error) { - // without tx - if tx == nil { - emptyBlock := types.MakeBlock(height, []types.Tx{}, nil, nil) - emptyBlock.ChainID = ChainID - resBlock := &tmrpctypes.ResultBlock{Block: emptyBlock} - client.On("Block", rpc.NewContextWithHeight(height), mock.AnythingOfType("*int64")).Return(resBlock, nil) - return resBlock, nil - } - - // with tx - block := types.MakeBlock(height, []types.Tx{tx}, nil, nil) - block.ChainID = ChainID - resBlock := &tmrpctypes.ResultBlock{Block: block} - client.On("Block", rpc.NewContextWithHeight(height), mock.AnythingOfType("*int64")).Return(resBlock, nil) - return resBlock, nil -} - -// Block returns error -func RegisterBlockError(client *mocks.Client, height int64) { - client.On("Block", rpc.NewContextWithHeight(height), mock.AnythingOfType("*int64")). - Return(nil, errortypes.ErrInvalidRequest) -} - -// Block not found -func RegisterBlockNotFound( - client *mocks.Client, - height int64, -) (*tmrpctypes.ResultBlock, error) { - client.On("Block", rpc.NewContextWithHeight(height), mock.AnythingOfType("*int64")). - Return(&tmrpctypes.ResultBlock{Block: nil}, nil) - - return &tmrpctypes.ResultBlock{Block: nil}, nil -} - -func TestRegisterBlock(t *testing.T) { - client := mocks.NewClient(t) - height := rpc.BlockNumber(1).Int64() - _, err := RegisterBlock(client, height, nil) - require.NoError(t, err) - - res, err := client.Block(rpc.NewContextWithHeight(height), &height) - - emptyBlock := types.MakeBlock(height, []types.Tx{}, nil, nil) - emptyBlock.ChainID = ChainID - resBlock := &tmrpctypes.ResultBlock{Block: emptyBlock} - require.Equal(t, resBlock, res) - require.NoError(t, err) -} - -// ConsensusParams -func RegisterConsensusParams(client *mocks.Client, height int64) { - consensusParams := types.DefaultConsensusParams() - client.On("ConsensusParams", rpc.NewContextWithHeight(height), mock.AnythingOfType("*int64")). - Return(&tmrpctypes.ResultConsensusParams{ConsensusParams: *consensusParams}, nil) -} - -func RegisterConsensusParamsError(client *mocks.Client, height int64) { - client.On("ConsensusParams", rpc.NewContextWithHeight(height), mock.AnythingOfType("*int64")). - Return(nil, errortypes.ErrInvalidRequest) -} - -func TestRegisterConsensusParams(t *testing.T) { - client := mocks.NewClient(t) - height := int64(1) - RegisterConsensusParams(client, height) - - res, err := client.ConsensusParams(rpc.NewContextWithHeight(height), &height) - consensusParams := types.DefaultConsensusParams() - require.Equal(t, &tmrpctypes.ResultConsensusParams{ConsensusParams: *consensusParams}, res) - require.NoError(t, err) -} - -// BlockResults - -func RegisterBlockResultsWithEventLog(client *mocks.Client, height int64) (*tmrpctypes.ResultBlockResults, error) { - res := &tmrpctypes.ResultBlockResults{ - Height: height, - TxsResults: []*abci.ResponseDeliverTx{ - {Code: 0, GasUsed: 0, Events: []abci.Event{{ - Type: evm.EventTypeTxLog, - Attributes: []abci.EventAttribute{{ - Key: evm.AttributeKeyTxLog, - Value: "{\"test\": \"hello\"}", // TODO refactor the value to unmarshall to a evmtypes.Log struct successfully - Index: true, - }}, - }}}, - }, - } - client.On("BlockResults", rpc.NewContextWithHeight(height), mock.AnythingOfType("*int64")). - Return(res, nil) - return res, nil -} - -func RegisterBlockResults( - client *mocks.Client, - height int64, -) (*tmrpctypes.ResultBlockResults, error) { - res := &tmrpctypes.ResultBlockResults{ - Height: height, - TxsResults: []*abci.ResponseDeliverTx{{Code: 0, GasUsed: 0}}, - } - - client.On("BlockResults", rpc.NewContextWithHeight(height), mock.AnythingOfType("*int64")). - Return(res, nil) - return res, nil -} - -func RegisterBlockResultsError(client *mocks.Client, height int64) { - client.On("BlockResults", rpc.NewContextWithHeight(height), mock.AnythingOfType("*int64")). - Return(nil, errortypes.ErrInvalidRequest) -} - -func TestRegisterBlockResults(t *testing.T) { - client := mocks.NewClient(t) - height := int64(1) - _, err := RegisterBlockResults(client, height) - require.NoError(t, err) - - res, err := client.BlockResults(rpc.NewContextWithHeight(height), &height) - expRes := &tmrpctypes.ResultBlockResults{ - Height: height, - TxsResults: []*abci.ResponseDeliverTx{{Code: 0, GasUsed: 0}}, - } - require.Equal(t, expRes, res) - require.NoError(t, err) -} - -// BlockByHash -func RegisterBlockByHash( - client *mocks.Client, - _ common.Hash, - tx []byte, -) (*tmrpctypes.ResultBlock, error) { - block := types.MakeBlock(1, []types.Tx{tx}, nil, nil) - resBlock := &tmrpctypes.ResultBlock{Block: block} - - client.On("BlockByHash", rpc.NewContextWithHeight(1), []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}). - Return(resBlock, nil) - return resBlock, nil -} - -func RegisterBlockByHashError(client *mocks.Client, _ common.Hash, _ []byte) { - client.On("BlockByHash", rpc.NewContextWithHeight(1), []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}). - Return(nil, errortypes.ErrInvalidRequest) -} - -func RegisterBlockByHashNotFound(client *mocks.Client, _ common.Hash, _ []byte) { - client.On("BlockByHash", rpc.NewContextWithHeight(1), []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}). - Return(nil, nil) -} - -func RegisterABCIQueryWithOptions(client *mocks.Client, height int64, path string, data bytes.HexBytes, opts tmrpcclient.ABCIQueryOptions) { - client.On("ABCIQueryWithOptions", context.Background(), path, data, opts). - Return(&tmrpctypes.ResultABCIQuery{ - Response: abci.ResponseQuery{ - Value: []byte{2}, // TODO replace with data.Bytes(), - Height: height, - }, - }, nil) -} +package backend_test diff --git a/eth/rpc/backend/evm_query_client_test.go b/eth/rpc/backend/evm_query_client_test.go index ee05fe7c2..f0dcea536 100644 --- a/eth/rpc/backend/evm_query_client_test.go +++ b/eth/rpc/backend/evm_query_client_test.go @@ -1,345 +1 @@ -package backend - -import ( - "context" - "encoding/json" - "fmt" - "strconv" - "testing" - - "cosmossdk.io/math" - - sdk "github.com/cosmos/cosmos-sdk/types" - errortypes "github.com/cosmos/cosmos-sdk/types/errors" - grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" - "github.com/ethereum/go-ethereum/common" - mock "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" - - "github.com/NibiruChain/nibiru/v2/eth" - "github.com/NibiruChain/nibiru/v2/eth/rpc" - "github.com/NibiruChain/nibiru/v2/eth/rpc/backend/mocks" - "github.com/NibiruChain/nibiru/v2/x/evm" - evmtest "github.com/NibiruChain/nibiru/v2/x/evm/evmtest" -) - -// QueryClient defines a mocked object that implements the ethermint GRPC -// QueryClient interface. It allows for performing QueryClient queries without having -// to run a ethermint GRPC server. -// -// To use a mock method it has to be registered in a given test. -var _ evm.QueryClient = &mocks.EVMQueryClient{} - -func TEST_CHAIN_ID_NUMBER() int64 { - n, _ := eth.ParseEthChainID(eth.EIP155ChainID_Testnet) - return n.Int64() -} - -// TraceTransaction -func RegisterTraceTransactionWithPredecessors( - queryClient *mocks.EVMQueryClient, msgEthTx *evm.MsgEthereumTx, predecessors []*evm.MsgEthereumTx, -) { - data := []byte{0x7b, 0x22, 0x74, 0x65, 0x73, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x22, 0x7d} - queryClient.On("TraceTx", rpc.NewContextWithHeight(1), - &evm.QueryTraceTxRequest{Msg: msgEthTx, BlockNumber: 1, Predecessors: predecessors, ChainId: TEST_CHAIN_ID_NUMBER(), BlockMaxGas: -1}). - Return(&evm.QueryTraceTxResponse{Data: data}, nil) -} - -func RegisterTraceTransaction( - queryClient *mocks.EVMQueryClient, msgEthTx *evm.MsgEthereumTx, -) { - data := []byte{0x7b, 0x22, 0x74, 0x65, 0x73, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x22, 0x7d} - queryClient.On("TraceTx", rpc.NewContextWithHeight(1), &evm.QueryTraceTxRequest{Msg: msgEthTx, BlockNumber: 1, ChainId: TEST_CHAIN_ID_NUMBER(), BlockMaxGas: -1}). - Return(&evm.QueryTraceTxResponse{Data: data}, nil) -} - -func RegisterTraceCall( - queryClient *mocks.EVMQueryClient, msgEthTx *evm.MsgEthereumTx, -) { - data := []byte{0x7b, 0x22, 0x74, 0x65, 0x73, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x22, 0x7d} - queryClient.On( - "TraceCall", - rpc.NewContextWithHeight(1), - &evm.QueryTraceTxRequest{ - Msg: msgEthTx, - BlockNumber: 1, - ChainId: TEST_CHAIN_ID_NUMBER(), - BlockMaxGas: -1, - TraceConfig: &evm.TraceConfig{}, - }, - ). - Return(&evm.QueryTraceTxResponse{Data: data}, nil) -} - -func RegisterTraceTransactionError( - queryClient *mocks.EVMQueryClient, msgEthTx *evm.MsgEthereumTx, -) { - queryClient.On("TraceTx", rpc.NewContextWithHeight(1), &evm.QueryTraceTxRequest{Msg: msgEthTx, BlockNumber: 1, ChainId: TEST_CHAIN_ID_NUMBER()}). - Return(nil, errortypes.ErrInvalidRequest) -} - -// TraceBlock -func RegisterTraceBlock( - queryClient *mocks.EVMQueryClient, txs []*evm.MsgEthereumTx, -) { - data := []byte{0x7b, 0x22, 0x74, 0x65, 0x73, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x22, 0x7d} - queryClient.On("TraceBlock", rpc.NewContextWithHeight(1), - &evm.QueryTraceBlockRequest{Txs: txs, BlockNumber: 1, TraceConfig: &evm.TraceConfig{}, ChainId: TEST_CHAIN_ID_NUMBER(), BlockMaxGas: -1}). - Return(&evm.QueryTraceBlockResponse{Data: data}, nil) -} - -func RegisterTraceBlockError(queryClient *mocks.EVMQueryClient) { - queryClient.On("TraceBlock", rpc.NewContextWithHeight(1), &evm.QueryTraceBlockRequest{}). - Return(nil, errortypes.ErrInvalidRequest) -} - -// Params -func RegisterParams( - queryClient *mocks.EVMQueryClient, header *metadata.MD, height int64, -) { - queryClient.On("Params", rpc.NewContextWithHeight(height), &evm.QueryParamsRequest{}, grpc.Header(header)). - Return(&evm.QueryParamsResponse{}, nil). - Run(func(args mock.Arguments) { - // If Params call is successful, also update the header height - arg := args.Get(2).(grpc.HeaderCallOption) - h := metadata.MD{} - h.Set(grpctypes.GRPCBlockHeightHeader, fmt.Sprint(height)) - *arg.HeaderAddr = h - }) -} - -func RegisterParamsWithoutHeader( - queryClient *mocks.EVMQueryClient, height int64, -) { - queryClient.On("Params", rpc.NewContextWithHeight(height), &evm.QueryParamsRequest{}). - Return(&evm.QueryParamsResponse{Params: evm.DefaultParams()}, nil) -} - -func RegisterParamsInvalidHeader( - queryClient *mocks.EVMQueryClient, header *metadata.MD, height int64, -) { - queryClient.On("Params", rpc.NewContextWithHeight(height), &evm.QueryParamsRequest{}, grpc.Header(header)). - Return(&evm.QueryParamsResponse{}, nil). - Run(func(args mock.Arguments) { - // If Params call is successful, also update the header height - arg := args.Get(2).(grpc.HeaderCallOption) - h := metadata.MD{} - *arg.HeaderAddr = h - }) -} - -func RegisterParamsInvalidHeight(queryClient *mocks.EVMQueryClient, header *metadata.MD, height int64) { - queryClient.On("Params", rpc.NewContextWithHeight(height), &evm.QueryParamsRequest{}, grpc.Header(header)). - Return(&evm.QueryParamsResponse{}, nil). - Run(func(args mock.Arguments) { - // If Params call is successful, also update the header height - arg := args.Get(2).(grpc.HeaderCallOption) - h := metadata.MD{} - h.Set(grpctypes.GRPCBlockHeightHeader, "invalid") - *arg.HeaderAddr = h - }) -} - -func RegisterParamsWithoutHeaderError(queryClient *mocks.EVMQueryClient, height int64) { - queryClient.On("Params", rpc.NewContextWithHeight(height), &evm.QueryParamsRequest{}). - Return(nil, errortypes.ErrInvalidRequest) -} - -// Params returns error -func RegisterParamsError( - queryClient *mocks.EVMQueryClient, header *metadata.MD, height int64, -) { - queryClient.On("Params", rpc.NewContextWithHeight(height), &evm.QueryParamsRequest{}, grpc.Header(header)). - Return(nil, errortypes.ErrInvalidRequest) -} - -func TestRegisterParams(t *testing.T) { - var header metadata.MD - queryClient := mocks.NewEVMQueryClient(t) - - height := int64(1) - RegisterParams(queryClient, &header, height) - - _, err := queryClient.Params(rpc.NewContextWithHeight(height), &evm.QueryParamsRequest{}, grpc.Header(&header)) - require.NoError(t, err) - blockHeightHeader := header.Get(grpctypes.GRPCBlockHeightHeader) - headerHeight, err := strconv.ParseInt(blockHeightHeader[0], 10, 64) - require.NoError(t, err) - require.Equal(t, height, headerHeight) -} - -func TestRegisterParamsError(t *testing.T) { - queryClient := mocks.NewEVMQueryClient(t) - RegisterBaseFeeError(queryClient) - _, err := queryClient.BaseFee(rpc.NewContextWithHeight(1), &evm.QueryBaseFeeRequest{}) - require.Error(t, err) -} - -// ETH Call -func RegisterEthCall( - queryClient *mocks.EVMQueryClient, request *evm.EthCallRequest, -) { - ctx, _ := context.WithCancel(rpc.NewContextWithHeight(1)) //nolint - queryClient.On("EthCall", ctx, request). - Return(&evm.MsgEthereumTxResponse{}, nil) -} - -func RegisterEthCallError( - queryClient *mocks.EVMQueryClient, request *evm.EthCallRequest, -) { - ctx, _ := context.WithCancel(rpc.NewContextWithHeight(1)) //nolint - queryClient.On("EthCall", ctx, request). - Return(nil, errortypes.ErrInvalidRequest) -} - -// Estimate Gas -func RegisterEstimateGas( - queryClient *mocks.EVMQueryClient, args evm.JsonTxArgs, -) { - bz, _ := json.Marshal(args) - queryClient.On("EstimateGas", rpc.NewContextWithHeight(1), &evm.EthCallRequest{Args: bz, ChainId: args.ChainID.ToInt().Int64()}). - Return(&evm.EstimateGasResponse{}, nil) -} - -// BaseFee -func RegisterBaseFee( - queryClient *mocks.EVMQueryClient, baseFee math.Int, -) { - queryClient.On("BaseFee", rpc.NewContextWithHeight(1), &evm.QueryBaseFeeRequest{}). - Return(&evm.QueryBaseFeeResponse{BaseFee: &baseFee}, nil) -} - -// Base fee returns error -func RegisterBaseFeeError(queryClient *mocks.EVMQueryClient) { - queryClient.On("BaseFee", rpc.NewContextWithHeight(1), &evm.QueryBaseFeeRequest{}). - Return(&evm.QueryBaseFeeResponse{}, evm.ErrInvalidBaseFee) -} - -// Base fee not enabled -func RegisterBaseFeeDisabled(queryClient *mocks.EVMQueryClient) { - queryClient.On("BaseFee", rpc.NewContextWithHeight(1), &evm.QueryBaseFeeRequest{}). - Return(&evm.QueryBaseFeeResponse{}, nil) -} - -func TestRegisterBaseFee(t *testing.T) { - baseFee := math.NewInt(1) - queryClient := mocks.NewEVMQueryClient(t) - RegisterBaseFee(queryClient, baseFee) - res, err := queryClient.BaseFee(rpc.NewContextWithHeight(1), &evm.QueryBaseFeeRequest{}) - require.Equal(t, &evm.QueryBaseFeeResponse{BaseFee: &baseFee}, res) - require.NoError(t, err) -} - -func TestRegisterBaseFeeError(t *testing.T) { - queryClient := mocks.NewEVMQueryClient(t) - RegisterBaseFeeError(queryClient) - res, err := queryClient.BaseFee(rpc.NewContextWithHeight(1), &evm.QueryBaseFeeRequest{}) - require.Equal(t, &evm.QueryBaseFeeResponse{}, res) - require.Error(t, err) -} - -func TestRegisterBaseFeeDisabled(t *testing.T) { - queryClient := mocks.NewEVMQueryClient(t) - RegisterBaseFeeDisabled(queryClient) - res, err := queryClient.BaseFee(rpc.NewContextWithHeight(1), &evm.QueryBaseFeeRequest{}) - require.Equal(t, &evm.QueryBaseFeeResponse{}, res) - require.NoError(t, err) -} - -// ValidatorAccount -func RegisterValidatorAccount( - queryClient *mocks.EVMQueryClient, validator sdk.AccAddress, -) { - queryClient.On("ValidatorAccount", rpc.NewContextWithHeight(1), &evm.QueryValidatorAccountRequest{}). - Return(&evm.QueryValidatorAccountResponse{AccountAddress: validator.String()}, nil) -} - -func RegisterValidatorAccountError(queryClient *mocks.EVMQueryClient) { - queryClient.On("ValidatorAccount", rpc.NewContextWithHeight(1), &evm.QueryValidatorAccountRequest{}). - Return(nil, status.Error(codes.InvalidArgument, "empty request")) -} - -func TestRegisterValidatorAccount(t *testing.T) { - queryClient := mocks.NewEVMQueryClient(t) - - validator := sdk.AccAddress(evmtest.NewEthPrivAcc().EthAddr.Bytes()) - RegisterValidatorAccount(queryClient, validator) - res, err := queryClient.ValidatorAccount(rpc.NewContextWithHeight(1), &evm.QueryValidatorAccountRequest{}) - require.Equal(t, &evm.QueryValidatorAccountResponse{AccountAddress: validator.String()}, res) - require.NoError(t, err) -} - -// Code -func RegisterCode( - queryClient *mocks.EVMQueryClient, addr common.Address, code []byte, -) { - queryClient.On("Code", rpc.NewContextWithHeight(1), &evm.QueryCodeRequest{Address: addr.String()}). - Return(&evm.QueryCodeResponse{Code: code}, nil) -} - -func RegisterCodeError(queryClient *mocks.EVMQueryClient, addr common.Address) { - queryClient.On("Code", rpc.NewContextWithHeight(1), &evm.QueryCodeRequest{Address: addr.String()}). - Return(nil, errortypes.ErrInvalidRequest) -} - -// Storage -func RegisterStorageAt( - queryClient *mocks.EVMQueryClient, addr common.Address, - key string, storage string, -) { - queryClient.On("Storage", rpc.NewContextWithHeight(1), &evm.QueryStorageRequest{Address: addr.String(), Key: key}). - Return(&evm.QueryStorageResponse{Value: storage}, nil) -} - -func RegisterStorageAtError( - queryClient *mocks.EVMQueryClient, addr common.Address, key string, -) { - queryClient.On("Storage", rpc.NewContextWithHeight(1), &evm.QueryStorageRequest{Address: addr.String(), Key: key}). - Return(nil, errortypes.ErrInvalidRequest) -} - -func RegisterAccount( - queryClient *mocks.EVMQueryClient, addr common.Address, height int64, -) { - queryClient.On("EthAccount", rpc.NewContextWithHeight(height), &evm.QueryEthAccountRequest{Address: addr.String()}). - Return(&evm.QueryEthAccountResponse{ - BalanceWei: "0", - CodeHash: "", - Nonce: 0, - }, - nil, - ) -} - -// Balance -func RegisterBalance( - queryClient *mocks.EVMQueryClient, addr common.Address, height int64, -) { - queryClient.On("Balance", rpc.NewContextWithHeight(height), &evm.QueryBalanceRequest{Address: addr.String()}). - Return(&evm.QueryBalanceResponse{BalanceWei: "1"}, nil) -} - -func RegisterBalanceInvalid( - queryClient *mocks.EVMQueryClient, addr common.Address, height int64, -) { - queryClient.On("Balance", rpc.NewContextWithHeight(height), &evm.QueryBalanceRequest{Address: addr.String()}). - Return(&evm.QueryBalanceResponse{BalanceWei: "invalid"}, nil) -} - -func RegisterBalanceNegative( - queryClient *mocks.EVMQueryClient, addr common.Address, height int64, -) { - queryClient.On("Balance", rpc.NewContextWithHeight(height), &evm.QueryBalanceRequest{Address: addr.String()}). - Return(&evm.QueryBalanceResponse{BalanceWei: "-1"}, nil) -} - -func RegisterBalanceError( - queryClient *mocks.EVMQueryClient, addr common.Address, height int64, -) { - queryClient.On("Balance", rpc.NewContextWithHeight(height), &evm.QueryBalanceRequest{Address: addr.String()}). - Return(nil, errortypes.ErrInvalidRequest) -} +package backend_test diff --git a/eth/rpc/backend/filters_test.go b/eth/rpc/backend/filters_test.go index e9c414648..f0dcea536 100644 --- a/eth/rpc/backend/filters_test.go +++ b/eth/rpc/backend/filters_test.go @@ -1,123 +1 @@ -package backend - -import ( - "encoding/json" - - tmtypes "github.com/cometbft/cometbft/types" - "github.com/ethereum/go-ethereum/common" - gethcore "github.com/ethereum/go-ethereum/core/types" - - "github.com/NibiruChain/nibiru/v2/eth/rpc" - "github.com/NibiruChain/nibiru/v2/eth/rpc/backend/mocks" - "github.com/NibiruChain/nibiru/v2/x/evm" -) - -func (s *BackendSuite) TestGetLogs() { - _, bz := s.buildEthereumTx() - block := tmtypes.MakeBlock(1, []tmtypes.Tx{bz}, nil, nil) - logs := make([]*evm.Log, 0, 1) - var log evm.Log - err := json.Unmarshal([]byte("{\"test\": \"hello\"}"), &log) // TODO refactor this to unmarshall to a log struct successfully - s.Require().NoError(err) - - logs = append(logs, &log) - - testCases := []struct { - name string - registerMock func(hash common.Hash) - blockHash common.Hash - expLogs [][]*gethcore.Log - expPass bool - }{ - { - "fail - no block with that hash", - func(hash common.Hash) { - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockByHashNotFound(client, hash, bz) - }, - common.Hash{}, - nil, - false, - }, - { - "fail - error fetching block by hash", - func(hash common.Hash) { - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockByHashError(client, hash, bz) - }, - common.Hash{}, - nil, - false, - }, - { - "fail - error getting block results", - func(hash common.Hash) { - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlockByHash(client, hash, bz) - s.Require().NoError(err) - RegisterBlockResultsError(client, 1) - }, - common.Hash{}, - nil, - false, - }, - { - "success - getting logs with block hash", - func(hash common.Hash) { - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlockByHash(client, hash, bz) - s.Require().NoError(err) - _, err = RegisterBlockResultsWithEventLog(client, rpc.BlockNumber(1).Int64()) - s.Require().NoError(err) - }, - common.BytesToHash(block.Hash()), - [][]*gethcore.Log{evm.LogsToEthereum(logs)}, - true, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() - - tc.registerMock(tc.blockHash) - logs, err := s.backend.GetLogs(tc.blockHash) - - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(tc.expLogs, logs) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestBloomStatus() { - testCases := []struct { - name string - registerMock func() - expResult uint64 - expPass bool - }{ - { - "pass - returns the BloomBitsBlocks and the number of processed sections maintained", - func() {}, - 4096, - true, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() - - tc.registerMock() - bloom, _ := s.backend.BloomStatus() - - if tc.expPass { - s.Require().Equal(tc.expResult, bloom) - } - }) - } -} +package backend_test diff --git a/eth/rpc/backend/mocks/README.md b/eth/rpc/backend/mocks/README.md deleted file mode 100644 index 376dbe6de..000000000 --- a/eth/rpc/backend/mocks/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Mocks Generation - -To generate mocks, install `mockery` tool: -https://vektra.github.io/mockery/latest/installation/ - -```bash -cd x/evm -mockery \ - --name QueryClient \ - --filename evm_query_client.go \ - --output ../../eth/rpc/backend/mocks \ - --structname EVMQueryClient -``` diff --git a/eth/rpc/backend/mocks/client.go b/eth/rpc/backend/mocks/client.go deleted file mode 100644 index 2fabaa113..000000000 --- a/eth/rpc/backend/mocks/client.go +++ /dev/null @@ -1,887 +0,0 @@ -// Code generated by mockery v2.14.0. DO NOT EDIT. - -package mocks - -import ( - bytes "github.com/cometbft/cometbft/libs/bytes" - client "github.com/cometbft/cometbft/rpc/client" - - context "context" - - coretypes "github.com/cometbft/cometbft/rpc/core/types" - - log "github.com/cometbft/cometbft/libs/log" - - mock "github.com/stretchr/testify/mock" - - types "github.com/cometbft/cometbft/types" -) - -// Client is an autogenerated mock type for the Client type -type Client struct { - mock.Mock -} - -// ABCIInfo provides a mock function with given fields: _a0 -func (_m *Client) ABCIInfo(_a0 context.Context) (*coretypes.ResultABCIInfo, error) { - ret := _m.Called(_a0) - - var r0 *coretypes.ResultABCIInfo - if rf, ok := ret.Get(0).(func(context.Context) *coretypes.ResultABCIInfo); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultABCIInfo) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(_a0) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ABCIQuery provides a mock function with given fields: ctx, path, data -func (_m *Client) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*coretypes.ResultABCIQuery, error) { - ret := _m.Called(ctx, path, data) - - var r0 *coretypes.ResultABCIQuery - if rf, ok := ret.Get(0).(func(context.Context, string, bytes.HexBytes) *coretypes.ResultABCIQuery); ok { - r0 = rf(ctx, path, data) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultABCIQuery) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, string, bytes.HexBytes) error); ok { - r1 = rf(ctx, path, data) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ABCIQueryWithOptions provides a mock function with given fields: ctx, path, data, opts -func (_m *Client) ABCIQueryWithOptions(ctx context.Context, path string, data bytes.HexBytes, opts client.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) { - ret := _m.Called(ctx, path, data, opts) - - var r0 *coretypes.ResultABCIQuery - if rf, ok := ret.Get(0).(func(context.Context, string, bytes.HexBytes, client.ABCIQueryOptions) *coretypes.ResultABCIQuery); ok { - r0 = rf(ctx, path, data, opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultABCIQuery) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, string, bytes.HexBytes, client.ABCIQueryOptions) error); ok { - r1 = rf(ctx, path, data, opts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Block provides a mock function with given fields: ctx, height -func (_m *Client) Block(ctx context.Context, height *int64) (*coretypes.ResultBlock, error) { - ret := _m.Called(ctx, height) - - var r0 *coretypes.ResultBlock - if rf, ok := ret.Get(0).(func(context.Context, *int64) *coretypes.ResultBlock); ok { - r0 = rf(ctx, height) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultBlock) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *int64) error); ok { - r1 = rf(ctx, height) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// BlockByHash provides a mock function with given fields: ctx, hash -func (_m *Client) BlockByHash(ctx context.Context, hash []byte) (*coretypes.ResultBlock, error) { - ret := _m.Called(ctx, hash) - - var r0 *coretypes.ResultBlock - if rf, ok := ret.Get(0).(func(context.Context, []byte) *coretypes.ResultBlock); ok { - r0 = rf(ctx, hash) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultBlock) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, []byte) error); ok { - r1 = rf(ctx, hash) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// BlockResults provides a mock function with given fields: ctx, height -func (_m *Client) BlockResults(ctx context.Context, height *int64) (*coretypes.ResultBlockResults, error) { - ret := _m.Called(ctx, height) - - var r0 *coretypes.ResultBlockResults - if rf, ok := ret.Get(0).(func(context.Context, *int64) *coretypes.ResultBlockResults); ok { - r0 = rf(ctx, height) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultBlockResults) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *int64) error); ok { - r1 = rf(ctx, height) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// BlockSearch provides a mock function with given fields: ctx, query, page, perPage, orderBy -func (_m *Client) BlockSearch(ctx context.Context, query string, page *int, perPage *int, orderBy string) (*coretypes.ResultBlockSearch, error) { - ret := _m.Called(ctx, query, page, perPage, orderBy) - - var r0 *coretypes.ResultBlockSearch - if rf, ok := ret.Get(0).(func(context.Context, string, *int, *int, string) *coretypes.ResultBlockSearch); ok { - r0 = rf(ctx, query, page, perPage, orderBy) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultBlockSearch) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, string, *int, *int, string) error); ok { - r1 = rf(ctx, query, page, perPage, orderBy) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// BlockchainInfo provides a mock function with given fields: ctx, minHeight, maxHeight -func (_m *Client) BlockchainInfo(ctx context.Context, minHeight int64, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) { - ret := _m.Called(ctx, minHeight, maxHeight) - - var r0 *coretypes.ResultBlockchainInfo - if rf, ok := ret.Get(0).(func(context.Context, int64, int64) *coretypes.ResultBlockchainInfo); ok { - r0 = rf(ctx, minHeight, maxHeight) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultBlockchainInfo) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, int64, int64) error); ok { - r1 = rf(ctx, minHeight, maxHeight) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// BroadcastEvidence provides a mock function with given fields: _a0, _a1 -func (_m *Client) BroadcastEvidence(_a0 context.Context, _a1 types.Evidence) (*coretypes.ResultBroadcastEvidence, error) { - ret := _m.Called(_a0, _a1) - - var r0 *coretypes.ResultBroadcastEvidence - if rf, ok := ret.Get(0).(func(context.Context, types.Evidence) *coretypes.ResultBroadcastEvidence); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultBroadcastEvidence) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.Evidence) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// BroadcastTxAsync provides a mock function with given fields: _a0, _a1 -func (_m *Client) BroadcastTxAsync(_a0 context.Context, _a1 types.Tx) (*coretypes.ResultBroadcastTx, error) { - ret := _m.Called(_a0, _a1) - - var r0 *coretypes.ResultBroadcastTx - if rf, ok := ret.Get(0).(func(context.Context, types.Tx) *coretypes.ResultBroadcastTx); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultBroadcastTx) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.Tx) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// BroadcastTxCommit provides a mock function with given fields: _a0, _a1 -func (_m *Client) BroadcastTxCommit(_a0 context.Context, _a1 types.Tx) (*coretypes.ResultBroadcastTxCommit, error) { - ret := _m.Called(_a0, _a1) - - var r0 *coretypes.ResultBroadcastTxCommit - if rf, ok := ret.Get(0).(func(context.Context, types.Tx) *coretypes.ResultBroadcastTxCommit); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultBroadcastTxCommit) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.Tx) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// BroadcastTxSync provides a mock function with given fields: _a0, _a1 -func (_m *Client) BroadcastTxSync(_a0 context.Context, _a1 types.Tx) (*coretypes.ResultBroadcastTx, error) { - ret := _m.Called(_a0, _a1) - - var r0 *coretypes.ResultBroadcastTx - if rf, ok := ret.Get(0).(func(context.Context, types.Tx) *coretypes.ResultBroadcastTx); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultBroadcastTx) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.Tx) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// CheckTx provides a mock function with given fields: _a0, _a1 -func (_m *Client) CheckTx(_a0 context.Context, _a1 types.Tx) (*coretypes.ResultCheckTx, error) { - ret := _m.Called(_a0, _a1) - - var r0 *coretypes.ResultCheckTx - if rf, ok := ret.Get(0).(func(context.Context, types.Tx) *coretypes.ResultCheckTx); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultCheckTx) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, types.Tx) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Commit provides a mock function with given fields: ctx, height -func (_m *Client) Commit(ctx context.Context, height *int64) (*coretypes.ResultCommit, error) { - ret := _m.Called(ctx, height) - - var r0 *coretypes.ResultCommit - if rf, ok := ret.Get(0).(func(context.Context, *int64) *coretypes.ResultCommit); ok { - r0 = rf(ctx, height) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultCommit) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *int64) error); ok { - r1 = rf(ctx, height) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ConsensusParams provides a mock function with given fields: ctx, height -func (_m *Client) ConsensusParams(ctx context.Context, height *int64) (*coretypes.ResultConsensusParams, error) { - ret := _m.Called(ctx, height) - - var r0 *coretypes.ResultConsensusParams - if rf, ok := ret.Get(0).(func(context.Context, *int64) *coretypes.ResultConsensusParams); ok { - r0 = rf(ctx, height) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultConsensusParams) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *int64) error); ok { - r1 = rf(ctx, height) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ConsensusState provides a mock function with given fields: _a0 -func (_m *Client) ConsensusState(_a0 context.Context) (*coretypes.ResultConsensusState, error) { - ret := _m.Called(_a0) - - var r0 *coretypes.ResultConsensusState - if rf, ok := ret.Get(0).(func(context.Context) *coretypes.ResultConsensusState); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultConsensusState) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(_a0) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DumpConsensusState provides a mock function with given fields: _a0 -func (_m *Client) DumpConsensusState(_a0 context.Context) (*coretypes.ResultDumpConsensusState, error) { - ret := _m.Called(_a0) - - var r0 *coretypes.ResultDumpConsensusState - if rf, ok := ret.Get(0).(func(context.Context) *coretypes.ResultDumpConsensusState); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultDumpConsensusState) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(_a0) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Genesis provides a mock function with given fields: _a0 -func (_m *Client) Genesis(_a0 context.Context) (*coretypes.ResultGenesis, error) { - ret := _m.Called(_a0) - - var r0 *coretypes.ResultGenesis - if rf, ok := ret.Get(0).(func(context.Context) *coretypes.ResultGenesis); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultGenesis) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(_a0) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GenesisChunked provides a mock function with given fields: _a0, _a1 -func (_m *Client) GenesisChunked(_a0 context.Context, _a1 uint) (*coretypes.ResultGenesisChunk, error) { - ret := _m.Called(_a0, _a1) - - var r0 *coretypes.ResultGenesisChunk - if rf, ok := ret.Get(0).(func(context.Context, uint) *coretypes.ResultGenesisChunk); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultGenesisChunk) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, uint) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Header provides a mock function with given fields: ctx, height -func (_m *Client) Header(ctx context.Context, height *int64) (*coretypes.ResultHeader, error) { - ret := _m.Called(ctx, height) - - var r0 *coretypes.ResultHeader - if rf, ok := ret.Get(0).(func(context.Context, *int64) *coretypes.ResultHeader); ok { - r0 = rf(ctx, height) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultHeader) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *int64) error); ok { - r1 = rf(ctx, height) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// HeaderByHash provides a mock function with given fields: ctx, hash -func (_m *Client) HeaderByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultHeader, error) { - ret := _m.Called(ctx, hash) - - var r0 *coretypes.ResultHeader - if rf, ok := ret.Get(0).(func(context.Context, bytes.HexBytes) *coretypes.ResultHeader); ok { - r0 = rf(ctx, hash) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultHeader) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, bytes.HexBytes) error); ok { - r1 = rf(ctx, hash) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Health provides a mock function with given fields: _a0 -func (_m *Client) Health(_a0 context.Context) (*coretypes.ResultHealth, error) { - ret := _m.Called(_a0) - - var r0 *coretypes.ResultHealth - if rf, ok := ret.Get(0).(func(context.Context) *coretypes.ResultHealth); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultHealth) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(_a0) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// IsRunning provides a mock function with given fields: -func (_m *Client) IsRunning() bool { - ret := _m.Called() - - var r0 bool - if rf, ok := ret.Get(0).(func() bool); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(bool) - } - - return r0 -} - -// NetInfo provides a mock function with given fields: _a0 -func (_m *Client) NetInfo(_a0 context.Context) (*coretypes.ResultNetInfo, error) { - ret := _m.Called(_a0) - - var r0 *coretypes.ResultNetInfo - if rf, ok := ret.Get(0).(func(context.Context) *coretypes.ResultNetInfo); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultNetInfo) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(_a0) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// NumUnconfirmedTxs provides a mock function with given fields: _a0 -func (_m *Client) NumUnconfirmedTxs(_a0 context.Context) (*coretypes.ResultUnconfirmedTxs, error) { - ret := _m.Called(_a0) - - var r0 *coretypes.ResultUnconfirmedTxs - if rf, ok := ret.Get(0).(func(context.Context) *coretypes.ResultUnconfirmedTxs); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultUnconfirmedTxs) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(_a0) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// OnReset provides a mock function with given fields: -func (_m *Client) OnReset() error { - ret := _m.Called() - - var r0 error - if rf, ok := ret.Get(0).(func() error); ok { - r0 = rf() - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// OnStart provides a mock function with given fields: -func (_m *Client) OnStart() error { - ret := _m.Called() - - var r0 error - if rf, ok := ret.Get(0).(func() error); ok { - r0 = rf() - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// OnStop provides a mock function with given fields: -func (_m *Client) OnStop() { - _m.Called() -} - -// Quit provides a mock function with given fields: -func (_m *Client) Quit() <-chan struct{} { - ret := _m.Called() - - var r0 <-chan struct{} - if rf, ok := ret.Get(0).(func() <-chan struct{}); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(<-chan struct{}) - } - } - - return r0 -} - -// Reset provides a mock function with given fields: -func (_m *Client) Reset() error { - ret := _m.Called() - - var r0 error - if rf, ok := ret.Get(0).(func() error); ok { - r0 = rf() - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// SetLogger provides a mock function with given fields: _a0 -func (_m *Client) SetLogger(_a0 log.Logger) { - _m.Called(_a0) -} - -// Start provides a mock function with given fields: -func (_m *Client) Start() error { - ret := _m.Called() - - var r0 error - if rf, ok := ret.Get(0).(func() error); ok { - r0 = rf() - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// Status provides a mock function with given fields: _a0 -func (_m *Client) Status(_a0 context.Context) (*coretypes.ResultStatus, error) { - ret := _m.Called(_a0) - - var r0 *coretypes.ResultStatus - if rf, ok := ret.Get(0).(func(context.Context) *coretypes.ResultStatus); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultStatus) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(_a0) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Stop provides a mock function with given fields: -func (_m *Client) Stop() error { - ret := _m.Called() - - var r0 error - if rf, ok := ret.Get(0).(func() error); ok { - r0 = rf() - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// String provides a mock function with given fields: -func (_m *Client) String() string { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - return r0 -} - -// Subscribe provides a mock function with given fields: ctx, subscriber, query, outCapacity -func (_m *Client) Subscribe(ctx context.Context, subscriber string, query string, outCapacity ...int) (<-chan coretypes.ResultEvent, error) { - _va := make([]interface{}, len(outCapacity)) - for _i := range outCapacity { - _va[_i] = outCapacity[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, subscriber, query) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 <-chan coretypes.ResultEvent - if rf, ok := ret.Get(0).(func(context.Context, string, string, ...int) <-chan coretypes.ResultEvent); ok { - r0 = rf(ctx, subscriber, query, outCapacity...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(<-chan coretypes.ResultEvent) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, string, string, ...int) error); ok { - r1 = rf(ctx, subscriber, query, outCapacity...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Tx provides a mock function with given fields: ctx, hash, prove -func (_m *Client) Tx(ctx context.Context, hash []byte, prove bool) (*coretypes.ResultTx, error) { - ret := _m.Called(ctx, hash, prove) - - var r0 *coretypes.ResultTx - if rf, ok := ret.Get(0).(func(context.Context, []byte, bool) *coretypes.ResultTx); ok { - r0 = rf(ctx, hash, prove) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultTx) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, []byte, bool) error); ok { - r1 = rf(ctx, hash, prove) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// TxSearch provides a mock function with given fields: ctx, query, prove, page, perPage, orderBy -func (_m *Client) TxSearch(ctx context.Context, query string, prove bool, page *int, perPage *int, orderBy string) (*coretypes.ResultTxSearch, error) { - ret := _m.Called(ctx, query, prove, page, perPage, orderBy) - - var r0 *coretypes.ResultTxSearch - if rf, ok := ret.Get(0).(func(context.Context, string, bool, *int, *int, string) *coretypes.ResultTxSearch); ok { - r0 = rf(ctx, query, prove, page, perPage, orderBy) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultTxSearch) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, string, bool, *int, *int, string) error); ok { - r1 = rf(ctx, query, prove, page, perPage, orderBy) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// UnconfirmedTxs provides a mock function with given fields: ctx, limit -func (_m *Client) UnconfirmedTxs(ctx context.Context, limit *int) (*coretypes.ResultUnconfirmedTxs, error) { - ret := _m.Called(ctx, limit) - - var r0 *coretypes.ResultUnconfirmedTxs - if rf, ok := ret.Get(0).(func(context.Context, *int) *coretypes.ResultUnconfirmedTxs); ok { - r0 = rf(ctx, limit) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultUnconfirmedTxs) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *int) error); ok { - r1 = rf(ctx, limit) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Unsubscribe provides a mock function with given fields: ctx, subscriber, query -func (_m *Client) Unsubscribe(ctx context.Context, subscriber string, query string) error { - ret := _m.Called(ctx, subscriber, query) - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, string, string) error); ok { - r0 = rf(ctx, subscriber, query) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// UnsubscribeAll provides a mock function with given fields: ctx, subscriber -func (_m *Client) UnsubscribeAll(ctx context.Context, subscriber string) error { - ret := _m.Called(ctx, subscriber) - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { - r0 = rf(ctx, subscriber) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// Validators provides a mock function with given fields: ctx, height, page, perPage -func (_m *Client) Validators(ctx context.Context, height *int64, page *int, perPage *int) (*coretypes.ResultValidators, error) { - ret := _m.Called(ctx, height, page, perPage) - - var r0 *coretypes.ResultValidators - if rf, ok := ret.Get(0).(func(context.Context, *int64, *int, *int) *coretypes.ResultValidators); ok { - r0 = rf(ctx, height, page, perPage) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coretypes.ResultValidators) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *int64, *int, *int) error); ok { - r1 = rf(ctx, height, page, perPage) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -type mockConstructorTestingTNewClient interface { - mock.TestingT - Cleanup(func()) -} - -// NewClient creates a new instance of Client. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewClient(t mockConstructorTestingTNewClient) *Client { - mock := &Client{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/eth/rpc/backend/mocks/evm_query_client.go b/eth/rpc/backend/mocks/evm_query_client.go deleted file mode 100644 index 301e84995..000000000 --- a/eth/rpc/backend/mocks/evm_query_client.go +++ /dev/null @@ -1,512 +0,0 @@ -// Code generated by mockery v2.45.0. DO NOT EDIT. - -package mocks - -import ( - context "context" - - evm "github.com/NibiruChain/nibiru/v2/x/evm" - grpc "google.golang.org/grpc" - - mock "github.com/stretchr/testify/mock" -) - -// EVMQueryClient is an autogenerated mock type for the QueryClient type -type EVMQueryClient struct { - mock.Mock -} - -// Balance provides a mock function with given fields: ctx, in, opts -func (_m *EVMQueryClient) Balance(ctx context.Context, in *evm.QueryBalanceRequest, opts ...grpc.CallOption) (*evm.QueryBalanceResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for Balance") - } - - var r0 *evm.QueryBalanceResponse - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryBalanceRequest, ...grpc.CallOption) (*evm.QueryBalanceResponse, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryBalanceRequest, ...grpc.CallOption) *evm.QueryBalanceResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*evm.QueryBalanceResponse) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *evm.QueryBalanceRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// BaseFee provides a mock function with given fields: ctx, in, opts -func (_m *EVMQueryClient) BaseFee(ctx context.Context, in *evm.QueryBaseFeeRequest, opts ...grpc.CallOption) (*evm.QueryBaseFeeResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for BaseFee") - } - - var r0 *evm.QueryBaseFeeResponse - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryBaseFeeRequest, ...grpc.CallOption) (*evm.QueryBaseFeeResponse, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryBaseFeeRequest, ...grpc.CallOption) *evm.QueryBaseFeeResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*evm.QueryBaseFeeResponse) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *evm.QueryBaseFeeRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Code provides a mock function with given fields: ctx, in, opts -func (_m *EVMQueryClient) Code(ctx context.Context, in *evm.QueryCodeRequest, opts ...grpc.CallOption) (*evm.QueryCodeResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for Code") - } - - var r0 *evm.QueryCodeResponse - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryCodeRequest, ...grpc.CallOption) (*evm.QueryCodeResponse, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryCodeRequest, ...grpc.CallOption) *evm.QueryCodeResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*evm.QueryCodeResponse) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *evm.QueryCodeRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// EstimateGas provides a mock function with given fields: ctx, in, opts -func (_m *EVMQueryClient) EstimateGas(ctx context.Context, in *evm.EthCallRequest, opts ...grpc.CallOption) (*evm.EstimateGasResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for EstimateGas") - } - - var r0 *evm.EstimateGasResponse - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *evm.EthCallRequest, ...grpc.CallOption) (*evm.EstimateGasResponse, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *evm.EthCallRequest, ...grpc.CallOption) *evm.EstimateGasResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*evm.EstimateGasResponse) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *evm.EthCallRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// EthAccount provides a mock function with given fields: ctx, in, opts -func (_m *EVMQueryClient) EthAccount(ctx context.Context, in *evm.QueryEthAccountRequest, opts ...grpc.CallOption) (*evm.QueryEthAccountResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for EthAccount") - } - - var r0 *evm.QueryEthAccountResponse - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryEthAccountRequest, ...grpc.CallOption) (*evm.QueryEthAccountResponse, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryEthAccountRequest, ...grpc.CallOption) *evm.QueryEthAccountResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*evm.QueryEthAccountResponse) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *evm.QueryEthAccountRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// EthCall provides a mock function with given fields: ctx, in, opts -func (_m *EVMQueryClient) EthCall(ctx context.Context, in *evm.EthCallRequest, opts ...grpc.CallOption) (*evm.MsgEthereumTxResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for EthCall") - } - - var r0 *evm.MsgEthereumTxResponse - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *evm.EthCallRequest, ...grpc.CallOption) (*evm.MsgEthereumTxResponse, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *evm.EthCallRequest, ...grpc.CallOption) *evm.MsgEthereumTxResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*evm.MsgEthereumTxResponse) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *evm.EthCallRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// FunTokenMapping provides a mock function with given fields: ctx, in, opts -func (_m *EVMQueryClient) FunTokenMapping(ctx context.Context, in *evm.QueryFunTokenMappingRequest, opts ...grpc.CallOption) (*evm.QueryFunTokenMappingResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for FunTokenMapping") - } - - var r0 *evm.QueryFunTokenMappingResponse - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryFunTokenMappingRequest, ...grpc.CallOption) (*evm.QueryFunTokenMappingResponse, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryFunTokenMappingRequest, ...grpc.CallOption) *evm.QueryFunTokenMappingResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*evm.QueryFunTokenMappingResponse) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *evm.QueryFunTokenMappingRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Params provides a mock function with given fields: ctx, in, opts -func (_m *EVMQueryClient) Params(ctx context.Context, in *evm.QueryParamsRequest, opts ...grpc.CallOption) (*evm.QueryParamsResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for Params") - } - - var r0 *evm.QueryParamsResponse - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryParamsRequest, ...grpc.CallOption) (*evm.QueryParamsResponse, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryParamsRequest, ...grpc.CallOption) *evm.QueryParamsResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*evm.QueryParamsResponse) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *evm.QueryParamsRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Storage provides a mock function with given fields: ctx, in, opts -func (_m *EVMQueryClient) Storage(ctx context.Context, in *evm.QueryStorageRequest, opts ...grpc.CallOption) (*evm.QueryStorageResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for Storage") - } - - var r0 *evm.QueryStorageResponse - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryStorageRequest, ...grpc.CallOption) (*evm.QueryStorageResponse, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryStorageRequest, ...grpc.CallOption) *evm.QueryStorageResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*evm.QueryStorageResponse) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *evm.QueryStorageRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// TraceBlock provides a mock function with given fields: ctx, in, opts -func (_m *EVMQueryClient) TraceBlock(ctx context.Context, in *evm.QueryTraceBlockRequest, opts ...grpc.CallOption) (*evm.QueryTraceBlockResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for TraceBlock") - } - - var r0 *evm.QueryTraceBlockResponse - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryTraceBlockRequest, ...grpc.CallOption) (*evm.QueryTraceBlockResponse, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryTraceBlockRequest, ...grpc.CallOption) *evm.QueryTraceBlockResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*evm.QueryTraceBlockResponse) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *evm.QueryTraceBlockRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// TraceCall provides a mock function with given fields: ctx, in, opts -func (_m *EVMQueryClient) TraceCall(ctx context.Context, in *evm.QueryTraceTxRequest, opts ...grpc.CallOption) (*evm.QueryTraceTxResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for TraceCall") - } - - var r0 *evm.QueryTraceTxResponse - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryTraceTxRequest, ...grpc.CallOption) (*evm.QueryTraceTxResponse, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryTraceTxRequest, ...grpc.CallOption) *evm.QueryTraceTxResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*evm.QueryTraceTxResponse) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *evm.QueryTraceTxRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// TraceTx provides a mock function with given fields: ctx, in, opts -func (_m *EVMQueryClient) TraceTx(ctx context.Context, in *evm.QueryTraceTxRequest, opts ...grpc.CallOption) (*evm.QueryTraceTxResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for TraceTx") - } - - var r0 *evm.QueryTraceTxResponse - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryTraceTxRequest, ...grpc.CallOption) (*evm.QueryTraceTxResponse, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryTraceTxRequest, ...grpc.CallOption) *evm.QueryTraceTxResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*evm.QueryTraceTxResponse) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *evm.QueryTraceTxRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ValidatorAccount provides a mock function with given fields: ctx, in, opts -func (_m *EVMQueryClient) ValidatorAccount(ctx context.Context, in *evm.QueryValidatorAccountRequest, opts ...grpc.CallOption) (*evm.QueryValidatorAccountResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for ValidatorAccount") - } - - var r0 *evm.QueryValidatorAccountResponse - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryValidatorAccountRequest, ...grpc.CallOption) (*evm.QueryValidatorAccountResponse, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryValidatorAccountRequest, ...grpc.CallOption) *evm.QueryValidatorAccountResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*evm.QueryValidatorAccountResponse) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *evm.QueryValidatorAccountRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// NewEVMQueryClient creates a new instance of EVMQueryClient. 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 NewEVMQueryClient(t interface { - mock.TestingT - Cleanup(func()) -}) *EVMQueryClient { - mock := &EVMQueryClient{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/eth/rpc/backend/node_info_test.go b/eth/rpc/backend/node_info_test.go index 9949defb1..f0dcea536 100644 --- a/eth/rpc/backend/node_info_test.go +++ b/eth/rpc/backend/node_info_test.go @@ -1,143 +1 @@ -package backend - -import ( - "fmt" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - - "github.com/NibiruChain/nibiru/v2/eth" - "github.com/NibiruChain/nibiru/v2/eth/rpc/backend/mocks" -) - -func (s *BackendSuite) TestRPCMinGasPrice() { - testCases := []struct { - name string - registerMock func() - expMinGasPrice int64 - expPass bool - }{ - { - "pass - default gas price", - func() { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterParamsWithoutHeaderError(queryClient, 1) - }, - eth.DefaultGasPrice, - true, - }, - { - "pass - min gas price is 0", - func() { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterParamsWithoutHeader(queryClient, 1) - }, - eth.DefaultGasPrice, - true, - }, - } - - for _, tc := range testCases { - s.Run(fmt.Sprintf("case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock() - - minPrice := s.backend.RPCMinGasPrice() - if tc.expPass { - s.Require().Equal(tc.expMinGasPrice, minPrice) - } else { - s.Require().NotEqual(tc.expMinGasPrice, minPrice) - } - }) - } -} - -func (s *BackendSuite) TestAccounts() { - testCases := []struct { - name string - registerMock func() - expAddr []common.Address - expPass bool - }{ - { - "pass - returns empty address", - func() {}, - []common.Address{}, - true, - }, - } - - for _, tc := range testCases { - s.Run(fmt.Sprintf("case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock() - - output, err := s.backend.Accounts() - - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(tc.expAddr, output) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestSyncing() { - testCases := []struct { - name string - registerMock func() - expResponse interface{} - expPass bool - }{ - { - "fail - Can't get status", - func() { - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterStatusError(client) - }, - false, - false, - }, - { - "pass - Node not catching up", - func() { - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterStatus(client) - }, - false, - true, - }, - { - "pass - Node is catching up", - func() { - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterStatus(client) - status, _ := client.Status(s.backend.ctx) - status.SyncInfo.CatchingUp = true - }, - map[string]interface{}{ - "startingBlock": hexutil.Uint64(0), - "currentBlock": hexutil.Uint64(0), - }, - true, - }, - } - - for _, tc := range testCases { - s.Run(fmt.Sprintf("case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock() - - output, err := s.backend.Syncing() - - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(tc.expResponse, output) - } else { - s.Require().Error(err) - } - }) - } -} +package backend_test diff --git a/eth/rpc/backend/sign_tx_test.go b/eth/rpc/backend/sign_tx_test.go index 559289d3f..f0dcea536 100644 --- a/eth/rpc/backend/sign_tx_test.go +++ b/eth/rpc/backend/sign_tx_test.go @@ -1,273 +1 @@ -package backend - -import ( - "fmt" - - "cosmossdk.io/math" - - "github.com/cosmos/cosmos-sdk/crypto" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - gethcore "github.com/ethereum/go-ethereum/core/types" - goethcrypto "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/signer/core/apitypes" - "google.golang.org/grpc/metadata" - - "github.com/NibiruChain/nibiru/v2/eth/crypto/ethsecp256k1" - "github.com/NibiruChain/nibiru/v2/eth/rpc/backend/mocks" - "github.com/NibiruChain/nibiru/v2/x/evm" - evmtest "github.com/NibiruChain/nibiru/v2/x/evm/evmtest" -) - -func (s *BackendSuite) TestSendTransaction() { - gasPrice := new(hexutil.Big) - gas := hexutil.Uint64(1) - zeroGas := hexutil.Uint64(0) - toAddr := evmtest.NewEthPrivAcc().EthAddr - priv, _ := ethsecp256k1.GenerateKey() - from := common.BytesToAddress(priv.PubKey().Address().Bytes()) - nonce := hexutil.Uint64(1) - baseFee := math.NewInt(1) - callArgsDefault := evm.JsonTxArgs{ - From: &from, - To: &toAddr, - GasPrice: gasPrice, - Gas: &gas, - Nonce: &nonce, - } - - hash := common.Hash{} - - testCases := []struct { - name string - registerMock func() - args evm.JsonTxArgs - expHash common.Hash - expPass bool - }{ - { - "fail - Can't find account in Keyring", - func() {}, - evm.JsonTxArgs{}, - hash, - false, - }, - { - "fail - Block error can't set Tx defaults", - func() { - var header metadata.MD - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - client := s.backend.clientCtx.Client.(*mocks.Client) - armor := crypto.EncryptArmorPrivKey(priv, "", "eth_secp256k1") - err := s.backend.clientCtx.Keyring.ImportPrivKey("test_key", armor, "") - s.Require().NoError(err) - RegisterParams(queryClient, &header, 1) - RegisterBlockError(client, 1) - }, - callArgsDefault, - hash, - false, - }, - { - "fail - Cannot validate transaction gas set to 0", - func() { - var header metadata.MD - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - client := s.backend.clientCtx.Client.(*mocks.Client) - armor := crypto.EncryptArmorPrivKey(priv, "", "eth_secp256k1") - err := s.backend.clientCtx.Keyring.ImportPrivKey("test_key", armor, "") - s.Require().NoError(err) - RegisterParams(queryClient, &header, 1) - _, err = RegisterBlock(client, 1, nil) - s.Require().NoError(err) - _, err = RegisterBlockResults(client, 1) - s.Require().NoError(err) - RegisterBaseFee(queryClient, baseFee) - RegisterParamsWithoutHeader(queryClient, 1) - }, - evm.JsonTxArgs{ - From: &from, - To: &toAddr, - GasPrice: gasPrice, - Gas: &zeroGas, - Nonce: &nonce, - }, - hash, - false, - }, - { - "fail - Cannot broadcast transaction", - func() { - client, txBytes := broadcastTx(s, priv, baseFee, callArgsDefault) - RegisterBroadcastTxError(client, txBytes) - }, - callArgsDefault, - common.Hash{}, - false, - }, - { - "pass - Return the transaction hash", - func() { - client, txBytes := broadcastTx(s, priv, baseFee, callArgsDefault) - RegisterBroadcastTx(client, txBytes) - }, - callArgsDefault, - hash, - true, - }, - } - - for _, tc := range testCases { - s.Run(fmt.Sprintf("case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock() - - if tc.expPass { - // Sign the transaction and get the hash - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterParamsWithoutHeader(queryClient, 1) - ethSigner := gethcore.LatestSigner(s.backend.ChainConfig()) - msg := callArgsDefault.ToMsgEthTx() - err := msg.Sign(ethSigner, s.backend.clientCtx.Keyring) - s.Require().NoError(err) - tc.expHash = msg.AsTransaction().Hash() - } - responseHash, err := s.backend.SendTransaction(tc.args) - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(tc.expHash, responseHash) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestSign() { - ethAcc := evmtest.NewEthPrivAcc() - from, priv := ethAcc.EthAddr, ethAcc.PrivKey - - testCases := []struct { - name string - registerMock func() - fromAddr common.Address - inputBz hexutil.Bytes - expPass bool - }{ - { - "fail - can't find key in Keyring", - func() {}, - from, - nil, - false, - }, - { - "pass - sign nil data", - func() { - armor := crypto.EncryptArmorPrivKey(priv, "", "eth_secp256k1") - err := s.backend.clientCtx.Keyring.ImportPrivKey("test_key", armor, "") - s.Require().NoError(err) - }, - from, - nil, - true, - }, - } - - for _, tc := range testCases { - s.Run(fmt.Sprintf("case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock() - - responseBz, err := s.backend.Sign(tc.fromAddr, tc.inputBz) - if tc.expPass { - signature, _, err := s.backend.clientCtx.Keyring.SignByAddress((sdk.AccAddress)(from.Bytes()), tc.inputBz) - signature[goethcrypto.RecoveryIDOffset] += 27 - s.Require().NoError(err) - s.Require().Equal((hexutil.Bytes)(signature), responseBz) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestSignTypedData() { - ethAcc := evmtest.NewEthPrivAcc() - from, priv := ethAcc.EthAddr, ethAcc.PrivKey - testCases := []struct { - name string - registerMock func() - fromAddr common.Address - inputTypedData apitypes.TypedData - expPass bool - }{ - { - "fail - can't find key in Keyring", - func() {}, - from, - apitypes.TypedData{}, - false, - }, - { - "fail - empty TypeData", - func() { - armor := crypto.EncryptArmorPrivKey(priv, "", "eth_secp256k1") - err := s.backend.clientCtx.Keyring.ImportPrivKey("test_key", armor, "") - s.Require().NoError(err) - }, - from, - apitypes.TypedData{}, - false, - }, - // TODO: Generate a TypedData msg - } - - for _, tc := range testCases { - s.Run(fmt.Sprintf("case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock() - - responseBz, err := s.backend.SignTypedData(tc.fromAddr, tc.inputTypedData) - - if tc.expPass { - sigHash, _, _ := apitypes.TypedDataAndHash(tc.inputTypedData) - signature, _, err := s.backend.clientCtx.Keyring.SignByAddress((sdk.AccAddress)(from.Bytes()), sigHash) - signature[goethcrypto.RecoveryIDOffset] += 27 - s.Require().NoError(err) - s.Require().Equal((hexutil.Bytes)(signature), responseBz) - } else { - s.Require().Error(err) - } - }) - } -} - -func broadcastTx( - s *BackendSuite, - priv *ethsecp256k1.PrivKey, - baseFee math.Int, - callArgsDefault evm.JsonTxArgs, -) (client *mocks.Client, txBytes []byte) { - var header metadata.MD - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - client = s.backend.clientCtx.Client.(*mocks.Client) - armor := crypto.EncryptArmorPrivKey(priv, "", "eth_secp256k1") - _ = s.backend.clientCtx.Keyring.ImportPrivKey("test_key", armor, "") - RegisterParams(queryClient, &header, 1) - _, err := RegisterBlock(client, 1, nil) - s.Require().NoError(err) - _, err = RegisterBlockResults(client, 1) - s.Require().NoError(err) - RegisterBaseFee(queryClient, baseFee) - RegisterParamsWithoutHeader(queryClient, 1) - ethSigner := gethcore.LatestSigner(s.backend.ChainConfig()) - msg := callArgsDefault.ToMsgEthTx() - err = msg.Sign(ethSigner, s.backend.clientCtx.Keyring) - s.Require().NoError(err) - tx, _ := msg.BuildTx(s.backend.clientCtx.TxConfig.NewTxBuilder(), evm.DefaultEVMDenom) - txEncoder := s.backend.clientCtx.TxConfig.TxEncoder() - txBytes, _ = txEncoder(tx) - return client, txBytes -} +package backend_test diff --git a/eth/rpc/backend/tracing.go b/eth/rpc/backend/tracing.go index 1362aab4f..425e3d00e 100644 --- a/eth/rpc/backend/tracing.go +++ b/eth/rpc/backend/tracing.go @@ -39,7 +39,7 @@ func (b *Backend) TraceTransaction(hash common.Hash, config *evm.TraceConfig) (i // check tx index is not out of bound if len(blk.Block.Txs) > math.MaxUint32 { - return nil, fmt.Errorf("tx count %d is overfloing", len(blk.Block.Txs)) + return nil, fmt.Errorf("tx count %d is overflowing", len(blk.Block.Txs)) } txsLen := uint32(len(blk.Block.Txs)) // #nosec G701 -- checked for int overflow already if txsLen < transaction.TxIndex { diff --git a/eth/rpc/backend/tracing_test.go b/eth/rpc/backend/tracing_test.go index 914524f55..e8c9a090c 100644 --- a/eth/rpc/backend/tracing_test.go +++ b/eth/rpc/backend/tracing_test.go @@ -1,321 +1,134 @@ -package backend +package backend_test import ( - "fmt" "math/big" + "strings" - dbm "github.com/cometbft/cometbft-db" - abci "github.com/cometbft/cometbft/abci/types" - tmlog "github.com/cometbft/cometbft/libs/log" tmrpctypes "github.com/cometbft/cometbft/rpc/core/types" - "github.com/cometbft/cometbft/types" - "github.com/cosmos/cosmos-sdk/crypto" - "github.com/ethereum/go-ethereum/common" + gethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - gethcore "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/params" - "github.com/NibiruChain/nibiru/v2/eth/crypto/ethsecp256k1" - "github.com/NibiruChain/nibiru/v2/eth/indexer" "github.com/NibiruChain/nibiru/v2/eth/rpc" - "github.com/NibiruChain/nibiru/v2/eth/rpc/backend/mocks" "github.com/NibiruChain/nibiru/v2/x/evm" ) -func (s *BackendSuite) TestTraceTransaction() { - msgEthereumTx, _ := s.buildEthereumTx() - msgEthereumTx2, _ := s.buildEthereumTx() - - txHash := msgEthereumTx.AsTransaction().Hash() - txHash2 := msgEthereumTx2.AsTransaction().Hash() - - priv, _ := ethsecp256k1.GenerateKey() - from := common.BytesToAddress(priv.PubKey().Address().Bytes()) - - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - RegisterParamsWithoutHeader(queryClient, 1) - - armor := crypto.EncryptArmorPrivKey(priv, "", "eth_secp256k1") - _ = s.backend.clientCtx.Keyring.ImportPrivKey("test_key", armor, "") - - ethSigner := gethcore.LatestSigner(s.backend.ChainConfig()) - - txEncoder := s.backend.clientCtx.TxConfig.TxEncoder() - - msgEthereumTx.From = from.String() - _ = msgEthereumTx.Sign(ethSigner, s.signer) - - tx, _ := msgEthereumTx.BuildTx(s.backend.clientCtx.TxConfig.NewTxBuilder(), evm.DefaultEVMDenom) - txBz, _ := txEncoder(tx) - - msgEthereumTx2.From = from.String() - _ = msgEthereumTx2.Sign(ethSigner, s.signer) - - tx2, _ := msgEthereumTx.BuildTx(s.backend.clientCtx.TxConfig.NewTxBuilder(), evm.DefaultEVMDenom) - txBz2, _ := txEncoder(tx2) +var traceConfig = &evm.TraceConfig{ + Tracer: "callTracer", + TracerConfig: &evm.TracerConfig{ + OnlyTopCall: true, + }, +} +func (s *BackendSuite) TestTraceTransaction() { testCases := []struct { - name string - registerMock func() - block *types.Block - responseBlock []*abci.ResponseDeliverTx - expResult interface{} - expPass bool + name string + txHash gethcommon.Hash + wantErr string }{ { - "fail - tx not found", - func() {}, - &types.Block{Header: types.Header{Height: 1}, Data: types.Data{Txs: []types.Tx{}}}, - []*abci.ResponseDeliverTx{ - { - Code: 0, - Events: []abci.Event{ - {Type: evm.EventTypeEthereumTx, Attributes: []abci.EventAttribute{ - {Key: "ethereumTxHash", Value: txHash.Hex()}, - {Key: "txIndex", Value: "0"}, - {Key: "amount", Value: "1000"}, - {Key: "txGasUsed", Value: "21000"}, - {Key: "txHash", Value: ""}, - {Key: "recipient", Value: "0x775b87ef5D82ca211811C1a02CE0fE0CA3a455d7"}, - }}, - }, - }, - }, - nil, - false, - }, - { - "fail - block not found", - func() { - // var header metadata.MD - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockError(client, 1) - }, - &types.Block{Header: types.Header{Height: 1}, Data: types.Data{Txs: []types.Tx{txBz}}}, - []*abci.ResponseDeliverTx{ - { - Code: 0, - Events: []abci.Event{ - {Type: evm.EventTypeEthereumTx, Attributes: []abci.EventAttribute{ - {Key: "ethereumTxHash", Value: txHash.Hex()}, - {Key: "txIndex", Value: "0"}, - {Key: "amount", Value: "1000"}, - {Key: "txGasUsed", Value: "21000"}, - {Key: "txHash", Value: ""}, - {Key: "recipient", Value: "0x775b87ef5D82ca211811C1a02CE0fE0CA3a455d7"}, - }}, - }, - }, - }, - map[string]interface{}{"test": "hello"}, - false, - }, - { - "pass - transaction found in a block with multiple transactions", - func() { - var ( - queryClient = s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - client = s.backend.clientCtx.Client.(*mocks.Client) - height int64 = 1 - ) - _, err := RegisterBlockMultipleTxs(client, height, []types.Tx{txBz, txBz2}) - s.Require().NoError(err) - RegisterTraceTransactionWithPredecessors(queryClient, msgEthereumTx, []*evm.MsgEthereumTx{msgEthereumTx}) - RegisterConsensusParams(client, height) - }, - &types.Block{Header: types.Header{Height: 1, ChainID: ChainID}, Data: types.Data{Txs: []types.Tx{txBz, txBz2}}}, - []*abci.ResponseDeliverTx{ - { - Code: 0, - Events: []abci.Event{ - {Type: evm.EventTypeEthereumTx, Attributes: []abci.EventAttribute{ - {Key: "ethereumTxHash", Value: txHash.Hex()}, - {Key: "txIndex", Value: "0"}, - {Key: "amount", Value: "1000"}, - {Key: "txGasUsed", Value: "21000"}, - {Key: "txHash", Value: ""}, - {Key: "recipient", Value: "0x775b87ef5D82ca211811C1a02CE0fE0CA3a455d7"}, - }}, - }, - }, - { - Code: 0, - Events: []abci.Event{ - {Type: evm.EventTypeEthereumTx, Attributes: []abci.EventAttribute{ - {Key: "ethereumTxHash", Value: txHash2.Hex()}, - {Key: "txIndex", Value: "1"}, - {Key: "amount", Value: "1000"}, - {Key: "txGasUsed", Value: "21000"}, - {Key: "txHash", Value: ""}, - {Key: "recipient", Value: "0x775b87ef5D82ca211811C1a02CE0fE0CA3a455d7"}, - }}, - }, - }, - }, - map[string]interface{}{"test": "hello"}, - true, + name: "sad: tx not found", + txHash: gethcommon.BytesToHash([]byte("0x0")), + wantErr: "not found", }, { - "pass - transaction found", - func() { - var ( - queryClient = s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - client = s.backend.clientCtx.Client.(*mocks.Client) - height int64 = 1 - ) - _, err := RegisterBlock(client, height, txBz) - s.Require().NoError(err) - RegisterTraceTransaction(queryClient, msgEthereumTx) - RegisterConsensusParams(client, height) - }, - &types.Block{Header: types.Header{Height: 1}, Data: types.Data{Txs: []types.Tx{txBz}}}, - []*abci.ResponseDeliverTx{ - { - Code: 0, - Events: []abci.Event{ - {Type: evm.EventTypeEthereumTx, Attributes: []abci.EventAttribute{ - {Key: "ethereumTxHash", Value: txHash.Hex()}, - {Key: "txIndex", Value: "0"}, - {Key: "amount", Value: "1000"}, - {Key: "txGasUsed", Value: "21000"}, - {Key: "txHash", Value: ""}, - {Key: "recipient", Value: "0x775b87ef5D82ca211811C1a02CE0fE0CA3a455d7"}, - }}, - }, - }, - }, - map[string]interface{}{"test": "hello"}, - true, + name: "happy: tx found", + txHash: transferTxHash, + wantErr: "", }, } for _, tc := range testCases { - s.Run(fmt.Sprintf("case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock() - - db := dbm.NewMemDB() - s.backend.indexer = indexer.NewKVIndexer(db, tmlog.NewNopLogger(), s.backend.clientCtx) - - err := s.backend.indexer.IndexBlock(tc.block, tc.responseBlock) - s.Require().NoError(err) - txResult, err := s.backend.TraceTransaction(txHash, nil) - - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(tc.expResult, txResult) - } else { - s.Require().Error(err) + s.Run(tc.name, func() { + res, err := s.backend.TraceTransaction( + tc.txHash, + traceConfig, + ) + if tc.wantErr != "" { + s.ErrorContains(err, tc.wantErr) + return } + s.Require().NoError(err) + s.Require().NotNil(res) + AssertTraceCall(s, res.(map[string]interface{})) }) } } func (s *BackendSuite) TestTraceBlock() { - msgEthTx, bz := s.buildEthereumTx() - emptyBlock := types.MakeBlock(1, []types.Tx{}, nil, nil) - emptyBlock.ChainID = ChainID - filledBlock := types.MakeBlock(1, []types.Tx{bz}, nil, nil) - filledBlock.ChainID = ChainID - resBlockEmpty := tmrpctypes.ResultBlock{Block: emptyBlock, BlockID: emptyBlock.LastBlockID} - resBlockFilled := tmrpctypes.ResultBlock{Block: filledBlock, BlockID: filledBlock.LastBlockID} + tmBlockWithTx, err := s.backend.TendermintBlockByNumber(transferTxBlockNumber) + s.Require().NoError(err) + + blockNumberWithoutTx := rpc.NewBlockNumber(big.NewInt(1)) + tmBlockWithoutTx, err := s.backend.TendermintBlockByNumber(1) + s.Require().NoError(err) testCases := []struct { - name string - registerMock func() - expTraceResults []*evm.TxTraceResult - resBlock *tmrpctypes.ResultBlock - config *evm.TraceConfig - expPass bool + name string + blockNumber rpc.BlockNumber + tmBlock *tmrpctypes.ResultBlock + txCount int }{ { - "pass - no transaction returning empty array", - func() {}, - []*evm.TxTraceResult{}, - &resBlockEmpty, - &evm.TraceConfig{}, - true, + name: "happy: block without txs", + blockNumber: blockNumberWithoutTx, + tmBlock: tmBlockWithoutTx, + txCount: 0, }, { - "fail - cannot unmarshal data", - func() { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterTraceBlock(queryClient, []*evm.MsgEthereumTx{msgEthTx}) - RegisterConsensusParams(client, 1) - }, - []*evm.TxTraceResult{}, - &resBlockFilled, - &evm.TraceConfig{}, - false, + name: "happy: block with txs", + blockNumber: transferTxBlockNumber, + tmBlock: tmBlockWithTx, + txCount: 1, }, } for _, tc := range testCases { - s.Run(fmt.Sprintf("case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock() - - traceResults, err := s.backend.TraceBlock(1, tc.config, tc.resBlock) - - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(tc.expTraceResults, traceResults) - } else { - s.Require().Error(err) + s.Run(tc.name, func() { + res, err := s.backend.TraceBlock( + tc.blockNumber, + traceConfig, + tc.tmBlock, + ) + s.Require().NoError(err) + s.Require().Equal(tc.txCount, len(res)) + if tc.txCount > 0 { + AssertTraceCall(s, res[0].Result.(map[string]interface{})) } }) } } func (s *BackendSuite) TestTraceCall() { - priv, _ := ethsecp256k1.GenerateKey() - from := common.BytesToAddress(priv.PubKey().Address().Bytes()) + block, err := s.backend.BlockNumber() + s.Require().NoError(err) + nonce, err := s.backend.GetTransactionCount(s.fundedAccEthAddr, rpc.BlockNumber(block)) + s.NoError(err) + gas := hexutil.Uint64(evm.NativeToWei(big.NewInt(int64(params.TxGas))).Uint64()) + amountToSendHex := hexutil.Big(*amountToSend) txArgs := evm.JsonTxArgs{ - From: &from, - Value: (*hexutil.Big)(big.NewInt(1e12)), - } - - testCases := []struct { - name string - registerMock func() - expResult interface{} - expPass bool - }{ - { - "pass - valid call", - func() { - var ( - queryClient = s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - client = s.backend.clientCtx.Client.(*mocks.Client) - height int64 = 1 - ) - - msgEthereumTx := txArgs.ToMsgEthTx() - - _, err := RegisterBlock(client, height, nil) - s.Require().NoError(err) - RegisterTraceCall(queryClient, msgEthereumTx) - RegisterConsensusParams(client, height) - }, - map[string]interface{}{"test": "hello"}, - true, - }, + Nonce: nonce, + From: &s.fundedAccEthAddr, + To: &recipient, + Value: &amountToSendHex, + Gas: &gas, } + s.Require().NoError(err) + + res, err := s.backend.TraceCall( + txArgs, + rpc.BlockNumber(block), + traceConfig, + ) + s.Require().NoError(err) + s.Require().NotNil(res) + AssertTraceCall(s, res.(map[string]interface{})) +} - for _, tc := range testCases { - s.Run(fmt.Sprintf("case %s", tc.name), func() { - s.SetupTest() // reset test and queries - tc.registerMock() - - txResult, err := s.backend.TraceCall(txArgs, rpc.NewBlockNumber(big.NewInt(1)), &evm.TraceConfig{}) - - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(tc.expResult, txResult) - } else { - s.Require().Error(err) - } - }) - } +func AssertTraceCall(s *BackendSuite, trace map[string]interface{}) { + s.Require().Equal("CALL", trace["type"]) + s.Require().Equal(strings.ToLower(s.fundedAccEthAddr.Hex()), trace["from"]) + s.Require().Equal(strings.ToLower(recipient.Hex()), trace["to"]) + s.Require().Equal("0x"+gethcommon.Bytes2Hex(amountToSend.Bytes()), trace["value"]) } diff --git a/eth/rpc/backend/tx_info.go b/eth/rpc/backend/tx_info.go index 2f5003d0b..9783ca747 100644 --- a/eth/rpc/backend/tx_info.go +++ b/eth/rpc/backend/tx_info.go @@ -11,7 +11,7 @@ import ( tmrpcclient "github.com/cometbft/cometbft/rpc/client" tmrpctypes "github.com/cometbft/cometbft/rpc/core/types" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/ethereum/go-ethereum/common" + gethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" gethcore "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" @@ -25,7 +25,7 @@ import ( // GetTransactionByHash returns the Ethereum format transaction identified by // Ethereum transaction hash. If the transaction is not found or has been // discarded from a pruning node, this resolves to nil. -func (b *Backend) GetTransactionByHash(txHash common.Hash) (*rpc.EthTxJsonRPC, error) { +func (b *Backend) GetTransactionByHash(txHash gethcommon.Hash) (*rpc.EthTxJsonRPC, error) { res, err := b.GetTxByEthHash(txHash) if err != nil { return b.getTransactionByHashPending(txHash) @@ -81,7 +81,7 @@ func (b *Backend) GetTransactionByHash(txHash common.Hash) (*rpc.EthTxJsonRPC, e index := uint64(res.EthTxIndex) //#nosec G701 -- checked for int overflow already return rpc.NewRPCTxFromMsg( msg, - common.BytesToHash(block.BlockID.Hash.Bytes()), + gethcommon.BytesToHash(block.BlockID.Hash.Bytes()), height, index, baseFee, @@ -90,7 +90,7 @@ func (b *Backend) GetTransactionByHash(txHash common.Hash) (*rpc.EthTxJsonRPC, e } // getTransactionByHashPending find pending tx from mempool -func (b *Backend) getTransactionByHashPending(txHash common.Hash) (*rpc.EthTxJsonRPC, error) { +func (b *Backend) getTransactionByHashPending(txHash gethcommon.Hash) (*rpc.EthTxJsonRPC, error) { hexTx := txHash.Hex() // try to find tx in mempool txs, err := b.PendingTransactions() @@ -110,7 +110,7 @@ func (b *Backend) getTransactionByHashPending(txHash common.Hash) (*rpc.EthTxJso // use zero block values since it's not included in a block yet rpctx, err := rpc.NewRPCTxFromMsg( msg, - common.Hash{}, + gethcommon.Hash{}, uint64(0), uint64(0), nil, @@ -137,7 +137,7 @@ func (b *Backend) GetGasUsed(res *eth.TxResult, price *big.Int, gas uint64) uint } // GetTransactionReceipt returns the transaction receipt identified by hash. -func (b *Backend) GetTransactionReceipt(hash common.Hash) (map[string]interface{}, error) { +func (b *Backend) GetTransactionReceipt(hash gethcommon.Hash) (map[string]interface{}, error) { hexTx := hash.Hex() b.logger.Debug("eth_getTransactionReceipt", "hash", hexTx) @@ -230,7 +230,7 @@ func (b *Backend) GetTransactionReceipt(hash common.Hash) (map[string]interface{ // Inclusion information: These fields provide information about the inclusion of the // transaction corresponding to this receipt. - "blockHash": common.BytesToHash(resBlock.Block.Header.Hash()).Hex(), + "blockHash": gethcommon.BytesToHash(resBlock.Block.Header.Hash()).Hex(), "blockNumber": hexutil.Uint64(res.Height), "transactionIndex": hexutil.Uint64(res.EthTxIndex), @@ -263,7 +263,7 @@ func (b *Backend) GetTransactionReceipt(hash common.Hash) (map[string]interface{ } // GetTransactionByBlockHashAndIndex returns the transaction identified by hash and index. -func (b *Backend) GetTransactionByBlockHashAndIndex(hash common.Hash, idx hexutil.Uint) (*rpc.EthTxJsonRPC, error) { +func (b *Backend) GetTransactionByBlockHashAndIndex(hash gethcommon.Hash, idx hexutil.Uint) (*rpc.EthTxJsonRPC, error) { b.logger.Debug("eth_getTransactionByBlockHashAndIndex", "hash", hash.Hex(), "index", idx) sc, ok := b.clientCtx.Client.(tmrpcclient.SignClient) if !ok { @@ -303,9 +303,10 @@ func (b *Backend) GetTransactionByBlockNumberAndIndex(blockNum rpc.BlockNumber, } // GetTxByEthHash uses `/tx_query` to find transaction by ethereum tx hash -// TODO: Don't need to convert once hashing is fixed on Tendermint -// https://github.com/cometbft/cometbft/issues/6539 -func (b *Backend) GetTxByEthHash(hash common.Hash) (*eth.TxResult, error) { +func (b *Backend) GetTxByEthHash(hash gethcommon.Hash) (*eth.TxResult, error) { + // NOTE: The Tendermint hash is not the same as the gethcommon.Hash. + // https://github.com/cometbft/cometbft/issues/342#issuecomment-1428836340 + // https://github.com/tendermint/tendermint/issues/6539 if b.indexer != nil { return b.indexer.GetByTxHash(hash) } @@ -414,7 +415,7 @@ func (b *Backend) GetTransactionByBlockAndIndex(block *tmrpctypes.ResultBlock, i index := uint64(idx) // #nosec G701 -- checked for int overflow already return rpc.NewRPCTxFromMsg( msg, - common.BytesToHash(block.Block.Hash()), + gethcommon.BytesToHash(block.Block.Hash()), height, index, baseFee, diff --git a/eth/rpc/backend/tx_info_test.go b/eth/rpc/backend/tx_info_test.go index 28f345eba..d203b2bc4 100644 --- a/eth/rpc/backend/tx_info_test.go +++ b/eth/rpc/backend/tx_info_test.go @@ -1,671 +1,179 @@ -package backend +package backend_test import ( - "fmt" "math/big" - "cosmossdk.io/math" - dbm "github.com/cometbft/cometbft-db" - abci "github.com/cometbft/cometbft/abci/types" - tmlog "github.com/cometbft/cometbft/libs/log" - tmrpctypes "github.com/cometbft/cometbft/rpc/core/types" - "github.com/cometbft/cometbft/types" - "github.com/ethereum/go-ethereum/common" + gethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "google.golang.org/grpc/metadata" - "github.com/NibiruChain/nibiru/v2/eth" - "github.com/NibiruChain/nibiru/v2/eth/indexer" "github.com/NibiruChain/nibiru/v2/eth/rpc" - "github.com/NibiruChain/nibiru/v2/eth/rpc/backend/mocks" - "github.com/NibiruChain/nibiru/v2/x/evm" ) func (s *BackendSuite) TestGetTransactionByHash() { - msgEthereumTx, _ := s.buildEthereumTx() - txHash := msgEthereumTx.AsTransaction().Hash() - - txBz := s.signAndEncodeEthTx(msgEthereumTx) - block := &types.Block{Header: types.Header{Height: 1, ChainID: "test"}, Data: types.Data{Txs: []types.Tx{txBz}}} - responseDeliver := []*abci.ResponseDeliverTx{ - { - Code: 0, - Events: []abci.Event{ - {Type: evm.EventTypeEthereumTx, Attributes: []abci.EventAttribute{ - {Key: "ethereumTxHash", Value: txHash.Hex()}, - {Key: "txIndex", Value: "0"}, - {Key: "amount", Value: "1000"}, - {Key: "txGasUsed", Value: "21000"}, - {Key: "txHash", Value: ""}, - {Key: "recipient", Value: ""}, - }}, - }, - }, - } - - rpcTransaction, _ := rpc.NewRPCTxFromEthTx(msgEthereumTx.AsTransaction(), common.Hash{}, 0, 0, big.NewInt(1), s.backend.chainID) - testCases := []struct { - name string - registerMock func() - tx *evm.MsgEthereumTx - expRPCTx *rpc.EthTxJsonRPC - expPass bool + name string + txHash gethcommon.Hash + wantTxFound bool }{ { - "fail - Block error", - func() { - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockError(client, 1) - }, - msgEthereumTx, - rpcTransaction, - false, - }, - { - "fail - Block Result error", - func() { - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlock(client, 1, txBz) - s.Require().NoError(err) - RegisterBlockResultsError(client, 1) - }, - msgEthereumTx, - nil, - true, + name: "happy: tx found", + txHash: transferTxHash, + wantTxFound: true, }, { - "pass - Base fee error", - func() { - client := s.backend.clientCtx.Client.(*mocks.Client) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - _, err := RegisterBlock(client, 1, txBz) - s.Require().NoError(err) - _, err = RegisterBlockResults(client, 1) - s.Require().NoError(err) - RegisterBaseFeeError(queryClient) - }, - msgEthereumTx, - rpcTransaction, - true, - }, - { - "pass - Transaction found and returned", - func() { - client := s.backend.clientCtx.Client.(*mocks.Client) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - _, err := RegisterBlock(client, 1, txBz) - s.Require().NoError(err) - _, err = RegisterBlockResults(client, 1) - s.Require().NoError(err) - RegisterBaseFee(queryClient, math.NewInt(1)) - }, - msgEthereumTx, - rpcTransaction, - true, + name: "sad: tx not found", + txHash: gethcommon.BytesToHash([]byte("0x0")), + wantTxFound: false, }, } for _, tc := range testCases { s.Run(tc.name, func() { - s.SetupTest() // reset - tc.registerMock() - - db := dbm.NewMemDB() - s.backend.indexer = indexer.NewKVIndexer(db, tmlog.NewNopLogger(), s.backend.clientCtx) - err := s.backend.indexer.IndexBlock(block, responseDeliver) - s.Require().NoError(err) - - rpcTx, err := s.backend.GetTransactionByHash(common.HexToHash(tc.tx.Hash)) - - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(rpcTx, tc.expRPCTx) - } else { - s.Require().Error(err) + txResponse, err := s.backend.GetTransactionByHash(tc.txHash) + if !tc.wantTxFound { + s.Require().Nil(txResponse) + return } + s.Require().NoError(err) + s.Require().NotNil(txResponse) + s.Require().Equal(tc.txHash, txResponse.Hash) + s.Require().Equal(s.fundedAccEthAddr, txResponse.From) + s.Require().Equal(&recipient, txResponse.To) + s.Require().Equal(amountToSend, txResponse.Value.ToInt()) }) } } -func (s *BackendSuite) TestGetTransactionsByHashPending() { - msgEthereumTx, bz := s.buildEthereumTx() - rpcTransaction, _ := rpc.NewRPCTxFromEthTx(msgEthereumTx.AsTransaction(), common.Hash{}, 0, 0, big.NewInt(1), s.backend.chainID) - +func (s *BackendSuite) TestGetTransactionReceipt() { testCases := []struct { - name string - registerMock func() - tx *evm.MsgEthereumTx - expRPCTx *rpc.EthTxJsonRPC - expPass bool + name string + txHash gethcommon.Hash + wantTxFound bool }{ { - "fail - Pending transactions returns error", - func() { - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterUnconfirmedTxsError(client, nil) - }, - msgEthereumTx, - nil, - true, - }, - { - "fail - Tx not found return nil", - func() { - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterUnconfirmedTxs(client, nil, nil) - }, - msgEthereumTx, - nil, - true, + name: "happy: tx found", + txHash: transferTxHash, + wantTxFound: true, }, { - "pass - Tx found and returned", - func() { - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterUnconfirmedTxs(client, nil, types.Txs{bz}) - }, - msgEthereumTx, - rpcTransaction, - true, + name: "sad: tx not found", + txHash: gethcommon.BytesToHash([]byte("0x0")), + wantTxFound: false, }, } for _, tc := range testCases { s.Run(tc.name, func() { - s.SetupTest() // reset - tc.registerMock() - - rpcTx, err := s.backend.getTransactionByHashPending(common.HexToHash(tc.tx.Hash)) - - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(rpcTx, tc.expRPCTx) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestGetTxByEthHash() { - msgEthereumTx, bz := s.buildEthereumTx() - rpcTransaction, _ := rpc.NewRPCTxFromEthTx(msgEthereumTx.AsTransaction(), common.Hash{}, 0, 0, big.NewInt(1), s.backend.chainID) - - testCases := []struct { - name string - registerMock func() - tx *evm.MsgEthereumTx - expRPCTx *rpc.EthTxJsonRPC - expPass bool - }{ - { - "fail - Indexer disabled can't find transaction", - func() { - s.backend.indexer = nil - client := s.backend.clientCtx.Client.(*mocks.Client) - query := fmt.Sprintf("%s.%s='%s'", evm.TypeMsgEthereumTx, evm.AttributeKeyEthereumTxHash, common.HexToHash(msgEthereumTx.Hash).Hex()) - RegisterTxSearch(client, query, bz) - }, - msgEthereumTx, - rpcTransaction, - false, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - tc.registerMock() - - rpcTx, err := s.backend.GetTxByEthHash(common.HexToHash(tc.tx.Hash)) - - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(rpcTx, tc.expRPCTx) - } else { - s.Require().Error(err) + receipt, err := s.backend.GetTransactionReceipt(tc.txHash) + if !tc.wantTxFound { + s.Require().Nil(receipt) + return } + s.Require().NoError(err) + s.Require().NotNil(receipt) + + // Check fields + // s.Equal(s.fundedAccEthAddr, receipt.From) + // s.Equal(&recipient, receipt.To) + // s.Greater(receipt.GasUsed, uint64(0)) + // s.Equal(receipt.GasUsed, receipt.CumulativeGasUsed) + // s.Equal(tc.txHash, receipt.TxHash) + // s.Nil(receipt.ContractAddress) + // s.Require().Equal(gethcore.ReceiptStatusSuccessful, receipt.Status) }) } } func (s *BackendSuite) TestGetTransactionByBlockHashAndIndex() { - _, bz := s.buildEthereumTx() + blockWithTx, err := s.backend.GetBlockByNumber(transferTxBlockNumber, false) + s.Require().NoError(err) + blockHash := gethcommon.BytesToHash(blockWithTx["hash"].(hexutil.Bytes)) testCases := []struct { - name string - registerMock func() - blockHash common.Hash - expRPCTx *rpc.EthTxJsonRPC - expPass bool + name string + blockHash gethcommon.Hash + txIndex uint + wantTxFound bool }{ { - "pass - block not found", - func() { - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockByHashError(client, common.Hash{}, bz) - }, - common.Hash{}, - nil, - true, + name: "happy: tx found", + blockHash: blockHash, + txIndex: 1, + wantTxFound: true, }, { - "pass - Block results error", - func() { - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlockByHash(client, common.Hash{}, bz) - s.Require().NoError(err) - RegisterBlockResultsError(client, 1) - }, - common.Hash{}, - nil, - true, + name: "sad: block not found", + blockHash: gethcommon.BytesToHash([]byte("0x0")), + txIndex: 1, + wantTxFound: false, }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - tc.registerMock() - - rpcTx, err := s.backend.GetTransactionByBlockHashAndIndex(tc.blockHash, 1) - - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(rpcTx, tc.expRPCTx) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestGetTransactionByBlockAndIndex() { - msgEthTx, bz := s.buildEthereumTx() - - defaultBlock := types.MakeBlock(1, []types.Tx{bz}, nil, nil) - defaultResponseDeliverTx := []*abci.ResponseDeliverTx{ { - Code: 0, - Events: []abci.Event{ - {Type: evm.EventTypeEthereumTx, Attributes: []abci.EventAttribute{ - {Key: "ethereumTxHash", Value: common.HexToHash(msgEthTx.Hash).Hex()}, - {Key: "txIndex", Value: "0"}, - {Key: "amount", Value: "1000"}, - {Key: "txGasUsed", Value: "21000"}, - {Key: "txHash", Value: ""}, - {Key: "recipient", Value: ""}, - }}, - }, - }, - } - - txFromMsg, _ := rpc.NewRPCTxFromMsg( - msgEthTx, - common.BytesToHash(defaultBlock.Hash().Bytes()), - 1, - 0, - big.NewInt(1), - s.backend.chainID, - ) - testCases := []struct { - name string - registerMock func() - block *tmrpctypes.ResultBlock - idx hexutil.Uint - expRPCTx *rpc.EthTxJsonRPC - expPass bool - }{ - { - "pass - block txs index out of bound", - func() { - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlockResults(client, 1) - s.Require().NoError(err) - }, - &tmrpctypes.ResultBlock{Block: types.MakeBlock(1, []types.Tx{bz}, nil, nil)}, - 1, - nil, - true, - }, - { - "pass - Can't fetch base fee", - func() { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlockResults(client, 1) - s.Require().NoError(err) - RegisterBaseFeeError(queryClient) - }, - &tmrpctypes.ResultBlock{Block: defaultBlock}, - 0, - txFromMsg, - true, - }, - { - "pass - Gets Tx by transaction index", - func() { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - client := s.backend.clientCtx.Client.(*mocks.Client) - db := dbm.NewMemDB() - s.backend.indexer = indexer.NewKVIndexer(db, tmlog.NewNopLogger(), s.backend.clientCtx) - txBz := s.signAndEncodeEthTx(msgEthTx) - block := &types.Block{Header: types.Header{Height: 1, ChainID: "test"}, Data: types.Data{Txs: []types.Tx{txBz}}} - err := s.backend.indexer.IndexBlock(block, defaultResponseDeliverTx) - s.Require().NoError(err) - _, err = RegisterBlockResults(client, 1) - s.Require().NoError(err) - RegisterBaseFee(queryClient, math.NewInt(1)) - }, - &tmrpctypes.ResultBlock{Block: defaultBlock}, - 0, - txFromMsg, - true, - }, - { - "pass - returns the Ethereum format transaction by the Ethereum hash", - func() { - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - client := s.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlockResults(client, 1) - s.Require().NoError(err) - RegisterBaseFee(queryClient, math.NewInt(1)) - }, - &tmrpctypes.ResultBlock{Block: defaultBlock}, - 0, - txFromMsg, - true, + name: "sad: tx not found", + blockHash: blockHash, + txIndex: 9999, + wantTxFound: false, }, } for _, tc := range testCases { s.Run(tc.name, func() { - s.SetupTest() // reset - tc.registerMock() - - rpcTx, err := s.backend.GetTransactionByBlockAndIndex(tc.block, tc.idx) - - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(rpcTx, tc.expRPCTx) - } else { - s.Require().Error(err) + tx, err := s.backend.GetTransactionByBlockHashAndIndex(tc.blockHash, hexutil.Uint(tc.txIndex)) + if !tc.wantTxFound { + s.Require().Nil(tx) + return } + s.Require().NoError(err) + s.Require().NotNil(tx) + AssertTxResults(s, tx, transferTxHash) }) } } func (s *BackendSuite) TestGetTransactionByBlockNumberAndIndex() { - msgEthTx, bz := s.buildEthereumTx() - defaultBlock := types.MakeBlock(1, []types.Tx{bz}, nil, nil) - txFromMsg, _ := rpc.NewRPCTxFromMsg( - msgEthTx, - common.BytesToHash(defaultBlock.Hash().Bytes()), - 1, - 0, - big.NewInt(1), - s.backend.chainID, - ) testCases := []struct { - name string - registerMock func() - blockNum rpc.BlockNumber - idx hexutil.Uint - expRPCTx *rpc.EthTxJsonRPC - expPass bool + name string + blockNumber rpc.BlockNumber + txIndex uint + wantTxFound bool }{ { - "fail - block not found return nil", - func() { - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockError(client, 1) - }, - 0, - 0, - nil, - true, + name: "happy: tx found", + blockNumber: transferTxBlockNumber, + txIndex: 1, + wantTxFound: true, }, { - "pass - returns the transaction identified by block number and index", - func() { - client := s.backend.clientCtx.Client.(*mocks.Client) - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - _, err := RegisterBlock(client, 1, bz) - s.Require().NoError(err) - _, err = RegisterBlockResults(client, 1) - s.Require().NoError(err) - RegisterBaseFee(queryClient, math.NewInt(1)) - }, - 0, - 0, - txFromMsg, - true, + name: "sad: block not found", + blockNumber: rpc.NewBlockNumber(big.NewInt(9999999)), + txIndex: 1, + wantTxFound: false, }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - tc.registerMock() - - rpcTx, err := s.backend.GetTransactionByBlockNumberAndIndex(tc.blockNum, tc.idx) - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(rpcTx, tc.expRPCTx) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestGetTransactionByTxIndex() { - _, bz := s.buildEthereumTx() - - testCases := []struct { - name string - registerMock func() - height int64 - index uint - expTxResult *eth.TxResult - expPass bool - }{ { - "fail - Ethereum tx with query not found", - func() { - client := s.backend.clientCtx.Client.(*mocks.Client) - s.backend.indexer = nil - RegisterTxSearch(client, "tx.height=0 AND ethereum_tx.txIndex=0", bz) - }, - 0, - 0, - ð.TxResult{}, - false, + name: "sad: tx not found", + blockNumber: transferTxBlockNumber, + txIndex: 9999, + wantTxFound: false, }, } for _, tc := range testCases { s.Run(tc.name, func() { - s.SetupTest() // reset - tc.registerMock() - - txResults, err := s.backend.GetTxByTxIndex(tc.height, tc.index) - - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(txResults, tc.expTxResult) - } else { - s.Require().Error(err) - } - }) - } -} - -func (s *BackendSuite) TestQueryTendermintTxIndexer() { - testCases := []struct { - name string - registerMock func() - txGetter func(*rpc.ParsedTxs) *rpc.ParsedTx - query string - expTxResult *eth.TxResult - expPass bool - }{ - { - "fail - Ethereum tx with query not found", - func() { - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterTxSearchEmpty(client, "") - }, - func(txs *rpc.ParsedTxs) *rpc.ParsedTx { - return &rpc.ParsedTx{} - }, - "", - ð.TxResult{}, - false, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - tc.registerMock() - - txResults, err := s.backend.queryTendermintTxIndexer(tc.query, tc.txGetter) - - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(txResults, tc.expTxResult) - } else { - s.Require().Error(err) + tx, err := s.backend.GetTransactionByBlockNumberAndIndex(tc.blockNumber, hexutil.Uint(tc.txIndex)) + if !tc.wantTxFound { + s.Require().Nil(tx) + return } - }) - } -} - -func (s *BackendSuite) TestGetTransactionReceipt() { - msgEthereumTx, _ := s.buildEthereumTx() - txHash := msgEthereumTx.AsTransaction().Hash() - - txBz := s.signAndEncodeEthTx(msgEthereumTx) - - testCases := []struct { - name string - registerMock func() - tx *evm.MsgEthereumTx - block *types.Block - blockResult []*abci.ResponseDeliverTx - expTxReceipt map[string]interface{} - expPass bool - }{ - { - "fail - Receipts do not match", - func() { - var header metadata.MD - queryClient := s.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) - client := s.backend.clientCtx.Client.(*mocks.Client) - RegisterParams(queryClient, &header, 1) - RegisterParamsWithoutHeader(queryClient, 1) - _, err := RegisterBlock(client, 1, txBz) - s.Require().NoError(err) - _, err = RegisterBlockResults(client, 1) - s.Require().NoError(err) - }, - msgEthereumTx, - &types.Block{Header: types.Header{Height: 1}, Data: types.Data{Txs: []types.Tx{txBz}}}, - []*abci.ResponseDeliverTx{ - { - Code: 0, - Events: []abci.Event{ - {Type: evm.EventTypeEthereumTx, Attributes: []abci.EventAttribute{ - {Key: "ethereumTxHash", Value: txHash.Hex()}, - {Key: "txIndex", Value: "0"}, - {Key: "amount", Value: "1000"}, - {Key: "txGasUsed", Value: "21000"}, - {Key: "txHash", Value: ""}, - {Key: "recipient", Value: "0x775b87ef5D82ca211811C1a02CE0fE0CA3a455d7"}, - }}, - }, - }, - }, - map[string]interface{}(nil), - false, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - tc.registerMock() - - db := dbm.NewMemDB() - s.backend.indexer = indexer.NewKVIndexer(db, tmlog.NewNopLogger(), s.backend.clientCtx) - err := s.backend.indexer.IndexBlock(tc.block, tc.blockResult) s.Require().NoError(err) - - txReceipt, err := s.backend.GetTransactionReceipt(common.HexToHash(tc.tx.Hash)) - if tc.expPass { - s.Require().NoError(err) - s.Require().Equal(txReceipt, tc.expTxReceipt) - } else { - s.Require().NotEqual(txReceipt, tc.expTxReceipt) - } + s.Require().NotNil(tx) + AssertTxResults(s, tx, transferTxHash) }) } } -func (s *BackendSuite) TestGetGasUsed() { - origin := s.backend.cfg.JSONRPC.FixRevertGasRefundHeight - testCases := []struct { - name string - fixRevertGasRefundHeight int64 - txResult *eth.TxResult - price *big.Int - gas uint64 - exp uint64 - }{ - { - "success txResult", - 1, - ð.TxResult{ - Height: 1, - Failed: false, - GasUsed: 53026, - }, - new(big.Int).SetUint64(0), - 0, - 53026, - }, - { - "fail txResult before cap", - 2, - ð.TxResult{ - Height: 1, - Failed: true, - GasUsed: 53026, - }, - new(big.Int).SetUint64(200000), - 5000000000000, - 1000000000000000000, - }, - { - "fail txResult after cap", - 2, - ð.TxResult{ - Height: 3, - Failed: true, - GasUsed: 53026, - }, - new(big.Int).SetUint64(200000), - 5000000000000, - 53026, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.backend.cfg.JSONRPC.FixRevertGasRefundHeight = tc.fixRevertGasRefundHeight - s.Require().Equal(tc.exp, s.backend.GetGasUsed(tc.txResult, tc.price, tc.gas)) - s.backend.cfg.JSONRPC.FixRevertGasRefundHeight = origin - }) - } +func AssertTxResults(s *BackendSuite, tx *rpc.EthTxJsonRPC, expectedTxHash gethcommon.Hash) { + s.Require().Equal(s.fundedAccEthAddr, tx.From) + s.Require().Equal(&recipient, tx.To) + s.Require().Greater(tx.Gas, uint64(0)) + s.Require().Equal(expectedTxHash, tx.Hash) + s.Require().Equal(uint64(1), uint64(*tx.TransactionIndex)) } diff --git a/eth/rpc/backend/utils.go b/eth/rpc/backend/utils.go index e436297bd..499bf107e 100644 --- a/eth/rpc/backend/utils.go +++ b/eth/rpc/backend/utils.go @@ -47,7 +47,6 @@ func (s sortGasAndReward) Less(i, j int) bool { // getAccountNonce returns the account nonce for the given account address. // If the pending value is true, it will iterate over the mempool (pending) // txs in order to compute and return the pending tx sequence. -// Todo: include the ability to specify a blockNumber func (b *Backend) getAccountNonce(accAddr common.Address, pending bool, height int64, logger log.Logger) (uint64, error) { queryClient := authtypes.NewQueryClient(b.clientCtx) adr := sdk.AccAddress(accAddr.Bytes()).String() @@ -72,8 +71,8 @@ func (b *Backend) getAccountNonce(accAddr common.Address, pending bool, height i return nonce, nil } - // the account retriever doesn't include the uncommitted transactions on the nonce so we need to - // to manually add them. + // the account retriever doesn't include the uncommitted transactions on the + // nonce so we need to to manually add them. pendingTxs, err := b.PendingTransactions() if err != nil { logger.Error("failed to fetch pending transactions", "error", err.Error()) diff --git a/eth/rpc/backend/utils_test.go b/eth/rpc/backend/utils_test.go index 4c7c14a74..f0dcea536 100644 --- a/eth/rpc/backend/utils_test.go +++ b/eth/rpc/backend/utils_test.go @@ -1,52 +1 @@ -package backend - -import ( - "fmt" - - "github.com/cometbft/cometbft/proto/tendermint/crypto" -) - -func mookProofs(num int, withData bool) *crypto.ProofOps { - var proofOps *crypto.ProofOps - if num > 0 { - proofOps = new(crypto.ProofOps) - for i := 0; i < num; i++ { - proof := crypto.ProofOp{} - if withData { - proof.Data = []byte("\n\031\n\003KEY\022\005VALUE\032\013\010\001\030\001 \001*\003\000\002\002") - } - proofOps.Ops = append(proofOps.Ops, proof) - } - } - return proofOps -} - -func (s *BackendSuite) TestGetHexProofs() { - defaultRes := []string{""} - testCases := []struct { - name string - proof *crypto.ProofOps - exp []string - }{ - { - "no proof provided", - mookProofs(0, false), - defaultRes, - }, - { - "no proof data provided", - mookProofs(1, false), - defaultRes, - }, - { - "valid proof provided", - mookProofs(1, true), - []string{"0x0a190a034b4559120556414c55451a0b0801180120012a03000202"}, - }, - } - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.name), func() { - s.Require().Equal(tc.exp, GetHexProofs(tc.proof)) - }) - } -} +package backend_test diff --git a/eth/rpc/rpcapi/eth_api_test.go b/eth/rpc/rpcapi/eth_api_test.go index 74f5a8af5..54e992462 100644 --- a/eth/rpc/rpcapi/eth_api_test.go +++ b/eth/rpc/rpcapi/eth_api_test.go @@ -86,7 +86,10 @@ func (s *NodeSuite) SetupSuite() { s.fundedAccNibiAddr = eth.EthAddrToNibiruAddr(s.fundedAccEthAddr) funds := sdk.NewCoins(sdk.NewInt64Coin(eth.EthBaseDenom, 100_000_000)) // 10 NIBI - s.NoError(testnetwork.FillWalletFromValidator(s.fundedAccNibiAddr, funds, s.val, eth.EthBaseDenom)) + _, err = testnetwork.FillWalletFromValidator( + s.fundedAccNibiAddr, funds, s.val, eth.EthBaseDenom, + ) + s.Require().NoError(err) s.NoError(s.network.WaitForNextBlock()) } @@ -219,9 +222,10 @@ func (s *NodeSuite) Test_SimpleTransferTransaction() { s.T().Log("make sure the sender has enough funds") weiToSend := evm.NativeToWei(big.NewInt(1)) // 1 unibi funds := sdk.NewCoins(sdk.NewInt64Coin(eth.EthBaseDenom, 5_000_000)) // 5 * 10^6 unibi - s.Require().NoError(testnetwork.FillWalletFromValidator( - s.fundedAccNibiAddr, funds, s.network.Validators[0], eth.EthBaseDenom), + _, err = testnetwork.FillWalletFromValidator( + s.fundedAccNibiAddr, funds, s.network.Validators[0], eth.EthBaseDenom, ) + s.Require().NoError(err) s.NoError(s.network.WaitForNextBlock()) senderBalanceBeforeWei, err := s.ethClient.BalanceAt( @@ -317,9 +321,10 @@ func (s *NodeSuite) Test_SmartContract() { s.T().Log("Make sure the account has funds.") funds := sdk.NewCoins(sdk.NewInt64Coin(eth.EthBaseDenom, 1_000_000_000)) - s.Require().NoError(testnetwork.FillWalletFromValidator( - s.fundedAccNibiAddr, funds, s.network.Validators[0], eth.EthBaseDenom), + _, err = testnetwork.FillWalletFromValidator( + s.fundedAccNibiAddr, funds, s.network.Validators[0], eth.EthBaseDenom, ) + s.Require().NoError(err) s.NoError(s.network.WaitForNextBlock()) grpcUrl := s.network.Validators[0].AppConfig.GRPC.Address diff --git a/x/common/testutil/testnetwork/start_node.go b/x/common/testutil/testnetwork/start_node.go index 6753ffdc5..a12317c10 100644 --- a/x/common/testutil/testnetwork/start_node.go +++ b/x/common/testutil/testnetwork/start_node.go @@ -160,7 +160,8 @@ func startNodeAndServers(cfg Config, val *Validator) error { val.Ctx.Logger, val.ClientCtx, val.AppConfig.JSONRPC.AllowUnprotectedTxs, - val.EthTxIndexer, + // TODO: reenable indexer when we have indexer service (process which does IndexBlock) implemented + nil, //val.EthTxIndexer ) val.Logger.Log("Expose typed methods for each namespace") diff --git a/x/common/testutil/testnetwork/tx_test.go b/x/common/testutil/testnetwork/tx_test.go index c3fdf9a46..94a9db6bd 100644 --- a/x/common/testutil/testnetwork/tx_test.go +++ b/x/common/testutil/testnetwork/tx_test.go @@ -69,7 +69,8 @@ func (s *TestSuite) TestFillWalletFromValidator() { sdk.NewInt64Coin(denoms.NIBI, 420), ) feeDenom := denoms.NIBI - s.NoError(testnetwork.FillWalletFromValidator( + _, err := testnetwork.FillWalletFromValidator( toAddr, funds, val, feeDenom, - )) + ) + s.Require().NoError(err) } diff --git a/x/common/testutil/testnetwork/util.go b/x/common/testutil/testnetwork/util.go index 4ba1e082d..6ecb36bba 100644 --- a/x/common/testutil/testnetwork/util.go +++ b/x/common/testutil/testnetwork/util.go @@ -126,7 +126,7 @@ func writeFile(name string, dir string, contents []byte) error { // validator. func FillWalletFromValidator( addr sdk.AccAddress, balance sdk.Coins, val *Validator, feesDenom string, -) error { +) (*sdk.TxResponse, error) { rawResp, err := clitestutil.MsgSendExec( val.ClientCtx, val.Address, @@ -137,19 +137,19 @@ func FillWalletFromValidator( fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewInt64Coin(feesDenom, 10000)), ) if err != nil { - return err + return nil, err } return txOK(val.ClientCtx.Codec, rawResp.Bytes()) } -func txOK(jsonCodec sdkcodec.JSONCodec, txBytes []byte) error { +func txOK(jsonCodec sdkcodec.JSONCodec, txBytes []byte) (*sdk.TxResponse, error) { resp := new(sdk.TxResponse) jsonCodec.MustUnmarshalJSON(txBytes, resp) if resp.Code != tmtypes.CodeTypeOK { - return fmt.Errorf("%s", resp.RawLog) + return resp, fmt.Errorf("%s", resp.RawLog) } - return nil + return resp, nil } /* diff --git a/x/common/testutil/testnetwork/validator_node.go b/x/common/testutil/testnetwork/validator_node.go index bbdb53395..131d74aa2 100644 --- a/x/common/testutil/testnetwork/validator_node.go +++ b/x/common/testutil/testnetwork/validator_node.go @@ -20,6 +20,7 @@ import ( "github.com/cometbft/cometbft/node" tmclient "github.com/cometbft/cometbft/rpc/client" + cmtcore "github.com/cometbft/cometbft/rpc/core/types" "github.com/cosmos/cosmos-sdk/client" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/server" @@ -265,3 +266,15 @@ func (val *Validator) AssertERC20Balance( balance := new(big.Int).SetBytes(recipientBalanceBeforeBytes) s.Equal(expectedBalance.String(), balance.String()) } + +func (node *Validator) BlockByEthTx( + ethTxHash gethcommon.Hash, +) (*cmtcore.ResultBlockResults, error) { + blankCtx := context.Background() + txReceipt, err := node.JSONRPCClient.TransactionReceipt(blankCtx, ethTxHash) + if err != nil { + return nil, err + } + blockHeightOfTx := txReceipt.BlockNumber.Int64() + return node.RPCClient.BlockResults(blankCtx, &blockHeightOfTx) +} diff --git a/x/sudo/cli/cli_test.go b/x/sudo/cli/cli_test.go index 2150f1c19..96baa5064 100644 --- a/x/sudo/cli/cli_test.go +++ b/x/sudo/cli/cli_test.go @@ -130,9 +130,11 @@ func (s *TestSuite) FundRoot(root Account) { sdk.NewInt64Coin(denoms.NIBI, 420*common.TO_MICRO), ) feeDenom := denoms.NIBI - s.NoError(testnetwork.FillWalletFromValidator( + + _, err := testnetwork.FillWalletFromValidator( root.addr, funds, val, feeDenom, - )) + ) + s.NoError(err) } func (s *TestSuite) AddRootToKeyring(root Account) {