github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/evm/handler_test.go (about)

     1  package evm_test
     2  
     3  import (
     4  	"crypto/ecdsa"
     5  	"fmt"
     6  	"math/big"
     7  	"strings"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/ethereum/go-ethereum/common"
    12  	ethcmn "github.com/ethereum/go-ethereum/common"
    13  	"github.com/ethereum/go-ethereum/common/hexutil"
    14  	ethcrypto "github.com/ethereum/go-ethereum/crypto"
    15  	"github.com/fibonacci-chain/fbc/app"
    16  	"github.com/fibonacci-chain/fbc/app/crypto/ethsecp256k1"
    17  	ethermint "github.com/fibonacci-chain/fbc/app/types"
    18  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
    19  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    20  	auth "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/types"
    21  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/supply"
    22  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    23  	"github.com/fibonacci-chain/fbc/x/evm"
    24  	"github.com/fibonacci-chain/fbc/x/evm/keeper"
    25  	"github.com/fibonacci-chain/fbc/x/evm/types"
    26  	govtypes "github.com/fibonacci-chain/fbc/x/gov/types"
    27  	"github.com/status-im/keycard-go/hexutils"
    28  	"github.com/stretchr/testify/suite"
    29  )
    30  
    31  // erc20 contract with params:
    32  //
    33  //	initial_supply:1000000000,    token_name:btc,    token_symbol:btc
    34  const hexPayloadContractDeployment = "0x60806040526012600260006101000a81548160ff021916908360ff1602179055503480156200002d57600080fd5b506040516200129738038062001297833981018060405281019080805190602001909291908051820192919060200180518201929190505050600260009054906101000a900460ff1660ff16600a0a8302600381905550600354600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160009080519060200190620000e292919062000105565b508060019080519060200190620000fb92919062000105565b50505050620001b4565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200014857805160ff191683800117855562000179565b8280016001018555821562000179579182015b82811115620001785782518255916020019190600101906200015b565b5b5090506200018891906200018c565b5090565b620001b191905b80821115620001ad57600081600090555060010162000193565b5090565b90565b6110d380620001c46000396000f3006080604052600436106100ba576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100bf578063095ea7b31461014f57806318160ddd146101b457806323b872dd146101df578063313ce5671461026457806342966c681461029557806370a08231146102da57806379cc67901461033157806395d89b4114610396578063a9059cbb14610426578063cae9ca5114610473578063dd62ed3e1461051e575b600080fd5b3480156100cb57600080fd5b506100d4610595565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101145780820151818401526020810190506100f9565b50505050905090810190601f1680156101415780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015b57600080fd5b5061019a600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610633565b604051808215151515815260200191505060405180910390f35b3480156101c057600080fd5b506101c96106c0565b6040518082815260200191505060405180910390f35b3480156101eb57600080fd5b5061024a600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506106c6565b604051808215151515815260200191505060405180910390f35b34801561027057600080fd5b506102796107f3565b604051808260ff1660ff16815260200191505060405180910390f35b3480156102a157600080fd5b506102c060048036038101908080359060200190929190505050610806565b604051808215151515815260200191505060405180910390f35b3480156102e657600080fd5b5061031b600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061090a565b6040518082815260200191505060405180910390f35b34801561033d57600080fd5b5061037c600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610922565b604051808215151515815260200191505060405180910390f35b3480156103a257600080fd5b506103ab610b3c565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103eb5780820151818401526020810190506103d0565b50505050905090810190601f1680156104185780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561043257600080fd5b50610471600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610bda565b005b34801561047f57600080fd5b50610504600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610be9565b604051808215151515815260200191505060405180910390f35b34801561052a57600080fd5b5061057f600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610d6c565b6040518082815260200191505060405180910390f35b60008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561062b5780601f106106005761010080835404028352916020019161062b565b820191906000526020600020905b81548152906001019060200180831161060e57829003601f168201915b505050505081565b600081600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506001905092915050565b60035481565b6000600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115151561075357600080fd5b81600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506107e8848484610d91565b600190509392505050565b600260009054906101000a900460ff1681565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561085657600080fd5b81600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816003600082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a260019050919050565b60046020528060005260406000206000915090505481565b600081600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561097257600080fd5b600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482111515156109fd57600080fd5b81600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816003600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a26001905092915050565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610bd25780601f10610ba757610100808354040283529160200191610bd2565b820191906000526020600020905b815481529060010190602001808311610bb557829003601f168201915b505050505081565b610be5338383610d91565b5050565b600080849050610bf98585610633565b15610d63578073ffffffffffffffffffffffffffffffffffffffff16638f4ffcb1338630876040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610cf3578082015181840152602081019050610cd8565b50505050905090810190601f168015610d205780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b158015610d4257600080fd5b505af1158015610d56573d6000803e3d6000fd5b5050505060019150610d64565b5b509392505050565b6005602052816000526040600020602052806000526040600020600091509150505481565b6000808373ffffffffffffffffffffffffffffffffffffffff1614151515610db857600080fd5b81600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610e0657600080fd5b600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401111515610e9457600080fd5b600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401905081600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a380600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054011415156110a157fe5b505050505600a165627a7a72305820ed94dd1ff19d5d05f76d2df0d1cb9002bb293a6fbb55f287f36aff57fba1b0420029000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000003627463000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036274630000000000000000000000000000000000000000000000000000000000"
    35  
    36  type EvmTestSuite struct {
    37  	suite.Suite
    38  
    39  	ctx        sdk.Context
    40  	handler    sdk.Handler
    41  	govHandler govtypes.Handler
    42  	querier    sdk.Querier
    43  	app        *app.FBChainApp
    44  	stateDB    *types.CommitStateDB
    45  	codec      *codec.Codec
    46  }
    47  
    48  func (suite *EvmTestSuite) SetupTest() {
    49  	checkTx := false
    50  	chain_id := "ethermint-3"
    51  
    52  	suite.app = app.Setup(checkTx)
    53  	suite.ctx = suite.app.BaseApp.NewContext(checkTx, abci.Header{Height: 1, ChainID: chain_id, Time: time.Now().UTC()})
    54  	suite.ctx.SetDeliver()
    55  	suite.stateDB = types.CreateEmptyCommitStateDB(suite.app.EvmKeeper.GenerateCSDBParams(), suite.ctx)
    56  	suite.handler = evm.NewHandler(suite.app.EvmKeeper)
    57  	suite.querier = keeper.NewQuerier(*suite.app.EvmKeeper)
    58  	suite.codec = codec.New()
    59  
    60  	err := ethermint.SetChainId(chain_id)
    61  	suite.Nil(err)
    62  
    63  	params := types.DefaultParams()
    64  	params.EnableCreate = true
    65  	params.EnableCall = true
    66  	suite.app.EvmKeeper.SetParams(suite.ctx, params)
    67  }
    68  
    69  func TestEvmTestSuite(t *testing.T) {
    70  	suite.Run(t, new(EvmTestSuite))
    71  }
    72  
    73  func (suite *EvmTestSuite) TestHandleMsgEthereumTx() {
    74  	privkey, err := ethsecp256k1.GenerateKey()
    75  	suite.Require().NoError(err)
    76  	sender := ethcmn.HexToAddress(privkey.PubKey().Address().String())
    77  
    78  	var tx *types.MsgEthereumTx
    79  
    80  	testCases := []struct {
    81  		msg      string
    82  		malleate func()
    83  		expPass  bool
    84  	}{
    85  		{
    86  			"passed",
    87  			func() {
    88  				suite.app.EvmKeeper.SetBalance(suite.ctx, sender, big.NewInt(100))
    89  				tx = types.NewMsgEthereumTx(0, &sender, big.NewInt(100), 3000000, big.NewInt(1), nil)
    90  
    91  				// parse context chain ID to big.Int
    92  				chainID, err := ethermint.ParseChainID(suite.ctx.ChainID())
    93  				suite.Require().NoError(err)
    94  
    95  				// sign transaction
    96  				err = tx.Sign(chainID, privkey.ToECDSA())
    97  				suite.Require().NoError(err)
    98  			},
    99  			true,
   100  		},
   101  		{
   102  			"insufficient balance",
   103  			func() {
   104  				suite.app.EvmKeeper.SetBalance(suite.ctx, sender, big.NewInt(1))
   105  				tx = types.NewMsgEthereumTxContract(0, big.NewInt(100), 3000000, big.NewInt(1), nil)
   106  
   107  				// parse context chain ID to big.Int
   108  				chainID, err := ethermint.ParseChainID(suite.ctx.ChainID())
   109  				suite.Require().NoError(err)
   110  
   111  				// sign transaction
   112  				err = tx.Sign(chainID, privkey.ToECDSA())
   113  				suite.Require().NoError(err)
   114  			},
   115  			false,
   116  		},
   117  		{
   118  			"tx encoding failed",
   119  			func() {
   120  				tx = types.NewMsgEthereumTxContract(0, big.NewInt(100), 3000000, big.NewInt(1), nil)
   121  			},
   122  			false,
   123  		},
   124  		{
   125  			"invalid chain ID",
   126  			func() {
   127  				suite.ctx.SetChainID("chainID")
   128  			},
   129  			false,
   130  		},
   131  		{
   132  			"VerifySig failed",
   133  			func() {
   134  				tx = types.NewMsgEthereumTxContract(0, big.NewInt(100), 3000000, big.NewInt(1), nil)
   135  			},
   136  			false,
   137  		},
   138  		{
   139  			"simulate tx",
   140  			func() {
   141  				suite.ctx.SetFrom(sender.String())
   142  				suite.ctx.SetIsCheckTx(true)
   143  				suite.app.EvmKeeper.SetBalance(suite.ctx, sender, big.NewInt(100))
   144  				tx = types.NewMsgEthereumTx(0, &sender, big.NewInt(100), 3000000, big.NewInt(1), nil)
   145  			},
   146  			true,
   147  		},
   148  		{
   149  			"trace log tx",
   150  			func() {
   151  				suite.ctx.SetFrom(sender.String())
   152  				suite.ctx.SetIsTraceTxLog(true)
   153  				suite.app.EvmKeeper.SetBalance(suite.ctx, sender, big.NewInt(100))
   154  				tx = types.NewMsgEthereumTx(0, &sender, big.NewInt(100), 3000000, big.NewInt(1), nil)
   155  			},
   156  			true,
   157  		},
   158  		{
   159  			"insufficient balance for transfer",
   160  			func() {
   161  				tx = types.NewMsgEthereumTx(0, &sender, big.NewInt(100), 3000000, big.NewInt(1), nil)
   162  			},
   163  			false,
   164  		},
   165  	}
   166  
   167  	for _, tc := range testCases {
   168  		suite.Run(tc.msg, func() {
   169  			suite.SetupTest() // reset
   170  			//nolint
   171  			tc.malleate()
   172  			suite.ctx.SetGasMeter(sdk.NewInfiniteGasMeter())
   173  			res, err := suite.handler(suite.ctx, tx)
   174  
   175  			//nolint
   176  			if tc.expPass {
   177  				suite.Require().NoError(err)
   178  				suite.Require().NotNil(res)
   179  				var expectedConsumedGas uint64 = 21000
   180  				suite.Require().EqualValues(expectedConsumedGas, suite.ctx.GasMeter().GasConsumed())
   181  			} else {
   182  				suite.Require().Error(err)
   183  				suite.Require().Nil(res)
   184  			}
   185  		})
   186  	}
   187  }
   188  
   189  func (suite *EvmTestSuite) TestHandlerLogs() {
   190  	// Test contract:
   191  
   192  	// pragma solidity ^0.5.1;
   193  
   194  	// contract Test {
   195  	//     event Hello(uint256 indexed world);
   196  
   197  	//     constructor() public {
   198  	//         emit Hello(17);
   199  	//     }
   200  	// }
   201  
   202  	// {
   203  	// 	"linkReferences": {},
   204  	// 	"object": "6080604052348015600f57600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a2603580604b6000396000f3fe6080604052600080fdfea165627a7a723058206cab665f0f557620554bb45adf266708d2bd349b8a4314bdff205ee8440e3c240029",
   205  	// 	"opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x11 PUSH32 0x775A94827B8FD9B519D36CD827093C664F93347070A554F65E4A6F56CD738898 PUSH1 0x40 MLOAD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 PUSH1 0x35 DUP1 PUSH1 0x4B PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG1 PUSH6 0x627A7A723058 KECCAK256 PUSH13 0xAB665F0F557620554BB45ADF26 PUSH8 0x8D2BD349B8A4314 0xbd SELFDESTRUCT KECCAK256 0x5e 0xe8 DIFFICULTY 0xe EXTCODECOPY 0x24 STOP 0x29 ",
   206  	// 	"sourceMap": "25:119:0:-;;;90:52;8:9:-1;5:2;;;30:1;27;20:12;5:2;90:52:0;132:2;126:9;;;;;;;;;;25:119;;;;;;"
   207  	// }
   208  
   209  	gasLimit := uint64(100000)
   210  	gasPrice := big.NewInt(1000000)
   211  
   212  	priv, err := ethsecp256k1.GenerateKey()
   213  	suite.Require().NoError(err, "failed to create key")
   214  
   215  	bytecode := common.FromHex("0x6080604052348015600f57600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a2603580604b6000396000f3fe6080604052600080fdfea165627a7a723058206cab665f0f557620554bb45adf266708d2bd349b8a4314bdff205ee8440e3c240029")
   216  	tx := types.NewMsgEthereumTx(1, nil, big.NewInt(0), gasLimit, gasPrice, bytecode)
   217  	err = tx.Sign(big.NewInt(3), priv.ToECDSA())
   218  	suite.Require().NoError(err)
   219  
   220  	result, err := suite.handler(suite.ctx, tx)
   221  	suite.Require().NoError(err, "failed to handle eth tx msg")
   222  
   223  	resultData, err := types.DecodeResultData(result.Data)
   224  	suite.Require().NoError(err, "failed to decode result data")
   225  
   226  	suite.Require().Equal(len(resultData.Logs), 1)
   227  	suite.Require().Equal(len(resultData.Logs[0].Topics), 2)
   228  
   229  	txHash := ethcmn.BytesToHash(tx.TxHash())
   230  	suite.stateDB.WithContext(suite.ctx).SetLogs(txHash, resultData.Logs)
   231  	logs, err := suite.stateDB.WithContext(suite.ctx).GetLogs(txHash)
   232  	suite.Require().NoError(err)
   233  	suite.Require().Equal(logs, resultData.Logs)
   234  }
   235  
   236  func (suite *EvmTestSuite) TestDeployAndCallContract() {
   237  	// Test contract:
   238  	//http://remix.ethereum.org/#optimize=false&evmVersion=istanbul&version=soljson-v0.5.15+commit.6a57276f.js
   239  	//2_Owner.sol
   240  	//
   241  	//pragma solidity >=0.4.22 <0.7.0;
   242  	//
   243  	///**
   244  	// * @title Owner
   245  	// * @dev Set & change owner
   246  	// */
   247  	//contract Owner {
   248  	//
   249  	//	address private owner;
   250  	//
   251  	//	// event for EVM logging
   252  	//	event OwnerSet(address indexed oldOwner, address indexed newOwner);
   253  	//
   254  	//	// modifier to check if caller is owner
   255  	//	modifier isOwner() {
   256  	//	// If the first argument of 'require' evaluates to 'false', execution terminates and all
   257  	//	// changes to the state and to Ether balances are reverted.
   258  	//	// This used to consume all gas in old EVM versions, but not anymore.
   259  	//	// It is often a good idea to use 'require' to check if functions are called correctly.
   260  	//	// As a second argument, you can also provide an explanation about what went wrong.
   261  	//	require(msg.sender == owner, "Caller is not owner");
   262  	//	_;
   263  	//}
   264  	//
   265  	//	/**
   266  	//	 * @dev Set contract deployer as owner
   267  	//	 */
   268  	//	constructor() public {
   269  	//	owner = msg.sender; // 'msg.sender' is sender of current call, contract deployer for a constructor
   270  	//	emit OwnerSet(address(0), owner);
   271  	//}
   272  	//
   273  	//	/**
   274  	//	 * @dev Change owner
   275  	//	 * @param newOwner address of new owner
   276  	//	 */
   277  	//	function changeOwner(address newOwner) public isOwner {
   278  	//	emit OwnerSet(owner, newOwner);
   279  	//	owner = newOwner;
   280  	//}
   281  	//
   282  	//	/**
   283  	//	 * @dev Return owner address
   284  	//	 * @return address of owner
   285  	//	 */
   286  	//	function getOwner() external view returns (address) {
   287  	//	return owner;
   288  	//}
   289  	//}
   290  
   291  	// Deploy contract - Owner.sol
   292  	gasLimit := uint64(100000000)
   293  	gasPrice := big.NewInt(10000)
   294  
   295  	priv, err := ethsecp256k1.GenerateKey()
   296  	suite.Require().NoError(err, "failed to create key")
   297  
   298  	bytecode := common.FromHex("0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a36102c4806100dc6000396000f3fe608060405234801561001057600080fd5b5060043610610053576000357c010000000000000000000000000000000000000000000000000000000090048063893d20e814610058578063a6f9dae1146100a2575b600080fd5b6100606100e6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100e4600480360360208110156100b857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061010f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f43616c6c6572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea265627a7a72315820f397f2733a89198bc7fed0764083694c5b828791f39ebcbc9e414bccef14b48064736f6c63430005100032")
   299  	tx := types.NewMsgEthereumTx(1, nil, big.NewInt(0), gasLimit, gasPrice, bytecode)
   300  	tx.Sign(big.NewInt(3), priv.ToECDSA())
   301  	suite.Require().NoError(err)
   302  
   303  	result, err := suite.handler(suite.ctx, tx)
   304  	suite.Require().NoError(err, "failed to handle eth tx msg")
   305  
   306  	resultData, err := types.DecodeResultData(result.Data)
   307  	suite.Require().NoError(err, "failed to decode result data")
   308  
   309  	// store - changeOwner
   310  	gasLimit = uint64(100000000000)
   311  	gasPrice = big.NewInt(100)
   312  	receiver := common.HexToAddress(resultData.ContractAddress.String())
   313  
   314  	storeAddr := "0xa6f9dae10000000000000000000000006a82e4a67715c8412a9114fbd2cbaefbc8181424"
   315  	bytecode = common.FromHex(storeAddr)
   316  	tx = types.NewMsgEthereumTx(2, &receiver, big.NewInt(0), gasLimit, gasPrice, bytecode)
   317  	tx.Sign(big.NewInt(3), priv.ToECDSA())
   318  	suite.Require().NoError(err)
   319  
   320  	result, err = suite.handler(suite.ctx, tx)
   321  	suite.Require().NoError(err, "failed to handle eth tx msg")
   322  
   323  	resultData, err = types.DecodeResultData(result.Data)
   324  	suite.Require().NoError(err, "failed to decode result data")
   325  
   326  	// query - getOwner
   327  	bytecode = common.FromHex("0x893d20e8")
   328  	tx = types.NewMsgEthereumTx(2, &receiver, big.NewInt(0), gasLimit, gasPrice, bytecode)
   329  	tx.Sign(big.NewInt(3), priv.ToECDSA())
   330  	suite.Require().NoError(err)
   331  
   332  	result, err = suite.handler(suite.ctx, tx)
   333  	suite.Require().NoError(err, "failed to handle eth tx msg")
   334  
   335  	resultData, err = types.DecodeResultData(result.Data)
   336  	suite.Require().NoError(err, "failed to decode result data")
   337  
   338  	getAddr := strings.ToLower(hexutils.BytesToHex(resultData.Ret))
   339  	suite.Require().Equal(true, strings.HasSuffix(storeAddr, getAddr), "Fail to query the address")
   340  }
   341  
   342  func (suite *EvmTestSuite) TestSendTransaction() {
   343  
   344  	gasLimit := uint64(100000)
   345  	gasPrice := big.NewInt(10000)
   346  
   347  	priv, err := ethsecp256k1.GenerateKey()
   348  	suite.Require().NoError(err, "failed to create key")
   349  	pub := priv.ToECDSA().Public().(*ecdsa.PublicKey)
   350  
   351  	suite.app.EvmKeeper.SetBalance(suite.ctx, ethcrypto.PubkeyToAddress(*pub), big.NewInt(100))
   352  
   353  	// send simple value transfer with gasLimit=21000
   354  	tx := types.NewMsgEthereumTx(1, &ethcmn.Address{0x1}, big.NewInt(1), gasLimit, gasPrice, nil)
   355  	err = tx.Sign(big.NewInt(3), priv.ToECDSA())
   356  	suite.Require().NoError(err)
   357  
   358  	suite.ctx.SetGasMeter(sdk.NewInfiniteGasMeter())
   359  	result, err := suite.handler(suite.ctx, tx)
   360  	suite.Require().NoError(err)
   361  	suite.Require().NotNil(result)
   362  	var expectedGas uint64 = 0x5208
   363  	suite.Require().EqualValues(expectedGas, suite.ctx.GasMeter().GasConsumed())
   364  }
   365  
   366  func (suite *EvmTestSuite) TestOutOfGasWhenDeployContract() {
   367  	// Test contract:
   368  	//http://remix.ethereum.org/#optimize=false&evmVersion=istanbul&version=soljson-v0.5.15+commit.6a57276f.js
   369  	//2_Owner.sol
   370  	//
   371  	//pragma solidity >=0.4.22 <0.7.0;
   372  	//
   373  	///**
   374  	// * @title Owner
   375  	// * @dev Set & change owner
   376  	// */
   377  	//contract Owner {
   378  	//
   379  	//	address private owner;
   380  	//
   381  	//	// event for EVM logging
   382  	//	event OwnerSet(address indexed oldOwner, address indexed newOwner);
   383  	//
   384  	//	// modifier to check if caller is owner
   385  	//	modifier isOwner() {
   386  	//	// If the first argument of 'require' evaluates to 'false', execution terminates and all
   387  	//	// changes to the state and to Ether balances are reverted.
   388  	//	// This used to consume all gas in old EVM versions, but not anymore.
   389  	//	// It is often a good idea to use 'require' to check if functions are called correctly.
   390  	//	// As a second argument, you can also provide an explanation about what went wrong.
   391  	//	require(msg.sender == owner, "Caller is not owner");
   392  	//	_;
   393  	//}
   394  	//
   395  	//	/**
   396  	//	 * @dev Set contract deployer as owner
   397  	//	 */
   398  	//	constructor() public {
   399  	//	owner = msg.sender; // 'msg.sender' is sender of current call, contract deployer for a constructor
   400  	//	emit OwnerSet(address(0), owner);
   401  	//}
   402  	//
   403  	//	/**
   404  	//	 * @dev Change owner
   405  	//	 * @param newOwner address of new owner
   406  	//	 */
   407  	//	function changeOwner(address newOwner) public isOwner {
   408  	//	emit OwnerSet(owner, newOwner);
   409  	//	owner = newOwner;
   410  	//}
   411  	//
   412  	//	/**
   413  	//	 * @dev Return owner address
   414  	//	 * @return address of owner
   415  	//	 */
   416  	//	function getOwner() external view returns (address) {
   417  	//	return owner;
   418  	//}
   419  	//}
   420  
   421  	// Deploy contract - Owner.sol
   422  	gasLimit := uint64(1)
   423  	suite.ctx.SetGasMeter(sdk.NewGasMeter(gasLimit))
   424  	gasPrice := big.NewInt(10000)
   425  
   426  	priv, err := ethsecp256k1.GenerateKey()
   427  	suite.Require().NoError(err, "failed to create key")
   428  
   429  	bytecode := common.FromHex("0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a36102c4806100dc6000396000f3fe608060405234801561001057600080fd5b5060043610610053576000357c010000000000000000000000000000000000000000000000000000000090048063893d20e814610058578063a6f9dae1146100a2575b600080fd5b6100606100e6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100e4600480360360208110156100b857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061010f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f43616c6c6572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea265627a7a72315820f397f2733a89198bc7fed0764083694c5b828791f39ebcbc9e414bccef14b48064736f6c63430005100032")
   430  	tx := types.NewMsgEthereumTx(1, nil, big.NewInt(0), gasLimit, gasPrice, bytecode)
   431  	tx.Sign(big.NewInt(3), priv.ToECDSA())
   432  	suite.Require().NoError(err)
   433  
   434  	defer func() {
   435  		r := recover()
   436  		suite.Require().NotNil(r, "panic for out of gas")
   437  	}()
   438  
   439  	suite.handler(suite.ctx, tx)
   440  	suite.Require().Fail("panic did not happen")
   441  }
   442  
   443  func (suite *EvmTestSuite) TestRevertErrorWhenCallContract() {
   444  	// Test contract:
   445  
   446  	//// SPDX-License-Identifier: GPL-3.0
   447  	//
   448  	//pragma solidity >=0.7.0 <0.8.0;
   449  	//
   450  	///**
   451  	// * @title Storage
   452  	// * @dev Store & retrieve value in a variable
   453  	// */
   454  	//contract Storage {
   455  	//
   456  	//	uint256 number;
   457  	//	event Test(address to);
   458  	//
   459  	//	/**
   460  	//	 * @dev Store value in variable
   461  	//	 * @param num value to store
   462  	//	 */
   463  	//	function store(uint256 num) public {
   464  	//	require(false,"this is my test failed message");
   465  	//	number = num;
   466  	//	emit Test(msg.sender);
   467  	//}
   468  	//
   469  	//	/**
   470  	//	 * @dev Return value
   471  	//	 * @return value of 'number'
   472  	//	 */
   473  	//	function retrieve() public view returns (uint256){
   474  	//	return number;
   475  	//}
   476  	//}
   477  
   478  	// Deploy contract - storage.sol
   479  	gasLimit := uint64(100000000)
   480  	gasPrice := big.NewInt(10000)
   481  
   482  	priv, err := ethsecp256k1.GenerateKey()
   483  	suite.Require().NoError(err, "failed to create key")
   484  
   485  	bytecode := common.FromHex("0x608060405234801561001057600080fd5b50610191806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd5b610043610087565b6040518082815260200191505060405180910390f35b6100856004803603602081101561006f57600080fd5b8101908080359060200190929190505050610090565b005b60008054905090565b6000610104576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f74686973206973206d792074657374206661696c6564206d657373616765000081525060200191505060405180910390fd5b806000819055507faa9449f2bca09a7b28319d46fd3f3b58a1bb7d94039fc4b69b7bfe5d8535d52733604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15056fea264697066735822122078908b7dd6de7f67bccf9fa221c027590325c5df3cd7d654ee654e4834ca952b64736f6c63430007060033")
   486  	tx := types.NewMsgEthereumTx(1, nil, big.NewInt(0), gasLimit, gasPrice, bytecode)
   487  	tx.Sign(big.NewInt(3), priv.ToECDSA())
   488  	suite.Require().NoError(err)
   489  
   490  	result, err := suite.handler(suite.ctx, tx)
   491  	suite.Require().NoError(err, "failed to handle eth tx msg")
   492  
   493  	resultData, err := types.DecodeResultData(result.Data)
   494  	suite.Require().NoError(err, "failed to decode result data")
   495  
   496  	// store - changeOwner
   497  	gasLimit = uint64(100000000000)
   498  	gasPrice = big.NewInt(100)
   499  	receiver := common.HexToAddress(resultData.ContractAddress.String())
   500  
   501  	storeAddr := "0x6057361d0000000000000000000000000000000000000000000000000000000000000001"
   502  	bytecode = common.FromHex(storeAddr)
   503  	tx = types.NewMsgEthereumTx(2, &receiver, big.NewInt(0), gasLimit, gasPrice, bytecode)
   504  	tx.Sign(big.NewInt(3), priv.ToECDSA())
   505  	suite.Require().NoError(err)
   506  
   507  	result, err = suite.handler(suite.ctx, tx)
   508  	suite.Require().Nil(result)
   509  	suite.Require().NotNil(err)
   510  	suite.Require().Equal(err.Error(), "[\"execution reverted\",\"execution reverted:this is my test failed message\",\"HexData\",\"0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001e74686973206973206d792074657374206661696c6564206d6573736167650000\"]")
   511  }
   512  
   513  func (suite *EvmTestSuite) TestGasConsume() {
   514  	// Test contract:
   515  	//
   516  	//pragma solidity ^0.8.0;
   517  	//contract Test {
   518  	//	event NotifyUint(string funcName, uint value);
   519  	//	event NotifyBytes32(string funcName, bytes32 value);
   520  	//	event NotifyAddress(string funcName, address value);
   521  	//	event NotifyUint256(string funcName, uint256 value);
   522  	//	event NotifyBytes(string funcName, bytes value);
   523  	//	event NotifyBytes4(string funcName, bytes4 value);
   524  	//
   525  	//	function rand() public payable{
   526  	//	// block releted
   527  	//	emit NotifyUint("block.difficulty", uint(block.difficulty));
   528  	//	emit NotifyUint("block.gaslimit", uint(block.gaslimit));
   529  	//
   530  	//	// not work until solidity v0.8.0
   531  	//	emit NotifyUint("block.chainid", uint(block.chainid));
   532  	//
   533  	//	uint num;
   534  	//	num = uint(block.number);
   535  	//	emit NotifyUint("block.number", num);
   536  	//	emit NotifyBytes32("blockhash", bytes32(blockhash(num)));
   537  	//	emit NotifyBytes32("last blockhash", bytes32(blockhash(num - 1)));
   538  	//	emit NotifyAddress("block.coinbase", address(block.coinbase));
   539  	//
   540  	//	emit NotifyUint("block.timestamp", uint(block.timestamp));
   541  	//	// not work since solidity v0.7.0
   542  	//	//emit NotifyUint("now", uint(now));
   543  	//
   544  	//
   545  	//	// msg releted
   546  	//	emit NotifyBytes("msg.data", bytes(msg.data));
   547  	//	emit NotifyAddress("msg.sender", address(msg.sender));
   548  	//	emit NotifyBytes4("msg.sig", bytes4(msg.sig));
   549  	//	emit NotifyUint("msg.value", uint(msg.value));
   550  	//	emit NotifyUint256("gasleft", uint256(gasleft()));
   551  	//
   552  	//
   553  	//	// tx releted
   554  	//	emit NotifyUint("tx.gasprice", uint(tx.gasprice));
   555  	//	emit NotifyAddress("tx.origin", address(tx.origin));
   556  	//}
   557  	//}
   558  
   559  	// Deploy contract - storage.sol
   560  	gasLimit := uint64(100000000)
   561  	gasPrice := big.NewInt(10000)
   562  
   563  	priv, err := ethsecp256k1.GenerateKey()
   564  	suite.Require().NoError(err, "failed to create key")
   565  
   566  	bytecode := common.FromHex("608060405234801561001057600080fd5b50610c88806100206000396000f3fe60806040526004361061001e5760003560e01c80633b3dca7614610023575b600080fd5b61002b61002d565b005b7f01710aa49abe19e9f1e69db68002b08e6fdc26b6603462ec5595143eb16bce0f4460405161005c91906107ee565b60405180910390a17f01710aa49abe19e9f1e69db68002b08e6fdc26b6603462ec5595143eb16bce0f4560405161009391906108a6565b60405180910390a17f01710aa49abe19e9f1e69db68002b08e6fdc26b6603462ec5595143eb16bce0f466040516100ca9190610619565b60405180910390a160004390507f01710aa49abe19e9f1e69db68002b08e6fdc26b6603462ec5595143eb16bce0f8160405161010691906106da565b60405180910390a17f66f9aff21094d330be5210a94aa9006bc73c58a78ffbc2fcf7459b469e90a91c814060405161013e919061081c565b60405180910390a17f66f9aff21094d330be5210a94aa9006bc73c58a78ffbc2fcf7459b469e90a91c60018261017491906108f6565b4060405161018291906107c0565b60405180910390a17fd1f988f2f9743dc861b689b05592f3f5a3c320f9ac7c058e7f1aed7c5302c0aa416040516101b99190610878565b60405180910390a17f01710aa49abe19e9f1e69db68002b08e6fdc26b6603462ec5595143eb16bce0f426040516101f09190610647565b60405180910390a17fc5eea5f168bedf3b83d910a0e351deae24dc0af984734c8d3ad930ddb385967c60003660405161022a9291906106a3565b60405180910390a17fd1f988f2f9743dc861b689b05592f3f5a3c320f9ac7c058e7f1aed7c5302c0aa336040516102619190610792565b60405180910390a17f06cfc4b8d6699a3e735d3478223775d7e9ba040403a71b442bca541d0e1e94bf6000357fffffffff00000000000000000000000000000000000000000000000000000000166040516102bc9190610675565b60405180910390a17f01710aa49abe19e9f1e69db68002b08e6fdc26b6603462ec5595143eb16bce0f346040516102f39190610708565b60405180910390a17f428932ecd90e05b8cebd39dcda376284a2ccf362d7081b287d54fbc07b4777265a60405161032a9190610764565b60405180910390a17f01710aa49abe19e9f1e69db68002b08e6fdc26b6603462ec5595143eb16bce0f3a604051610361919061084a565b60405180910390a17fd1f988f2f9743dc861b689b05592f3f5a3c320f9ac7c058e7f1aed7c5302c0aa326040516103989190610736565b60405180910390a150565b6103ac8161092a565b82525050565b6103bb8161093c565b82525050565b6103ca81610946565b82525050565b60006103dc83856108d4565b93506103e983858461099c565b6103f2836109da565b840190509392505050565b600061040a600d836108e5565b9150610415826109eb565b602082019050919050565b600061042d600f836108e5565b915061043882610a14565b602082019050919050565b60006104506007836108e5565b915061045b82610a3d565b602082019050919050565b60006104736008836108e5565b915061047e82610a66565b602082019050919050565b6000610496600c836108e5565b91506104a182610a8f565b602082019050919050565b60006104b96009836108e5565b91506104c482610ab8565b602082019050919050565b60006104dc6009836108e5565b91506104e782610ae1565b602082019050919050565b60006104ff6007836108e5565b915061050a82610b0a565b602082019050919050565b6000610522600a836108e5565b915061052d82610b33565b602082019050919050565b6000610545600e836108e5565b915061055082610b5c565b602082019050919050565b60006105686010836108e5565b915061057382610b85565b602082019050919050565b600061058b6009836108e5565b915061059682610bae565b602082019050919050565b60006105ae600b836108e5565b91506105b982610bd7565b602082019050919050565b60006105d1600e836108e5565b91506105dc82610c00565b602082019050919050565b60006105f4600e836108e5565b91506105ff82610c29565b602082019050919050565b61061381610992565b82525050565b60006040820190508181036000830152610632816103fd565b9050610641602083018461060a565b92915050565b6000604082019050818103600083015261066081610420565b905061066f602083018461060a565b92915050565b6000604082019050818103600083015261068e81610443565b905061069d60208301846103c1565b92915050565b600060408201905081810360008301526106bc81610466565b905081810360208301526106d18184866103d0565b90509392505050565b600060408201905081810360008301526106f381610489565b9050610702602083018461060a565b92915050565b60006040820190508181036000830152610721816104ac565b9050610730602083018461060a565b92915050565b6000604082019050818103600083015261074f816104cf565b905061075e60208301846103a3565b92915050565b6000604082019050818103600083015261077d816104f2565b905061078c602083018461060a565b92915050565b600060408201905081810360008301526107ab81610515565b90506107ba60208301846103a3565b92915050565b600060408201905081810360008301526107d981610538565b90506107e860208301846103b2565b92915050565b600060408201905081810360008301526108078161055b565b9050610816602083018461060a565b92915050565b600060408201905081810360008301526108358161057e565b905061084460208301846103b2565b92915050565b60006040820190508181036000830152610863816105a1565b9050610872602083018461060a565b92915050565b60006040820190508181036000830152610891816105c4565b90506108a060208301846103a3565b92915050565b600060408201905081810360008301526108bf816105e7565b90506108ce602083018461060a565b92915050565b600082825260208201905092915050565b600082825260208201905092915050565b600061090182610992565b915061090c83610992565b92508282101561091f5761091e6109ab565b5b828203905092915050565b600061093582610972565b9050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000601f19601f8301169050919050565b7f626c6f636b2e636861696e696400000000000000000000000000000000000000600082015250565b7f626c6f636b2e74696d657374616d700000000000000000000000000000000000600082015250565b7f6d73672e73696700000000000000000000000000000000000000000000000000600082015250565b7f6d73672e64617461000000000000000000000000000000000000000000000000600082015250565b7f626c6f636b2e6e756d6265720000000000000000000000000000000000000000600082015250565b7f6d73672e76616c75650000000000000000000000000000000000000000000000600082015250565b7f74782e6f726967696e0000000000000000000000000000000000000000000000600082015250565b7f6761736c65667400000000000000000000000000000000000000000000000000600082015250565b7f6d73672e73656e64657200000000000000000000000000000000000000000000600082015250565b7f6c61737420626c6f636b68617368000000000000000000000000000000000000600082015250565b7f626c6f636b2e646966666963756c747900000000000000000000000000000000600082015250565b7f626c6f636b686173680000000000000000000000000000000000000000000000600082015250565b7f74782e6761737072696365000000000000000000000000000000000000000000600082015250565b7f626c6f636b2e636f696e62617365000000000000000000000000000000000000600082015250565b7f626c6f636b2e6761736c696d697400000000000000000000000000000000000060008201525056fea264697066735822122002530b5caa31bb9ea0bb1b97d1d7d7225a527bfdedadb22ac0f809fd2d21bed064736f6c63430008010033")
   567  	tx := types.NewMsgEthereumTx(1, nil, big.NewInt(0), gasLimit, gasPrice, bytecode)
   568  	tx.Sign(big.NewInt(3), priv.ToECDSA())
   569  	suite.Require().NoError(err)
   570  
   571  	_, err = suite.handler(suite.ctx, tx)
   572  	suite.Require().NoError(err, "failed to handle eth tx msg")
   573  	var expectedConsumedGas sdk.Gas = 741212
   574  	suite.Require().Equal(expectedConsumedGas, suite.ctx.GasMeter().GasConsumed())
   575  }
   576  
   577  func (suite *EvmTestSuite) TestErrorWhenDeployContract() {
   578  	gasLimit := uint64(1000000)
   579  	gasPrice := big.NewInt(10000)
   580  
   581  	priv, err := ethsecp256k1.GenerateKey()
   582  	suite.Require().NoError(err, "failed to create key")
   583  
   584  	bytecode := common.FromHex("0xa6f9dae10000000000000000000000006a82e4a67715c8412a9114fbd2cbaefbc8181424")
   585  
   586  	tx := types.NewMsgEthereumTx(1, nil, big.NewInt(0), gasLimit, gasPrice, bytecode)
   587  	tx.Sign(big.NewInt(3), priv.ToECDSA())
   588  	suite.Require().NoError(err)
   589  
   590  	_, sdkErr := suite.handler(suite.ctx, tx)
   591  	suite.Require().NotNil(sdkErr)
   592  }
   593  
   594  func (suite *EvmTestSuite) TestDefaultMsgHandler() {
   595  	tx := sdk.NewTestMsg()
   596  	_, sdkErr := suite.handler(suite.ctx, tx)
   597  	suite.Require().NotNil(sdkErr)
   598  }
   599  
   600  func (suite *EvmTestSuite) TestSimulateConflict() {
   601  
   602  	gasLimit := uint64(100000)
   603  	gasPrice := big.NewInt(10000)
   604  
   605  	priv, err := ethsecp256k1.GenerateKey()
   606  	suite.Require().NoError(err, "failed to create key")
   607  	pub := priv.ToECDSA().Public().(*ecdsa.PublicKey)
   608  
   609  	suite.app.EvmKeeper.SetBalance(suite.ctx, ethcrypto.PubkeyToAddress(*pub), big.NewInt(100))
   610  
   611  	// send simple value transfer with gasLimit=21000
   612  	tx := types.NewMsgEthereumTx(1, &ethcmn.Address{0x1}, big.NewInt(100), gasLimit, gasPrice, nil)
   613  	err = tx.Sign(big.NewInt(3), priv.ToECDSA())
   614  	suite.Require().NoError(err)
   615  
   616  	suite.ctx.SetGasMeter(sdk.NewInfiniteGasMeter())
   617  	suite.ctx.SetIsCheckTx(true).SetIsDeliverTx(false)
   618  	result, err := suite.handler(suite.ctx, tx)
   619  	suite.Require().NotNil(result)
   620  	suite.Require().Nil(err)
   621  
   622  	suite.ctx.SetIsCheckTx(false).SetIsDeliverTx(true)
   623  	result, err = suite.handler(suite.ctx, tx)
   624  	suite.Require().NotNil(result)
   625  	suite.Require().Nil(err)
   626  	var expectedGas uint64 = 22336
   627  	suite.Require().EqualValues(expectedGas, suite.ctx.GasMeter().GasConsumed())
   628  }
   629  
   630  func (suite *EvmTestSuite) TestEvmParamsAndContractDeploymentWhitelistControlling_MsgEthereumTx() {
   631  	params := suite.app.EvmKeeper.GetParams(suite.ctx)
   632  
   633  	privkey, err := ethsecp256k1.GenerateKey()
   634  	suite.Require().NoError(err)
   635  	addrQualified := privkey.PubKey().Address().Bytes()
   636  
   637  	privkeyUnqualified, err := ethsecp256k1.GenerateKey()
   638  	suite.Require().NoError(err)
   639  	addrUnqualified := privkeyUnqualified.PubKey().Address().Bytes()
   640  
   641  	// parse context chain ID to big.Int
   642  	chainID, err := ethermint.ParseChainID(suite.ctx.ChainID())
   643  	suite.Require().NoError(err)
   644  
   645  	// build a tx with contract deployment
   646  	payload, err := hexutil.Decode(hexPayloadContractDeployment)
   647  	suite.Require().NoError(err)
   648  	tx := types.NewMsgEthereumTx(0, nil, nil, 3000000, big.NewInt(1), payload)
   649  
   650  	testCases := []struct {
   651  		msg                               string
   652  		enableContractDeploymentWhitelist bool
   653  		contractDeploymentWhitelist       types.AddressList
   654  		expPass                           bool
   655  	}{
   656  		{
   657  			"every address could deploy contract when contract deployment whitelist is disabled",
   658  			false,
   659  			nil,
   660  			true,
   661  		},
   662  		{
   663  			"every address could deploy contract when contract deployment whitelist is disabled whatever whitelist members are",
   664  			false,
   665  			types.AddressList{addrUnqualified},
   666  			true,
   667  		},
   668  		{
   669  			"every address in whitelist could deploy contract when contract deployment whitelist is disabled",
   670  			false,
   671  			types.AddressList{addrQualified},
   672  			true,
   673  		},
   674  		{
   675  			"address in whitelist could deploy contract when contract deployment whitelist is enabled",
   676  			true,
   677  			types.AddressList{addrQualified},
   678  			true,
   679  		},
   680  		{
   681  			"no address could deploy contract when contract deployment whitelist is enabled and whitelist is nil",
   682  			true,
   683  			nil,
   684  			false,
   685  		},
   686  		{
   687  			"address not in the whitelist couldn't deploy contract when contract deployment whitelist is enabled",
   688  			true,
   689  			types.AddressList{addrUnqualified},
   690  			false,
   691  		},
   692  	}
   693  
   694  	for _, tc := range testCases {
   695  		suite.Run(tc.msg, func() {
   696  			suite.SetupTest()
   697  
   698  			// reset FeeCollector
   699  			feeCollectorAcc := supply.NewEmptyModuleAccount(auth.FeeCollectorName)
   700  			feeCollectorAcc.Coins = sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneDec()))
   701  			suite.app.SupplyKeeper.SetModuleAccount(suite.ctx, feeCollectorAcc)
   702  
   703  			// set account sufficient balance for sender
   704  			suite.app.EvmKeeper.SetBalance(suite.ctx, ethcmn.BytesToAddress(addrQualified), sdk.NewDec(1024).BigInt())
   705  
   706  			// reset params
   707  			params.EnableContractDeploymentWhitelist = tc.enableContractDeploymentWhitelist
   708  			suite.app.EvmKeeper.SetParams(suite.ctx, params)
   709  
   710  			// set target whitelist
   711  			suite.stateDB.SetContractDeploymentWhitelist(tc.contractDeploymentWhitelist)
   712  
   713  			// sign transaction
   714  			err = tx.Sign(chainID, privkey.ToECDSA())
   715  			suite.Require().NoError(err)
   716  
   717  			// handle tx
   718  			res, err := suite.handler(suite.ctx, tx)
   719  
   720  			//nolint
   721  			if tc.expPass {
   722  				suite.Require().NoError(err)
   723  				suite.Require().NotNil(res)
   724  			} else {
   725  				suite.Require().Error(err)
   726  				suite.Require().Nil(res)
   727  			}
   728  		})
   729  	}
   730  }
   731  
   732  const (
   733  	// contracts solidity codes:
   734  	//
   735  	//		pragma solidity >=0.6.0 <0.8.0;
   736  	//
   737  	//		contract Contract1 {
   738  	//
   739  	//		    uint256 public num;
   740  	//
   741  	//		    function add() public {
   742  	//		        num = num + 1;
   743  	//		    }
   744  	//		}
   745  	//
   746  	//
   747  	//		contract Contract2 {
   748  	//
   749  	//		    address public c1;
   750  	//
   751  	//		    function setAddr(address _c1) public {
   752  	//		        c1 = _c1;
   753  	//		    }
   754  	//
   755  	//		    function add() public {
   756  	//		        Contract1(c1).add();
   757  	//		    }
   758  	//
   759  	//		    function number() public view returns (uint256) {
   760  	//		        return Contract1(c1).num();
   761  	//		    }
   762  	//
   763  	//		}
   764  
   765  	// Contract1's deployment
   766  	contract1DeployedHexPayload = "0x6080604052348015600f57600080fd5b5060a58061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80634e70b1dc1460375780634f2be91f146053575b600080fd5b603d605b565b6040518082815260200191505060405180910390f35b60596061565b005b60005481565b60016000540160008190555056fea2646970667358221220892505b233ac0976b1a78e3fb9cee468a1c25027c175e73386f2d1920579520b64736f6c63430007060033"
   767  	// Contract2's deployment
   768  	contract2DeployedHexPayload = "0x608060405234801561001057600080fd5b506102b9806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80634f2be91f146100515780635f57697c1461005b5780638381f58a1461008f578063d1d80fdf146100ad575b600080fd5b6100596100f1565b005b610063610173565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610097610197565b6040518082815260200191505060405180910390f35b6100ef600480360360208110156100c357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610240565b005b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634f2be91f6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561015957600080fd5b505af115801561016d573d6000803e3d6000fd5b50505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634e70b1dc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561020057600080fd5b505afa158015610214573d6000803e3d6000fd5b505050506040513d602081101561022a57600080fd5b8101908080519060200190929190505050905090565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea2646970667358221220ae5d2293d42642ceaab5fae3db75e377553fcb7099f8b5bd24d3b9e740ba8f0e64736f6c63430007060033"
   769  	// invoke Contract2's 'setAddr' function to set Contract1's address into Contract2
   770  	contract2SetContact1HexPayloadFormat = "0xd1d80fdf000000000000000000000000%s"
   771  	// invoke Contract1's 'add' function
   772  	invokeContract1HexPayload = "0x4f2be91f"
   773  	// invoke Contract2's 'add' function(it will invoke Contract1)
   774  	invokeContract2HexPayload = "0x4f2be91f"
   775  )
   776  
   777  type EvmContractBlockedListTestSuite struct {
   778  	suite.Suite
   779  
   780  	ctx     sdk.Context
   781  	handler sdk.Handler
   782  	app     *app.FBChainApp
   783  	stateDB *types.CommitStateDB
   784  
   785  	// global data for test
   786  	chainID                 *big.Int
   787  	contractDeployerPrivKey ethsecp256k1.PrivKey
   788  	contract1Addr           ethcmn.Address
   789  	contract2Addr           ethcmn.Address
   790  }
   791  
   792  func TestEvmContractBlockedListTestSuite(t *testing.T) {
   793  	suite.Run(t, new(EvmContractBlockedListTestSuite))
   794  }
   795  
   796  func (suite *EvmContractBlockedListTestSuite) SetupTest() {
   797  	var err error
   798  	checkTx := false
   799  
   800  	suite.app = app.Setup(checkTx)
   801  	suite.ctx = suite.app.BaseApp.NewContext(checkTx, abci.Header{Height: 1, ChainID: "ethermint-3", Time: time.Now().UTC()})
   802  	suite.ctx.SetDeliver()
   803  	suite.stateDB = types.CreateEmptyCommitStateDB(suite.app.EvmKeeper.GenerateCSDBParams(), suite.ctx)
   804  	suite.handler = evm.NewHandler(suite.app.EvmKeeper)
   805  
   806  	// parse context chain ID to big.Int
   807  	suite.chainID, err = ethermint.ParseChainID(suite.ctx.ChainID())
   808  	suite.Require().NoError(err)
   809  
   810  	// set priv key and address for mock contract deployer
   811  	suite.contractDeployerPrivKey, err = ethsecp256k1.GenerateKey()
   812  	suite.Require().NoError(err)
   813  
   814  	// set contract address for Contract1 and Contract2 as we know the deployer address and nonce in advance
   815  	contractDeployerAddr := ethcmn.BytesToAddress(suite.contractDeployerPrivKey.PubKey().Address().Bytes())
   816  	suite.contract1Addr = ethcrypto.CreateAddress(contractDeployerAddr, 0)
   817  	suite.contract2Addr = ethcrypto.CreateAddress(contractDeployerAddr, 1)
   818  
   819  	// set new params
   820  	params := types.DefaultParams()
   821  	params.EnableCreate = true
   822  	params.EnableCall = true
   823  	suite.app.EvmKeeper.SetParams(suite.ctx, params)
   824  
   825  	// fill the fee collector for mock refunding
   826  	feeCollectorAcc := supply.NewEmptyModuleAccount(auth.FeeCollectorName)
   827  	feeCollectorAcc.Coins = sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneDec()))
   828  	suite.app.SupplyKeeper.SetModuleAccount(suite.ctx, feeCollectorAcc)
   829  
   830  	// init contracts for test environment
   831  	suite.deployInterdependentContracts()
   832  	suite.app.EndBlock(abci.RequestEndBlock{Height: 1})
   833  }
   834  
   835  // deployInterdependentContracts deploys two contracts that Contract1 will be invoked by Contract2
   836  func (suite *EvmContractBlockedListTestSuite) deployInterdependentContracts() {
   837  	// deploy Contract1
   838  	err := suite.deployOrInvokeContract(suite.contractDeployerPrivKey, contract1DeployedHexPayload, 0, nil)
   839  	suite.Require().NoError(err)
   840  	// deploy Contract2
   841  	err = suite.deployOrInvokeContract(suite.contractDeployerPrivKey, contract2DeployedHexPayload, 1, nil)
   842  	suite.Require().NoError(err)
   843  	// set Contract1 into Contract2
   844  	payload := fmt.Sprintf(contract2SetContact1HexPayloadFormat, suite.contract1Addr.Hex()[2:])
   845  	err = suite.deployOrInvokeContract(suite.contractDeployerPrivKey, payload, 2, &suite.contract2Addr)
   846  	suite.Require().NoError(err)
   847  }
   848  
   849  func (suite *EvmContractBlockedListTestSuite) deployOrInvokeContract(source interface{}, hexPayload string,
   850  	nonce uint64, to *ethcmn.Address) error {
   851  	payload, err := hexutil.Decode(hexPayload)
   852  	suite.Require().NoError(err)
   853  
   854  	var msg interface{}
   855  	switch s := source.(type) {
   856  	case ethsecp256k1.PrivKey:
   857  		msgEthereumTx := types.NewMsgEthereumTx(nonce, to, nil, 3000000, big.NewInt(1), payload)
   858  		// sign transaction
   859  		err = msgEthereumTx.Sign(suite.chainID, s.ToECDSA())
   860  		suite.Require().NoError(err)
   861  		msg = msgEthereumTx
   862  	}
   863  
   864  	m, ok := msg.(sdk.Msg)
   865  	suite.Require().True(ok)
   866  	_, err = suite.handler(suite.ctx, m)
   867  	return err
   868  }
   869  
   870  func (suite *EvmContractBlockedListTestSuite) TestEvmParamsAndContractBlockedListControlling_MsgEthereumTx() {
   871  	callerPrivKey, err := ethsecp256k1.GenerateKey()
   872  	suite.Require().NoError(err)
   873  
   874  	testCases := []struct {
   875  		msg                       string
   876  		enableContractBlockedList bool
   877  		contractBlockedList       types.AddressList
   878  		expectedErrorForContract1 bool
   879  		expectedErrorForContract2 bool
   880  	}{
   881  		{
   882  			msg:                       "every contract could be invoked with empty blocked list which is disabled",
   883  			enableContractBlockedList: false,
   884  			contractBlockedList:       types.AddressList{},
   885  			expectedErrorForContract1: false,
   886  			expectedErrorForContract2: false,
   887  		},
   888  		{
   889  			msg:                       "every contract could be invoked with empty blocked list which is enabled",
   890  			enableContractBlockedList: true,
   891  			contractBlockedList:       types.AddressList{},
   892  			expectedErrorForContract1: false,
   893  			expectedErrorForContract2: false,
   894  		},
   895  		{
   896  			msg:                       "every contract in the blocked list could be invoked when contract blocked list is disabled",
   897  			enableContractBlockedList: false,
   898  			contractBlockedList:       types.AddressList{suite.contract1Addr.Bytes(), suite.contract2Addr.Bytes()},
   899  			expectedErrorForContract1: false,
   900  			expectedErrorForContract2: false,
   901  		},
   902  		{
   903  			msg:                       "Contract1 could be invoked but Contract2 couldn't when Contract2 is in block list which is enabled",
   904  			enableContractBlockedList: true,
   905  			contractBlockedList:       types.AddressList{suite.contract2Addr.Bytes()},
   906  			expectedErrorForContract1: false,
   907  			expectedErrorForContract2: true,
   908  		},
   909  		{
   910  			msg:                       "neither Contract1 nor Contract2 could be invoked when Contract1 is in block list which is enabled",
   911  			enableContractBlockedList: true,
   912  			contractBlockedList:       types.AddressList{suite.contract1Addr.Bytes()},
   913  			expectedErrorForContract1: true,
   914  			expectedErrorForContract2: true,
   915  		},
   916  	}
   917  
   918  	for _, tc := range testCases {
   919  		suite.Run(tc.msg, func() {
   920  			// update params
   921  			params := suite.app.EvmKeeper.GetParams(suite.ctx)
   922  			params.EnableContractBlockedList = tc.enableContractBlockedList
   923  			suite.app.EvmKeeper.SetParams(suite.ctx, params)
   924  
   925  			// reset contract blocked list
   926  			suite.stateDB.DeleteContractBlockedList(suite.stateDB.GetContractBlockedList())
   927  			suite.stateDB.SetContractBlockedList(tc.contractBlockedList)
   928  
   929  			// nonce here could be any value
   930  			err = suite.deployOrInvokeContract(callerPrivKey, invokeContract1HexPayload, 1024, &suite.contract1Addr)
   931  			if tc.expectedErrorForContract1 {
   932  				suite.Require().Error(err)
   933  			} else {
   934  				suite.Require().NoError(err)
   935  			}
   936  
   937  			// nonce here could be any value
   938  			err = suite.deployOrInvokeContract(callerPrivKey, invokeContract2HexPayload, 1024, &suite.contract2Addr)
   939  			if tc.expectedErrorForContract2 {
   940  				suite.Require().Error(err)
   941  			} else {
   942  				suite.Require().NoError(err)
   943  			}
   944  		})
   945  	}
   946  }
   947  
   948  var (
   949  	callAddr                  = "0x2B2641734D81a6B93C9aE1Ee6290258FB6666921"
   950  	callCode                  = "0x608060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630c55699c1461008857806350cd4df2146100b35780637811c6c1146100de578063a6516bda14610121578063a7126c2d14610164578063a9421619146101a7578063d3ab86a1146101ea575b600080fd5b34801561009457600080fd5b5061009d610241565b6040518082815260200191505060405180910390f35b3480156100bf57600080fd5b506100c8610247565b6040518082815260200191505060405180910390f35b3480156100ea57600080fd5b5061011f600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061024d565b005b34801561012d57600080fd5b50610162600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610304565b005b34801561017057600080fd5b506101a5600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506103bb565b005b3480156101b357600080fd5b506101e8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610470565b005b3480156101f657600080fd5b506101ff610527565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60005481565b60015481565b600060405180807f696e6328290000000000000000000000000000000000000000000000000000008152506005019050604051809103902090508173ffffffffffffffffffffffffffffffffffffffff16817c010000000000000000000000000000000000000000000000000000000090046040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016000604051808303816000875af292505050505050565b600060405180807f6f6e6328290000000000000000000000000000000000000000000000000000008152506005019050604051809103902090508173ffffffffffffffffffffffffffffffffffffffff16817c010000000000000000000000000000000000000000000000000000000090046040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016000604051808303816000875af192505050505050565b600060405180807f696e6328290000000000000000000000000000000000000000000000000000008152506005019050604051809103902090508173ffffffffffffffffffffffffffffffffffffffff16817c010000000000000000000000000000000000000000000000000000000090046040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401600060405180830381865af492505050505050565b600060405180807f696e6328290000000000000000000000000000000000000000000000000000008152506005019050604051809103902090508173ffffffffffffffffffffffffffffffffffffffff16817c010000000000000000000000000000000000000000000000000000000090046040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016000604051808303816000875af192505050505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16815600a165627a7a7230582003530ba5d655e02d210fb630e4067ad896add11d3c99c6c69165d11ce4855ca90029"
   951  	callAcc, _                = sdk.AccAddressFromBech32(callAddr)
   952  	callEthAcc                = common.BytesToAddress(callAcc.Bytes())
   953  	callBuffer                = hexutil.MustDecode(callCode)
   954  	blockedAddr               = "0xf297Ab486Be410A2649901849B0477D519E99960"
   955  	blockedCode               = "0x60806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630c55699c14610072578063371303c01461009d57806350cd4df2146100b4578063579be378146100df578063d3ab86a1146100f6575b600080fd5b34801561007e57600080fd5b5061008761014d565b6040518082815260200191505060405180910390f35b3480156100a957600080fd5b506100b2610153565b005b3480156100c057600080fd5b506100c96101ba565b6040518082815260200191505060405180910390f35b3480156100eb57600080fd5b506100f46101c0565b005b34801561010257600080fd5b5061010b6101d9565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60005481565b33600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160008154809291906001900391905055506000808154809291906001019190505550565b60015481565b3373ffffffffffffffffffffffffffffffffffffffff16ff5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16815600a165627a7a72305820b537b2bbcf121c2be169c4f990888d02d3bbab4fd6a806c3d4a0f3643cebd4590029"
   956  	blockedAcc, _             = sdk.AccAddressFromBech32(blockedAddr)
   957  	blockedBuffer             = hexutil.MustDecode(blockedCode)
   958  	blockedEthAcc             = common.BytesToAddress(blockedAcc.Bytes())
   959  	callMethodBlocked         = "0xa9421619000000000000000000000000f297ab486be410a2649901849b0477d519e99960"
   960  	selfdestructMethodBlocked = "0xa6516bda000000000000000000000000f297ab486be410a2649901849b0477d519e99960"
   961  	callcodeMethodBlocked     = "0x7811c6c1000000000000000000000000f297ab486be410a2649901849b0477d519e99960"
   962  	delegatecallMethodBlocked = "0xa7126c2d000000000000000000000000f297ab486be410a2649901849b0477d519e99960"
   963  	blockedMethods            = types.ContractMethods{
   964  		types.ContractMethod{
   965  			Sign:  "0x371303c0",
   966  			Extra: "inc()",
   967  		},
   968  		types.ContractMethod{
   969  			Sign:  "0x579be378",
   970  			Extra: "onc",
   971  		},
   972  	}
   973  	blockedContract = types.BlockedContract{
   974  		Address:      blockedAcc,
   975  		BlockMethods: blockedMethods,
   976  	}
   977  )
   978  
   979  func (suite *EvmContractBlockedListTestSuite) TestEvmParamsAndContractMethodBlockedListControlling_MsgEthereumTx() {
   980  	callerPrivKey, err := ethsecp256k1.GenerateKey()
   981  	suite.Require().NoError(err)
   982  	testCases := []struct {
   983  		msg                       string
   984  		enableContractBlockedList bool
   985  		contractBlockedList       types.AddressList
   986  		contractMethodBlockedList types.BlockedContractList
   987  		expectedErrorForContract  bool
   988  		expectedErrorContains     string
   989  	}{
   990  		{
   991  			msg:                       "contract could be invoked with empty blocked list which is disabled",
   992  			enableContractBlockedList: false,
   993  			contractMethodBlockedList: types.BlockedContractList{},
   994  			expectedErrorForContract:  false,
   995  		},
   996  		{
   997  			msg:                       "contract could be invoked with empty blocked list which is enabled",
   998  			enableContractBlockedList: true,
   999  			contractMethodBlockedList: types.BlockedContractList{},
  1000  			expectedErrorForContract:  false,
  1001  		},
  1002  		{
  1003  			msg:                       "contract in the blocked list could be invoked when contract blocked list is disabled",
  1004  			enableContractBlockedList: false,
  1005  			contractMethodBlockedList: types.BlockedContractList{blockedContract},
  1006  			expectedErrorForContract:  false,
  1007  		},
  1008  		{
  1009  			msg:                       "Contract method could not be invoked when Contract method is in block list which is enabled",
  1010  			enableContractBlockedList: true,
  1011  			contractMethodBlockedList: types.BlockedContractList{blockedContract},
  1012  			expectedErrorForContract:  true,
  1013  			expectedErrorContains:     "It's not allow to",
  1014  		},
  1015  		{
  1016  			msg:                       "Contract method could be invoked which method which is out of blocked list",
  1017  			enableContractBlockedList: true,
  1018  			contractMethodBlockedList: types.BlockedContractList{types.BlockedContract{
  1019  				blockedAcc,
  1020  				types.ContractMethods{
  1021  					types.ContractMethod{
  1022  						Sign:  "0x579be372",
  1023  						Extra: "test",
  1024  					},
  1025  				},
  1026  			}},
  1027  			expectedErrorForContract: false,
  1028  		},
  1029  		{
  1030  			msg:                       "Contract method could not be invoked when Contract is in block list which is enabled",
  1031  			enableContractBlockedList: true,
  1032  			contractMethodBlockedList: types.BlockedContractList{},
  1033  			contractBlockedList:       types.AddressList{blockedAcc},
  1034  			expectedErrorForContract:  true,
  1035  			expectedErrorContains:     "is not allowed to invoke",
  1036  		},
  1037  	}
  1038  
  1039  	for _, tc := range testCases {
  1040  		suite.Run(tc.msg, func() {
  1041  			suite.ctx.SetIsDeliverTx(true).SetIsCheckTx(false)
  1042  
  1043  			// set contract code
  1044  			suite.stateDB.CreateAccount(callEthAcc)
  1045  			suite.stateDB.CreateAccount(blockedEthAcc)
  1046  			suite.stateDB.SetCode(callEthAcc, callBuffer)
  1047  			suite.stateDB.SetCode(blockedEthAcc, blockedBuffer)
  1048  
  1049  			// update params
  1050  			params := suite.app.EvmKeeper.GetParams(suite.ctx)
  1051  			params.EnableContractBlockedList = tc.enableContractBlockedList
  1052  			suite.app.EvmKeeper.SetParams(suite.ctx, params)
  1053  
  1054  			// reset contract blocked list
  1055  			suite.stateDB.DeleteContractMethodBlockedList(suite.stateDB.GetContractMethodBlockedList())
  1056  			suite.stateDB.DeleteContractBlockedList(suite.stateDB.GetContractBlockedList())
  1057  			if len(tc.contractMethodBlockedList) != 0 {
  1058  				suite.stateDB.InsertContractMethodBlockedList(tc.contractMethodBlockedList)
  1059  			} else {
  1060  				suite.stateDB.SetContractBlockedList(tc.contractBlockedList)
  1061  			}
  1062  
  1063  			suite.stateDB.Commit(true)
  1064  
  1065  			// nonce here could be any value
  1066  			err = suite.deployOrInvokeContract(callerPrivKey, callMethodBlocked, 1024, &callEthAcc)
  1067  			if tc.expectedErrorForContract {
  1068  				if len(tc.expectedErrorContains) != 0 {
  1069  					//suite.Require().Contains(err.Error(), tc.expectedErrorContains)
  1070  				}
  1071  				suite.Require().Error(err)
  1072  			} else {
  1073  				suite.Require().NoError(err)
  1074  			}
  1075  
  1076  			// nonce here could be any value
  1077  			err = suite.deployOrInvokeContract(callerPrivKey, delegatecallMethodBlocked, 1024, &callEthAcc)
  1078  			if tc.expectedErrorForContract {
  1079  				if len(tc.expectedErrorContains) != 0 {
  1080  					//suite.Require().Contains(err.Error(), tc.expectedErrorContains)
  1081  				}
  1082  				suite.Require().Error(err)
  1083  			} else {
  1084  				suite.Require().NoError(err)
  1085  			}
  1086  
  1087  			// nonce here could be any value
  1088  			err = suite.deployOrInvokeContract(callerPrivKey, callcodeMethodBlocked, 1024, &callEthAcc)
  1089  			if tc.expectedErrorForContract {
  1090  				if len(tc.expectedErrorContains) != 0 {
  1091  					//suite.Require().Contains(err.Error(), tc.expectedErrorContains)
  1092  				}
  1093  				suite.Require().Error(err)
  1094  			} else {
  1095  				suite.Require().NoError(err)
  1096  			}
  1097  
  1098  			// nonce here could be any value
  1099  			err = suite.deployOrInvokeContract(callerPrivKey, selfdestructMethodBlocked, 1024, &callEthAcc)
  1100  			if tc.msg == "Contract method could be invoked which method which is out of blocked list" {
  1101  				if len(tc.expectedErrorContains) != 0 {
  1102  					suite.Require().Contains(err.Error(), tc.expectedErrorContains)
  1103  				}
  1104  				suite.Require().Error(err)
  1105  			} else {
  1106  				if tc.expectedErrorForContract {
  1107  					if len(tc.expectedErrorContains) != 0 {
  1108  						suite.Require().Contains(err.Error(), tc.expectedErrorContains)
  1109  					}
  1110  					suite.Require().Error(err)
  1111  				} else {
  1112  					suite.Require().NoError(err)
  1113  				}
  1114  			}
  1115  
  1116  		})
  1117  	}
  1118  }