Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QB-1761: Fix evm contract destroy #236

Merged
merged 1 commit into from
Mar 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions x/evm/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func InitGenesis(
panic("code don't match codeHash")
}

k.SetCode(ctx, codeHash.Bytes(), code)
k.SetCode(ctx, address, codeHash.Bytes(), code)

for _, storage := range account.Storage {
k.SetState(ctx, address, common.HexToHash(storage.Key), common.HexToHash(storage.Value).Bytes())
Expand All @@ -82,7 +82,7 @@ func ExportGenesis(ctx sdk.Context, k *keeper.Keeper, ak types.AccountKeeper) *t

genAccount := types.GenesisAccount{
Address: addr.String(),
Code: common.Bytes2Hex(k.GetCode(ctx, ethAccount.GetCodeHash())),
Code: common.Bytes2Hex(k.GetCode(ctx, addr, ethAccount.GetCodeHash())),
Storage: storage,
}

Expand Down
2 changes: 1 addition & 1 deletion x/evm/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ func (k Keeper) Code(c context.Context, req *types.QueryCodeRequest) (*types.Que

var code []byte
if acct != nil && acct.IsContract() {
code = k.GetCode(ctx, common.BytesToHash(acct.CodeHash))
code = k.GetCode(ctx, address, common.BytesToHash(acct.CodeHash))
}

return &types.QueryCodeResponse{
Expand Down
18 changes: 10 additions & 8 deletions x/evm/keeper/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ func (k *Keeper) GetState(ctx sdk.Context, addr common.Address, key common.Hash)
}

// GetCode loads contract code from database, implements `statedb.Keeper` interface.
func (k *Keeper) GetCode(ctx sdk.Context, codeHash common.Hash) []byte {
func (k *Keeper) GetCode(ctx sdk.Context, addr common.Address, codeHash common.Hash) []byte {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixCode)
return store.Get(codeHash.Bytes())
return store.Get(append(addr.Bytes(), codeHash.Bytes()...))
}

// ForEachStorage iterate contract storage, callback return false to break early
Expand Down Expand Up @@ -126,8 +126,7 @@ func (k *Keeper) SetAccount(ctx sdk.Context, addr common.Address, account stated
}
k.accountKeeper.SetAccount(ctx, acct)
} else {
var baseAcc *authtypes.BaseAccount
baseAcc = acct.(*authtypes.BaseAccount)
baseAcc := acct.(*authtypes.BaseAccount)

if !bytes.Equal(codeHash.Bytes(), types.EmptyCodeHash) {
//if codeHash is not empty, and the acct is new created baseAccount, convert to ethAccount first
Expand Down Expand Up @@ -174,19 +173,22 @@ func (k *Keeper) SetState(ctx sdk.Context, addr common.Address, key common.Hash,
}

// SetCode set contract code, delete if code is empty.
func (k *Keeper) SetCode(ctx sdk.Context, codeHash, code []byte) {
func (k *Keeper) SetCode(ctx sdk.Context, addr common.Address, codeHash, code []byte) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixCode)

key := append(addr.Bytes(), codeHash...)

// store or delete code
action := "updated"
if len(code) == 0 {
store.Delete(codeHash)
store.Delete(key)
action = "deleted"
} else {
store.Set(codeHash, code)
store.Set(key, code)
}
k.Logger(ctx).Debug(
fmt.Sprintf("code %s", action),
"addr", common.BytesToHash(addr.Bytes()).Hex(),
"code-hash", common.BytesToHash(codeHash).Hex(),
)
}
Expand Down Expand Up @@ -217,7 +219,7 @@ func (k *Keeper) DeleteAccount(ctx sdk.Context, addr common.Address) error {
// remove code
codeHashBz := ethAcct.GetCodeHash().Bytes()
if !bytes.Equal(codeHashBz, types.EmptyCodeHash) {
k.SetCode(ctx, codeHashBz, nil)
k.SetCode(ctx, addr, codeHashBz, nil)
}

// clear storage
Expand Down
4 changes: 2 additions & 2 deletions x/evm/statedb/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ type Keeper interface {
// Read methods
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
GetCode(ctx sdk.Context, addr common.Address, codeHash common.Hash) []byte

// the callback returns false to break early
ForEachStorage(ctx sdk.Context, addr common.Address, cb func(key, value common.Hash) bool)

// Write methods, only called by `StateDB.Commit()`
SetAccount(ctx sdk.Context, addr common.Address, account Account) error
SetState(ctx sdk.Context, addr common.Address, key common.Hash, value []byte)
SetCode(ctx sdk.Context, codeHash []byte, code []byte)
SetCode(ctx sdk.Context, addr common.Address, codeHash []byte, code []byte)
DeleteAccount(ctx sdk.Context, addr common.Address) error
}
2 changes: 1 addition & 1 deletion x/evm/statedb/state_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ func (s *stateObject) Code() []byte {
if bytes.Equal(s.CodeHash(), emptyCodeHash) {
return nil
}
code := s.db.keeper.GetCode(s.db.ctx, common.BytesToHash(s.CodeHash()))
code := s.db.keeper.GetCode(s.db.ctx, s.Address(), common.BytesToHash(s.CodeHash()))
s.code = code
return code
}
Expand Down
6 changes: 3 additions & 3 deletions x/evm/statedb/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,8 @@ func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject)
// CreateAccount is called during the EVM CREATE operation. The situation might arise that
// a contract does the following:
//
// 1. sends funds to sha(account ++ (nonce + 1))
// 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1)
// 1. sends funds to sha(account ++ (nonce + 1))
// 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1)
//
// Carrying over the balance ensures that Ether doesn't disappear.
func (s *StateDB) CreateAccount(addr common.Address) {
Expand Down Expand Up @@ -444,7 +444,7 @@ func (s *StateDB) Commit() error {
}
} else {
if obj.code != nil && obj.dirtyCode {
s.keeper.SetCode(s.ctx, obj.CodeHash(), obj.code)
s.keeper.SetCode(s.ctx, obj.Address(), obj.CodeHash(), obj.code)
}
if err := s.keeper.SetAccount(s.ctx, obj.Address(), obj.account); err != nil {
return sdkerrors.Wrap(err, "failed to set account")
Expand Down