mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-26 20:19:31 +00:00
Implement EIP-6780: SELFDESTRUCT only in same transaction
This commit is contained in:
parent
dd9e181acc
commit
467e6fffa6
@ -29,6 +29,7 @@ type
|
||||
CodeLoaded
|
||||
CodeChanged
|
||||
StorageChanged
|
||||
NewlyCreated # EIP-6780: self destruct only in same transaction
|
||||
|
||||
AccountFlags = set[AccountFlag]
|
||||
|
||||
@ -76,7 +77,8 @@ const
|
||||
IsNew,
|
||||
Touched,
|
||||
CodeChanged,
|
||||
StorageChanged
|
||||
StorageChanged,
|
||||
NewlyCreated
|
||||
}
|
||||
|
||||
ripemdAddr* = block:
|
||||
@ -485,8 +487,11 @@ proc setStorage*(ac: AccountsCache, address: EthAddress, slot, value: UInt256) =
|
||||
acc.flags.incl StorageChanged
|
||||
|
||||
proc clearStorage*(ac: AccountsCache, address: EthAddress) =
|
||||
# a.k.a createStateObject. If there is an existing account with
|
||||
# the given address, it is overwritten.
|
||||
|
||||
let acc = ac.getAccount(address)
|
||||
acc.flags.incl {Alive}
|
||||
acc.flags.incl {Alive, NewlyCreated}
|
||||
if acc.account.storageRoot != EMPTY_ROOT_HASH:
|
||||
# there is no point to clone the storage since we want to remove it
|
||||
let acc = ac.makeDirty(address, cloneStorage = false)
|
||||
@ -506,6 +511,14 @@ proc deleteAccount*(ac: AccountsCache, address: EthAddress) =
|
||||
proc selfDestruct*(ac: AccountsCache, address: EthAddress) =
|
||||
ac.savePoint.selfDestruct.incl address
|
||||
|
||||
proc selfDestruct6780*(ac: AccountsCache, address: EthAddress) =
|
||||
let acc = ac.getAccount(address, false)
|
||||
if acc.isNil:
|
||||
return
|
||||
|
||||
if NewlyCreated in acc.flags:
|
||||
ac.selfDestruct(address)
|
||||
|
||||
proc selfDestructLen*(ac: AccountsCache): int =
|
||||
ac.savePoint.selfDestruct.len
|
||||
|
||||
|
@ -350,6 +350,7 @@ proc merge*(c, child: Computation) =
|
||||
|
||||
proc execSelfDestruct*(c: Computation, beneficiary: EthAddress)
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
|
||||
c.vmState.mutateStateDB:
|
||||
let localBalance = c.getBalance(c.msg.contractAddress)
|
||||
|
||||
@ -362,7 +363,10 @@ proc execSelfDestruct*(c: Computation, beneficiary: EthAddress)
|
||||
db.setBalance(c.msg.contractAddress, 0.u256)
|
||||
|
||||
# Register the account to be deleted
|
||||
db.selfDestruct(c.msg.contractAddress)
|
||||
if c.fork >= FkCancun:
|
||||
db.selfDestruct6780(c.msg.contractAddress)
|
||||
else:
|
||||
db.selfDestruct(c.msg.contractAddress)
|
||||
|
||||
trace "SELFDESTRUCT",
|
||||
contractAddress = c.msg.contractAddress.toHex,
|
||||
|
@ -150,7 +150,7 @@ const
|
||||
gasCost = gasCost + ColdAccountAccessCost
|
||||
|
||||
cpt.gasMeter.consumeGas(
|
||||
gasCost, reason = "SELFDESTRUCT EIP161")
|
||||
gasCost, reason = "SELFDESTRUCT EIP2929")
|
||||
cpt.selfDestruct(beneficiary)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -229,7 +229,10 @@ proc selfDestruct(host: TransactionHost, address, beneficiary: HostAddress) {.sh
|
||||
# This must come after sending to the beneficiary in case the
|
||||
# contract named itself as the beneficiary.
|
||||
db.setBalance(address, 0.u256)
|
||||
db.selfDestruct(address)
|
||||
if host.vmState.fork >= FkCancun:
|
||||
db.selfDestruct6780(address)
|
||||
else:
|
||||
db.selfDestruct(address)
|
||||
|
||||
template call(host: TransactionHost, msg: EvmcMessage): EvmcResult =
|
||||
# `call` is special. The C stack usage must be kept small for deeply nested
|
||||
|
Loading…
x
Reference in New Issue
Block a user