mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
core/state: remove reset-account notion in statedb
This commit is contained in:
parent
43df612268
commit
4e1deabe59
4 changed files with 13 additions and 57 deletions
|
|
@ -618,16 +618,16 @@ func (s *StateDB) setStateObject(object *stateObject) {
|
||||||
func (s *StateDB) GetOrNewStateObject(addr common.Address) *stateObject {
|
func (s *StateDB) GetOrNewStateObject(addr common.Address) *stateObject {
|
||||||
stateObject := s.getStateObject(addr)
|
stateObject := s.getStateObject(addr)
|
||||||
if stateObject == nil {
|
if stateObject == nil {
|
||||||
stateObject, _ = s.createObject(addr)
|
stateObject = s.createObject(addr)
|
||||||
}
|
}
|
||||||
return stateObject
|
return stateObject
|
||||||
}
|
}
|
||||||
|
|
||||||
// createObject creates a new state object. If there is an existing account with
|
// 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.
|
// the given address, it is overwritten and returned as the second return value.
|
||||||
func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) {
|
func (s *StateDB) createObject(addr common.Address) *stateObject {
|
||||||
prev = s.getDeletedStateObject(addr) // Note, prev might have been deleted, we need that!
|
prev := s.getDeletedStateObject(addr) // Note, prev might have been deleted, we need that!
|
||||||
newobj = newObject(s, addr, nil)
|
newobj := newObject(s, addr, nil)
|
||||||
if prev == nil {
|
if prev == nil {
|
||||||
s.journal.append(createObjectChange{account: &addr})
|
s.journal.append(createObjectChange{account: &addr})
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -662,27 +662,13 @@ func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject)
|
||||||
newobj.created = true
|
newobj.created = true
|
||||||
|
|
||||||
s.setStateObject(newobj)
|
s.setStateObject(newobj)
|
||||||
if prev != nil && !prev.deleted {
|
return newobj
|
||||||
return newobj, prev
|
|
||||||
}
|
|
||||||
return newobj, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateAccount explicitly creates a state object. If a state object with the address
|
// CreateAccount creates a new account at the given address. This function
|
||||||
// already exists the balance is carried over to the new account.
|
// assumes the address is unoccupied to avoid unintentional overwrites.
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
func (s *StateDB) CreateAccount(addr common.Address) {
|
func (s *StateDB) CreateAccount(addr common.Address) {
|
||||||
newObj, prev := s.createObject(addr)
|
s.createObject(addr)
|
||||||
if prev != nil {
|
|
||||||
newObj.setBalance(prev.data.Balance)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy creates a deep, independent copy of the state.
|
// Copy creates a deep, independent copy of the state.
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
func TestDeleteStorage(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
disk = rawdb.NewMemoryDatabase()
|
disk = rawdb.NewMemoryDatabase()
|
||||||
|
|
|
||||||
|
|
@ -441,7 +441,9 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
|
||||||
}
|
}
|
||||||
// Create a new account on the state
|
// Create a new account on the state
|
||||||
snapshot := evm.StateDB.Snapshot()
|
snapshot := evm.StateDB.Snapshot()
|
||||||
evm.StateDB.CreateAccount(address)
|
if !evm.StateDB.Exist(address) {
|
||||||
|
evm.StateDB.CreateAccount(address)
|
||||||
|
}
|
||||||
if evm.chainRules.IsEIP158 {
|
if evm.chainRules.IsEIP158 {
|
||||||
evm.StateDB.SetNonce(address, 1)
|
evm.StateDB.SetNonce(address, 1)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@ import (
|
||||||
|
|
||||||
// StateDB is an EVM database for full state querying.
|
// StateDB is an EVM database for full state querying.
|
||||||
type StateDB interface {
|
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)
|
CreateAccount(common.Address)
|
||||||
|
|
||||||
SubBalance(common.Address, *big.Int)
|
SubBalance(common.Address, *big.Int)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue