types, evm: refactor accounts (#884)
* types,evm: refactor accounts * fix * fix panic * changelog * fix * lint, rm dbErr
This commit is contained in:
parent
eea80d50c3
commit
4320f46fc8
@ -56,6 +56,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
|
||||
### Improvements
|
||||
|
||||
* (types) [tharsis#884](https://github.com/tharsis/ethermint/pull/884) Introduce a new `EthAccountI` interface for EVM-compatible account types.
|
||||
* (types) [tharsis#849](https://github.com/tharsis/ethermint/pull/849) Add `Type` function to distinguish EOAs from Contract accounts.
|
||||
* (evm) [tharsis#826](https://github.com/tharsis/ethermint/issues/826) Improve allocation of bytes of `tx.To` address.
|
||||
* (evm) [tharsis#827](https://github.com/tharsis/ethermint/issues/827) Speed up creation of event logs by using the slice insertion idiom with indices.
|
||||
@ -64,6 +65,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* (evm) [tharsis#884](https://github.com/tharsis/ethermint/pull/884) Support multiple account types on the EVM `StateDB`.
|
||||
* (rpc) [tharsis#831](https://github.com/tharsis/ethermint/pull/831) Fix BaseFee value when height is specified.
|
||||
* (evm) [tharsis#838](https://github.com/tharsis/ethermint/pull/838) Fix splitting of trace.Memory into 32 chunks.
|
||||
* (rpc) [tharsis#860](https://github.com/tharsis/ethermint/pull/860) Fix `eth_getLogs` when specify blockHash without address/topics, and limit the response size.
|
||||
|
@ -115,11 +115,8 @@ func (avd EthAccountVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx
|
||||
|
||||
// check whether the sender address is EOA
|
||||
fromAddr := common.BytesToAddress(from)
|
||||
acct, err := avd.evmKeeper.GetAccount(ctx, fromAddr)
|
||||
if err != nil {
|
||||
return ctx, sdkerrors.Wrapf(sdkerrors.ErrInvalidType,
|
||||
"the sender is not EthAccount: address %s", fromAddr)
|
||||
}
|
||||
acct := avd.evmKeeper.GetAccount(ctx, fromAddr)
|
||||
|
||||
if acct == nil {
|
||||
acc := avd.ak.NewAccountWithAddress(ctx, from)
|
||||
avd.ak.SetAccount(ctx, acc)
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
tx "github.com/cosmos/cosmos-sdk/types/tx"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
@ -23,6 +24,7 @@ type EVMKeeper interface {
|
||||
ctx sdk.Context, msgEthTx evmtypes.MsgEthereumTx, txData evmtypes.TxData, denom string, homestead, istanbul, london bool,
|
||||
) (sdk.Coins, error)
|
||||
BaseFee(ctx sdk.Context, ethCfg *params.ChainConfig) *big.Int
|
||||
GetBalance(ctx sdk.Context, addr common.Address) *big.Int
|
||||
}
|
||||
|
||||
type protoTxProvider interface {
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
|
||||
var (
|
||||
_ authtypes.AccountI = (*EthAccount)(nil)
|
||||
_ EthAccountI = (*EthAccount)(nil)
|
||||
_ authtypes.GenesisAccount = (*EthAccount)(nil)
|
||||
_ codectypes.UnpackInterfacesMessage = (*EthAccount)(nil)
|
||||
)
|
||||
@ -25,6 +26,19 @@ const (
|
||||
AccountTypeContract
|
||||
)
|
||||
|
||||
// EthAccountI represents the interface of an EVM compatible account
|
||||
type EthAccountI interface {
|
||||
authtypes.AccountI
|
||||
// EthAddress returns the ethereum Address representation of the AccAddress
|
||||
EthAddress() common.Address
|
||||
// CodeHash is the keccak256 hash of the contract code (if any)
|
||||
GetCodeHash() common.Hash
|
||||
// SetCodeHash sets the code hash to the account fields
|
||||
SetCodeHash(code common.Hash) error
|
||||
// Type returns the type of Ethereum Account (EOA or Contract)
|
||||
Type() int8
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Main Ethermint account
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -48,6 +62,12 @@ func (acc EthAccount) GetCodeHash() common.Hash {
|
||||
return common.HexToHash(acc.CodeHash)
|
||||
}
|
||||
|
||||
// SetCodeHash sets the account code hash to the EthAccount fields
|
||||
func (acc *EthAccount) SetCodeHash(codeHash common.Hash) error {
|
||||
acc.CodeHash = codeHash.Hex()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Type returns the type of Ethereum Account (EOA or Contract)
|
||||
func (acc EthAccount) Type() int8 {
|
||||
if bytes.Equal(emptyCodeHash, common.Hex2Bytes(acc.CodeHash)) {
|
||||
|
@ -1,12 +0,0 @@
|
||||
package types
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Code
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Code is account Code type alias
|
||||
type Code []byte
|
||||
|
||||
func (c Code) String() string {
|
||||
return string(c)
|
||||
}
|
@ -40,20 +40,21 @@ func InitGenesis(
|
||||
panic(fmt.Errorf("account not found for address %s", account.Address))
|
||||
}
|
||||
|
||||
ethAcct, ok := acc.(*ethermint.EthAccount)
|
||||
ethAcct, ok := acc.(ethermint.EthAccountI)
|
||||
if !ok {
|
||||
panic(
|
||||
fmt.Errorf("account %s must be an %T type, got %T",
|
||||
account.Address, ðermint.EthAccount{}, acc,
|
||||
fmt.Errorf("account %s must be an EthAccount interface, got %T",
|
||||
account.Address, acc,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
code := common.Hex2Bytes(account.Code)
|
||||
codeHash := crypto.Keccak256Hash(code)
|
||||
if !bytes.Equal(common.HexToHash(ethAcct.CodeHash).Bytes(), codeHash.Bytes()) {
|
||||
if !bytes.Equal(ethAcct.GetCodeHash().Bytes(), codeHash.Bytes()) {
|
||||
panic("code don't match codeHash")
|
||||
}
|
||||
|
||||
k.SetCode(ctx, codeHash.Bytes(), code)
|
||||
|
||||
for _, storage := range account.Storage {
|
||||
@ -68,7 +69,7 @@ func InitGenesis(
|
||||
func ExportGenesis(ctx sdk.Context, k *keeper.Keeper, ak types.AccountKeeper) *types.GenesisState {
|
||||
var ethGenAccounts []types.GenesisAccount
|
||||
ak.IterateAccounts(ctx, func(account authtypes.AccountI) bool {
|
||||
ethAccount, ok := account.(*ethermint.EthAccount)
|
||||
ethAccount, ok := account.(ethermint.EthAccountI)
|
||||
if !ok {
|
||||
// ignore non EthAccounts
|
||||
return false
|
||||
|
@ -48,10 +48,8 @@ func (k Keeper) Account(c context.Context, req *types.QueryAccountRequest) (*typ
|
||||
addr := common.HexToAddress(req.Address)
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
acct, err := k.GetAccountOrEmpty(ctx, addr)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||
}
|
||||
acct := k.GetAccountOrEmpty(ctx, addr)
|
||||
|
||||
return &types.QueryAccountResponse{
|
||||
Balance: acct.Balance.String(),
|
||||
CodeHash: common.BytesToHash(acct.CodeHash).Hex(),
|
||||
@ -186,10 +184,7 @@ func (k Keeper) Code(c context.Context, req *types.QueryCodeRequest) (*types.Que
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
address := common.HexToAddress(req.Address)
|
||||
acct, err := k.GetAccountWithoutBalance(ctx, address)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||
}
|
||||
acct := k.GetAccountWithoutBalance(ctx, address)
|
||||
|
||||
var code []byte
|
||||
if acct != nil && acct.IsContract() {
|
||||
|
@ -345,9 +345,7 @@ func (suite *KeeperTestSuite) TestQueryCode() {
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestQueryTxLogs() {
|
||||
var (
|
||||
expLogs []*types.Log
|
||||
)
|
||||
var expLogs []*types.Log
|
||||
txHash := common.BytesToHash([]byte("tx_hash"))
|
||||
txIndex := uint(1)
|
||||
logIndex := uint(1)
|
||||
@ -593,7 +591,7 @@ func (suite *KeeperTestSuite) TestEstimateGas() {
|
||||
rsp, err := suite.queryClient.EstimateGas(sdk.WrapSDKContext(suite.ctx), &req)
|
||||
if tc.expPass {
|
||||
suite.Require().NoError(err)
|
||||
suite.Require().Equal(tc.expGas, rsp.Gas)
|
||||
suite.Require().Equal(int64(tc.expGas), int64(rsp.Gas))
|
||||
} else {
|
||||
suite.Require().Error(err)
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/store/prefix"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
@ -235,38 +234,37 @@ func (k Keeper) Tracer(ctx sdk.Context, msg core.Message, ethCfg *params.ChainCo
|
||||
|
||||
// GetAccountWithoutBalance load nonce and codehash without balance,
|
||||
// more efficient in cases where balance is not needed.
|
||||
func (k *Keeper) GetAccountWithoutBalance(ctx sdk.Context, addr common.Address) (*statedb.Account, error) {
|
||||
func (k *Keeper) GetAccountWithoutBalance(ctx sdk.Context, addr common.Address) *statedb.Account {
|
||||
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
||||
acct := k.accountKeeper.GetAccount(ctx, cosmosAddr)
|
||||
if acct == nil {
|
||||
return nil, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
ethAcct, ok := acct.(*ethermint.EthAccount)
|
||||
if !ok {
|
||||
return nil, sdkerrors.Wrapf(types.ErrInvalidAccount, "type %T, address %s", acct, addr)
|
||||
codeHash := types.EmptyCodeHash
|
||||
ethAcct, ok := acct.(ethermint.EthAccountI)
|
||||
if ok {
|
||||
codeHash = ethAcct.GetCodeHash().Bytes()
|
||||
}
|
||||
|
||||
return &statedb.Account{
|
||||
Nonce: ethAcct.Sequence,
|
||||
CodeHash: common.FromHex(ethAcct.CodeHash),
|
||||
}, nil
|
||||
Nonce: acct.GetSequence(),
|
||||
CodeHash: codeHash,
|
||||
}
|
||||
}
|
||||
|
||||
// GetAccountOrEmpty returns empty account if not exist, returns error if it's not `EthAccount`
|
||||
func (k *Keeper) GetAccountOrEmpty(ctx sdk.Context, addr common.Address) (statedb.Account, error) {
|
||||
acct, err := k.GetAccount(ctx, addr)
|
||||
if err != nil {
|
||||
return statedb.Account{}, err
|
||||
func (k *Keeper) GetAccountOrEmpty(ctx sdk.Context, addr common.Address) statedb.Account {
|
||||
acct := k.GetAccount(ctx, addr)
|
||||
if acct != nil {
|
||||
return *acct
|
||||
}
|
||||
if acct == nil {
|
||||
// empty account
|
||||
return statedb.Account{
|
||||
Balance: new(big.Int),
|
||||
CodeHash: types.EmptyCodeHash,
|
||||
}, nil
|
||||
|
||||
// empty account
|
||||
return statedb.Account{
|
||||
Balance: new(big.Int),
|
||||
CodeHash: types.EmptyCodeHash,
|
||||
}
|
||||
return *acct, nil
|
||||
}
|
||||
|
||||
// GetNonce returns the sequence number of an account, returns 0 if not exists.
|
||||
@ -277,12 +275,7 @@ func (k *Keeper) GetNonce(ctx sdk.Context, addr common.Address) uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
ethAcct, ok := acct.(*ethermint.EthAccount)
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
|
||||
return ethAcct.Sequence
|
||||
return acct.GetSequence()
|
||||
}
|
||||
|
||||
// GetBalance load account's balance of gas token
|
||||
|
@ -17,18 +17,18 @@ import (
|
||||
var _ statedb.Keeper = &Keeper{}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// statedb.Keeper implementation
|
||||
// StateDB Keeper implementation
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// GetAccount returns nil if account is not exist, returns error if it's not `EthAccount`
|
||||
func (k *Keeper) GetAccount(ctx sdk.Context, addr common.Address) (*statedb.Account, error) {
|
||||
acct, err := k.GetAccountWithoutBalance(ctx, addr)
|
||||
if acct == nil || err != nil {
|
||||
return acct, err
|
||||
// GetAccount returns nil if account is not exist, returns error if it's not `EthAccountI`
|
||||
func (k *Keeper) GetAccount(ctx sdk.Context, addr common.Address) *statedb.Account {
|
||||
acct := k.GetAccountWithoutBalance(ctx, addr)
|
||||
if acct == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
acct.Balance = k.GetBalance(ctx, addr)
|
||||
return acct, nil
|
||||
return acct
|
||||
}
|
||||
|
||||
// GetState loads contract state from database, implements `statedb.Keeper` interface.
|
||||
@ -109,25 +109,33 @@ func (k *Keeper) SetAccount(ctx sdk.Context, addr common.Address, account stated
|
||||
if acct == nil {
|
||||
acct = k.accountKeeper.NewAccountWithAddress(ctx, cosmosAddr)
|
||||
}
|
||||
ethAcct, ok := acct.(*ethermint.EthAccount)
|
||||
if !ok {
|
||||
return sdkerrors.Wrapf(types.ErrInvalidAccount, "type %T, address %s", acct, addr)
|
||||
}
|
||||
if err := ethAcct.SetSequence(account.Nonce); err != nil {
|
||||
|
||||
if err := acct.SetSequence(account.Nonce); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
codeHash := common.BytesToHash(account.CodeHash)
|
||||
|
||||
if ethAcct, ok := acct.(ethermint.EthAccountI); ok {
|
||||
if err := ethAcct.SetCodeHash(codeHash); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
k.accountKeeper.SetAccount(ctx, acct)
|
||||
|
||||
if err := k.SetBalance(ctx, addr, account.Balance); err != nil {
|
||||
return err
|
||||
}
|
||||
ethAcct.CodeHash = common.BytesToHash(account.CodeHash).Hex()
|
||||
k.accountKeeper.SetAccount(ctx, ethAcct)
|
||||
|
||||
err := k.SetBalance(ctx, addr, account.Balance)
|
||||
k.Logger(ctx).Debug(
|
||||
"account updated",
|
||||
"ethereum-address", addr.Hex(),
|
||||
"nonce", account.Nonce,
|
||||
"codeHash", common.BytesToHash(account.CodeHash).Hex(),
|
||||
"codeHash", codeHash.Hex(),
|
||||
"balance", account.Balance,
|
||||
)
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetState update contract storage, delete if value is empty.
|
||||
@ -177,7 +185,8 @@ func (k *Keeper) DeleteAccount(ctx sdk.Context, addr common.Address) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
ethAcct, ok := acct.(*ethermint.EthAccount)
|
||||
// NOTE: only Ethereum accounts (contracts) can be selfdestructed
|
||||
ethAcct, ok := acct.(ethermint.EthAccountI)
|
||||
if !ok {
|
||||
return sdkerrors.Wrapf(types.ErrInvalidAccount, "type %T, address %s", acct, addr)
|
||||
}
|
||||
@ -188,9 +197,9 @@ func (k *Keeper) DeleteAccount(ctx sdk.Context, addr common.Address) error {
|
||||
}
|
||||
|
||||
// remove code
|
||||
codeHash := common.HexToHash(ethAcct.CodeHash).Bytes()
|
||||
if !bytes.Equal(codeHash, types.EmptyCodeHash) {
|
||||
k.SetCode(ctx, codeHash, nil)
|
||||
codeHashBz := ethAcct.GetCodeHash().Bytes()
|
||||
if !bytes.Equal(codeHashBz, types.EmptyCodeHash) {
|
||||
k.SetCode(ctx, codeHashBz, nil)
|
||||
}
|
||||
|
||||
// clear storage
|
||||
|
@ -235,9 +235,9 @@ func (suite *KeeperTestSuite) TestGetCodeHash() {
|
||||
func(vm.StateDB) {},
|
||||
},
|
||||
{
|
||||
"account not EthAccount type, error",
|
||||
"account not EthAccount type, EmptyCodeHash",
|
||||
addr,
|
||||
common.Hash{},
|
||||
common.BytesToHash(types.EmptyCodeHash),
|
||||
func(vm.StateDB) {},
|
||||
},
|
||||
{
|
||||
@ -469,27 +469,21 @@ func (suite *KeeperTestSuite) TestExist() {
|
||||
|
||||
func (suite *KeeperTestSuite) TestEmpty() {
|
||||
suite.SetupTest()
|
||||
addr := tests.GenerateAddress()
|
||||
baseAcc := &authtypes.BaseAccount{Address: sdk.AccAddress(addr.Bytes()).String()}
|
||||
suite.app.AccountKeeper.SetAccount(suite.ctx, baseAcc)
|
||||
|
||||
acct, err := suite.app.EvmKeeper.GetAccount(suite.ctx, suite.address)
|
||||
suite.Require().NoError(err)
|
||||
fmt.Println("default address", acct)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
address common.Address
|
||||
malleate func(vm.StateDB)
|
||||
empty bool
|
||||
expErr bool
|
||||
}{
|
||||
{"empty, account exists", suite.address, func(vm.StateDB) {}, true, false},
|
||||
{"error, non ethereum account", addr, func(vm.StateDB) {}, true, true},
|
||||
{"not empty, positive balance", suite.address, func(vmdb vm.StateDB) {
|
||||
vmdb.AddBalance(suite.address, big.NewInt(100))
|
||||
}, false, false},
|
||||
{"empty, account doesn't exist", tests.GenerateAddress(), func(vm.StateDB) {}, true, false},
|
||||
{"empty, account exists", suite.address, func(vm.StateDB) {}, true},
|
||||
{
|
||||
"not empty, positive balance",
|
||||
suite.address,
|
||||
func(vmdb vm.StateDB) { vmdb.AddBalance(suite.address, big.NewInt(100)) },
|
||||
false,
|
||||
},
|
||||
{"empty, account doesn't exist", tests.GenerateAddress(), func(vm.StateDB) {}, true},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
@ -498,11 +492,6 @@ func (suite *KeeperTestSuite) TestEmpty() {
|
||||
tc.malleate(vmdb)
|
||||
|
||||
suite.Require().Equal(tc.empty, vmdb.Empty(tc.address))
|
||||
if tc.expErr {
|
||||
suite.Require().Error(vmdb.Error())
|
||||
} else {
|
||||
suite.Require().NoError(vmdb.Error())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -235,9 +235,8 @@ func (suite *KeeperTestSuite) TestCheckSenderBalance() {
|
||||
|
||||
txData, _ := evmtypes.UnpackTxData(tx.Data)
|
||||
|
||||
acct, err := suite.app.EvmKeeper.GetAccountOrEmpty(suite.ctx, suite.address)
|
||||
suite.Require().NoError(err)
|
||||
err = evmkeeper.CheckSenderBalance(
|
||||
acct := suite.app.EvmKeeper.GetAccountOrEmpty(suite.ctx, suite.address)
|
||||
err := evmkeeper.CheckSenderBalance(
|
||||
sdk.NewIntFromBigInt(acct.Balance),
|
||||
txData,
|
||||
)
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
// Keeper provide underlying storage of StateDB
|
||||
type Keeper interface {
|
||||
// Read methods
|
||||
GetAccount(ctx sdk.Context, addr common.Address) (*Account, error)
|
||||
GetAccount(ctx sdk.Context, addr common.Address) *Account
|
||||
GetState(ctx sdk.Context, addr common.Address, key common.Hash) common.Hash
|
||||
GetCode(ctx sdk.Context, codeHash common.Hash) []byte
|
||||
// the callback returns false to break early
|
||||
|
@ -1,7 +1,6 @@
|
||||
package statedb_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math/big"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@ -29,15 +28,12 @@ func NewMockKeeper() *MockKeeper {
|
||||
}
|
||||
}
|
||||
|
||||
func (k MockKeeper) GetAccount(ctx sdk.Context, addr common.Address) (*statedb.Account, error) {
|
||||
if addr == k.errAddress {
|
||||
return nil, errors.New("mock db error")
|
||||
}
|
||||
func (k MockKeeper) GetAccount(ctx sdk.Context, addr common.Address) *statedb.Account {
|
||||
acct, ok := k.accounts[addr]
|
||||
if !ok {
|
||||
return nil, nil
|
||||
return nil
|
||||
}
|
||||
return &acct, nil
|
||||
return &acct
|
||||
}
|
||||
|
||||
func (k MockKeeper) GetState(ctx sdk.Context, addr common.Address, key common.Hash) common.Hash {
|
||||
|
@ -31,7 +31,6 @@ var _ vm.StateDB = &StateDB{}
|
||||
type StateDB struct {
|
||||
keeper Keeper
|
||||
ctx sdk.Context
|
||||
dbErr error
|
||||
|
||||
// Journal of state modifications. This is the backbone of
|
||||
// Snapshot and RevertToSnapshot.
|
||||
@ -76,18 +75,6 @@ func (s *StateDB) Context() sdk.Context {
|
||||
return s.ctx
|
||||
}
|
||||
|
||||
// setError remembers the first non-nil error it is called with.
|
||||
func (s *StateDB) setError(err error) {
|
||||
if s.dbErr == nil {
|
||||
s.dbErr = err
|
||||
}
|
||||
}
|
||||
|
||||
// Error returns the database error recorded.
|
||||
func (s *StateDB) Error() error {
|
||||
return s.dbErr
|
||||
}
|
||||
|
||||
// AddLog adds a log, called by evm.
|
||||
func (s *StateDB) AddLog(log *ethtypes.Log) {
|
||||
s.journal.append(addLogChange{})
|
||||
@ -235,11 +222,7 @@ func (s *StateDB) getStateObject(addr common.Address) *stateObject {
|
||||
return obj
|
||||
}
|
||||
// If no live objects are available, load it from keeper
|
||||
account, err := s.keeper.GetAccount(s.ctx, addr)
|
||||
if err != nil {
|
||||
s.setError(err)
|
||||
return nil
|
||||
}
|
||||
account := s.keeper.GetAccount(s.ctx, addr)
|
||||
if account == nil {
|
||||
return nil
|
||||
}
|
||||
@ -468,9 +451,6 @@ func (s *StateDB) RevertToSnapshot(revid int) {
|
||||
// Commit writes the dirty states to keeper
|
||||
// the StateDB object should be discarded after committed.
|
||||
func (s *StateDB) Commit() error {
|
||||
if s.dbErr != nil {
|
||||
return fmt.Errorf("commit aborted due to earlier error: %v", s.dbErr)
|
||||
}
|
||||
for _, addr := range s.journal.sortedDirties() {
|
||||
obj := s.stateObjects[addr]
|
||||
if obj.suicided {
|
||||
|
@ -17,7 +17,6 @@ type StateDBTestSuite struct {
|
||||
}
|
||||
|
||||
func (suite *StateDBTestSuite) TestAccounts() {
|
||||
addrErr := common.BigToAddress(big.NewInt(1))
|
||||
addr2 := common.BigToAddress(big.NewInt(2))
|
||||
testTxConfig := statedb.NewTxConfig(
|
||||
common.BigToHash(big.NewInt(10)), // tx hash
|
||||
@ -31,7 +30,7 @@ func (suite *StateDBTestSuite) TestAccounts() {
|
||||
test func(*statedb.StateDB)
|
||||
}{
|
||||
{
|
||||
"success,empty account",
|
||||
"success, empty account",
|
||||
func(db *statedb.StateDB) {
|
||||
suite.Require().Equal(true, db.Empty(addr2))
|
||||
suite.Require().Equal(big.NewInt(0), db.GetBalance(addr2))
|
||||
@ -40,21 +39,14 @@ func (suite *StateDBTestSuite) TestAccounts() {
|
||||
},
|
||||
},
|
||||
{
|
||||
"success,GetBalance",
|
||||
"success, GetBalance",
|
||||
func(db *statedb.StateDB) {
|
||||
db.AddBalance(addr2, big.NewInt(1))
|
||||
suite.Require().Equal(big.NewInt(1), db.GetBalance(addr2))
|
||||
},
|
||||
},
|
||||
{
|
||||
"fail,GetBalance dbErr",
|
||||
func(db *statedb.StateDB) {
|
||||
suite.Require().Equal(big.NewInt(0), db.GetBalance(addrErr))
|
||||
suite.Require().Error(db.Commit())
|
||||
},
|
||||
},
|
||||
{
|
||||
"success,change balance",
|
||||
"success, change balance",
|
||||
func(db *statedb.StateDB) {
|
||||
db.AddBalance(addr2, big.NewInt(2))
|
||||
suite.Require().Equal(big.NewInt(2), db.GetBalance(addr2))
|
||||
@ -69,7 +61,7 @@ func (suite *StateDBTestSuite) TestAccounts() {
|
||||
},
|
||||
},
|
||||
{
|
||||
"success,SetState",
|
||||
"success, SetState",
|
||||
func(db *statedb.StateDB) {
|
||||
key := common.BigToHash(big.NewInt(1))
|
||||
value := common.BigToHash(big.NewInt(1))
|
||||
@ -81,7 +73,7 @@ func (suite *StateDBTestSuite) TestAccounts() {
|
||||
},
|
||||
},
|
||||
{
|
||||
"success,SetCode",
|
||||
"success, SetCode",
|
||||
func(db *statedb.StateDB) {
|
||||
code := []byte("hello world")
|
||||
codeHash := crypto.Keccak256Hash(code)
|
||||
@ -98,7 +90,7 @@ func (suite *StateDBTestSuite) TestAccounts() {
|
||||
},
|
||||
},
|
||||
{
|
||||
"success,CreateAccount",
|
||||
"success, CreateAccount",
|
||||
func(db *statedb.StateDB) {
|
||||
// test balance carry over when overwritten
|
||||
amount := big.NewInt(1)
|
||||
@ -131,7 +123,7 @@ func (suite *StateDBTestSuite) TestAccounts() {
|
||||
},
|
||||
},
|
||||
{
|
||||
"success,nested snapshot revert",
|
||||
"success, nested snapshot revert",
|
||||
func(db *statedb.StateDB) {
|
||||
key := common.BigToHash(big.NewInt(1))
|
||||
value1 := common.BigToHash(big.NewInt(1))
|
||||
@ -152,7 +144,7 @@ func (suite *StateDBTestSuite) TestAccounts() {
|
||||
},
|
||||
},
|
||||
{
|
||||
"success,nonce",
|
||||
"success, nonce",
|
||||
func(db *statedb.StateDB) {
|
||||
suite.Require().Equal(uint64(0), db.GetNonce(addr2))
|
||||
db.SetNonce(addr2, 1)
|
||||
@ -165,7 +157,7 @@ func (suite *StateDBTestSuite) TestAccounts() {
|
||||
},
|
||||
},
|
||||
{
|
||||
"success,logs",
|
||||
"success, logs",
|
||||
func(db *statedb.StateDB) {
|
||||
data := []byte("hello world")
|
||||
db.AddLog(ðtypes.Log{
|
||||
@ -203,7 +195,7 @@ func (suite *StateDBTestSuite) TestAccounts() {
|
||||
},
|
||||
},
|
||||
{
|
||||
"success,refund",
|
||||
"success, refund",
|
||||
func(db *statedb.StateDB) {
|
||||
db.AddRefund(uint64(10))
|
||||
suite.Require().Equal(uint64(10), db.GetRefund())
|
||||
@ -218,7 +210,7 @@ func (suite *StateDBTestSuite) TestAccounts() {
|
||||
},
|
||||
},
|
||||
{
|
||||
"success,empty",
|
||||
"success, empty",
|
||||
func(db *statedb.StateDB) {
|
||||
suite.Require().False(db.Exist(addr2))
|
||||
suite.Require().True(db.Empty(addr2))
|
||||
@ -233,7 +225,7 @@ func (suite *StateDBTestSuite) TestAccounts() {
|
||||
},
|
||||
},
|
||||
{
|
||||
"success,suicide commit",
|
||||
"success, suicide commit",
|
||||
func(db *statedb.StateDB) {
|
||||
code := []byte("hello world")
|
||||
db.SetCode(addr2, code)
|
||||
@ -253,7 +245,7 @@ func (suite *StateDBTestSuite) TestAccounts() {
|
||||
},
|
||||
},
|
||||
{
|
||||
"success,suicide revert",
|
||||
"success, suicide revert",
|
||||
func(db *statedb.StateDB) {
|
||||
code := []byte("hello world")
|
||||
db.SetCode(addr2, code)
|
||||
|
Loading…
Reference in New Issue
Block a user