implement EIP150 and EIP161 SelfDestruct OpCode

This commit is contained in:
andri lim 2019-04-07 11:29:09 +07:00
parent 77e9c18f91
commit 6f51cf9103
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
2 changed files with 37 additions and 5 deletions

View File

@ -75,6 +75,8 @@ type
cr_currentMemSize*: Natural
cr_memOffset*: Natural
cr_memLength*: Natural
of SelfDestruct:
sd_condition*: bool
else:
discard
@ -344,8 +346,10 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) =
`prefix gasMemoryExpansion`(currentMemSize, memOffset, memLength)
func `prefix gasSelfDestruct`(value: Uint256, gasParams: Gasparams): GasResult {.nimcall.} =
# TODO
discard
result.gasCost += static(FeeSchedule[GasSelfDestruct])
when fork >= FkTangerine:
if gasParams.sd_condition:
result.gasCost += static(FeeSchedule[GasNewAccount])
# ###################################################################################################

View File

@ -815,13 +815,11 @@ op revert, inline = false, startPos, size:
computation.memory.extend(pos, len)
computation.output = computation.memory.read(pos, len)
op selfDestruct, inline = false:
proc selfDestructImpl(computation: BaseComputation, beneficiary: EthAddress) =
## 0xff Halt execution and register account for later deletion.
# TODO: This is the basic implementation of the self destruct op,
# Other forks have some extra functionality around this call.
# In particular, EIP150 and EIP161 have extra requirements.
let beneficiary = computation.stack.popAddress()
computation.vmState.mutateStateDB:
let
localBalance = db.getBalance(computation.msg.storageAddress)
@ -842,3 +840,33 @@ op selfDestruct, inline = false:
storageAddress = computation.msg.storageAddress.toHex,
localBalance = localBalance.toString,
beneficiary = beneficiary.toHex
op selfDestruct, inline = false:
let beneficiary = computation.stack.popAddress()
selfDestructImpl(computation, beneficiary)
op selfDestructEip150, inline = false:
let beneficiary = computation.stack.popAddress()
let gasParams = GasParams(kind: SelfDestruct,
sd_condition: not computation.vmState.readOnlyStateDb.accountExists(beneficiary)
)
let gasCost = computation.gasCosts[SelfDestruct].c_handler(0.u256, gasParams).gasCost
computation.gasMeter.consumeGas(gasCost, reason = "SELFDESTRUCT EIP150")
selfDestructImpl(computation, beneficiary)
op selfDestructEip161, inline = false:
let
beneficiary = computation.stack.popAddress()
stateDb = computation.vmState.readOnlyStateDb
isDead = stateDb.isDeadAccount(beneficiary)
balance = stateDb.getBalance(computation.msg.storageAddress)
let gasParams = GasParams(kind: SelfDestruct,
sd_condition: isDead and not balance.isZero
)
let gasCost = computation.gasCosts[SelfDestruct].c_handler(0.u256, gasParams).gasCost
computation.gasMeter.consumeGas(gasCost, reason = "SELFDESTRUCT EIP161")
selfDestructImpl(computation, beneficiary)