switch to new toFork

This commit is contained in:
andri lim 2020-04-12 17:33:17 +07:00
parent e324a7342d
commit 87bae2bb78
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
12 changed files with 49 additions and 102 deletions

View File

@ -5,7 +5,7 @@ import options, sets,
../vm_state, ../vm_types, ../vm_state_transactions,
../vm/[computation, message],
../vm/interpreter/vm_forks,
./dao
./dao, ../config
proc processTransaction*(tx: Transaction, sender: EthAddress, vmState: BaseVMState, fork: Fork): GasInt =
## Process the transaction, write the results to db.
@ -82,16 +82,13 @@ const
eth2 = 2.eth
blockRewards*: array[Fork, Uint256] = [
eth5, # FkFrontier
eth5, # FkThawing
eth5, # FkHomestead
eth5, # FkDao
eth5, # FkTangerine
eth5, # FkSpurious
eth3, # FkByzantium
eth2, # FkConstantinople
eth2, # FkPetersburg
eth2, # FkIstanbul
eth2 # FkMuirGlacier
eth2 # FkIstanbul
]
proc processBlock*(chainDB: BaseChainDB, header: BlockHeader, body: BlockBody, vmState: BaseVMState): ValidationResult =
@ -106,7 +103,7 @@ proc processBlock*(chainDB: BaseChainDB, header: BlockHeader, body: BlockBody, v
debug "Mismatched txRoot", blockNumber=header.blockNumber
return ValidationResult.Error
let fork = vmState.blockNumber.toFork
let fork = chainDB.config.toFork(vmState.blockNumber)
if header.txRoot != BLANK_ROOT_HASH:
if body.transactions.len == 0:

View File

@ -37,6 +37,8 @@ template balance(addressDb: ReadOnlyStateDb, address: EthAddress): GasInt =
proc binarySearchGas(vmState: var BaseVMState, transaction: Transaction, sender: EthAddress, gasPrice: GasInt, tolerance = 1): GasInt =
proc dummyComputation(vmState: var BaseVMState, transaction: Transaction, sender: EthAddress): Computation =
# Note that vmState may be altered
var chainDB = vmState.chainDB
let fork = chainDB.config.toFork(vmState.blockNumber)
setupComputation(
vmState,
transaction,
@ -52,7 +54,8 @@ proc binarySearchGas(vmState: var BaseVMState, transaction: Transaction, sender:
value: value
)
var
fork = vmState.blockNumber.toFork
chainDB = vmState.chainDB
fork = chainDB.config.toFork(vmState.blockNumber)
hiGas = vmState.gasLimit
loGas = transaction.intrinsicGas(fork)
gasPrice = transaction.gasPrice # TODO: Or zero?

View File

@ -3,7 +3,7 @@ import
constants, vm_state, vm_types, transaction, p2p/executor,
eth/trie/db, nimcrypto, strutils, stew/ranges,
chronicles, rpc/hexstrings, launcher,
vm/interpreter/vm_forks
vm/interpreter/vm_forks, ./config
proc getParentHeader(self: BaseChainDB, header: BlockHeader): BlockHeader =
self.getBlockHeader(header.parentHash)
@ -66,14 +66,14 @@ const
uncleName = "uncle"
internalTxName = "internalTx"
proc traceTransaction*(db: BaseChainDB, header: BlockHeader,
proc traceTransaction*(chainDB: BaseChainDB, header: BlockHeader,
body: BlockBody, txIndex: int, tracerFlags: set[TracerFlags] = {}): JsonNode =
let
parent = db.getParentHeader(header)
parent = chainDB.getParentHeader(header)
# we add a memory layer between backend/lower layer db
# and capture state db snapshot during transaction execution
memoryDB = newMemoryDB()
captureDB = newCaptureDB(db.db, memoryDB)
captureDB = newCaptureDB(chainDB.db, memoryDB)
captureTrieDB = trieDB captureDB
captureChainDB = newBaseChainDB(captureTrieDB, false) # prune or not prune?
vmState = newBaseVMState(parent.stateRoot, header, captureChainDB, tracerFlags + {EnableAccount})
@ -91,7 +91,7 @@ proc traceTransaction*(db: BaseChainDB, header: BlockHeader,
stateDiff = %{"before": before, "after": after}
beforeRoot: Hash256
let fork = header.blockNumber.toFork
let fork = chainDB.config.toFork(header.blockNumber)
for idx, tx in body.transactions:
let sender = tx.getSender
@ -116,7 +116,7 @@ proc traceTransaction*(db: BaseChainDB, header: BlockHeader,
break
# internal transactions:
var stateBefore = newAccountStateDB(captureTrieDB, beforeRoot, db.pruneTrie)
var stateBefore = newAccountStateDB(captureTrieDB, beforeRoot, chainDB.pruneTrie)
for idx, acc in tracedAccountsPairs(vmState):
before.captureAccount(stateBefore, acc, internalTxName & $idx)
@ -189,11 +189,11 @@ proc dumpBlockState*(db: BaseChainDB, header: BlockHeader, body: BlockBody, dump
if dumpState:
result.dumpMemoryDB(memoryDB)
proc traceBlock*(db: BaseChainDB, header: BlockHeader, body: BlockBody, tracerFlags: set[TracerFlags] = {}): JsonNode =
proc traceBlock*(chainDB: BaseChainDB, header: BlockHeader, body: BlockBody, tracerFlags: set[TracerFlags] = {}): JsonNode =
let
parent = db.getParentHeader(header)
parent = chainDB.getParentHeader(header)
memoryDB = newMemoryDB()
captureDB = newCaptureDB(db.db, memoryDB)
captureDB = newCaptureDB(chainDB.db, memoryDB)
captureTrieDB = trieDB captureDB
captureChainDB = newBaseChainDB(captureTrieDB, false)
vmState = newBaseVMState(parent.stateRoot, header, captureChainDB, tracerFlags + {EnableTracing})
@ -203,7 +203,7 @@ proc traceBlock*(db: BaseChainDB, header: BlockHeader, body: BlockBody, tracerFl
doAssert(body.transactions.len != 0)
var gasUsed = GasInt(0)
let fork = header.blockNumber.toFork
let fork = chainDB.config.toFork(header.blockNumber)
for tx in body.transactions:
let sender = tx.getSender

View File

@ -1,7 +1,8 @@
import
times,
eth/common, stint,
../constants, ../vm/interpreter/vm_forks
../constants, ../vm/interpreter/vm_forks,
../config
const
ExpDiffPeriod = 100000.u256
@ -143,28 +144,15 @@ 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 =
func calcDifficulty*(c: ChainConfig, timeStamp: EthTime, parent: BlockHeader): DifficultyInt =
let next = parent.blockNumber + bigOne
if next >= forkBlocks[FkMuirGlacier]:
if next >= c.muirGlacierBlock:
result = calcDifficultyGlacierMuir(timeStamp, parent)
elif next >= forkBlocks[FkConstantinople]:
elif next >= c.constantinopleBlock:
result = calcDifficultyConstantinople(timeStamp, parent)
elif next >= forkBlocks[FkByzantium]:
elif next >= c.byzantiumBlock:
result = calcDifficultyByzantium(timeStamp, parent)
elif next >= forkBlocks[FkHomestead]:
elif next >= c.homesteadBlock:
result = calcDifficultyHomestead(timeStamp, parent)
else:
result = calcDifficultyFrontier(timeStamp, parent)
func calcDifficulty*(timeStamp: EthTime, parent: BlockHeader, fork: Fork): DifficultyInt =
case fork
of FkMuirGlacier:
result = calcDifficultyGlacierMuir(timeStamp, parent)
of FkConstantinople..FkPetersburg:
result = calcDifficultyConstantinople(timeStamp, parent)
of FkByzantium:
result = calcDifficultyByzantium(timeStamp, parent)
of FkHomestead..FkSpurious:
result = calcDifficultyHomestead(timeStamp, parent)
else:
result = calcDifficultyFrontier(timeStamp, parent)

View File

@ -9,7 +9,8 @@
import
strformat, times, options,
eth/[common, rlp],
./difficulty, ../vm/interpreter/vm_forks, ../constants
./difficulty, ../vm/interpreter/vm_forks, ../constants,
../config
export BlockHeader
@ -66,8 +67,8 @@ proc computeGasLimit*(parent: BlockHeader, gasLimitFloor: GasInt): GasInt =
else:
return gasLimit
proc generateHeaderFromParentHeader*(parent: BlockHeader,
coinbase: EthAddress, fork: Fork, timestamp: Option[EthTime],
proc generateHeaderFromParentHeader*(config: ChainConfig, parent: BlockHeader,
coinbase: EthAddress, timestamp: Option[EthTime],
gasLimit: Option[GasInt], extraData: Blob): BlockHeader =
var lcTimestamp: EthTime
@ -82,7 +83,7 @@ proc generateHeaderFromParentHeader*(parent: BlockHeader,
result = BlockHeader(
timestamp: lcTimestamp,
blockNumber: (parent.blockNumber + 1),
difficulty: calcDifficulty(lcTimestamp, parent, fork),
difficulty: config.calcDifficulty(lcTimestamp, parent),
gasLimit: if gasLimit.isSome: gasLimit.get() else: computeGasLimit(parent, gasLimitFloor = GENESIS_GAS_LIMIT),
stateRoot: parent.stateRoot,
coinbase: coinbase,

View File

@ -715,16 +715,13 @@ const
gasFees*: array[Fork, GasFeeSchedule] = [
FkFrontier: BaseGasFees,
FkThawing: BaseGasFees,
FkHomestead: HomesteadGasFees,
FkDao: HomesteadGasFees,
FkTangerine: TangerineGasFees,
FkSpurious: SpuriousGasFees,
FkByzantium: SpuriousGasFees,
FkConstantinople: SpuriousGasFees,
FkPetersburg: SpuriousGasFees,
FkIstanbul: IstanbulGasFees,
FkMuirGlacier: IstanbulGasFees
FkIstanbul: IstanbulGasFees
]

View File

@ -10,63 +10,21 @@ import stint, eth/common/eth_types
type
Fork* = enum
FkFrontier,
FkThawing,
FkHomestead,
FkDao,
FkTangerine,
FkSpurious,
FkByzantium,
FkConstantinople,
FkPetersburg,
FkIstanbul,
FkMuirGlacier
const
forkBlocks*: array[Fork, BlockNumber] = [
FkFrontier: 1.toBlockNumber, # 30/07/2015 19:26:28
FkThawing: 200_000.toBlockNumber, # 08/09/2015 01:33:09
FkHomestead: 1_150_000.toBlockNumber, # 14/03/2016 20:49:53
FkDao: 1_920_000.toBlockNumber, # 20/07/2016 17:20:40
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, # 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
FkMuirGlacier: 9_200_000.toBlockNumber # 02/01/2020 08:30:49
]
proc toFork*(blockNumber: BlockNumber): Fork =
# TODO: uint256 comparison is probably quite expensive
# hence binary search is probably worth it earlier than
# linear search
# TODO: all toFork usage currently incurs comparison to get the fork and then another comparison to
# go to the ultimate needed result.
# Genesis block 0 also uses the Frontier code path
if blockNumber < forkBlocks[FkThawing]: FkFrontier
elif blockNumber < forkBlocks[FkHomestead]: FkThawing
elif blockNumber < forkBlocks[FkDao]: FkHomestead
elif blockNumber < forkBlocks[FkTangerine]: FkDao
elif blockNumber < forkBlocks[FkSpurious]: FkTangerine
elif blockNumber < forkBlocks[FkByzantium]: FkSpurious
elif blockNumber < forkBlocks[FkConstantinople]: FkByzantium
elif blockNumber < forkBlocks[FkIstanbul]: FkPetersburg
elif blockNumber < forkBlocks[FkMuirGlacier]: FkIstanbul
else: FkMuirGlacier
FkIstanbul
proc `$`*(fork: Fork): string =
case fork
of FkFrontier: result = "Frontier"
of FkThawing: result = "Thawing"
of FkHomestead: result = "Homestead"
of FkDao: result = "Dao"
of FkTangerine: result = "Tangerine Whistle"
of FkSpurious: result = "Spurious Dragon"
of FkByzantium: result = "Byzantium"
of FkConstantinople: result = "Constantinople"
of FkPetersburg: result = "Petersburg"
of FkIstanbul: result = "Istanbul"
of FkMuirGlacier: result = "Glacier Muir"

View File

@ -336,9 +336,9 @@ proc istanbulVM(c: Computation) {.gcsafe.} =
proc selectVM(c: Computation, fork: Fork) {.gcsafe.} =
# TODO: Optimise getting fork and updating opCodeExec only when necessary
case fork
of FkFrontier..FkThawing:
of FkFrontier:
c.frontierVM()
of FkHomestead..FkDao:
of FkHomestead:
c.homesteadVM()
of FkTangerine:
c.tangerineVM()

View File

@ -10,7 +10,8 @@ import
eth/common,
vm/interpreter/[vm_forks, gas_costs],
./constants, ./db/[db_chain, state_db],
./utils, json, vm_types, vm/transaction_tracer
./utils, json, vm_types, vm/transaction_tracer,
./config
proc newAccessLogs*: AccessLogs =
AccessLogs(reads: initTable[string, string](), writes: initTable[string, string]())
@ -52,7 +53,7 @@ proc setupTxContext*(vmState: BaseVMState, origin: EthAddress, gasPrice: GasInt,
if forkOverride.isSome:
forkOverride.get
else:
vmState.blockHeader.blockNumber.toFork
vmState.chainDB.config.toFork(vmState.blockHeader.blockNumber)
vmState.gasCosts = vmState.fork.forkToSchedule
method blockhash*(vmState: BaseVMState): Hash256 {.base, gcsafe.} =

View File

@ -2,7 +2,7 @@ import
macrocache, strutils, unittest2,
stew/byteutils, chronicles, stew/ranges, eth/common,
../nimbus/vm/interpreter/opcode_values,
stew/shims/macros
stew/shims/macros, ../nimbus/config
import
options, json, os, eth/trie/[db, hexary],
@ -201,7 +201,7 @@ proc initComputation(vmState: BaseVMState, tx: Transaction, sender: EthAddress,
if forkOverride.isSome:
forkOverride.get
else:
vmState.blockNumber.toFork
vmState.chainDB.config.toFork(vmState.blockNumber)
let gasUsed = 0 #tx.payload.intrinsicGas.GasInt + gasFees[fork][GasTXCreate]
@ -225,7 +225,7 @@ proc initComputation(vmState: BaseVMState, tx: Transaction, sender: EthAddress,
vmState.mutateStateDb:
db.setCode(contractAddress, tx.payload.toRange)
newComputation(vmState, msg)
proc initDatabase*(): (Uint256, BaseChainDB) =

View File

@ -509,9 +509,9 @@ proc importBlock(tester: var Tester, chainDB: BaseChainDB,
preminedBlock: PlainBlock, fork: Fork, checkSeal, validation = true): PlainBlock =
let parentHeader = chainDB.getBlockHeader(preminedBlock.header.parentHash)
let baseHeaderForImport = generateHeaderFromParentHeader(parentHeader,
preminedBlock.header.coinbase,
fork,
let baseHeaderForImport = generateHeaderFromParentHeader(chainDB.config,
parentHeader,
preminedBlock.header.coinbase,
some(preminedBlock.header.timestamp),
some(preminedBlock.header.gasLimit),
@[]

View File

@ -1,7 +1,8 @@
import unittest2, strutils, tables, os, json,
../nimbus/utils/difficulty, stint, times,
eth/common, test_helpers, stew/byteutils,
../nimbus/constants, ../nimbus/vm/interpreter/vm_forks
../nimbus/constants, ../nimbus/vm/interpreter/vm_forks,
../nimbus/config
type
Tester = object
@ -59,10 +60,11 @@ template runTests(name: string, hex: bool, calculator: typed) =
let diff = calculator(times.fromUnix(t.currentTimeStamp), p)
check diff == t.currentDifficulty
func calcDifficultyMainNetWork(timeStamp: EthTime, parent: BlockHeader): DifficultyInt =
calcDifficulty(timeStamp, parent, parent.blockNumber.toFork)
proc difficultyMain*() =
let mainnetConfig = publicChainConfig(MainNet)
func calcDifficultyMainNetWork(timeStamp: EthTime, parent: BlockHeader): DifficultyInt =
mainnetConfig.calcDifficulty(timeStamp, parent)
suite "DifficultyTest":
runTests("EIP2384_random_to20M", true, calcDifficultyGlacierMuir)
runTests("EIP2384_random", true, calcDifficultyGlacierMuir)
@ -72,7 +74,7 @@ proc difficultyMain*() =
runTests("Homestead", true, calcDifficultyHomestead)
runTests("MainNetwork", true, calcDifficultyMainNetwork)
runTests("Frontier", true, calcDifficultyFrontier)
runTests("", false, calcDifficulty)
runTests("", false, calcDifficultyMainNetWork)
when isMainModule:
difficultyMain()