laconicd/x/evm/statedb/mock_test.go
yihuang e6c9b7723b
evm: improve test coverage of statedb package (#888)
Closes: #876
- coverage: 99.3% of statements
2022-01-06 18:10:51 +01:00

115 lines
2.7 KiB
Go

package statedb_test
import (
"bytes"
"errors"
"math/big"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/tharsis/ethermint/x/evm/statedb"
)
var (
_ statedb.Keeper = &MockKeeper{}
errAddress common.Address = common.BigToAddress(big.NewInt(100))
emptyCodeHash = crypto.Keccak256(nil)
)
type MockAcount struct {
account statedb.Account
states statedb.Storage
}
type MockKeeper struct {
accounts map[common.Address]MockAcount
codes map[common.Hash][]byte
}
func NewMockKeeper() *MockKeeper {
return &MockKeeper{
accounts: make(map[common.Address]MockAcount),
codes: make(map[common.Hash][]byte),
}
}
func (k MockKeeper) GetAccount(ctx sdk.Context, addr common.Address) *statedb.Account {
acct, ok := k.accounts[addr]
if !ok {
return nil
}
return &acct.account
}
func (k MockKeeper) GetState(ctx sdk.Context, addr common.Address, key common.Hash) common.Hash {
return k.accounts[addr].states[key]
}
func (k MockKeeper) GetCode(ctx sdk.Context, codeHash common.Hash) []byte {
return k.codes[codeHash]
}
func (k MockKeeper) ForEachStorage(ctx sdk.Context, addr common.Address, cb func(key, value common.Hash) bool) {
if acct, ok := k.accounts[addr]; ok {
for k, v := range acct.states {
if !cb(k, v) {
return
}
}
}
}
func (k MockKeeper) SetAccount(ctx sdk.Context, addr common.Address, account statedb.Account) error {
if addr == errAddress {
return errors.New("mock db error")
}
acct, exists := k.accounts[addr]
if exists {
// update
acct.account = account
k.accounts[addr] = acct
} else {
k.accounts[addr] = MockAcount{account: account, states: make(statedb.Storage)}
}
return nil
}
func (k MockKeeper) SetState(ctx sdk.Context, addr common.Address, key common.Hash, value []byte) {
if acct, ok := k.accounts[addr]; ok {
if len(value) == 0 {
delete(acct.states, key)
} else {
acct.states[key] = common.BytesToHash(value)
}
}
}
func (k MockKeeper) SetCode(ctx sdk.Context, codeHash []byte, code []byte) {
k.codes[common.BytesToHash(codeHash)] = code
}
func (k MockKeeper) DeleteAccount(ctx sdk.Context, addr common.Address) error {
if addr == errAddress {
return errors.New("mock db error")
}
old := k.accounts[addr]
delete(k.accounts, addr)
if !bytes.Equal(old.account.CodeHash, emptyCodeHash) {
delete(k.codes, common.BytesToHash(old.account.CodeHash))
}
return nil
}
func (k MockKeeper) Clone() *MockKeeper {
accounts := make(map[common.Address]MockAcount, len(k.accounts))
for k, v := range k.accounts {
accounts[k] = v
}
codes := make(map[common.Hash][]byte, len(k.codes))
for k, v := range k.codes {
codes[k] = v
}
return &MockKeeper{accounts, codes}
}