Implement EIP-6780: SELFDESTRUCT only in same transaction

This commit is contained in:
jangko 2023-08-18 10:12:18 +07:00
parent dd9e181acc
commit 467e6fffa6
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
4 changed files with 25 additions and 5 deletions

View File

@ -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

View File

@ -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,

View File

@ -150,7 +150,7 @@ const
gasCost = gasCost + ColdAccountAccessCost
cpt.gasMeter.consumeGas(
gasCost, reason = "SELFDESTRUCT EIP161")
gasCost, reason = "SELFDESTRUCT EIP2929")
cpt.selfDestruct(beneficiary)
# ------------------------------------------------------------------------------

View File

@ -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