core/state, core/vm: implement createcontract journal event

This commit is contained in:
Martin Holst Swende 2024-04-12 15:20:15 +02:00
parent 2cf971248c
commit e8ea4ee43f
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0
4 changed files with 39 additions and 0 deletions

View file

@ -105,6 +105,11 @@ type (
createObjectChange struct { createObjectChange struct {
account *common.Address account *common.Address
} }
createContractChange struct {
account common.Address
}
selfDestructChange struct { selfDestructChange struct {
account *common.Address account *common.Address
prev bool // whether account had already self-destructed prev bool // whether account had already self-destructed
@ -173,6 +178,20 @@ func (ch createObjectChange) copy() journalEntry {
} }
} }
func (ch createContractChange) revert(s *StateDB) {
s.stateObjects[ch.account].created = false
}
func (ch createContractChange) dirtied() *common.Address {
return &ch.account
}
func (ch createContractChange) copy() journalEntry {
return createContractChange{
account: ch.account,
}
}
func (ch selfDestructChange) revert(s *StateDB) { func (ch selfDestructChange) revert(s *StateDB) {
obj := s.getStateObject(*ch.account) obj := s.getStateObject(*ch.account)
if obj != nil { if obj != nil {

View file

@ -662,6 +662,19 @@ func (s *StateDB) CreateAccount(addr common.Address) {
s.createObject(addr) s.createObject(addr)
} }
// CreateContract is used whenever a contract is created. This may be preceded
// by CreateAccount, but that is not required if it already existed
// in the state due to funds sent beforehand.
// This operation sets the 'created'-flag, which is required in order to
// correctly handle EIP-6780 'delete-in-same-transaction' logic.
func (s *StateDB) CreateContract(addr common.Address) {
obj := s.getStateObject(addr)
if !obj.created {
obj.created = true
s.journal.append(createContractChange{account: addr})
}
}
// Copy creates a deep, independent copy of the state. // Copy creates a deep, independent copy of the state.
// Snapshots of the copied state cannot be applied to the copy. // Snapshots of the copied state cannot be applied to the copy.
func (s *StateDB) Copy() *StateDB { func (s *StateDB) Copy() *StateDB {

View file

@ -462,6 +462,12 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
if !evm.StateDB.Exist(address) { if !evm.StateDB.Exist(address) {
evm.StateDB.CreateAccount(address) evm.StateDB.CreateAccount(address)
} }
// CreateContract means that regardless of whether the acccount existed
// in the state trie or not, previously, it _now_ becomes created as a
// _contract_ account. This is performed _prior_ to executing the initcode,
// since the initcode acts inside that account.
evm.StateDB.CreateContract(address)
if evm.chainRules.IsEIP158 { if evm.chainRules.IsEIP158 {
evm.StateDB.SetNonce(address, 1) evm.StateDB.SetNonce(address, 1)
} }

View file

@ -29,6 +29,7 @@ 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(common.Address) CreateAccount(common.Address)
CreateContract(common.Address)
SubBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason) SubBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason)
AddBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason) AddBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason)