Merge branch 'jangko-eip150_fork'

This commit is contained in:
Ștefan Talpalaru 2019-04-08 19:46:26 +02:00
commit 97c762baf8
No known key found for this signature in database
GPG Key ID: CBF7934204F1B6F9
6 changed files with 115 additions and 41 deletions

View File

@ -406,7 +406,7 @@ OK: 23/30 Fail: 0/30 Skip: 7/30
+ CallLoseGasOOG.json OK
+ CallRecursiveBombPreCall.json OK
+ CallcodeLoseGasOOG.json OK
+ Delegatecall1024.json OK
Delegatecall1024.json Skip
+ Delegatecall1024OOG.json OK
+ callOutput1.json OK
+ callOutput2.json OK
@ -435,24 +435,24 @@ OK: 23/30 Fail: 0/30 Skip: 7/30
+ delegatecodeDynamicCode.json OK
+ delegatecodeDynamicCode2SelfCall.json OK
```
OK: 34/34 Fail: 0/34 Skip: 0/34
OK: 33/34 Fail: 0/34 Skip: 1/34
## stEIP150Specific
```diff
CallAndCallcodeConsumeMoreGasThenTransactionHas.json Skip
CallAskMoreGasOnDepth2ThenTransactionHas.json Skip
CallGoesOOGOnSecondLevel.json Skip
CallGoesOOGOnSecondLevel2.json Skip
CreateAndGasInsideCreate.json Skip
DelegateCallOnEIP.json Skip
ExecuteCallThatAskForeGasThenTrabsactionHas.json Skip
+ CallAndCallcodeConsumeMoreGasThenTransactionHas.json OK
+ CallAskMoreGasOnDepth2ThenTransactionHas.json OK
+ CallGoesOOGOnSecondLevel.json OK
+ CallGoesOOGOnSecondLevel2.json OK
+ CreateAndGasInsideCreate.json OK
+ DelegateCallOnEIP.json OK
+ ExecuteCallThatAskForeGasThenTrabsactionHas.json OK
+ NewGasPriceForCodes.json OK
SuicideToExistingContract.json Skip
SuicideToNotExistingContract.json Skip
Transaction64Rule_d64e0.json Skip
Transaction64Rule_d64m1.json Skip
Transaction64Rule_d64p1.json Skip
+ SuicideToExistingContract.json OK
+ SuicideToNotExistingContract.json OK
+ Transaction64Rule_d64e0.json OK
+ Transaction64Rule_d64m1.json OK
+ Transaction64Rule_d64p1.json OK
```
OK: 1/13 Fail: 0/13 Skip: 12/13
OK: 13/13 Fail: 0/13 Skip: 0/13
## stEIP150singleCodeGasPrices
```diff
+ RawBalanceGas.json OK
@ -491,12 +491,12 @@ OK: 30/30 Fail: 0/30 Skip: 0/30
```diff
CALL_OneVCallSuicide.json Skip
CALL_ZeroVCallSuicide.json Skip
EXP_Empty.json Skip
+ EXP_Empty.json OK
EXTCODESIZE_toEpmty.json Skip
EXTCODESIZE_toNonExistent.json Skip
vitalikTransactionTest.json Skip
+ vitalikTransactionTest.json OK
```
OK: 0/6 Fail: 0/6 Skip: 6/6
OK: 2/6 Fail: 0/6 Skip: 4/6
## stExample
```diff
+ add11.json OK
@ -740,7 +740,7 @@ OK: 24/24 Fail: 0/24 Skip: 0/24
```diff
identity_to_bigger.json Skip
identity_to_smaller.json Skip
modexp.json Skip
+ modexp.json OK
modexp_0_0_0_1000000.json Skip
modexp_0_0_0_155000.json Skip
modexp_0_1_0_1000000.json Skip
@ -835,7 +835,7 @@ OK: 24/24 Fail: 0/24 Skip: 0/24
modexp_9_3711_37111_25000.json Skip
sec80.json Skip
```
OK: 0/96 Fail: 0/96 Skip: 96/96
OK: 1/96 Fail: 0/96 Skip: 95/96
## stPreCompiledContracts2
```diff
+ CALLCODEEcrecover0.json OK
@ -1552,7 +1552,7 @@ OK: 19/19 Fail: 0/19 Skip: 0/19
+ call_then_call_value_fail_then_returndatasize.json OK
+ call_then_create_successful_then_returndatasize.json OK
+ create_callprecompile_returndatasize.json OK
modexp_modsize0_returndatasize.json Skip
+ modexp_modsize0_returndatasize.json OK
+ returndatacopy_0_0_following_successful_create.json OK
returndatacopy_afterFailing_create.json Skip
+ returndatacopy_after_failing_callcode.json OK
@ -1585,7 +1585,7 @@ OK: 19/19 Fail: 0/19 Skip: 0/19
+ returndatasize_initial.json OK
+ returndatasize_initial_zero_read.json OK
```
OK: 34/37 Fail: 0/37 Skip: 3/37
OK: 35/37 Fail: 0/37 Skip: 2/37
## stRevertTest
```diff
+ LoopCallsDepthThenRevert.json OK
@ -1732,7 +1732,7 @@ OK: 1/7 Fail: 0/7 Skip: 6/7
static_ABAcalls2.json Skip
static_ABAcalls3.json Skip
static_ABAcallsSuicide0.json Skip
static_ABAcallsSuicide1.json Skip
+ static_ABAcallsSuicide1.json OK
static_CALL_OneVCallSuicide.json Skip
static_CALL_ZeroVCallSuicide.json Skip
static_CREATE_ContractSuicideDuringInit.json Skip
@ -2012,13 +2012,13 @@ OK: 1/7 Fail: 0/7 Skip: 6/7
static_refund_CallToSuicideNoStorage.json Skip
static_refund_CallToSuicideTwice.json Skip
```
OK: 0/284 Fail: 0/284 Skip: 284/284
OK: 1/284 Fail: 0/284 Skip: 283/284
## stSystemOperationsTest
```diff
+ ABAcalls0.json OK
+ ABAcalls1.json OK
+ ABAcalls2.json OK
+ ABAcalls3.json OK
ABAcalls2.json Skip
ABAcalls3.json Skip
+ ABAcallsSuicide0.json OK
+ ABAcallsSuicide1.json OK
+ Call10.json OK
@ -2066,8 +2066,8 @@ OK: 0/284 Fail: 0/284 Skip: 284/284
+ createNameRegistratorZeroMemExpansion.json OK
+ createWithInvalidOpcode.json OK
+ currentAccountBalance.json OK
+ doubleSelfdestructTest.json OK
+ doubleSelfdestructTest2.json OK
doubleSelfdestructTest.json Skip
doubleSelfdestructTest2.json Skip
+ extcodecopy.json OK
+ return0.json OK
+ return1.json OK
@ -2083,7 +2083,7 @@ OK: 0/284 Fail: 0/284 Skip: 284/284
+ suicideSendEtherToMe.json OK
+ testRandomTest.json OK
```
OK: 65/67 Fail: 0/67 Skip: 2/67
OK: 61/67 Fail: 0/67 Skip: 6/67
## stTransactionTest
```diff
+ ContractStoreClearsOOG.json OK
@ -2520,4 +2520,4 @@ OK: 5/133 Fail: 0/133 Skip: 128/133
OK: 0/130 Fail: 0/130 Skip: 130/130
---TOTAL---
OK: 1485/2334 Fail: 0/2334 Skip: 849/2334
OK: 1497/2334 Fail: 0/2334 Skip: 837/2334

