Skip to content

Commit

Permalink
Problem: no unit test for native action (#337)
Browse files Browse the repository at this point in the history
* Problem: no unit test for native action

Solution:
- add unit test

* test nested cases
  • Loading branch information
yihuang authored Sep 8, 2023
1 parent c12fa3b commit 7909c18
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 3 deletions.
16 changes: 13 additions & 3 deletions x/evm/statedb/mock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,23 @@ type MockAcount struct {
type MockKeeper struct {
accounts map[common.Address]MockAcount
codes map[common.Hash][]byte
keys map[string]*storetypes.KVStoreKey
}

func NewMockKeeper() *MockKeeper {
func NewMockKeeperWithKeys(keys map[string]*storetypes.KVStoreKey) *MockKeeper {
return &MockKeeper{
accounts: make(map[common.Address]MockAcount),
codes: make(map[common.Hash][]byte),
keys: keys,
}
}

func NewMockKeeper() *MockKeeper {
return NewMockKeeperWithKeys(nil)
}

func (k MockKeeper) StoreKeys() map[string]*storetypes.KVStoreKey {
return nil
return k.keys
}

func (k MockKeeper) GetAccount(ctx sdk.Context, addr common.Address) *statedb.Account {
Expand Down Expand Up @@ -115,5 +121,9 @@ func (k MockKeeper) Clone() *MockKeeper {
for k, v := range k.codes {
codes[k] = v
}
return &MockKeeper{accounts, codes}
keys := make(map[string]*storetypes.KVStoreKey, len(k.keys))
for k, v := range k.keys {
keys[k] = v
}
return &MockKeeper{accounts, codes, keys}
}
88 changes: 88 additions & 0 deletions x/evm/statedb/statedb_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package statedb_test

import (
"errors"
"math/big"
"testing"

dbm "github.com/cometbft/cometbft-db"
"github.com/cometbft/cometbft/libs/log"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/store/rootmulti"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
Expand Down Expand Up @@ -565,6 +571,88 @@ func (suite *StateDBTestSuite) TestIterateStorage() {
suite.Require().Equal(1, len(storage))
}

func (suite *StateDBTestSuite) TestNativeAction() {
db := dbm.NewMemDB()
ms := rootmulti.NewStore(db, log.NewNopLogger())
keys := map[string]*storetypes.KVStoreKey{
"storekey": storetypes.NewKVStoreKey("storekey"),
}
ms.MountStoreWithDB(keys["storekey"], storetypes.StoreTypeIAVL, nil)
suite.Require().NoError(ms.LoadLatestVersion())
ctx := sdk.NewContext(ms, tmproto.Header{}, false, log.NewNopLogger())

keeper := NewMockKeeperWithKeys(keys)
stateDB := statedb.New(ctx, keeper, emptyTxConfig)

stateDB.ExecuteNativeAction(func(ctx sdk.Context) error {
store := ctx.KVStore(keys["storekey"])
store.Set([]byte("success1"), []byte("value"))
return nil
})
stateDB.ExecuteNativeAction(func(ctx sdk.Context) error {
store := ctx.KVStore(keys["storekey"])
store.Set([]byte("failure1"), []byte("value"))
return errors.New("failure")
})

// test query
stateDB.ExecuteNativeAction(func(ctx sdk.Context) error {
store := ctx.KVStore(keys["storekey"])
suite.Require().Equal([]byte("value"), store.Get([]byte("success1")))
suite.Require().Nil(store.Get([]byte("failure1")))
return nil
})

rev1 := stateDB.Snapshot()
stateDB.ExecuteNativeAction(func(ctx sdk.Context) error {
store := ctx.KVStore(keys["storekey"])
store.Set([]byte("success2"), []byte("value"))
return nil
})
stateDB.ExecuteNativeAction(func(ctx sdk.Context) error {
store := ctx.KVStore(keys["storekey"])
store.Set([]byte("failure2"), []byte("value"))
return errors.New("failure")
})

// test query
stateDB.ExecuteNativeAction(func(ctx sdk.Context) error {
store := ctx.KVStore(keys["storekey"])
suite.Require().Equal([]byte("value"), store.Get([]byte("success1")))
suite.Require().Equal([]byte("value"), store.Get([]byte("success2")))
suite.Require().Nil(store.Get([]byte("failure2")))
return nil
})

stateDB.RevertToSnapshot(rev1)

_ = stateDB.Snapshot()
stateDB.ExecuteNativeAction(func(ctx sdk.Context) error {
store := ctx.KVStore(keys["storekey"])
store.Set([]byte("success3"), []byte("value"))
return nil
})

// test query
stateDB.ExecuteNativeAction(func(ctx sdk.Context) error {
store := ctx.KVStore(keys["storekey"])
suite.Require().Equal([]byte("value"), store.Get([]byte("success1")))
suite.Require().Nil(store.Get([]byte("success2")))
suite.Require().Equal([]byte("value"), store.Get([]byte("success3")))
return nil
})

suite.Require().NoError(stateDB.Commit())

// query committed state
store := ctx.KVStore(keys["storekey"])
suite.Require().Equal([]byte("value"), store.Get([]byte("success1")))
suite.Require().Nil(store.Get([]byte("success2")))
suite.Require().Equal([]byte("value"), store.Get([]byte("success3")))
suite.Require().Nil(store.Get([]byte("failure1")))
suite.Require().Nil(store.Get([]byte("failure2")))
}

func CollectContractStorage(db vm.StateDB) statedb.Storage {
storage := make(statedb.Storage)
db.ForEachStorage(address, func(k, v common.Hash) bool {
Expand Down

0 comments on commit 7909c18

Please sign in to comment.