forked from cerc-io/laconicd-deprecated
9e5f4aaa73
* test: add preliminary unit tests and additional mocks for chain_info, account_info and filters * tests: added additional mocked client calls * tests: bumped coverage of call_tx to 56% and chain_info to 77% * tests: bumped call_tx coverage to 70.2% and added additional mock client calls * tests: tx_info preliminary tests added for debugging. * tests: added test coverage for sign_tx and additional mocks * tests: tx_info test coverage bumped to 60.3% * test: coverage for tracing_tests now at 72% * tests: added fee makert query client mocks and bumped chain_info to 87.6% coverage. * tests: failing Cosmos auth module account query. * tests: added FeeMarket Params mock to call_tx_test * cleanup some unused code * tests: added helper function to test suite for signing a Tx and bumped coverage of tx_info to 71.2% * test: commented GetAccount error case and bumped chain_info to 90.3% coverage * test: cleanup of tests in node_info, sign_tx and account_info * Clean up print Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Apply suggestions from code review * fix import issues Co-authored-by: Vladislav Varadinov <vlad@evmos.org> Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Freddy Caceres <facs95@gmail.com>
485 lines
12 KiB
Go
485 lines
12 KiB
Go
package backend
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
"github.com/ethereum/go-ethereum/common"
|
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
"github.com/ethereum/go-ethereum/rlp"
|
|
"github.com/evmos/ethermint/rpc/backend/mocks"
|
|
rpctypes "github.com/evmos/ethermint/rpc/types"
|
|
"github.com/evmos/ethermint/tests"
|
|
evmtypes "github.com/evmos/ethermint/x/evm/types"
|
|
"google.golang.org/grpc/metadata"
|
|
"math/big"
|
|
)
|
|
|
|
func (suite *BackendTestSuite) TestResend() {
|
|
txNonce := (hexutil.Uint64)(1)
|
|
baseFee := sdk.NewInt(1)
|
|
gasPrice := new(hexutil.Big)
|
|
toAddr := tests.GenerateAddress()
|
|
callArgs := evmtypes.TransactionArgs{
|
|
From: nil,
|
|
To: &toAddr,
|
|
Gas: nil,
|
|
GasPrice: nil,
|
|
MaxFeePerGas: gasPrice,
|
|
MaxPriorityFeePerGas: gasPrice,
|
|
Value: gasPrice,
|
|
Nonce: nil,
|
|
Input: nil,
|
|
Data: nil,
|
|
AccessList: nil,
|
|
}
|
|
|
|
testCases := []struct {
|
|
name string
|
|
registerMock func()
|
|
args evmtypes.TransactionArgs
|
|
gasPrice *hexutil.Big
|
|
gasLimit *hexutil.Uint64
|
|
expHash common.Hash
|
|
expPass bool
|
|
}{
|
|
{
|
|
"fail - Missing transaction nonce ",
|
|
func() {},
|
|
evmtypes.TransactionArgs{
|
|
Nonce: nil,
|
|
},
|
|
nil,
|
|
nil,
|
|
common.Hash{},
|
|
false,
|
|
},
|
|
{
|
|
"pass - Can't set Tx defaults BaseFee disabled",
|
|
func() {
|
|
var header metadata.MD
|
|
client := suite.backend.clientCtx.Client.(*mocks.Client)
|
|
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
|
|
RegisterParams(queryClient, &header, 1)
|
|
RegisterBlock(client, 1, nil)
|
|
RegisterBlockResults(client, 1)
|
|
RegisterBaseFeeDisabled(queryClient)
|
|
},
|
|
evmtypes.TransactionArgs{
|
|
Nonce: &txNonce,
|
|
},
|
|
nil,
|
|
nil,
|
|
common.Hash{},
|
|
true,
|
|
},
|
|
{
|
|
"pass - Can't set Tx defaults ",
|
|
func() {
|
|
var header metadata.MD
|
|
client := suite.backend.clientCtx.Client.(*mocks.Client)
|
|
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
|
|
feeMarketClient := suite.backend.queryClient.FeeMarket.(*mocks.FeeMarketQueryClient)
|
|
RegisterParams(queryClient, &header, 1)
|
|
RegisterFeeMarketParams(feeMarketClient, 1)
|
|
RegisterBlock(client, 1, nil)
|
|
RegisterBlockResults(client, 1)
|
|
RegisterBaseFee(queryClient, baseFee)
|
|
},
|
|
evmtypes.TransactionArgs{
|
|
Nonce: &txNonce,
|
|
},
|
|
nil,
|
|
nil,
|
|
common.Hash{},
|
|
true,
|
|
},
|
|
{
|
|
"pass - MaxFeePerGas is nil",
|
|
func() {
|
|
var header metadata.MD
|
|
client := suite.backend.clientCtx.Client.(*mocks.Client)
|
|
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
|
|
RegisterParams(queryClient, &header, 1)
|
|
RegisterBlock(client, 1, nil)
|
|
RegisterBlockResults(client, 1)
|
|
RegisterBaseFeeDisabled(queryClient)
|
|
},
|
|
evmtypes.TransactionArgs{
|
|
Nonce: &txNonce,
|
|
MaxPriorityFeePerGas: nil,
|
|
GasPrice: nil,
|
|
MaxFeePerGas: nil,
|
|
},
|
|
nil,
|
|
nil,
|
|
common.Hash{},
|
|
true,
|
|
},
|
|
{
|
|
"fail - GasPrice and (MaxFeePerGas or MaxPriorityPerGas specified",
|
|
func() {},
|
|
evmtypes.TransactionArgs{
|
|
Nonce: &txNonce,
|
|
MaxPriorityFeePerGas: nil,
|
|
GasPrice: gasPrice,
|
|
MaxFeePerGas: gasPrice,
|
|
},
|
|
nil,
|
|
nil,
|
|
common.Hash{},
|
|
false,
|
|
},
|
|
{
|
|
"fail - Block error",
|
|
func() {
|
|
var header metadata.MD
|
|
client := suite.backend.clientCtx.Client.(*mocks.Client)
|
|
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
|
|
RegisterParams(queryClient, &header, 1)
|
|
RegisterBlockError(client, 1)
|
|
},
|
|
evmtypes.TransactionArgs{
|
|
Nonce: &txNonce,
|
|
},
|
|
nil,
|
|
nil,
|
|
common.Hash{},
|
|
false,
|
|
},
|
|
{
|
|
"pass - MaxFeePerGas is nil",
|
|
func() {
|
|
var header metadata.MD
|
|
client := suite.backend.clientCtx.Client.(*mocks.Client)
|
|
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
|
|
RegisterParams(queryClient, &header, 1)
|
|
RegisterBlock(client, 1, nil)
|
|
RegisterBlockResults(client, 1)
|
|
RegisterBaseFee(queryClient, baseFee)
|
|
},
|
|
evmtypes.TransactionArgs{
|
|
Nonce: &txNonce,
|
|
GasPrice: nil,
|
|
MaxPriorityFeePerGas: gasPrice,
|
|
MaxFeePerGas: gasPrice,
|
|
},
|
|
nil,
|
|
nil,
|
|
common.Hash{},
|
|
true,
|
|
},
|
|
{
|
|
"pass - Chain Id is nil",
|
|
func() {
|
|
var header metadata.MD
|
|
client := suite.backend.clientCtx.Client.(*mocks.Client)
|
|
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
|
|
RegisterParams(queryClient, &header, 1)
|
|
RegisterBlock(client, 1, nil)
|
|
RegisterBlockResults(client, 1)
|
|
RegisterBaseFee(queryClient, baseFee)
|
|
},
|
|
evmtypes.TransactionArgs{
|
|
Nonce: &txNonce,
|
|
MaxPriorityFeePerGas: gasPrice,
|
|
ChainID: nil,
|
|
},
|
|
nil,
|
|
nil,
|
|
common.Hash{},
|
|
true,
|
|
},
|
|
{
|
|
"fail - Pending transactions error",
|
|
func() {
|
|
var header metadata.MD
|
|
client := suite.backend.clientCtx.Client.(*mocks.Client)
|
|
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
|
|
RegisterBlock(client, 1, nil)
|
|
RegisterBlockResults(client, 1)
|
|
RegisterBaseFee(queryClient, baseFee)
|
|
RegisterEstimateGas(queryClient, callArgs)
|
|
RegisterParams(queryClient, &header, 1)
|
|
RegisterParamsWithoutHeader(queryClient, 1)
|
|
RegisterUnconfirmedTxsError(client, nil)
|
|
},
|
|
evmtypes.TransactionArgs{
|
|
Nonce: &txNonce,
|
|
To: &toAddr,
|
|
MaxFeePerGas: gasPrice,
|
|
MaxPriorityFeePerGas: gasPrice,
|
|
Gas: nil,
|
|
},
|
|
gasPrice,
|
|
nil,
|
|
common.Hash{},
|
|
false,
|
|
},
|
|
{
|
|
"fail - Not Ethereum txs",
|
|
func() {
|
|
var header metadata.MD
|
|
client := suite.backend.clientCtx.Client.(*mocks.Client)
|
|
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
|
|
RegisterBlock(client, 1, nil)
|
|
RegisterBlockResults(client, 1)
|
|
RegisterBaseFee(queryClient, baseFee)
|
|
RegisterEstimateGas(queryClient, callArgs)
|
|
RegisterParams(queryClient, &header, 1)
|
|
RegisterParamsWithoutHeader(queryClient, 1)
|
|
RegisterUnconfirmedTxsEmpty(client, nil)
|
|
},
|
|
evmtypes.TransactionArgs{
|
|
Nonce: &txNonce,
|
|
To: &toAddr,
|
|
MaxFeePerGas: gasPrice,
|
|
MaxPriorityFeePerGas: gasPrice,
|
|
Gas: nil,
|
|
},
|
|
gasPrice,
|
|
nil,
|
|
common.Hash{},
|
|
false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
suite.Run(fmt.Sprintf("case %s", tc.name), func() {
|
|
suite.SetupTest() // reset test and queries
|
|
tc.registerMock()
|
|
|
|
hash, err := suite.backend.Resend(tc.args, tc.gasPrice, tc.gasLimit)
|
|
|
|
if tc.expPass {
|
|
suite.Require().Equal(tc.expHash, hash)
|
|
} else {
|
|
suite.Require().Error(err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *BackendTestSuite) TestSendRawTransaction() {
|
|
ethTx, bz := suite.buildEthereumTx()
|
|
rlpEncodedBz, _ := rlp.EncodeToBytes(ethTx.AsTransaction())
|
|
cosmosTx, _ := ethTx.BuildTx(suite.backend.clientCtx.TxConfig.NewTxBuilder(), "aphoton")
|
|
txBytes, _ := suite.backend.clientCtx.TxConfig.TxEncoder()(cosmosTx)
|
|
|
|
testCases := []struct {
|
|
name string
|
|
registerMock func()
|
|
rawTx []byte
|
|
expHash common.Hash
|
|
expPass bool
|
|
}{
|
|
{
|
|
"fail - empty bytes",
|
|
func() {},
|
|
[]byte{},
|
|
common.Hash{},
|
|
false,
|
|
},
|
|
{
|
|
"fail - no RLP encoded bytes",
|
|
func() {},
|
|
bz,
|
|
common.Hash{},
|
|
false,
|
|
},
|
|
{
|
|
"fail - unprotected transactions",
|
|
func() {
|
|
suite.backend.allowUnprotectedTxs = false
|
|
},
|
|
rlpEncodedBz,
|
|
common.Hash{},
|
|
false,
|
|
},
|
|
{
|
|
"fail - failed to get evm params",
|
|
func() {
|
|
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
|
|
suite.backend.allowUnprotectedTxs = true
|
|
RegisterParamsWithoutHeaderError(queryClient, 1)
|
|
},
|
|
rlpEncodedBz,
|
|
common.Hash{},
|
|
false,
|
|
},
|
|
{
|
|
"fail - failed to broadcast transaction",
|
|
func() {
|
|
client := suite.backend.clientCtx.Client.(*mocks.Client)
|
|
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
|
|
suite.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 := suite.backend.clientCtx.Client.(*mocks.Client)
|
|
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
|
|
suite.backend.allowUnprotectedTxs = true
|
|
RegisterParamsWithoutHeader(queryClient, 1)
|
|
RegisterBroadcastTx(client, txBytes)
|
|
},
|
|
rlpEncodedBz,
|
|
common.HexToHash(ethTx.Hash),
|
|
true,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
suite.Run(fmt.Sprintf("case %s", tc.name), func() {
|
|
suite.SetupTest() // reset test and queries
|
|
tc.registerMock()
|
|
|
|
hash, err := suite.backend.SendRawTransaction(tc.rawTx)
|
|
|
|
if tc.expPass {
|
|
suite.Require().Equal(tc.expHash, hash)
|
|
} else {
|
|
suite.Require().Error(err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *BackendTestSuite) TestDoCall() {
|
|
_, bz := suite.buildEthereumTx()
|
|
gasPrice := (*hexutil.Big)(big.NewInt(1))
|
|
toAddr := tests.GenerateAddress()
|
|
callArgs := evmtypes.TransactionArgs{
|
|
From: nil,
|
|
To: &toAddr,
|
|
Gas: nil,
|
|
GasPrice: nil,
|
|
MaxFeePerGas: gasPrice,
|
|
MaxPriorityFeePerGas: gasPrice,
|
|
Value: gasPrice,
|
|
Input: nil,
|
|
Data: nil,
|
|
AccessList: nil,
|
|
}
|
|
argsBz, err := json.Marshal(callArgs)
|
|
suite.Require().NoError(err)
|
|
|
|
testCases := []struct {
|
|
name string
|
|
registerMock func()
|
|
blockNum rpctypes.BlockNumber
|
|
callArgs evmtypes.TransactionArgs
|
|
expEthTx *evmtypes.MsgEthereumTxResponse
|
|
expPass bool
|
|
}{
|
|
{
|
|
"fail - Invalid request",
|
|
func() {
|
|
client := suite.backend.clientCtx.Client.(*mocks.Client)
|
|
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
|
|
RegisterBlock(client, 1, bz)
|
|
RegisterEthCallError(queryClient, &evmtypes.EthCallRequest{Args: argsBz})
|
|
},
|
|
|
|
rpctypes.BlockNumber(1),
|
|
callArgs,
|
|
&evmtypes.MsgEthereumTxResponse{},
|
|
false,
|
|
},
|
|
{
|
|
"pass - Returned transaction response",
|
|
func() {
|
|
client := suite.backend.clientCtx.Client.(*mocks.Client)
|
|
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
|
|
RegisterBlock(client, 1, bz)
|
|
RegisterEthCall(queryClient, &evmtypes.EthCallRequest{Args: argsBz})
|
|
},
|
|
|
|
rpctypes.BlockNumber(1),
|
|
callArgs,
|
|
&evmtypes.MsgEthereumTxResponse{},
|
|
true,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
suite.Run(fmt.Sprintf("case %s", tc.name), func() {
|
|
suite.SetupTest() // reset test and queries
|
|
tc.registerMock()
|
|
|
|
msgEthTx, err := suite.backend.DoCall(tc.callArgs, tc.blockNum)
|
|
|
|
if tc.expPass {
|
|
suite.Require().Equal(tc.expEthTx, msgEthTx)
|
|
} else {
|
|
suite.Require().Error(err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *BackendTestSuite) 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 := suite.backend.clientCtx.Client.(*mocks.Client)
|
|
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
|
|
feeMarketClient := suite.backend.queryClient.FeeMarket.(*mocks.FeeMarketQueryClient)
|
|
RegisterFeeMarketParams(feeMarketClient, 1)
|
|
RegisterParams(queryClient, &header, 1)
|
|
RegisterBlock(client, 1, nil)
|
|
RegisterBlockResults(client, 1)
|
|
RegisterBaseFee(queryClient, sdk.NewInt(1))
|
|
},
|
|
defaultGasPrice,
|
|
true,
|
|
},
|
|
{
|
|
"fail - can't get gasFee, FeeMarketParams error",
|
|
func() {
|
|
var header metadata.MD
|
|
client := suite.backend.clientCtx.Client.(*mocks.Client)
|
|
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
|
|
feeMarketClient := suite.backend.queryClient.FeeMarket.(*mocks.FeeMarketQueryClient)
|
|
RegisterFeeMarketParamsError(feeMarketClient, 1)
|
|
RegisterParams(queryClient, &header, 1)
|
|
RegisterBlock(client, 1, nil)
|
|
RegisterBlockResults(client, 1)
|
|
RegisterBaseFee(queryClient, sdk.NewInt(1))
|
|
},
|
|
defaultGasPrice,
|
|
false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
suite.Run(fmt.Sprintf("case %s", tc.name), func() {
|
|
suite.SetupTest() // reset test and queries
|
|
tc.registerMock()
|
|
|
|
gasPrice, err := suite.backend.GasPrice()
|
|
if tc.expPass {
|
|
suite.Require().Equal(tc.expGas, gasPrice)
|
|
} else {
|
|
suite.Require().Error(err)
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|