Skip to content

Commit e8ea4ee

Browse files
committed
core/state, core/vm: implement createcontract journal event
1 parent 2cf9712 commit e8ea4ee

File tree

4 files changed

+39
-0
lines changed

4 files changed

+39
-0
lines changed

core/state/journal.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ type (
105105
createObjectChange struct {
106106
account *common.Address
107107
}
108+
109+
createContractChange struct {
110+
account common.Address
111+
}
112+
108113
selfDestructChange struct {
109114
account *common.Address
110115
prev bool // whether account had already self-destructed
@@ -173,6 +178,20 @@ func (ch createObjectChange) copy() journalEntry {
173178
}
174179
}
175180

181+
func (ch createContractChange) revert(s *StateDB) {
182+
s.stateObjects[ch.account].created = false
183+
}
184+
185+
func (ch createContractChange) dirtied() *common.Address {
186+
return &ch.account
187+
}
188+
189+
func (ch createContractChange) copy() journalEntry {
190+
return createContractChange{
191+
account: ch.account,
192+
}
193+
}
194+
176195
func (ch selfDestructChange) revert(s *StateDB) {
177196
obj := s.getStateObject(*ch.account)
178197
if obj != nil {

core/state/statedb.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,19 @@ func (s *StateDB) CreateAccount(addr common.Address) {
662662
s.createObject(addr)
663663
}
664664

665+
// CreateContract is used whenever a contract is created. This may be preceded
666+
// by CreateAccount, but that is not required if it already existed
667+
// in the state due to funds sent beforehand.
668+
// This operation sets the 'created'-flag, which is required in order to
669+
// correctly handle EIP-6780 'delete-in-same-transaction' logic.
670+
func (s *StateDB) CreateContract(addr common.Address) {
671+
obj := s.getStateObject(addr)
672+
if !obj.created {
673+
obj.created = true
674+
s.journal.append(createContractChange{account: addr})
675+
}
676+
}
677+
665678
// Copy creates a deep, independent copy of the state.
666679
// Snapshots of the copied state cannot be applied to the copy.
667680
func (s *StateDB) Copy() *StateDB {

core/vm/evm.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,12 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
462462
if !evm.StateDB.Exist(address) {
463463
evm.StateDB.CreateAccount(address)
464464
}
465+
// CreateContract means that regardless of whether the acccount existed
466+
// in the state trie or not, previously, it _now_ becomes created as a
467+
// _contract_ account. This is performed _prior_ to executing the initcode,
468+
// since the initcode acts inside that account.
469+
evm.StateDB.CreateContract(address)
470+
465471
if evm.chainRules.IsEIP158 {
466472
evm.StateDB.SetNonce(address, 1)
467473
}

core/vm/interface.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
// StateDB is an EVM database for full state querying.
3030
type StateDB interface {
3131
CreateAccount(common.Address)
32+
CreateContract(common.Address)
3233

3334
SubBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason)
3435
AddBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason)

0 commit comments

Comments
 (0)