From 266e0ddb1ec37ae1424b028614316f70f406550f Mon Sep 17 00:00:00 2001 From: andri lim Date: Wed, 4 Mar 2020 16:32:30 +0700 Subject: [PATCH 1/3] room for EIP-1283 --- nimbus/p2p/executor.nim | 1 + nimbus/utils/difficulty.nim | 6 +++--- nimbus/vm/interpreter/gas_costs.nim | 6 +++++- nimbus/vm/interpreter/opcodes_impl.nim | 12 ++++++++++-- nimbus/vm/interpreter/vm_forks.nim | 7 +++++-- nimbus/vm/interpreter_dispatch.nim | 17 ++++++++++++++++- tests/test_blockchain_json.nim | 6 +++--- tests/test_helpers.nim | 4 +++- 8 files changed, 46 insertions(+), 13 deletions(-) diff --git a/nimbus/p2p/executor.nim b/nimbus/p2p/executor.nim index 2bf4aac0b..fafd21bc6 100644 --- a/nimbus/p2p/executor.nim +++ b/nimbus/p2p/executor.nim @@ -89,6 +89,7 @@ const eth5, # FkSpurious eth3, # FkByzantium eth2, # FkConstantinople + eth2, # FkPetersburg eth2, # FkIstanbul eth2 # FkGlacierMuir ] diff --git a/nimbus/utils/difficulty.nim b/nimbus/utils/difficulty.nim index 173e52c37..887628378 100644 --- a/nimbus/utils/difficulty.nim +++ b/nimbus/utils/difficulty.nim @@ -1,4 +1,4 @@ -import +import times, eth/common, stint, ../constants, ../vm/interpreter/vm_forks @@ -142,7 +142,7 @@ template calcDifficultyConstantinople*(timeStamp: EthTime, parent: BlockHeader): template calcDifficultyGlacierMuir*(timeStamp: EthTime, parent: BlockHeader): DifficultyInt = makeDifficultyCalculator(9_000_000, timeStamp, parent) - + func calcDifficulty*(timeStamp: EthTime, parent: BlockHeader): DifficultyInt = let next = parent.blockNumber + bigOne if next >= forkBlocks[FkGlacierMuir]: @@ -160,7 +160,7 @@ func calcDifficulty*(timeStamp: EthTime, parent: BlockHeader, fork: Fork): Diffi case fork of FkGlacierMuir: result = calcDifficultyGlacierMuir(timeStamp, parent) - of FkConstantinople: + of FkConstantinople..FkPetersburg: result = calcDifficultyConstantinople(timeStamp, parent) of FkByzantium: result = calcDifficultyByzantium(timeStamp, parent) diff --git a/nimbus/vm/interpreter/gas_costs.nim b/nimbus/vm/interpreter/gas_costs.nim index cf0eea587..d99f67ca2 100644 --- a/nimbus/vm/interpreter/gas_costs.nim +++ b/nimbus/vm/interpreter/gas_costs.nim @@ -248,7 +248,7 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) = else: result.gasRefund += CleanRefundEIP2200 else: - when fork < FkIstanbul: + when fork < FkConstantinople or fork == FkPetersburg: # workaround for static evaluation not working for if expression const gSet = FeeSchedule[GasSset] @@ -721,6 +721,7 @@ const FkSpurious: SpuriousGasFees, FkByzantium: SpuriousGasFees, FkConstantinople: SpuriousGasFees, + FkPetersburg: SpuriousGasFees, FkIstanbul: IstanbulGasFees, FkGlacierMuir: IstanbulGasFees ] @@ -730,6 +731,7 @@ gasCosts(FkFrontier, base, BaseGasCosts) gasCosts(FkHomestead, homestead, HomesteadGasCosts) gasCosts(FkTangerine, tangerine, TangerineGasCosts) gasCosts(FkSpurious, spurious, SpuriousGasCosts) +gasCosts(FkConstantinople, constantinople, ConstantinopleGasCosts) gasCosts(FkIstanbul, istanbul, IstanbulGasCosts) proc forkToSchedule*(fork: Fork): GasCosts = @@ -739,6 +741,8 @@ proc forkToSchedule*(fork: Fork): GasCosts = HomesteadGasCosts elif fork < FkSpurious: TangerineGasCosts + elif fork == FkConstantinople: + ConstantinopleGasCosts # with EIP-1283 elif fork < FkIstanbul: SpuriousGasCosts else: diff --git a/nimbus/vm/interpreter/opcodes_impl.nim b/nimbus/vm/interpreter/opcodes_impl.nim index 1efd15a2a..24aa99149 100644 --- a/nimbus/vm/interpreter/opcodes_impl.nim +++ b/nimbus/vm/interpreter/opcodes_impl.nim @@ -462,7 +462,7 @@ op sstore, inline = false, slot, newValue: else: sstoreImpl(c, slot, newValue) -template sstoreEIP2200Impl(c: Computation, slot, newValue: Uint256) = +template sstoreNetGasMeteringImpl(c: Computation, slot, newValue: Uint256) = let stateDB = c.vmState.readOnlyStateDB let currentValue {.inject.} = c.getStorage(slot) @@ -492,7 +492,15 @@ op sstoreEIP2200, inline = false, slot, newValue: when evmc_enabled: sstoreEvmc(c, slot, newValue) else: - sstoreEIP2200Impl(c, slot, newValue) + sstoreNetGasMeteringImpl(c, slot, newValue) + +op sstoreEIP1283, inline = false, slot, newValue: + checkInStaticContext(c) + + when evmc_enabled: + sstoreEvmc(c, slot, newValue) + else: + sstoreNetGasMeteringImpl(c, slot, newValue) proc jumpImpl(c: Computation, jumpTarget: UInt256) = if jumpTarget >= c.code.len.u256: diff --git a/nimbus/vm/interpreter/vm_forks.nim b/nimbus/vm/interpreter/vm_forks.nim index 405d7c523..4aaee54cb 100644 --- a/nimbus/vm/interpreter/vm_forks.nim +++ b/nimbus/vm/interpreter/vm_forks.nim @@ -17,6 +17,7 @@ type FkSpurious, FkByzantium, FkConstantinople, + FkPetersburg, FkIstanbul, FkGlacierMuir @@ -29,7 +30,8 @@ const FkTangerine: 2_463_000.toBlockNumber, # 18/10/2016 17:19:31 FkSpurious: 2_675_000.toBlockNumber, # 22/11/2016 18:15:44 FkByzantium: 4_370_000.toBlockNumber, # 16/10/2017 09:22:11 - FkConstantinople: 7_280_000.toBlockNumber, # 28/02/2019 07:52:04 + FkConstantinople: 7_280_000.toBlockNumber, # Never Occured in MainNet + FkPetersburg: 7_280_000.toBlockNumber, # 28/02/2019 07:52:04 FkIstanbul: 9_069_000.toBlockNumber, # 08/12/2019 12:25:09 FkGlacierMuir: 9_200_000.toBlockNumber # 02/01/2020 08:30:49 ] @@ -51,7 +53,7 @@ proc toFork*(blockNumber: BlockNumber): Fork = elif blockNumber < forkBlocks[FkSpurious]: FkTangerine elif blockNumber < forkBlocks[FkByzantium]: FkSpurious elif blockNumber < forkBlocks[FkConstantinople]: FkByzantium - elif blockNumber < forkBlocks[FkIstanbul]: FkConstantinople + elif blockNumber < forkBlocks[FkIstanbul]: FkPetersburg elif blockNumber < forkBlocks[FkGlacierMuir]: FkIstanbul else: FkGlacierMuir @@ -65,5 +67,6 @@ proc `$`*(fork: Fork): string = of FkSpurious: result = "Spurious Dragon" of FkByzantium: result = "Byzantium" of FkConstantinople: result = "Constantinople" + of FkPetersburg: result = "Petersburg" of FkIstanbul: result = "Istanbul" of FkGlacierMuir: result = "Glacier Muir" diff --git a/nimbus/vm/interpreter_dispatch.nim b/nimbus/vm/interpreter_dispatch.nim index 260a8032a..e034c9847 100644 --- a/nimbus/vm/interpreter_dispatch.nim +++ b/nimbus/vm/interpreter_dispatch.nim @@ -212,16 +212,23 @@ proc genConstantinopleJumpTable(ops: array[Op, NimNode]): array[Op, NimNode] {.c result[Sar] = newIdentNode "sarOp" result[ExtCodeHash] = newIdentNode "extCodeHash" result[Create2] = newIdentNode "create2" + result[SStore] = newIdentNode "sstoreEIP1283" let ConstantinopleOpDispatch {.compileTime.}: array[Op, NimNode] = genConstantinopleJumpTable(ByzantiumOpDispatch) +proc genPetersburgJumpTable(ops: array[Op, NimNode]): array[Op, NimNode] {.compileTime.} = + result = ops + result[SStore] = newIdentNode "sstore" # disable EIP-1283 + +let PetersburgOpDispatch {.compileTime.}: array[Op, NimNode] = genPetersburgJumpTable(ConstantinopleOpDispatch) + proc genIstanbulJumpTable(ops: array[Op, NimNode]): array[Op, NimNode] {.compileTime.} = result = ops result[ChainId] = newIdentNode "chainId" result[SelfBalance] = newIdentNode "selfBalance" result[SStore] = newIdentNode "sstoreEIP2200" -let IstanbulOpDispatch {.compileTime.}: array[Op, NimNode] = genIstanbulJumpTable(ConstantinopleOpDispatch) +let IstanbulOpDispatch {.compileTime.}: array[Op, NimNode] = genIstanbulJumpTable(PetersburgOpDispatch) proc opTableToCaseStmt(opTable: array[Op, NimNode], c: NimNode): NimNode = @@ -296,6 +303,9 @@ macro genByzantiumDispatch(c: Computation): untyped = macro genConstantinopleDispatch(c: Computation): untyped = result = opTableToCaseStmt(ConstantinopleOpDispatch, c) +macro genPetersburgDispatch(c: Computation): untyped = + result = opTableToCaseStmt(PetersburgOpDispatch, c) + macro genIstanbulDispatch(c: Computation): untyped = result = opTableToCaseStmt(IstanbulOpDispatch, c) @@ -317,6 +327,9 @@ proc byzantiumVM(c: Computation) {.gcsafe.} = proc constantinopleVM(c: Computation) {.gcsafe.} = genConstantinopleDispatch(c) +proc petersburgVM(c: Computation) {.gcsafe.} = + genPetersburgDispatch(c) + proc istanbulVM(c: Computation) {.gcsafe.} = genIstanbulDispatch(c) @@ -335,6 +348,8 @@ proc selectVM(c: Computation, fork: Fork) {.gcsafe.} = c.byzantiumVM() of FkConstantinople: c.constantinopleVM() + of FkPetersburg: + c.petersburgVM() else: c.istanbulVM() diff --git a/tests/test_blockchain_json.nim b/tests/test_blockchain_json.nim index 77e27b7b0..3c896a1f8 100644 --- a/tests/test_blockchain_json.nim +++ b/tests/test_blockchain_json.nim @@ -190,7 +190,7 @@ proc parseBlocks(blocks: JsonNode, testStatusIMPL: var TestStatus): seq[TesterBl func vmConfiguration(network: string): VMConfig = case network of "EIP150": result = [(0, FkTangerine), (0, FkTangerine)] - of "ConstantinopleFix": result = [(0, FkConstantinople), (0, FkConstantinople)] + of "ConstantinopleFix": result = [(0, FkPetersburg), (0, FkPetersburg)] of "Homestead": result = [(0, FkHomestead), (0, FkHomestead)] of "Frontier": result = [(0, FkFrontier), (0, FkFrontier)] of "Byzantium": result = [(0, FkByzantium), (0, FkByzantium)] @@ -200,7 +200,7 @@ func vmConfiguration(network: string): VMConfig = of "Constantinople": result = [(0, FkConstantinople), (0, FkConstantinople)] of "HomesteadToEIP150At5": result = [(0, FkHomestead), (5, FkTangerine)] of "FrontierToHomesteadAt5": result = [(0, FkFrontier), (5, FkHomestead)] - of "ByzantiumToConstantinopleFixAt5": result = [(0, FkByzantium), (5, FkConstantinople)] + of "ByzantiumToConstantinopleFixAt5": result = [(0, FkByzantium), (5, FkPetersburg)] of "Istanbul": result = [(0, FkIstanbul), (0, FkIstanbul)] else: raise newException(ValueError, "unsupported network") @@ -232,7 +232,7 @@ proc parseTester(fixture: JsonNode, testStatusIMPL: var TestStatus): Tester = result.good = false # TODO: implement missing VM - if network in ["Constantinople", "HomesteadToDaoAt5"]: + if network in ["HomesteadToDaoAt5"]: result.good = false proc assignBlockRewards(minedBlock: PlainBlock, vmState: BaseVMState, fork: Fork, chainDB: BaseChainDB) = diff --git a/tests/test_helpers.nim b/tests/test_helpers.nim index f86a719f6..0eeefb246 100644 --- a/tests/test_helpers.nim +++ b/tests/test_helpers.nim @@ -26,7 +26,8 @@ const FkTangerine: "EIP150", FkSpurious: "EIP158", FkByzantium: "Byzantium", - FkConstantinople: "ConstantinopleFix", + FkConstantinople: "Constantinople", + FkPetersburg: "ConstantinopleFix", FkIstanbul: "Istanbul" }.toTable @@ -37,6 +38,7 @@ const FkSpurious, FkByzantium, FkConstantinople, + FkPetersburg, FkIstanbul} nameToFork* = revmap(forkNames) From b5850ca748126e4f4fb9081c02ac90cb72be6ea0 Mon Sep 17 00:00:00 2001 From: jangko Date: Mon, 9 Mar 2020 17:20:08 +0700 Subject: [PATCH 2/3] fix evmc compilation issue --- nimbus/vm/computation.nim | 2 +- nimbus/vm/evmc_host.nim | 6 +++--- nimbus/vm/interpreter/opcodes_impl.nim | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/nimbus/vm/computation.nim b/nimbus/vm/computation.nim index 7455cee74..989981ddf 100644 --- a/nimbus/vm/computation.nim +++ b/nimbus/vm/computation.nim @@ -11,7 +11,7 @@ import ../constants, ../errors, ../vm_state, ../vm_types, ./interpreter/[opcode_values, gas_meter, gas_costs, vm_forks], ./code_stream, ./memory, ./message, ./stack, ../db/[state_db, db_chain], - ../utils/header, stew/[byteutils, ranges], precompiles, + ../utils/header, stew/[byteutils, ranges, ranges/ptr_arith], precompiles, transaction_tracer, ../utils when defined(evmc_enabled): diff --git a/nimbus/vm/evmc_host.nim b/nimbus/vm/evmc_host.nim index 6686dbd22..ae1298535 100644 --- a/nimbus/vm/evmc_host.nim +++ b/nimbus/vm/evmc_host.nim @@ -116,7 +116,7 @@ proc hostEmitLogImpl(ctx: Computation, address: EthAddress, for i in 0 ..< topicsCount: log.topics[i] = topics[i].bytes - log.data = @makeOpenArray(data, dataSize) + log.data = @(makeOpenArray(data, dataSize)) log.address = address ctx.addLogEntry(log) @@ -128,7 +128,7 @@ template createImpl(c: Computation, m: nimbus_message, res: nimbus_result) = gas: m.gas, sender: m.sender, value: Uint256.fromEvmc(m.value), - data: @makeOpenArray(m.inputData, m.inputSize.int) + data: @(makeOpenArray(m.inputData, m.inputSize.int)) ) let child = newComputation(c.vmState, childMsg, Uint256.fromEvmc(m.create2_salt)) @@ -159,7 +159,7 @@ template callImpl(c: Computation, m: nimbus_message, res: nimbus_result) = codeAddress: m.destination, contractAddress: if m.kind == EVMC_CALL: m.destination else: c.msg.contractAddress, value: Uint256.fromEvmc(m.value), - data: @makeOpenArray(m.inputData, m.inputSize.int) + data: @(makeOpenArray(m.inputData, m.inputSize.int)), flags: MsgFlags(m.flags) ) diff --git a/nimbus/vm/interpreter/opcodes_impl.nim b/nimbus/vm/interpreter/opcodes_impl.nim index 24aa99149..8abf0cdfc 100644 --- a/nimbus/vm/interpreter/opcodes_impl.nim +++ b/nimbus/vm/interpreter/opcodes_impl.nim @@ -614,7 +614,7 @@ template genCreate(callName: untyped, opCode: Op): untyped = ) var res = c.host.call(msg) - c.returnData = @makeOpenArray(res.outputData, res.outputSize.int) + c.returnData = @(makeOpenArray(res.outputData, res.outputSize.int)) c.gasMeter.returnGas(res.gas_left) if res.status_code == EVMC_SUCCESS: @@ -780,7 +780,7 @@ template genCall(callName: untyped, opCode: Op): untyped = ) var res = c.host.call(msg) - c.returnData = @makeOpenArray(res.outputData, res.outputSize.int) + c.returnData = @(makeOpenArray(res.outputData, res.outputSize.int)) let actualOutputSize = min(memOutLen, c.returnData.len) if actualOutputSize > 0: From 32f5fd9b9076a33af8f6570678b6ff045a41b2e3 Mon Sep 17 00:00:00 2001 From: jangko Date: Mon, 9 Mar 2020 21:14:18 +0700 Subject: [PATCH 3/3] fix evmc sstore gas cost related to EIP 1283 --- nimbus/vm/interpreter/gas_costs.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimbus/vm/interpreter/gas_costs.nim b/nimbus/vm/interpreter/gas_costs.nim index d99f67ca2..f4f4864af 100644 --- a/nimbus/vm/interpreter/gas_costs.nim +++ b/nimbus/vm/interpreter/gas_costs.nim @@ -222,7 +222,8 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) = sstoreLoad = FeeSchedule[GasSload] sstoreSet = FeeSchedule[GasSset] sstoreReset= FeeSchedule[GasSreset] - sstoreDirty= when fork >= FkIstanbul: sstoreLoad else: sstoreReset + sstoreDirty= when fork < FkConstantinople or fork == FkPetersburg: sstoreReset + else: sstoreLoad InitRefundEIP2200 = FeeSchedule[GasSset] - FeeSchedule[GasSload] CleanRefundEIP2200 = FeeSchedule[GasSreset] - FeeSchedule[GasSload] ClearRefundEIP2200 = FeeSchedule[RefundsClear]