View File

@ -75,6 +75,8 @@ type
cr_currentMemSize*: Natural
cr_memOffset*: Natural
cr_memLength*: Natural
of SelfDestruct:
sd_condition*: bool
else:
discard
@ -303,7 +305,7 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) =
# Cnew_account
if gasParams.c_isNewAccount and gasParams.kind == Call:
if fork < FkSpurious:
when fork < FkSpurious:
# Pre-EIP161 all account creation calls consumed 25000 gas.
result.gasCost += static(FeeSchedule[GasNewAccount])
else:
@ -321,7 +323,7 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) =
result.gasCost += static(FeeSchedule[GasCall])
# Cgascap
if fork >= FkTangerine:
when fork >= FkTangerine:
# https://github.com/ethereum/EIPs/blob/master/EIPS/eip-150.md
result.gasRefund =
if gasParams.c_gasBalance >= result.gasCost:
@ -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])
# ###################################################################################################
@ -523,7 +527,7 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) =
Return: memExpansion `prefix gasHalt`,
DelegateCall: complex `prefix gasCall`,
StaticCall: complex `prefix gasCall`,
Op.Revert: memExpansion `prefix gasHalt`,
Revert: memExpansion `prefix gasHalt`,
Invalid: fixed GasZero,
SelfDestruct: complex `prefix gasSelfDestruct`
]
@ -578,10 +582,11 @@ func homesteadGasFees(previous_fees: GasFeeSchedule): GasFeeSchedule =
func tangerineGasFees(previous_fees: GasFeeSchedule): GasFeeSchedule =
# https://github.com/ethereum/EIPs/blob/master/EIPS/eip-150.md
result = previous_fees
result[GasExtCode] = 700
result[GasSload] = 200
result[GasSelfDestruct] = 5000
result[GasBalance] = 400
result[GasCall] = 40
result[GasCall] = 700
func spuriousGasFees(previous_fees: GasFeeSchedule): GasFeeSchedule =
# https://github.com/ethereum/EIPs/blob/master/EIPS/eip-160.md

