From d6e3e5699bc5192d09347e6a4df25b33d213e963 Mon Sep 17 00:00:00 2001 From: Jared Wasinger Date: Sat, 15 Jul 2023 19:33:22 +0200 Subject: [PATCH 1/4] core/vm, core/state: implement eip-6780 --- core/state/state_object.go | 3 +++ core/state/statedb.go | 15 +++++++++++++++ core/vm/eips.go | 12 ++++++++++++ core/vm/instructions.go | 16 ++++++++++++++++ core/vm/interface.go | 2 ++ core/vm/jump_table.go | 2 ++ 6 files changed, 50 insertions(+) diff --git a/core/state/state_object.go b/core/state/state_object.go index ed5f2b2945403..fbd858468f0b0 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -86,6 +86,9 @@ type stateObject struct { // or an account that is considered as empty will be marked as deleted at // the end of transaction and no longer accessible anymore. deleted bool + + // Flag whether the object was created in the current transaction + created bool } // empty returns whether the account is considered empty. diff --git a/core/state/statedb.go b/core/state/statedb.go index 4b17e70255e04..fdcc76310f4f0 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -493,6 +493,17 @@ func (s *StateDB) SelfDestruct(addr common.Address) { stateObject.data.Balance = new(big.Int) } +func (s *StateDB) Selfdestruct6780(addr common.Address) { + stateObject := s.getStateObject(addr) + if stateObject == nil { + return + } + + if stateObject.created { + s.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. @@ -681,6 +692,9 @@ func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) delete(s.accountsOrigin, prev.addrHash) delete(s.storagesOrigin, prev.addrHash) } + + newobj.created = true + s.setStateObject(newobj) if prev != nil && !prev.deleted { return newobj, prev @@ -910,6 +924,7 @@ func (s *StateDB) Finalise(deleteEmptyObjects bool) { } else { obj.finalise(true) // Prefetch slots in the background } + obj.created = false s.stateObjectsPending[addr] = struct{}{} s.stateObjectsDirty[addr] = struct{}{} diff --git a/core/vm/eips.go b/core/vm/eips.go index 0daa122ca0505..398ca20d8cb2b 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -27,6 +27,7 @@ import ( var activators = map[int]func(*JumpTable){ 5656: enable5656, + 6780: enable6780, 3855: enable3855, 3860: enable3860, 3529: enable3529, @@ -291,3 +292,14 @@ func enable4844(jt *JumpTable) { maxStack: maxStack(1, 1), } } + +// enable4844 applies EIP-6780 (deactivate SELFDESTRUCT) +func enable6780(jt *JumpTable) { + jt[SELFDESTRUCT] = &operation{ + execute: opSelfdestruct6780, + dynamicGas: gasSelfdestructEIP3529, + constantGas: params.SelfdestructGasEIP150, + minStack: minStack(1, 0), + maxStack: maxStack(1, 0), + } +} diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 4b6514ec8c328..2105201fce428 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -829,6 +829,22 @@ 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() + balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address()) + interpreter.evm.StateDB.SubBalance(scope.Contract.Address(), balance) + interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance) + interpreter.evm.StateDB.Selfdestruct6780(scope.Contract.Address()) + if tracer := interpreter.evm.Config.Tracer; tracer != nil { + tracer.CaptureEnter(SELFDESTRUCT, scope.Contract.Address(), beneficiary.Bytes20(), []byte{}, 0, balance) + tracer.CaptureExit([]byte{}, 0, nil) + } + return nil, errStopToken +} + // following functions are used by the instruction jump table // make log instruction function diff --git a/core/vm/interface.go b/core/vm/interface.go index 05fb480f968c8..26814d3d2f0e6 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -54,6 +54,8 @@ type StateDB interface { SelfDestruct(common.Address) HasSelfDestructed(common.Address) bool + Selfdestruct6780(common.Address) + // Exist reports whether the given account exists in state. // Notably this should also return true for self-destructed accounts. Exist(common.Address) bool diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go index a59fa8747323a..64fc64f53cf56 100644 --- a/core/vm/jump_table.go +++ b/core/vm/jump_table.go @@ -85,6 +85,7 @@ func newCancunInstructionSet() JumpTable { enable4844(&instructionSet) // EIP-4844 (DATAHASH opcode) enable1153(&instructionSet) // EIP-1153 "Transient Storage" enable5656(&instructionSet) // EIP-5656 (MCOPY opcode) + enable6780(&instructionSet) // deactivate SELFDESTRUCT return validate(instructionSet) } @@ -92,6 +93,7 @@ func newShanghaiInstructionSet() JumpTable { instructionSet := newMergeInstructionSet() enable3855(&instructionSet) // PUSH0 instruction enable3860(&instructionSet) // Limit and meter initcode + return validate(instructionSet) } From f419b846c5891aa0904e3611c0a1b6a241ba07a9 Mon Sep 17 00:00:00 2001 From: Jared Wasinger Date: Sat, 15 Jul 2023 20:16:25 +0200 Subject: [PATCH 2/4] goimports --- core/state/state_object.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/state/state_object.go b/core/state/state_object.go index fbd858468f0b0..6fea47f05b0e6 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -88,7 +88,7 @@ type stateObject struct { deleted bool // Flag whether the object was created in the current transaction - created bool + created bool } // empty returns whether the account is considered empty. From 95d7fc2afd3ca00ec803bc1296954ec05043913c Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Sat, 15 Jul 2023 14:41:34 -0400 Subject: [PATCH 3/4] Update core/vm/eips.go --- core/vm/eips.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/vm/eips.go b/core/vm/eips.go index 398ca20d8cb2b..704c1ce127451 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -293,7 +293,7 @@ func enable4844(jt *JumpTable) { } } -// enable4844 applies EIP-6780 (deactivate SELFDESTRUCT) +// enable6780 applies EIP-6780 (deactivate SELFDESTRUCT) func enable6780(jt *JumpTable) { jt[SELFDESTRUCT] = &operation{ execute: opSelfdestruct6780, From d5bc69e0eb0eead54e249dc43bf308f935389299 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Sat, 15 Jul 2023 14:41:42 -0400 Subject: [PATCH 4/4] Update core/vm/jump_table.go --- core/vm/jump_table.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go index 64fc64f53cf56..702b18661545b 100644 --- a/core/vm/jump_table.go +++ b/core/vm/jump_table.go @@ -85,7 +85,7 @@ func newCancunInstructionSet() JumpTable { enable4844(&instructionSet) // EIP-4844 (DATAHASH opcode) enable1153(&instructionSet) // EIP-1153 "Transient Storage" enable5656(&instructionSet) // EIP-5656 (MCOPY opcode) - enable6780(&instructionSet) // deactivate SELFDESTRUCT + enable6780(&instructionSet) // EIP-6780 SELFDESTRUCT only in same transaction return validate(instructionSet) }