Merge pull request #488 from status-im/tofork_reform

toFork reform
This commit is contained in:
andri lim 2020-04-15 16:46:17 +07:00 committed by GitHub
commit ad28b641cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 20466 additions and 142 deletions

View File

@ -136,6 +136,7 @@ type
constantinopleBlock*: BlockNumber
petersburgBlock*: BlockNumber
istanbulBlock*: BlockNumber
muirGlacierBlock*: BlockNumber
NimbusConfiguration* = ref object
## Main Nimbus configuration object
@ -161,6 +162,7 @@ type
constantinopleBlock*: BlockNumber
petersburgBlock*: BlockNumber
istanbulBlock*: BlockNumber
muirGlacierBlock*: BlockNumber
nonce*: BlockNonce
extraData*: seq[byte]
gasLimit*: int64
@ -180,6 +182,16 @@ var nimbusConfig {.threadvar.}: NimbusConfiguration
proc getConfiguration*(): NimbusConfiguration {.gcsafe.}
proc toFork*(c: ChainConfig, number: BlockNumber): Fork =
if number >= c.istanbulBlock: FkIstanbul
elif number >= c.petersburgBlock: FkPetersburg
elif number >= c.constantinopleBlock: FkConstantinople
elif number >= c.byzantiumBlock: FkByzantium
elif number >= c.eip158Block: FkSpurious
elif number >= c.eip150Block: FkTangerine
elif number >= c.homesteadBlock: FkHomestead
else: FkFrontier
proc privateChainConfig*(): ChainConfig =
let config = getConfiguration()
result = ChainConfig(
@ -194,7 +206,8 @@ proc privateChainConfig*(): ChainConfig =
byzantiumBlock: config.customGenesis.byzantiumBlock,
constantinopleBlock: config.customGenesis.constantinopleBlock,
petersburgBlock: config.customGenesis.petersburgBlock,
istanbulBlock: config.customGenesis.istanbulBlock
istanbulBlock: config.customGenesis.istanbulBlock,
muirGlacierBlock: config.customGenesis.muirGlacierBlock
)
trace "Custom genesis block configuration loaded", configuration=result
@ -203,14 +216,18 @@ proc publicChainConfig*(id: PublicNetwork): ChainConfig =
of MainNet:
ChainConfig(
chainId: MainNet.uint,
homesteadBlock: forkBlocks[FkHomestead],
daoForkBlock: forkBlocks[FkDao],
homesteadBlock: 1_150_000.toBlockNumber, # 14/03/2016 20:49:53
daoForkBlock: 1_920_000.toBlockNumber,
daoForkSupport: true,
eip150Block: forkBlocks[FkTangerine],
eip150Block: 2_463_000.toBlockNumber, # 18/10/2016 17:19:31
eip150Hash: toDigest("2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"),
eip155Block: forkBlocks[FkSpurious],
eip158Block: forkBlocks[FkSpurious],
byzantiumBlock: forkBlocks[FkByzantium]
eip155Block: 2_675_000.toBlockNumber, # 22/11/2016 18:15:44
eip158Block: 2_675_000.toBlockNumber,
byzantiumBlock: 4_370_000.toBlockNumber, # 16/10/2017 09:22:11
constantinopleBlock: 7_280_000.toBlockNumber, # Never Occured in MainNet
petersburgBlock:7_280_000.toBlockNumber, # 28/02/2019 07:52:04
istanbulBlock: 9_069_000.toBlockNumber, # 08/12/2019 12:25:09
muirGlacierBlock: 9_200_000.toBlockNumber # 02/01/2020 08:30:49
)
of RopstenNet:
ChainConfig(
@ -221,7 +238,11 @@ proc publicChainConfig*(id: PublicNetwork): ChainConfig =
eip150Hash: toDigest("41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"),
eip155Block: 10.toBlockNumber,
eip158Block: 10.toBlockNumber,
byzantiumBlock: 1700000.toBlockNumber
byzantiumBlock: 1_700_000.toBlockNumber,
constantinopleBlock: 4_230_000.toBlockNumber,
petersburgBlock:4_939_394.toBlockNumber,
istanbulBlock: 6_485_846.toBlockNumber,
muirGlacierBlock: 7_117_117.toBlockNumber
)
of RinkebyNet:
ChainConfig(
@ -232,7 +253,11 @@ proc publicChainConfig*(id: PublicNetwork): ChainConfig =
eip150Hash: toDigest("9b095b36c15eaf13044373aef8ee0bd3a382a5abb92e402afa44b8249c3a90e9"),
eip155Block: 3.toBlockNumber,
eip158Block: 3.toBlockNumber,
byzantiumBlock: 1035301.toBlockNumber
byzantiumBlock: 1_035_301.toBlockNumber,
constantinopleBlock: 3_660_663.toBlockNumber,
petersburgBlock:4_321_234.toBlockNumber,
istanbulBlock: 5_435_345.toBlockNumber,
muirGlacierBlock: high(BlockNumber).toBlockNumber
)
of GoerliNet:
ChainConfig(
@ -244,7 +269,10 @@ proc publicChainConfig*(id: PublicNetwork): ChainConfig =
eip155Block: 0.toBlockNumber,
eip158Block: 0.toBlockNumber,
byzantiumBlock: 0.toBlockNumber,
istanbulBlock: 1561651.toBlockNumber
constantinopleBlock: 0.toBlockNumber,
petersburgBlock: 0.toBlockNumber,
istanbulBlock: 1_561_651.toBlockNumber,
muirGlacierBlock: high(BlockNumber).toBlockNumber
)
of CustomNet:
privateChainConfig()
@ -312,7 +340,7 @@ proc processCustomGenesisConfig(customGenesis: JsonNode): ConfigStatus =
var
chainId = 0.uint
homesteadBlock, daoForkblock, eip150Block, eip155Block, eip158Block, byzantiumBlock, constantinopleBlock = 0.toBlockNumber
petersburgBlock, istanbulBlock = 0.toBlockNumber
petersburgBlock, istanbulBlock, muirGlacierBlock = 0.toBlockNumber
eip150Hash, mixHash : MDigest[256]
daoForkSupport = false
nonce = 66.toBlockNonce
@ -342,6 +370,7 @@ proc processCustomGenesisConfig(customGenesis: JsonNode): ConfigStatus =
checkForFork(forkDetails, constantinopleBlock, byzantiumBlock)
checkForFork(forkDetails, petersburgBlock, constantinopleBlock)
checkForFork(forkDetails, istanbulBlock, petersburgBlock)
checkForFork(forkDetails, muirGlacierBlock, istanbulBlock)
else:
error "No chain configuration found."
quit(1)
@ -368,6 +397,7 @@ proc processCustomGenesisConfig(customGenesis: JsonNode): ConfigStatus =
constantinopleBlock: constantinopleBlock,
petersburgBlock: petersburgBlock,
istanbulBlock: istanbulBlock,
muirGlacierBlock: muirGlacierBlock,
nonce: nonce,
extraData: extraData,
gasLimit: gasLimit,

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 # FkGlacierMuir
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,11 +37,13 @@ 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,
sender,
vmState.blockNumber.toFork)
fork)
proc dummyTransaction(gasLimit, gasPrice: GasInt, destination: EthAddress, value: UInt256): Transaction =
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
@ -140,31 +141,18 @@ template calcDifficultyByzantium*(timeStamp: EthTime, parent: BlockHeader): Diff
template calcDifficultyConstantinople*(timeStamp: EthTime, parent: BlockHeader): DifficultyInt =
makeDifficultyCalculator(5_000_000, timeStamp, parent)
template calcDifficultyGlacierMuir*(timeStamp: EthTime, parent: BlockHeader): DifficultyInt =
template calcDifficultyMuirGlacier*(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[FkGlacierMuir]:
result = calcDifficultyGlacierMuir(timeStamp, parent)
elif next >= forkBlocks[FkConstantinople]:
if next >= c.muirGlacierBlock:
result = calcDifficultyMuirGlacier(timeStamp, parent)
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 FkGlacierMuir:
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,
FkGlacierMuir: 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,
FkGlacierMuir
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
FkGlacierMuir: 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[FkGlacierMuir]: FkIstanbul
else: FkGlacierMuir
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 FkGlacierMuir: 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.} =