View File

@ -540,8 +540,13 @@ proc canTransfer(computation: BaseComputation, memPos, memLen: int, value: Uint2
proc setupCreate(computation: BaseComputation, memPos, len: int, value: Uint256): BaseComputation =
let
callData = computation.memory.read(memPos, len)
var
createMsgGas = computation.getGasRemaining()
if getFork(computation) >= FkTangerine:
createMsgGas -= createMsgGas div 64
# Consume gas here that will be passed to child
computation.gasMeter.consumeGas(createMsgGas, reason="CREATE")
@ -810,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)
@ -837,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)

View File

@ -184,6 +184,18 @@ proc genHomesteadJumpTable(ops: array[Op, NimNode]): array[Op, NimNode] {.compil
let HomesteadOpDispatch {.compileTime.}: array[Op, NimNode] = genHomesteadJumpTable(FrontierOpDispatch)
proc genTangerineJumpTable(ops: array[Op, NimNode]): array[Op, NimNode] {.compileTime.} =
result = ops
result[SelfDestruct] = newIdentNode "selfDestructEIP150"
let TangerineOpDispatch {.compileTime.}: array[Op, NimNode] = genTangerineJumpTable(HomesteadOpDispatch)
proc genSpuriousJumpTable(ops: array[Op, NimNode]): array[Op, NimNode] {.compileTime.} =
result = ops
result[SelfDestruct] = newIdentNode "selfDestructEIP161"
let SpuriousOpDispatch {.compileTime.}: array[Op, NimNode] = genSpuriousJumpTable(TangerineOpDispatch)
proc opTableToCaseStmt(opTable: array[Op, NimNode], computation: NimNode): NimNode =
let instr = quote do: `computation`.instr
@ -245,19 +257,35 @@ macro genFrontierDispatch(computation: BaseComputation): untyped =
macro genHomesteadDispatch(computation: BaseComputation): untyped =
result = opTableToCaseStmt(HomesteadOpDispatch, computation)
macro genTangerineDispatch(computation: BaseComputation): untyped =
result = opTableToCaseStmt(TangerineOpDispatch, computation)
macro genSpuriousDispatch(computation: BaseComputation): untyped =
result = opTableToCaseStmt(SpuriousOpDispatch, computation)
proc frontierVM(computation: BaseComputation) =
genFrontierDispatch(computation)
proc homesteadVM(computation: BaseComputation) =
genHomesteadDispatch(computation)
proc tangerineVM(computation: BaseComputation) =
genTangerineDispatch(computation)
proc spuriousVM(computation: BaseComputation) =
genSpuriousDispatch(computation)
proc selectVM(computation: BaseComputation, fork: Fork) =
# TODO: Optimise getting fork and updating opCodeExec only when necessary
case fork
of FkFrontier..FkThawing:
computation.frontierVM()
of FkHomestead..FkSpurious:
of FkHomestead..FkDao:
computation.homesteadVM()
of FkTangerine:
computation.tangerineVM()
of FkSpurious:
computation.spuriousVM()
else:
raise newException(VMError, "Unknown or not implemented fork: " & $fork)

View File

@ -15,6 +15,14 @@ func allowedFailingGeneralStateTest*(folder, name: string): bool =
let allowedFailingGeneralStateTests = @[
"randomStatetest14.json", # SHA3 offset
"randomStatetest85.json", # CALL* memoffset
# Tangerine failed GST
"Delegatecall1024.json",
"ABAcalls2.json",
"ABAcalls3.json",
"doubleSelfdestructTest.json",
"doubleSelfdestructTest2.json",
# Homestead recursives
#["ContractCreationSpam.json",
"Call1024OOG.json",

View File

@ -24,7 +24,7 @@ const
FkByzantium: "Byzantium",
}.toTable
supportedForks* = {FkFrontier, FkHomestead}
supportedForks* = {FkFrontier, FkHomestead, FkTangerine}
type
Status* {.pure.} = enum OK, Fail, Skip