forked from cerc-io/laconicd-deprecated
		
	x/evm: state_transition test (#389)
* draft state_transition * working test * keeper test * Update x/evm/types/state_transition_test.go * update state_transition_test.go * failed Finalize test case Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Federico Kunze <federico.kunze94@gmail.com>
This commit is contained in:
		
							parent
							
								
									90f39390bc
								
							
						
					
					
						commit
						6bc80c5357
					
				@ -19,10 +19,10 @@ import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const addrHex = "0x756F45E3FA69347A9A973A725E3C98bC4db0b4c1"
 | 
			
		||||
const hex = "0x0d87a3a5f73140f46aac1bf419263e4e94e87c292f25007700ab7f2060e2af68"
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	address = ethcmn.HexToAddress(addrHex)
 | 
			
		||||
	hash    = ethcmn.FromHex("0x0d87a3a5f73140f46aac1bf419263e4e94e87c292f25007700ab7f2060e2af68")
 | 
			
		||||
	hash = ethcmn.FromHex(hex)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type KeeperTestSuite struct {
 | 
			
		||||
@ -31,6 +31,7 @@ type KeeperTestSuite struct {
 | 
			
		||||
	ctx     sdk.Context
 | 
			
		||||
	querier sdk.Querier
 | 
			
		||||
	app     *app.EthermintApp
 | 
			
		||||
	address ethcmn.Address
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (suite *KeeperTestSuite) SetupTest() {
 | 
			
		||||
@ -39,6 +40,7 @@ func (suite *KeeperTestSuite) SetupTest() {
 | 
			
		||||
	suite.app = app.Setup(checkTx)
 | 
			
		||||
	suite.ctx = suite.app.BaseApp.NewContext(checkTx, abci.Header{Height: 1, ChainID: "3", Time: time.Now().UTC()})
 | 
			
		||||
	suite.querier = keeper.NewQuerier(suite.app.EvmKeeper)
 | 
			
		||||
	suite.address = ethcmn.HexToAddress(addrHex)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestKeeperTestSuite(t *testing.T) {
 | 
			
		||||
@ -48,12 +50,12 @@ func TestKeeperTestSuite(t *testing.T) {
 | 
			
		||||
func (suite *KeeperTestSuite) TestTransactionLogs() {
 | 
			
		||||
	ethHash := ethcmn.BytesToHash(hash)
 | 
			
		||||
	log := ðtypes.Log{
 | 
			
		||||
		Address:     address,
 | 
			
		||||
		Address:     suite.address,
 | 
			
		||||
		Data:        []byte("log"),
 | 
			
		||||
		BlockNumber: 10,
 | 
			
		||||
	}
 | 
			
		||||
	log2 := ðtypes.Log{
 | 
			
		||||
		Address:     address,
 | 
			
		||||
		Address:     suite.address,
 | 
			
		||||
		Data:        []byte("log2"),
 | 
			
		||||
		BlockNumber: 11,
 | 
			
		||||
	}
 | 
			
		||||
@ -75,7 +77,7 @@ func (suite *KeeperTestSuite) TestTransactionLogs() {
 | 
			
		||||
 | 
			
		||||
	// add another log under the zero hash
 | 
			
		||||
	log3 := ðtypes.Log{
 | 
			
		||||
		Address:     address,
 | 
			
		||||
		Address:     suite.address,
 | 
			
		||||
		Data:        []byte("log3"),
 | 
			
		||||
		BlockNumber: 10,
 | 
			
		||||
	}
 | 
			
		||||
@ -93,11 +95,11 @@ func (suite *KeeperTestSuite) TestTransactionLogs() {
 | 
			
		||||
 | 
			
		||||
func (suite *KeeperTestSuite) TestDBStorage() {
 | 
			
		||||
	// Perform state transitions
 | 
			
		||||
	suite.app.EvmKeeper.CreateAccount(suite.ctx, address)
 | 
			
		||||
	suite.app.EvmKeeper.SetBalance(suite.ctx, address, big.NewInt(5))
 | 
			
		||||
	suite.app.EvmKeeper.SetNonce(suite.ctx, address, 4)
 | 
			
		||||
	suite.app.EvmKeeper.SetState(suite.ctx, address, ethcmn.HexToHash("0x2"), ethcmn.HexToHash("0x3"))
 | 
			
		||||
	suite.app.EvmKeeper.SetCode(suite.ctx, address, []byte{0x1})
 | 
			
		||||
	suite.app.EvmKeeper.CreateAccount(suite.ctx, suite.address)
 | 
			
		||||
	suite.app.EvmKeeper.SetBalance(suite.ctx, suite.address, big.NewInt(5))
 | 
			
		||||
	suite.app.EvmKeeper.SetNonce(suite.ctx, suite.address, 4)
 | 
			
		||||
	suite.app.EvmKeeper.SetState(suite.ctx, suite.address, ethcmn.HexToHash("0x2"), ethcmn.HexToHash("0x3"))
 | 
			
		||||
	suite.app.EvmKeeper.SetCode(suite.ctx, suite.address, []byte{0x1})
 | 
			
		||||
 | 
			
		||||
	// Test block hash mapping functionality
 | 
			
		||||
	suite.app.EvmKeeper.SetBlockHash(suite.ctx, hash, 7)
 | 
			
		||||
@ -112,10 +114,10 @@ func (suite *KeeperTestSuite) TestDBStorage() {
 | 
			
		||||
	suite.app.EvmKeeper.SetBlockBloom(suite.ctx, 4, testBloom)
 | 
			
		||||
 | 
			
		||||
	// Get those state transitions
 | 
			
		||||
	suite.Require().Equal(suite.app.EvmKeeper.GetBalance(suite.ctx, address).Cmp(big.NewInt(5)), 0)
 | 
			
		||||
	suite.Require().Equal(suite.app.EvmKeeper.GetNonce(suite.ctx, address), uint64(4))
 | 
			
		||||
	suite.Require().Equal(suite.app.EvmKeeper.GetState(suite.ctx, address, ethcmn.HexToHash("0x2")), ethcmn.HexToHash("0x3"))
 | 
			
		||||
	suite.Require().Equal(suite.app.EvmKeeper.GetCode(suite.ctx, address), []byte{0x1})
 | 
			
		||||
	suite.Require().Equal(suite.app.EvmKeeper.GetBalance(suite.ctx, suite.address).Cmp(big.NewInt(5)), 0)
 | 
			
		||||
	suite.Require().Equal(suite.app.EvmKeeper.GetNonce(suite.ctx, suite.address), uint64(4))
 | 
			
		||||
	suite.Require().Equal(suite.app.EvmKeeper.GetState(suite.ctx, suite.address, ethcmn.HexToHash("0x2")), ethcmn.HexToHash("0x3"))
 | 
			
		||||
	suite.Require().Equal(suite.app.EvmKeeper.GetCode(suite.ctx, suite.address), []byte{0x1})
 | 
			
		||||
 | 
			
		||||
	height, found = suite.app.EvmKeeper.GetBlockHash(suite.ctx, hash)
 | 
			
		||||
	suite.Require().True(found)
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,7 @@ import (
 | 
			
		||||
	"math/big"
 | 
			
		||||
 | 
			
		||||
	"github.com/cosmos/ethermint/x/evm/types"
 | 
			
		||||
	ethtypes "github.com/ethereum/go-ethereum/core/types"
 | 
			
		||||
 | 
			
		||||
	abci "github.com/tendermint/tendermint/abci/types"
 | 
			
		||||
)
 | 
			
		||||
@ -18,15 +19,20 @@ func (suite *KeeperTestSuite) TestQuerier() {
 | 
			
		||||
	}{
 | 
			
		||||
		{"protocol version", []string{types.QueryProtocolVersion}, func() {}, true},
 | 
			
		||||
		{"balance", []string{types.QueryBalance, addrHex}, func() {
 | 
			
		||||
			suite.app.EvmKeeper.SetBalance(suite.ctx, address, big.NewInt(5))
 | 
			
		||||
			suite.app.EvmKeeper.SetBalance(suite.ctx, suite.address, big.NewInt(5))
 | 
			
		||||
		}, true},
 | 
			
		||||
		// {"balance", []string{types.QueryBalance, "0x01232"}, func() {}, false},
 | 
			
		||||
		// {"balance fail", []string{types.QueryBalance, "0x01232"}, func() {}, false},
 | 
			
		||||
		{"block number", []string{types.QueryBlockNumber, "0x0"}, func() {}, true},
 | 
			
		||||
		{"storage", []string{types.QueryStorage, "0x0", "0x0"}, func() {}, true},
 | 
			
		||||
		{"code", []string{types.QueryCode, "0x0"}, func() {}, true},
 | 
			
		||||
		// {"hash to height", []string{types.QueryHashToHeight, "0x0"}, func() {}, true},
 | 
			
		||||
		{"hash to height", []string{types.QueryHashToHeight, hex}, func() {
 | 
			
		||||
			suite.app.EvmKeeper.SetBlockHash(suite.ctx, hash, 8)
 | 
			
		||||
		}, true},
 | 
			
		||||
		{"tx logs", []string{types.QueryTransactionLogs, "0x0"}, func() {}, true},
 | 
			
		||||
		// {"logs bloom", []string{types.QueryLogsBloom, "0x0"}, func() {}, true},
 | 
			
		||||
		{"bloom", []string{types.QueryBloom, "4"}, func() {
 | 
			
		||||
			testBloom := ethtypes.BytesToBloom([]byte{0x1, 0x3})
 | 
			
		||||
			suite.app.EvmKeeper.SetBlockBloom(suite.ctx, 4, testBloom)
 | 
			
		||||
		}, true},
 | 
			
		||||
		{"logs", []string{types.QueryLogs, "0x0"}, func() {}, true},
 | 
			
		||||
		{"account", []string{types.QueryAccount, "0x0"}, func() {}, true},
 | 
			
		||||
		{"exportAccount", []string{types.QueryExportAccount, "0x0"}, func() {}, true},
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										163
									
								
								x/evm/types/state_transition_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								x/evm/types/state_transition_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,163 @@
 | 
			
		||||
package types_test
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"math/big"
 | 
			
		||||
 | 
			
		||||
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
			
		||||
 | 
			
		||||
	"github.com/cosmos/ethermint/crypto"
 | 
			
		||||
	ethermint "github.com/cosmos/ethermint/types"
 | 
			
		||||
	"github.com/cosmos/ethermint/x/evm/types"
 | 
			
		||||
 | 
			
		||||
	ethcmn "github.com/ethereum/go-ethereum/common"
 | 
			
		||||
	ethcrypto "github.com/ethereum/go-ethereum/crypto"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (suite *StateDBTestSuite) TestTransitionDb() {
 | 
			
		||||
	suite.stateDB.SetNonce(suite.address, 123)
 | 
			
		||||
 | 
			
		||||
	addr := sdk.AccAddress(suite.address.Bytes())
 | 
			
		||||
	balance := sdk.NewCoin(ethermint.DenomDefault, sdk.NewInt(5000))
 | 
			
		||||
	suite.app.BankKeeper.SetBalance(suite.ctx, addr, balance)
 | 
			
		||||
 | 
			
		||||
	priv, err := crypto.GenerateKey()
 | 
			
		||||
	suite.Require().NoError(err)
 | 
			
		||||
	recipient := ethcrypto.PubkeyToAddress(priv.ToECDSA().PublicKey)
 | 
			
		||||
 | 
			
		||||
	testCase := []struct {
 | 
			
		||||
		name     string
 | 
			
		||||
		malleate func()
 | 
			
		||||
		state    types.StateTransition
 | 
			
		||||
		expPass  bool
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"passing state transition",
 | 
			
		||||
			func() {},
 | 
			
		||||
			types.StateTransition{
 | 
			
		||||
				AccountNonce: 123,
 | 
			
		||||
				Price:        big.NewInt(10),
 | 
			
		||||
				GasLimit:     11,
 | 
			
		||||
				Recipient:    &recipient,
 | 
			
		||||
				Amount:       big.NewInt(50),
 | 
			
		||||
				Payload:      []byte("data"),
 | 
			
		||||
				ChainID:      big.NewInt(1),
 | 
			
		||||
				Csdb:         suite.stateDB,
 | 
			
		||||
				TxHash:       ðcmn.Hash{},
 | 
			
		||||
				Sender:       suite.address,
 | 
			
		||||
				Simulate:     suite.ctx.IsCheckTx(),
 | 
			
		||||
			},
 | 
			
		||||
			true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"contract creation",
 | 
			
		||||
			func() {},
 | 
			
		||||
			types.StateTransition{
 | 
			
		||||
				AccountNonce: 123,
 | 
			
		||||
				Price:        big.NewInt(10),
 | 
			
		||||
				GasLimit:     11,
 | 
			
		||||
				Recipient:    nil,
 | 
			
		||||
				Amount:       big.NewInt(10),
 | 
			
		||||
				Payload:      []byte("data"),
 | 
			
		||||
				ChainID:      big.NewInt(1),
 | 
			
		||||
				Csdb:         suite.stateDB,
 | 
			
		||||
				TxHash:       ðcmn.Hash{},
 | 
			
		||||
				Sender:       suite.address,
 | 
			
		||||
				Simulate:     true,
 | 
			
		||||
			},
 | 
			
		||||
			true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"state transition simulation",
 | 
			
		||||
			func() {},
 | 
			
		||||
			types.StateTransition{
 | 
			
		||||
				AccountNonce: 123,
 | 
			
		||||
				Price:        big.NewInt(10),
 | 
			
		||||
				GasLimit:     11,
 | 
			
		||||
				Recipient:    &recipient,
 | 
			
		||||
				Amount:       big.NewInt(10),
 | 
			
		||||
				Payload:      []byte("data"),
 | 
			
		||||
				ChainID:      big.NewInt(1),
 | 
			
		||||
				Csdb:         suite.stateDB,
 | 
			
		||||
				TxHash:       ðcmn.Hash{},
 | 
			
		||||
				Sender:       suite.address,
 | 
			
		||||
				Simulate:     true,
 | 
			
		||||
			},
 | 
			
		||||
			true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"fail by sending more than balance",
 | 
			
		||||
			func() {},
 | 
			
		||||
			types.StateTransition{
 | 
			
		||||
				AccountNonce: 123,
 | 
			
		||||
				Price:        big.NewInt(10),
 | 
			
		||||
				GasLimit:     11,
 | 
			
		||||
				Recipient:    &recipient,
 | 
			
		||||
				Amount:       big.NewInt(4951),
 | 
			
		||||
				Payload:      []byte("data"),
 | 
			
		||||
				ChainID:      big.NewInt(1),
 | 
			
		||||
				Csdb:         suite.stateDB,
 | 
			
		||||
				TxHash:       ðcmn.Hash{},
 | 
			
		||||
				Sender:       suite.address,
 | 
			
		||||
				Simulate:     suite.ctx.IsCheckTx(),
 | 
			
		||||
			},
 | 
			
		||||
			false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"failed to Finalize",
 | 
			
		||||
			func() {},
 | 
			
		||||
			types.StateTransition{
 | 
			
		||||
				AccountNonce: 123,
 | 
			
		||||
				Price:        big.NewInt(10),
 | 
			
		||||
				GasLimit:     11,
 | 
			
		||||
				Recipient:    &recipient,
 | 
			
		||||
				Amount:       big.NewInt(-5000),
 | 
			
		||||
				Payload:      []byte("data"),
 | 
			
		||||
				ChainID:      big.NewInt(1),
 | 
			
		||||
				Csdb:         suite.stateDB,
 | 
			
		||||
				TxHash:       ðcmn.Hash{},
 | 
			
		||||
				Sender:       suite.address,
 | 
			
		||||
				Simulate:     false,
 | 
			
		||||
			},
 | 
			
		||||
			false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"nil gas price",
 | 
			
		||||
			func() {
 | 
			
		||||
				invalidGas := sdk.DecCoins{
 | 
			
		||||
					{Denom: ethermint.DenomDefault},
 | 
			
		||||
				}
 | 
			
		||||
				suite.ctx = suite.ctx.WithMinGasPrices(invalidGas)
 | 
			
		||||
			},
 | 
			
		||||
			types.StateTransition{
 | 
			
		||||
				AccountNonce: 123,
 | 
			
		||||
				Price:        big.NewInt(10),
 | 
			
		||||
				GasLimit:     11,
 | 
			
		||||
				Recipient:    &recipient,
 | 
			
		||||
				Amount:       big.NewInt(10),
 | 
			
		||||
				Payload:      []byte("data"),
 | 
			
		||||
				ChainID:      big.NewInt(1),
 | 
			
		||||
				Csdb:         suite.stateDB,
 | 
			
		||||
				TxHash:       ðcmn.Hash{},
 | 
			
		||||
				Sender:       suite.address,
 | 
			
		||||
				Simulate:     suite.ctx.IsCheckTx(),
 | 
			
		||||
			},
 | 
			
		||||
			false,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCase {
 | 
			
		||||
		tc.malleate()
 | 
			
		||||
 | 
			
		||||
		_, err = tc.state.TransitionDb(suite.ctx)
 | 
			
		||||
 | 
			
		||||
		if tc.expPass {
 | 
			
		||||
			suite.Require().NoError(err, tc.name)
 | 
			
		||||
			fromBalance := suite.app.EvmKeeper.GetBalance(suite.ctx, suite.address)
 | 
			
		||||
			toBalance := suite.app.EvmKeeper.GetBalance(suite.ctx, recipient)
 | 
			
		||||
			suite.Require().Equal(fromBalance, big.NewInt(4950), tc.name)
 | 
			
		||||
			suite.Require().Equal(toBalance, big.NewInt(50), tc.name)
 | 
			
		||||
		} else {
 | 
			
		||||
			suite.Require().Error(err, tc.name)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user