File diff suppressed because it is too large Load Diff

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

@ -16,7 +16,8 @@ import
../nimbus/[vm_state, utils, vm_types, errors, transaction, constants],
../nimbus/db/[db_chain, state_db],
../nimbus/utils/header,
../nimbus/p2p/executor
../nimbus/p2p/[executor, dao],
../nimbus/config
type
SealEngine = enum
@ -51,6 +52,7 @@ type
trace: bool
vmState: BaseVMState
debugData: JsonNode
network: string
MiningHeader* = object
parentHash*: Hash256
@ -187,21 +189,65 @@ proc parseBlocks(blocks: JsonNode, testStatusIMPL: var TestStatus): seq[TesterBl
result.add t
func vmConfiguration(network: string): VMConfig =
func vmConfiguration(network: string, c: var ChainConfig): VMConfig =
c.homesteadBlock = high(BlockNumber)
c.daoForkBlock = high(BlockNumber)
c.daoForkSupport = false
c.eip150Block = high(BlockNumber)
c.eip158Block = high(BlockNumber)
c.byzantiumBlock = high(BlockNumber)
c.constantinopleBlock = high(BlockNumber)
c.petersburgBlock = high(BlockNumber)
c.istanbulBlock = high(BlockNumber)
c.muirGlacierBlock = high(BlockNumber)
case network
of "EIP150": result = [(0, FkTangerine), (0, FkTangerine)]
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)]
of "EIP158ToByzantiumAt5": result = [(0, FkSpurious), (5, FkByzantium)]
of "EIP158": result = [(0, FkSpurious), (0, FkSpurious)]
of "HomesteadToDaoAt5": result = [(0, FkHomestead), (5, FkHomestead)]
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, FkPetersburg)]
of "Istanbul": result = [(0, FkIstanbul), (0, FkIstanbul)]
of "EIP150":
result = [(0, FkTangerine), (0, FkTangerine)]
c.eip150Block = 0.toBlockNumber
of "ConstantinopleFix":
result = [(0, FkPetersburg), (0, FkPetersburg)]
c.petersburgBlock = 0.toBlockNumber
of "Homestead":
result = [(0, FkHomestead), (0, FkHomestead)]
c.homesteadBlock = 0.toBlockNumber
of "Frontier":
result = [(0, FkFrontier), (0, FkFrontier)]
#c.frontierBlock = 0.toBlockNumber
of "Byzantium":
result = [(0, FkByzantium), (0, FkByzantium)]
c.byzantiumBlock = 0.toBlockNumber
of "EIP158ToByzantiumAt5":
result = [(0, FkSpurious), (5, FkByzantium)]
c.eip158Block = 0.toBlockNumber
c.byzantiumBlock = 5.toBlockNumber
of "EIP158":
result = [(0, FkSpurious), (0, FkSpurious)]
c.eip158Block = 0.toBlockNumber
of "HomesteadToDaoAt5":
result = [(0, FkHomestead), (5, FkHomestead)]
c.homesteadBlock = 0.toBlockNumber
c.daoForkBlock = 5.toBlockNumber
c.daoForkSupport = true
of "Constantinople":
result = [(0, FkConstantinople), (0, FkConstantinople)]
c.constantinopleBlock = 0.toBlockNumber
of "HomesteadToEIP150At5":
result = [(0, FkHomestead), (5, FkTangerine)]
c.homesteadBlock = 0.toBlockNumber
c.eip150Block = 5.toBlockNumber
of "FrontierToHomesteadAt5":
result = [(0, FkFrontier), (5, FkHomestead)]
#c.frontierBlock = 0.toBlockNumber
c.homesteadBlock = 5.toBlockNumber
of "ByzantiumToConstantinopleFixAt5":
result = [(0, FkByzantium), (5, FkPetersburg)]
c.byzantiumBlock = 0.toBlockNumber
c.petersburgBlock = 5.toBlockNumber
of "Istanbul":
result = [(0, FkIstanbul), (0, FkIstanbul)]
c.istanbulBlock = 0.toBlockNumber
else:
raise newException(ValueError, "unsupported network")
@ -223,8 +269,7 @@ proc parseTester(fixture: JsonNode, testStatusIMPL: var TestStatus): Tester =
if "sealEngine" in fixture:
result.sealEngine = some(parseEnum[SealEngine](fixture["sealEngine"].getStr))
let network = fixture["network"].getStr
result.vmConfig = vmConfiguration(network)
result.network = fixture["network"].getStr
try:
result.blocks = parseBlocks(fixture["blocks"], testStatusIMPL)
@ -232,8 +277,8 @@ proc parseTester(fixture: JsonNode, testStatusIMPL: var TestStatus): Tester =
result.good = false
# TODO: implement missing VM
if network in ["HomesteadToDaoAt5"]:
result.good = false
#if result.network in ["HomesteadToDaoAt5"]:
#result.good = false
proc assignBlockRewards(minedBlock: PlainBlock, vmState: BaseVMState, fork: Fork, chainDB: BaseChainDB) =
let blockReward = blockRewards[fork]
@ -275,6 +320,10 @@ proc processBlock(chainDB: BaseChainDB, vmState: BaseVMState, minedBlock: PlainB
var dbTx = chainDB.db.beginTransaction()
defer: dbTx.dispose()
if chainDB.config.daoForkSupport and minedBlock.header.blockNumber == chainDB.config.daoForkBlock:
vmState.mutateStateDB:
db.applyDAOHardFork()
vmState.receipts = newSeq[Receipt](minedBlock.transactions.len)
vmState.cumulativeGasUsed = 0
@ -509,9 +558,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,
let baseHeaderForImport = generateHeaderFromParentHeader(chainDB.config,
parentHeader,
preminedBlock.header.coinbase,
fork,
some(preminedBlock.header.timestamp),
some(preminedBlock.header.gasLimit),
@[]
@ -537,6 +586,10 @@ proc importBlock(tester: var Tester, chainDB: BaseChainDB,
proc applyFixtureBlockToChain(tester: var Tester, tb: TesterBlock,
chainDB: BaseChainDB, checkSeal, validation = true): (PlainBlock, PlainBlock, Blob) =
# we hack the ChainConfig here and let it works with calcDifficulty
tester.vmConfig = vmConfiguration(tester.network, chainDB.config)
var
preminedBlock = rlp.decode(tb.headerRLP, PlainBlock)
fork = vmConfigToFork(tester.vmConfig, preminedBlock.header.blockNumber)
@ -625,7 +678,7 @@ proc testFixture(node: JsonNode, testStatusIMPL: var TestStatus, debugMode = fal
# - mine block
# 3 - diff resulting state with expected state
# 4 - check that all previous blocks were valid
let specifyIndex = getConfiguration().index
let specifyIndex = test_config.getConfiguration().index
var fixtureIndex = 0
var fixtureTested = false
@ -635,7 +688,7 @@ proc testFixture(node: JsonNode, testStatusIMPL: var TestStatus, debugMode = fal
continue
var tester = parseTester(fixture, testStatusIMPL)
var chainDB = newBaseChainDB(newMemoryDb(), pruneTrie = getConfiguration().pruning)
var chainDB = newBaseChainDB(newMemoryDb(), pruneTrie = test_config.getConfiguration().pruning)
echo "TESTING: ", fixtureName
if not tester.good: continue
@ -670,7 +723,7 @@ proc testFixture(node: JsonNode, testStatusIMPL: var TestStatus, debugMode = fal
check success == true
if not fixtureTested:
echo getConfiguration().testSubject, " not tested at all, wrong index?"
echo test_config.getConfiguration().testSubject, " not tested at all, wrong index?"
if specifyIndex <= 0 or specifyIndex > node.len:
echo "Maximum subtest available: ", node.len
@ -683,7 +736,7 @@ proc blockchainJsonMain*(debugMode = false) =
jsonTest("newBlockChainTests", testFixture, skipNewBCTests)
else:
# execute single test in debug mode
let config = getConfiguration()
let config = test_config.getConfiguration()
if config.testSubject.len == 0:
echo "missing test subject"
quit(QuitFailure)
@ -698,7 +751,7 @@ when isMainModule:
var message: string
## Processing command line arguments
if processArguments(message) != Success:
if test_config.processArguments(message) != test_config.Success:
echo message
quit(QuitFailure)
else:

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,20 +60,26 @@ 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)
let ropstenConfig = publicChainConfig(RopstenNet)
func calcDifficultyRopsten(timeStamp: EthTime, parent: BlockHeader): DifficultyInt =
ropstenConfig.calcDifficulty(timeStamp, parent)
suite "DifficultyTest":
runTests("EIP2384_random_to20M", true, calcDifficultyGlacierMuir)
runTests("EIP2384_random", true, calcDifficultyGlacierMuir)
runTests("EIP2384", true, calcDifficultyGlacierMuir)
runTests("EIP2384_random_to20M", true, calcDifficultyMuirGlacier)
runTests("EIP2384_random", true, calcDifficultyMuirGlacier)
runTests("EIP2384", true, calcDifficultyMuirGlacier)
runTests("Byzantium", true, calcDifficultyByzantium)
runTests("Constantinople", true, calcDifficultyConstantinople)
runTests("Homestead", true, calcDifficultyHomestead)
runTests("MainNetwork", true, calcDifficultyMainNetwork)
runTests("Frontier", true, calcDifficultyFrontier)
runTests("", false, calcDifficulty)
runTests("", false, calcDifficultyMainNetWork)
runTests("Ropsten", true, calcDifficultyRopsten)
when isMainModule:
difficultyMain()