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

Implement EIP-6780: SELFDESTRUCT only in same transaction #7976

Merged
merged 2 commits into from
Aug 6, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 20 additions & 8 deletions core/state/intra_block_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ func (sdb *IntraBlockState) HasSelfdestructed(addr libcommon.Address) bool {
if stateObject.deleted {
return false
}
if stateObject.created {
if stateObject.createdContract {
return false
}
return stateObject.selfdestructed
Expand Down Expand Up @@ -415,12 +415,23 @@ func (sdb *IntraBlockState) Selfdestruct(addr libcommon.Address) bool {
prevbalance: *stateObject.Balance(),
})
stateObject.markSelfdestructed()
stateObject.created = false
stateObject.createdContract = false
stateObject.data.Balance.Clear()

return true
}

func (sdb *IntraBlockState) Selfdestruct6780(addr libcommon.Address) {
stateObject := sdb.getStateObject(addr)
if stateObject == nil {
return
}

if stateObject.newlyCreated {
sdb.Selfdestruct(addr)
}
}

// SetTransientState sets transient storage for a given account. It
// adds the change to the journal so that it can be rolled back
// to its previous value if there is a revert.
Expand Down Expand Up @@ -518,6 +529,7 @@ func (sdb *IntraBlockState) createObject(addr libcommon.Address, previous *state
} else {
sdb.journal.append(resetObjectChange{account: &addr, prev: previous})
}
newobj.newlyCreated = true
sdb.setStateObject(addr, newobj)
return newobj
}
Expand Down Expand Up @@ -554,7 +566,7 @@ func (sdb *IntraBlockState) CreateAccount(addr libcommon.Address, contractCreati
newObj.data.Initialised = true

if contractCreation {
newObj.created = true
newObj.createdContract = true
newObj.data.Incarnation = prevInc + 1
} else {
newObj.selfdestructed = false
Expand Down Expand Up @@ -598,15 +610,15 @@ func updateAccount(EIP161Enabled bool, isAura bool, stateWriter StateWriter, add
}
stateObject.deleted = true
}
if isDirty && (stateObject.created || !stateObject.selfdestructed) && !emptyRemoval {
if isDirty && (stateObject.createdContract || !stateObject.selfdestructed) && !emptyRemoval {
stateObject.deleted = false
// Write any contract code associated with the state object
if stateObject.code != nil && stateObject.dirtyCode {
if err := stateWriter.UpdateAccountCode(addr, stateObject.data.Incarnation, stateObject.data.CodeHash, stateObject.code); err != nil {
return err
}
}
if stateObject.created {
if stateObject.createdContract {
if err := stateWriter.CreateContract(addr); err != nil {
return err
}
Expand All @@ -626,12 +638,12 @@ func printAccount(EIP161Enabled bool, addr libcommon.Address, stateObject *state
if stateObject.selfdestructed || (isDirty && emptyRemoval) {
fmt.Printf("delete: %x\n", addr)
}
if isDirty && (stateObject.created || !stateObject.selfdestructed) && !emptyRemoval {
if isDirty && (stateObject.createdContract || !stateObject.selfdestructed) && !emptyRemoval {
// Write any contract code associated with the state object
if stateObject.code != nil && stateObject.dirtyCode {
fmt.Printf("UpdateCode: %x,%x\n", addr, stateObject.CodeHash())
}
if stateObject.created {
if stateObject.createdContract {
fmt.Printf("CreateContract: %x\n", addr)
}
stateObject.printTrie()
Expand Down Expand Up @@ -666,7 +678,7 @@ func (sdb *IntraBlockState) FinalizeTx(chainRules *chain.Rules, stateWriter Stat
if err := updateAccount(chainRules.IsSpuriousDragon, chainRules.IsAura, stateWriter, addr, so, true); err != nil {
return err
}

so.newlyCreated = false
sdb.stateObjectsDirty[addr] = struct{}{}
}
// Invalidate journal because reverting across transactions is not allowed.
Expand Down
11 changes: 6 additions & 5 deletions core/state/state_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,11 @@ type stateObject struct {
// Cache flags.
// When an object is marked selfdestructed it will be delete from the trie
// during the "update" phase of the state transition.
dirtyCode bool // true if the code was updated
selfdestructed bool
deleted bool // true if account was deleted during the lifetime of this object
created bool // true if this object represents a newly created contract
dirtyCode bool // true if the code was updated
selfdestructed bool
deleted bool // true if account was deleted during the lifetime of this object
newlyCreated bool // true if this object was created in the current transaction
createdContract bool // true if this object represents a newly created contract
}

// empty returns whether the account is considered empty.
Expand Down Expand Up @@ -179,7 +180,7 @@ func (so *stateObject) GetCommittedState(key *libcommon.Hash, out *uint256.Int)
return
}
}
if so.created {
if so.createdContract {
out.Clear()
return
}
Expand Down
12 changes: 12 additions & 0 deletions core/vm/eips.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
)

var activators = map[int]func(*JumpTable){
6780: enable6780,
5656: enable5656,
4844: enable4844,
3860: enable3860,
Expand Down Expand Up @@ -291,3 +292,14 @@ func opMcopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]by
scope.Memory.Copy(dst.Uint64(), src.Uint64(), length.Uint64())
return nil, nil
}

// enable6780 applies EIP-6780 (deactivate SELFDESTRUCT)
func enable6780(jt *JumpTable) {
jt[SELFDESTRUCT] = &operation{
execute: opSelfdestruct6780,
dynamicGas: gasSelfdestructEIP3529,
constantGas: params.SelfdestructGasEIP150,
numPop: 1,
numPush: 0,
}
}
1 change: 1 addition & 0 deletions core/vm/evmtypes/evmtypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ type IntraBlockState interface {

Selfdestruct(common.Address) bool
HasSelfdestructed(common.Address) bool
Selfdestruct6780(common.Address)

// Exist reports whether the given account exists in state.
// Notably this should also return true for suicided accounts.
Expand Down
20 changes: 20 additions & 0 deletions core/vm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,26 @@ func opSelfdestruct(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext
return nil, errStopToken
}

func opSelfdestruct6780(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
if interpreter.readOnly {
return nil, ErrWriteProtection
}
beneficiary := scope.Stack.Pop()
callerAddr := scope.Contract.Address()
beneficiaryAddr := libcommon.Address(beneficiary.Bytes20())
balance := interpreter.evm.IntraBlockState().GetBalance(callerAddr)
if interpreter.evm.Config().Debug {
if interpreter.cfg.Debug {
interpreter.cfg.Tracer.CaptureEnter(SELFDESTRUCT, callerAddr, beneficiaryAddr, false /* precompile */, false /* create */, []byte{}, 0, balance, nil /* code */)
interpreter.cfg.Tracer.CaptureExit([]byte{}, 0, nil)
}
}
interpreter.evm.IntraBlockState().SubBalance(callerAddr, balance)
interpreter.evm.IntraBlockState().AddBalance(beneficiaryAddr, balance)
interpreter.evm.IntraBlockState().Selfdestruct6780(callerAddr)
return nil, errStopToken
}

// following functions are used by the instruction jump table

// make log instruction function
Expand Down
1 change: 1 addition & 0 deletions core/vm/jump_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ func newCancunInstructionSet() JumpTable {
enable1153(&instructionSet) // Transient storage opcodes
enable4844(&instructionSet) // BLOBHASH opcode
enable5656(&instructionSet) // MCOPY opcode
enable6780(&instructionSet) // SELFDESTRUCT only in same transaction
validateAndFillMaxStack(&instructionSet)
return instructionSet
}
Expand Down