Skip to content

core/state: remove reset-account notion in statedb #28100

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

Closed
wants to merge 1 commit into from
Closed
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
30 changes: 8 additions & 22 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -618,16 +618,16 @@ func (s *StateDB) setStateObject(object *stateObject) {
func (s *StateDB) GetOrNewStateObject(addr common.Address) *stateObject {
stateObject := s.getStateObject(addr)
if stateObject == nil {
stateObject, _ = s.createObject(addr)
stateObject = s.createObject(addr)
}
return stateObject
}

// createObject creates a new state object. If there is an existing account with
// the given address, it is overwritten and returned as the second return value.
func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) {
prev = s.getDeletedStateObject(addr) // Note, prev might have been deleted, we need that!
newobj = newObject(s, addr, nil)
func (s *StateDB) createObject(addr common.Address) *stateObject {
prev := s.getDeletedStateObject(addr) // Note, prev might have been deleted, we need that!
newobj := newObject(s, addr, nil)
if prev == nil {
s.journal.append(createObjectChange{account: &addr})
} else {
Expand Down Expand Up @@ -662,27 +662,13 @@ func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject)
newobj.created = true

s.setStateObject(newobj)
if prev != nil && !prev.deleted {
return newobj, prev
}
return newobj, nil
return newobj
}

// CreateAccount explicitly creates a state object. If a state object with the address
// already exists the balance is carried over to the new account.
//
// 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)
//
// Carrying over the balance ensures that Ether doesn't disappear.
// CreateAccount creates a new account at the given address. This function
// assumes the address is unoccupied to avoid unintentional overwrites.
func (s *StateDB) CreateAccount(addr common.Address) {
newObj, prev := s.createObject(addr)
if prev != nil {
newObj.setBalance(prev.data.Balance)
}
s.createObject(addr)
}

// Copy creates a deep, independent copy of the state.
Expand Down
34 changes: 0 additions & 34 deletions core/state/statedb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1104,40 +1104,6 @@ func TestStateDBTransientStorage(t *testing.T) {
}
}

func TestResetObject(t *testing.T) {
var (
disk = rawdb.NewMemoryDatabase()
tdb = trie.NewDatabase(disk, nil)
db = NewDatabaseWithNodeDB(disk, tdb)
snaps, _ = snapshot.New(snapshot.Config{CacheSize: 10}, disk, tdb, types.EmptyRootHash)
state, _ = New(types.EmptyRootHash, db, snaps)
addr = common.HexToAddress("0x1")
slotA = common.HexToHash("0x1")
slotB = common.HexToHash("0x2")
)
// Initialize account with balance and storage in first transaction.
state.SetBalance(addr, big.NewInt(1))
state.SetState(addr, slotA, common.BytesToHash([]byte{0x1}))
state.IntermediateRoot(true)

// Reset account and mutate balance and storages
state.CreateAccount(addr)
state.SetBalance(addr, big.NewInt(2))
state.SetState(addr, slotB, common.BytesToHash([]byte{0x2}))
root, _ := state.Commit(0, true)

// Ensure the original account is wiped properly
snap := snaps.Snapshot(root)
slot, _ := snap.Storage(crypto.Keccak256Hash(addr.Bytes()), crypto.Keccak256Hash(slotA.Bytes()))
if len(slot) != 0 {
t.Fatalf("Unexpected storage slot")
}
slot, _ = snap.Storage(crypto.Keccak256Hash(addr.Bytes()), crypto.Keccak256Hash(slotB.Bytes()))
if !bytes.Equal(slot, []byte{0x2}) {
t.Fatalf("Unexpected storage slot value %v", slot)
}
}

func TestDeleteStorage(t *testing.T) {
var (
disk = rawdb.NewMemoryDatabase()
Expand Down
4 changes: 3 additions & 1 deletion core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,9 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
}
// Create a new account on the state
snapshot := evm.StateDB.Snapshot()
evm.StateDB.CreateAccount(address)
if !evm.StateDB.Exist(address) {
evm.StateDB.CreateAccount(address)
}
if evm.chainRules.IsEIP158 {
evm.StateDB.SetNonce(address, 1)
}
Expand Down
2 changes: 2 additions & 0 deletions core/vm/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import (

// StateDB is an EVM database for full state querying.
type StateDB interface {
// CreateAccount creates a new account at the given address. This function
// assumes the address is unoccupied to avoid unintentional overwrites.
CreateAccount(common.Address)

SubBalance(common.Address, *big.Int)
Expand Down