mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-02-26 10:55:41 +00:00
Merge pull request #516 from status-im/validate_block_witness
syncing with PoA chain
This commit is contained in:
commit
6ea488e037
@ -33,6 +33,7 @@ type
|
|||||||
trie: SecureHexaryTrie
|
trie: SecureHexaryTrie
|
||||||
savePoint: SavePoint
|
savePoint: SavePoint
|
||||||
witnessCache: Table[EthAddress, WitnessData]
|
witnessCache: Table[EthAddress, WitnessData]
|
||||||
|
isDirty: bool
|
||||||
|
|
||||||
ReadOnlyStateDB* = distinct AccountsCache
|
ReadOnlyStateDB* = distinct AccountsCache
|
||||||
|
|
||||||
@ -46,7 +47,17 @@ type
|
|||||||
cache: Table[EthAddress, RefAccount]
|
cache: Table[EthAddress, RefAccount]
|
||||||
state: TransactionState
|
state: TransactionState
|
||||||
|
|
||||||
const emptyAcc = newAccount()
|
const
|
||||||
|
emptyAcc = newAccount()
|
||||||
|
|
||||||
|
resetFlags = {
|
||||||
|
IsDirty,
|
||||||
|
IsNew,
|
||||||
|
IsTouched,
|
||||||
|
IsClone,
|
||||||
|
CodeChanged,
|
||||||
|
StorageChanged
|
||||||
|
}
|
||||||
|
|
||||||
proc beginSavepoint*(ac: var AccountsCache): SavePoint {.gcsafe.}
|
proc beginSavepoint*(ac: var AccountsCache): SavePoint {.gcsafe.}
|
||||||
|
|
||||||
@ -66,7 +77,7 @@ proc rootHash*(ac: AccountsCache): KeccakHash =
|
|||||||
# make sure all savepoint already committed
|
# make sure all savepoint already committed
|
||||||
doAssert(ac.savePoint.parentSavePoint.isNil)
|
doAssert(ac.savePoint.parentSavePoint.isNil)
|
||||||
# make sure all cache already committed
|
# make sure all cache already committed
|
||||||
doAssert(ac.savePoint.cache.len == 0)
|
doAssert(ac.isDirty == false)
|
||||||
ac.trie.rootHash
|
ac.trie.rootHash
|
||||||
|
|
||||||
proc beginSavepoint*(ac: var AccountsCache): SavePoint =
|
proc beginSavepoint*(ac: var AccountsCache): SavePoint =
|
||||||
@ -222,14 +233,20 @@ proc persistMode(acc: RefAccount): PersistMode =
|
|||||||
|
|
||||||
proc persistCode(acc: RefAccount, db: TrieDatabaseRef) =
|
proc persistCode(acc: RefAccount, db: TrieDatabaseRef) =
|
||||||
if acc.code.len != 0:
|
if acc.code.len != 0:
|
||||||
db.put(contractHashKey(acc.account.codeHash).toOpenArray, acc.code)
|
when defined(geth):
|
||||||
|
db.put(acc.account.codeHash.data, acc.code)
|
||||||
|
else:
|
||||||
|
db.put(contractHashKey(acc.account.codeHash).toOpenArray, acc.code)
|
||||||
|
|
||||||
proc persistStorage(acc: RefAccount, db: TrieDatabaseRef) =
|
proc persistStorage(acc: RefAccount, db: TrieDatabaseRef, clearCache: bool) =
|
||||||
if acc.overlayStorage.len == 0:
|
if acc.overlayStorage.len == 0:
|
||||||
# TODO: remove the storage too if we figure out
|
# TODO: remove the storage too if we figure out
|
||||||
# how to create 'virtual' storage room for each account
|
# how to create 'virtual' storage room for each account
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if not clearCache and acc.originalStorage.isNil:
|
||||||
|
acc.originalStorage = newTable[UInt256, UInt256]()
|
||||||
|
|
||||||
var accountTrie = getAccountTrie(db, acc)
|
var accountTrie = getAccountTrie(db, acc)
|
||||||
|
|
||||||
for slot, value in acc.overlayStorage:
|
for slot, value in acc.overlayStorage:
|
||||||
@ -246,9 +263,21 @@ proc persistStorage(acc: RefAccount, db: TrieDatabaseRef) =
|
|||||||
# slotHash can be obtained from accountTrie.put?
|
# slotHash can be obtained from accountTrie.put?
|
||||||
let slotHash = keccakHash(slotAsKey)
|
let slotHash = keccakHash(slotAsKey)
|
||||||
db.put(slotHashToSlotKey(slotHash.data).toOpenArray, rlp.encode(slot))
|
db.put(slotHashToSlotKey(slotHash.data).toOpenArray, rlp.encode(slot))
|
||||||
|
|
||||||
|
if not clearCache:
|
||||||
|
# if we preserve cache, move the overlayStorage
|
||||||
|
# to originalStorage, related to EIP2200, EIP1283
|
||||||
|
for slot, value in acc.overlayStorage:
|
||||||
|
if value > 0:
|
||||||
|
acc.originalStorage[slot] = value
|
||||||
|
else:
|
||||||
|
acc.originalStorage.del(slot)
|
||||||
|
acc.overlayStorage.clear()
|
||||||
|
|
||||||
acc.account.storageRoot = accountTrie.rootHash
|
acc.account.storageRoot = accountTrie.rootHash
|
||||||
|
|
||||||
proc makeDirty(ac: AccountsCache, address: EthAddress, cloneStorage = true): RefAccount =
|
proc makeDirty(ac: AccountsCache, address: EthAddress, cloneStorage = true): RefAccount =
|
||||||
|
ac.isDirty = true
|
||||||
result = ac.getAccount(address)
|
result = ac.getAccount(address)
|
||||||
if address in ac.savePoint.cache:
|
if address in ac.savePoint.cache:
|
||||||
# it's already in latest savepoint
|
# it's already in latest savepoint
|
||||||
@ -283,7 +312,11 @@ proc getCode*(ac: AccountsCache, address: EthAddress): seq[byte] =
|
|||||||
if CodeLoaded in acc.flags or CodeChanged in acc.flags:
|
if CodeLoaded in acc.flags or CodeChanged in acc.flags:
|
||||||
result = acc.code
|
result = acc.code
|
||||||
else:
|
else:
|
||||||
let data = ac.db.get(contractHashKey(acc.account.codeHash).toOpenArray)
|
when defined(geth):
|
||||||
|
let data = ac.db.get(acc.account.codeHash.data)
|
||||||
|
else:
|
||||||
|
let data = ac.db.get(contractHashKey(acc.account.codeHash).toOpenArray)
|
||||||
|
|
||||||
acc.code = data
|
acc.code = data
|
||||||
acc.flags.incl CodeLoaded
|
acc.flags.incl CodeLoaded
|
||||||
result = acc.code
|
result = acc.code
|
||||||
@ -384,9 +417,11 @@ proc deleteAccount*(ac: var AccountsCache, address: EthAddress) =
|
|||||||
let acc = ac.getAccount(address)
|
let acc = ac.getAccount(address)
|
||||||
acc.kill()
|
acc.kill()
|
||||||
|
|
||||||
proc persist*(ac: var AccountsCache) =
|
proc persist*(ac: var AccountsCache, clearCache: bool = true) =
|
||||||
# make sure all savepoint already committed
|
# make sure all savepoint already committed
|
||||||
doAssert(ac.savePoint.parentSavePoint.isNil)
|
doAssert(ac.savePoint.parentSavePoint.isNil)
|
||||||
|
var cleanAccounts = initHashSet[EthAddress]()
|
||||||
|
|
||||||
for address, acc in ac.savePoint.cache:
|
for address, acc in ac.savePoint.cache:
|
||||||
case acc.persistMode()
|
case acc.persistMode()
|
||||||
of Update:
|
of Update:
|
||||||
@ -395,13 +430,24 @@ proc persist*(ac: var AccountsCache) =
|
|||||||
if StorageChanged in acc.flags:
|
if StorageChanged in acc.flags:
|
||||||
# storageRoot must be updated first
|
# storageRoot must be updated first
|
||||||
# before persisting account into merkle trie
|
# before persisting account into merkle trie
|
||||||
acc.persistStorage(ac.db)
|
acc.persistStorage(ac.db, clearCache)
|
||||||
ac.trie.put address, rlp.encode(acc.account)
|
ac.trie.put address, rlp.encode(acc.account)
|
||||||
of Remove:
|
of Remove:
|
||||||
ac.trie.del address
|
ac.trie.del address
|
||||||
|
if not clearCache:
|
||||||
|
#
|
||||||
|
cleanAccounts.incl address
|
||||||
of DoNothing:
|
of DoNothing:
|
||||||
discard
|
discard
|
||||||
ac.savePoint.cache.clear()
|
|
||||||
|
acc.flags = acc.flags - resetFlags
|
||||||
|
|
||||||
|
if clearCache:
|
||||||
|
ac.savePoint.cache.clear()
|
||||||
|
else:
|
||||||
|
for x in cleanAccounts:
|
||||||
|
ac.savePoint.cache.del x
|
||||||
|
ac.isDirty = false
|
||||||
|
|
||||||
iterator storage*(ac: AccountsCache, address: EthAddress): (UInt256, UInt256) =
|
iterator storage*(ac: AccountsCache, address: EthAddress): (UInt256, UInt256) =
|
||||||
# beware that if the account not persisted,
|
# beware that if the account not persisted,
|
||||||
@ -411,10 +457,11 @@ iterator storage*(ac: AccountsCache, address: EthAddress): (UInt256, UInt256) =
|
|||||||
let storageRoot = acc.account.storageRoot
|
let storageRoot = acc.account.storageRoot
|
||||||
var trie = initHexaryTrie(ac.db, storageRoot)
|
var trie = initHexaryTrie(ac.db, storageRoot)
|
||||||
|
|
||||||
for slot, value in trie:
|
for slotHash, value in trie:
|
||||||
if slot.len != 0:
|
if slotHash.len == 0: continue
|
||||||
var keyData = ac.db.get(slotHashToSlotKey(slot).toOpenArray)
|
let keyData = ac.db.get(slotHashToSlotKey(slotHash).toOpenArray)
|
||||||
yield (rlp.decode(keyData, UInt256), rlp.decode(value, UInt256))
|
if keyData.len == 0: continue
|
||||||
|
yield (rlp.decode(keyData, UInt256), rlp.decode(value, UInt256))
|
||||||
|
|
||||||
proc getStorageRoot*(ac: AccountsCache, address: EthAddress): Hash256 =
|
proc getStorageRoot*(ac: AccountsCache, address: EthAddress): Hash256 =
|
||||||
# beware that if the account not persisted,
|
# beware that if the account not persisted,
|
||||||
|
35
nimbus/db/geth_db.nim
Normal file
35
nimbus/db/geth_db.nim
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import eth/[rlp, common], db_chain, eth/trie/db
|
||||||
|
|
||||||
|
const
|
||||||
|
headerPrefix = 'h'.byte # headerPrefix + num (uint64 big endian) + hash -> header
|
||||||
|
headerHashSuffix = 'n'.byte # headerPrefix + num (uint64 big endian) + headerHashSuffix -> hash
|
||||||
|
blockBodyPrefix = 'b'.byte # blockBodyPrefix + num (uint64 big endian) + hash -> block body
|
||||||
|
|
||||||
|
proc headerHash*(db: BaseChainDB, number: uint64): Hash256 =
|
||||||
|
var key: array[10, byte]
|
||||||
|
key[0] = headerPrefix
|
||||||
|
key[1..8] = toBytesBE(number)[0..^1]
|
||||||
|
key[^1] = headerHashSuffix
|
||||||
|
let res = db.db.get(key)
|
||||||
|
doAssert(res.len == 32)
|
||||||
|
result.data[0..31] = res[0..31]
|
||||||
|
|
||||||
|
proc blockHeader*(db: BaseChainDB, hash: Hash256, number: uint64): BlockHeader =
|
||||||
|
var key: array[41, byte]
|
||||||
|
key[0] = headerPrefix
|
||||||
|
key[1..8] = toBytesBE(number)[0..^1]
|
||||||
|
key[9..40] = hash.data[0..^1]
|
||||||
|
let res = db.db.get(key)
|
||||||
|
result = rlp.decode(res, BlockHeader)
|
||||||
|
|
||||||
|
proc blockHeader*(db: BaseChainDB, number: uint64): BlockHeader =
|
||||||
|
let hash = db.headerHash(number)
|
||||||
|
db.blockHeader(hash, number)
|
||||||
|
|
||||||
|
proc blockBody*(db: BaseChainDB, hash: Hash256, number: uint64): BlockBody =
|
||||||
|
var key: array[41, byte]
|
||||||
|
key[0] = blockBodyPrefix
|
||||||
|
key[1..8] = toBytesBE(number)[0..^1]
|
||||||
|
key[9..40] = hash.data[0..^1]
|
||||||
|
let res = db.db.get(key)
|
||||||
|
result = rlp.decode(res, BlockBody)
|
@ -36,7 +36,7 @@ method getAncestorHeader*(c: Chain, h: BlockHeader, output: var BlockHeader, ski
|
|||||||
method getBlockBody*(c: Chain, blockHash: KeccakHash): BlockBodyRef =
|
method getBlockBody*(c: Chain, blockHash: KeccakHash): BlockBodyRef =
|
||||||
result = nil
|
result = nil
|
||||||
|
|
||||||
method persistBlocks*(c: Chain, headers: openarray[BlockHeader], bodies: openarray[BlockBody]): ValidationResult =
|
method persistBlocks*(c: Chain, headers: openarray[BlockHeader], bodies: openarray[BlockBody]): ValidationResult {.gcsafe.} =
|
||||||
# Run the VM here
|
# Run the VM here
|
||||||
if headers.len != bodies.len:
|
if headers.len != bodies.len:
|
||||||
debug "Number of headers not matching number of bodies"
|
debug "Number of headers not matching number of bodies"
|
||||||
|
@ -26,16 +26,18 @@ proc processTransaction*(tx: Transaction, sender: EthAddress, vmState: BaseVMSta
|
|||||||
|
|
||||||
vmState.cumulativeGasUsed += result
|
vmState.cumulativeGasUsed += result
|
||||||
|
|
||||||
|
let miner = vmState.coinbase()
|
||||||
|
|
||||||
vmState.mutateStateDB:
|
vmState.mutateStateDB:
|
||||||
# miner fee
|
# miner fee
|
||||||
let txFee = result.u256 * tx.gasPrice.u256
|
let txFee = result.u256 * tx.gasPrice.u256
|
||||||
db.addBalance(vmState.blockHeader.coinbase, txFee)
|
db.addBalance(miner, txFee)
|
||||||
|
|
||||||
for deletedAccount in vmState.suicides:
|
for deletedAccount in vmState.suicides:
|
||||||
db.deleteAccount deletedAccount
|
db.deleteAccount deletedAccount
|
||||||
|
|
||||||
if fork >= FkSpurious:
|
if fork >= FkSpurious:
|
||||||
vmState.touchedAccounts.incl(vmState.blockHeader.coinbase)
|
vmState.touchedAccounts.incl(miner)
|
||||||
# EIP158/161 state clearing
|
# EIP158/161 state clearing
|
||||||
for account in vmState.touchedAccounts:
|
for account in vmState.touchedAccounts:
|
||||||
if db.accountExists(account) and db.isEmptyAccount(account):
|
if db.accountExists(account) and db.isEmptyAccount(account):
|
||||||
@ -44,7 +46,7 @@ proc processTransaction*(tx: Transaction, sender: EthAddress, vmState: BaseVMSta
|
|||||||
|
|
||||||
if vmState.generateWitness:
|
if vmState.generateWitness:
|
||||||
vmState.accountDb.collectWitnessData()
|
vmState.accountDb.collectWitnessData()
|
||||||
vmState.accountDb.persist()
|
vmState.accountDb.persist(clearCache = false)
|
||||||
|
|
||||||
type
|
type
|
||||||
# TODO: these types need to be removed
|
# TODO: these types need to be removed
|
||||||
@ -93,6 +95,25 @@ const
|
|||||||
eth2 # FkIstanbul
|
eth2 # FkIstanbul
|
||||||
]
|
]
|
||||||
|
|
||||||
|
proc calculateReward(fork: Fork, header: BlockHeader, body: BlockBody, vmState: BaseVMState) =
|
||||||
|
# PoA consensus engine have no reward for miner
|
||||||
|
if vmState.consensusEnginePoA: return
|
||||||
|
|
||||||
|
let blockReward = blockRewards[fork]
|
||||||
|
var mainReward = blockReward
|
||||||
|
|
||||||
|
for uncle in body.uncles:
|
||||||
|
var uncleReward = uncle.blockNumber.u256 + 8.u256
|
||||||
|
uncleReward -= header.blockNumber.u256
|
||||||
|
uncleReward = uncleReward * blockReward
|
||||||
|
uncleReward = uncleReward div 8.u256
|
||||||
|
vmState.mutateStateDB:
|
||||||
|
db.addBalance(uncle.coinbase, uncleReward)
|
||||||
|
mainReward += blockReward div 32.u256
|
||||||
|
|
||||||
|
vmState.mutateStateDB:
|
||||||
|
db.addBalance(header.coinbase, mainReward)
|
||||||
|
|
||||||
proc processBlock*(chainDB: BaseChainDB, header: BlockHeader, body: BlockBody, vmState: BaseVMState): ValidationResult =
|
proc processBlock*(chainDB: BaseChainDB, header: BlockHeader, body: BlockBody, vmState: BaseVMState): ValidationResult =
|
||||||
var dbTx = chainDB.db.beginTransaction()
|
var dbTx = chainDB.db.beginTransaction()
|
||||||
defer: dbTx.dispose()
|
defer: dbTx.dispose()
|
||||||
@ -125,32 +146,26 @@ proc processBlock*(chainDB: BaseChainDB, header: BlockHeader, body: BlockBody, v
|
|||||||
return ValidationResult.Error
|
return ValidationResult.Error
|
||||||
vmState.receipts[txIndex] = makeReceipt(vmState, fork)
|
vmState.receipts[txIndex] = makeReceipt(vmState, fork)
|
||||||
|
|
||||||
let blockReward = blockRewards[fork]
|
|
||||||
var mainReward = blockReward
|
|
||||||
if header.ommersHash != EMPTY_UNCLE_HASH:
|
if header.ommersHash != EMPTY_UNCLE_HASH:
|
||||||
let h = chainDB.persistUncles(body.uncles)
|
let h = chainDB.persistUncles(body.uncles)
|
||||||
if h != header.ommersHash:
|
if h != header.ommersHash:
|
||||||
debug "Uncle hash mismatch"
|
debug "Uncle hash mismatch"
|
||||||
return ValidationResult.Error
|
return ValidationResult.Error
|
||||||
for uncle in body.uncles:
|
|
||||||
var uncleReward = uncle.blockNumber.u256 + 8.u256
|
calculateReward(fork, header, body, vmState)
|
||||||
uncleReward -= header.blockNumber.u256
|
|
||||||
uncleReward = uncleReward * blockReward
|
|
||||||
uncleReward = uncleReward div 8.u256
|
|
||||||
vmState.mutateStateDB:
|
|
||||||
db.addBalance(uncle.coinbase, uncleReward)
|
|
||||||
mainReward += blockReward div 32.u256
|
|
||||||
|
|
||||||
# Reward beneficiary
|
# Reward beneficiary
|
||||||
vmState.mutateStateDB:
|
vmState.mutateStateDB:
|
||||||
db.addBalance(header.coinbase, mainReward)
|
|
||||||
if vmState.generateWitness:
|
if vmState.generateWitness:
|
||||||
db.collectWitnessData()
|
db.collectWitnessData()
|
||||||
db.persist()
|
db.persist(ClearCache in vmState.flags)
|
||||||
|
|
||||||
let stateDb = vmState.accountDb
|
let stateDb = vmState.accountDb
|
||||||
if header.stateRoot != stateDb.rootHash:
|
if header.stateRoot != stateDb.rootHash:
|
||||||
error "Wrong state root in block", blockNumber=header.blockNumber, expected=header.stateRoot, actual=stateDb.rootHash, arrivedFrom=chainDB.getCanonicalHead().stateRoot
|
when defined(geth):
|
||||||
|
error "Wrong state root in block", blockNumber=header.blockNumber, expected=header.stateRoot, actual=stateDb.rootHash
|
||||||
|
else:
|
||||||
|
error "Wrong state root in block", blockNumber=header.blockNumber, expected=header.stateRoot, actual=stateDb.rootHash, arrivedFrom=chainDB.getCanonicalHead().stateRoot
|
||||||
# this one is a show stopper until we are confident in our VM's
|
# this one is a show stopper until we are confident in our VM's
|
||||||
# compatibility with the main chain
|
# compatibility with the main chain
|
||||||
return ValidationResult.Error
|
return ValidationResult.Error
|
||||||
|
@ -86,11 +86,10 @@ proc binarySearchGas(vmState: var BaseVMState, transaction: Transaction, sender:
|
|||||||
|
|
||||||
proc setupEthRpc*(node: EthereumNode, chain: BaseChainDB, rpcsrv: RpcServer) =
|
proc setupEthRpc*(node: EthereumNode, chain: BaseChainDB, rpcsrv: RpcServer) =
|
||||||
|
|
||||||
func getAccountDb(header: BlockHeader): ReadOnlyStateDB =
|
proc getAccountDb(header: BlockHeader): ReadOnlyStateDB =
|
||||||
## Retrieves the account db from canonical head
|
## Retrieves the account db from canonical head
|
||||||
# TODO: header.stateRoot to prevStateRoot
|
let ac = AccountsCache.init(chain.db, header.stateRoot, chain.pruneTrie)
|
||||||
let vmState = newBaseVMState(header.stateRoot, header, chain)
|
result = ReadOnlyStateDB(ac)
|
||||||
result = vmState.readOnlyStateDB()
|
|
||||||
|
|
||||||
proc accountDbFromTag(tag: string, readOnly = true): ReadOnlyStateDB =
|
proc accountDbFromTag(tag: string, readOnly = true): ReadOnlyStateDB =
|
||||||
result = getAccountDb(chain.headerFromTag(tag))
|
result = getAccountDb(chain.headerFromTag(tag))
|
||||||
|
@ -5,8 +5,15 @@ import
|
|||||||
chronicles, rpc/hexstrings, launcher,
|
chronicles, rpc/hexstrings, launcher,
|
||||||
vm/interpreter/vm_forks, ./config
|
vm/interpreter/vm_forks, ./config
|
||||||
|
|
||||||
proc getParentHeader(self: BaseChainDB, header: BlockHeader): BlockHeader =
|
when defined(geth):
|
||||||
self.getBlockHeader(header.parentHash)
|
import db/geth_db
|
||||||
|
|
||||||
|
proc getParentHeader(db: BaseChainDB, header: BlockHeader): BlockHeader =
|
||||||
|
db.blockHeader(header.blockNumber.truncate(uint64) - 1)
|
||||||
|
|
||||||
|
else:
|
||||||
|
proc getParentHeader(self: BaseChainDB, header: BlockHeader): BlockHeader =
|
||||||
|
self.getBlockHeader(header.parentHash)
|
||||||
|
|
||||||
proc `%`(x: openArray[byte]): JsonNode =
|
proc `%`(x: openArray[byte]): JsonNode =
|
||||||
result = %toHex(x, false)
|
result = %toHex(x, false)
|
||||||
@ -80,7 +87,7 @@ proc traceTransaction*(chainDB: BaseChainDB, header: BlockHeader,
|
|||||||
memoryDB = newMemoryDB()
|
memoryDB = newMemoryDB()
|
||||||
captureDB = newCaptureDB(chainDB.db, memoryDB)
|
captureDB = newCaptureDB(chainDB.db, memoryDB)
|
||||||
captureTrieDB = trieDB captureDB
|
captureTrieDB = trieDB captureDB
|
||||||
captureChainDB = newBaseChainDB(captureTrieDB, false) # prune or not prune?
|
captureChainDB = newBaseChainDB(captureTrieDB, false, PublicNetWork(chainDB.config.chainId)) # prune or not prune?
|
||||||
vmState = newBaseVMState(parent.stateRoot, header, captureChainDB, tracerFlags + {EnableAccount})
|
vmState = newBaseVMState(parent.stateRoot, header, captureChainDB, tracerFlags + {EnableAccount})
|
||||||
|
|
||||||
var stateDb = vmState.accountDb
|
var stateDb = vmState.accountDb
|
||||||
@ -96,7 +103,9 @@ proc traceTransaction*(chainDB: BaseChainDB, header: BlockHeader,
|
|||||||
stateDiff = %{"before": before, "after": after}
|
stateDiff = %{"before": before, "after": after}
|
||||||
beforeRoot: Hash256
|
beforeRoot: Hash256
|
||||||
|
|
||||||
let fork = chainDB.config.toFork(header.blockNumber)
|
let
|
||||||
|
fork = chainDB.config.toFork(header.blockNumber)
|
||||||
|
miner = vmState.coinbase()
|
||||||
|
|
||||||
for idx, tx in body.transactions:
|
for idx, tx in body.transactions:
|
||||||
let sender = tx.getSender
|
let sender = tx.getSender
|
||||||
@ -106,7 +115,7 @@ proc traceTransaction*(chainDB: BaseChainDB, header: BlockHeader,
|
|||||||
vmState.enableTracing()
|
vmState.enableTracing()
|
||||||
before.captureAccount(stateDb, sender, senderName)
|
before.captureAccount(stateDb, sender, senderName)
|
||||||
before.captureAccount(stateDb, recipient, recipientName)
|
before.captureAccount(stateDb, recipient, recipientName)
|
||||||
before.captureAccount(stateDb, header.coinbase, minerName)
|
before.captureAccount(stateDb, miner, minerName)
|
||||||
stateDb.persist()
|
stateDb.persist()
|
||||||
stateDiff["beforeRoot"] = %($stateDb.rootHash)
|
stateDiff["beforeRoot"] = %($stateDb.rootHash)
|
||||||
beforeRoot = stateDb.rootHash
|
beforeRoot = stateDb.rootHash
|
||||||
@ -116,8 +125,8 @@ proc traceTransaction*(chainDB: BaseChainDB, header: BlockHeader,
|
|||||||
if idx == txIndex:
|
if idx == txIndex:
|
||||||
after.captureAccount(stateDb, sender, senderName)
|
after.captureAccount(stateDb, sender, senderName)
|
||||||
after.captureAccount(stateDb, recipient, recipientName)
|
after.captureAccount(stateDb, recipient, recipientName)
|
||||||
after.captureAccount(stateDb, header.coinbase, minerName)
|
after.captureAccount(stateDb, miner, minerName)
|
||||||
vmState.removeTracedAccounts(sender, recipient, header.coinbase)
|
vmState.removeTracedAccounts(sender, recipient, miner)
|
||||||
stateDb.persist()
|
stateDb.persist()
|
||||||
stateDiff["afterRoot"] = %($stateDb.rootHash)
|
stateDiff["afterRoot"] = %($stateDb.rootHash)
|
||||||
break
|
break
|
||||||
@ -146,9 +155,10 @@ proc dumpBlockState*(db: BaseChainDB, header: BlockHeader, body: BlockBody, dump
|
|||||||
memoryDB = newMemoryDB()
|
memoryDB = newMemoryDB()
|
||||||
captureDB = newCaptureDB(db.db, memoryDB)
|
captureDB = newCaptureDB(db.db, memoryDB)
|
||||||
captureTrieDB = trieDB captureDB
|
captureTrieDB = trieDB captureDB
|
||||||
captureChainDB = newBaseChainDB(captureTrieDB, false)
|
captureChainDB = newBaseChainDB(captureTrieDB, false, PublicNetWork(db.config.chainId))
|
||||||
# we only need stack dump if we want to scan for internal transaction address
|
# we only need stack dump if we want to scan for internal transaction address
|
||||||
vmState = newBaseVMState(parent.stateRoot, header, captureChainDB, {EnableTracing, DisableMemory, DisableStorage, EnableAccount})
|
vmState = newBaseVMState(parent.stateRoot, header, captureChainDB, {EnableTracing, DisableMemory, DisableStorage, EnableAccount})
|
||||||
|
miner = vmState.coinbase()
|
||||||
|
|
||||||
var
|
var
|
||||||
before = newJArray()
|
before = newJArray()
|
||||||
@ -161,7 +171,7 @@ proc dumpBlockState*(db: BaseChainDB, header: BlockHeader, body: BlockBody, dump
|
|||||||
before.captureAccount(stateBefore, sender, senderName & $idx)
|
before.captureAccount(stateBefore, sender, senderName & $idx)
|
||||||
before.captureAccount(stateBefore, recipient, recipientName & $idx)
|
before.captureAccount(stateBefore, recipient, recipientName & $idx)
|
||||||
|
|
||||||
before.captureAccount(stateBefore, header.coinbase, minerName)
|
before.captureAccount(stateBefore, miner, minerName)
|
||||||
|
|
||||||
for idx, uncle in body.uncles:
|
for idx, uncle in body.uncles:
|
||||||
before.captureAccount(stateBefore, uncle.coinbase, uncleName & $idx)
|
before.captureAccount(stateBefore, uncle.coinbase, uncleName & $idx)
|
||||||
@ -177,8 +187,8 @@ proc dumpBlockState*(db: BaseChainDB, header: BlockHeader, body: BlockBody, dump
|
|||||||
after.captureAccount(stateAfter, recipient, recipientName & $idx)
|
after.captureAccount(stateAfter, recipient, recipientName & $idx)
|
||||||
vmState.removeTracedAccounts(sender, recipient)
|
vmState.removeTracedAccounts(sender, recipient)
|
||||||
|
|
||||||
after.captureAccount(stateAfter, header.coinbase, minerName)
|
after.captureAccount(stateAfter, miner, minerName)
|
||||||
vmState.removeTracedAccounts(header.coinbase)
|
vmState.removeTracedAccounts(miner)
|
||||||
|
|
||||||
for idx, uncle in body.uncles:
|
for idx, uncle in body.uncles:
|
||||||
after.captureAccount(stateAfter, uncle.coinbase, uncleName & $idx)
|
after.captureAccount(stateAfter, uncle.coinbase, uncleName & $idx)
|
||||||
@ -202,7 +212,7 @@ proc traceBlock*(chainDB: BaseChainDB, header: BlockHeader, body: BlockBody, tra
|
|||||||
memoryDB = newMemoryDB()
|
memoryDB = newMemoryDB()
|
||||||
captureDB = newCaptureDB(chainDB.db, memoryDB)
|
captureDB = newCaptureDB(chainDB.db, memoryDB)
|
||||||
captureTrieDB = trieDB captureDB
|
captureTrieDB = trieDB captureDB
|
||||||
captureChainDB = newBaseChainDB(captureTrieDB, false)
|
captureChainDB = newBaseChainDB(captureTrieDB, false, PublicNetWork(chainDB.config.chainId))
|
||||||
vmState = newBaseVMState(parent.stateRoot, header, captureChainDB, tracerFlags + {EnableTracing})
|
vmState = newBaseVMState(parent.stateRoot, header, captureChainDB, tracerFlags + {EnableTracing})
|
||||||
|
|
||||||
if header.txRoot == BLANK_ROOT_HASH: return newJNull()
|
if header.txRoot == BLANK_ROOT_HASH: return newJNull()
|
||||||
@ -236,7 +246,7 @@ proc dumpDebuggingMetaData*(chainDB: BaseChainDB, header: BlockHeader,
|
|||||||
memoryDB = newMemoryDB()
|
memoryDB = newMemoryDB()
|
||||||
captureDB = newCaptureDB(chainDB.db, memoryDB)
|
captureDB = newCaptureDB(chainDB.db, memoryDB)
|
||||||
captureTrieDB = trieDB captureDB
|
captureTrieDB = trieDB captureDB
|
||||||
captureChainDB = newBaseChainDB(captureTrieDB, false)
|
captureChainDB = newBaseChainDB(captureTrieDB, false, PublicNetWork(chainDB.config.chainId))
|
||||||
bloom = createBloom(vmState.receipts)
|
bloom = createBloom(vmState.receipts)
|
||||||
|
|
||||||
let blockSummary = %{
|
let blockSummary = %{
|
||||||
|
@ -7,11 +7,11 @@
|
|||||||
|
|
||||||
import
|
import
|
||||||
macros, strformat, tables, sets, options,
|
macros, strformat, tables, sets, options,
|
||||||
eth/common,
|
eth/[common, keys, rlp], nimcrypto/keccak,
|
||||||
vm/interpreter/[vm_forks, gas_costs],
|
vm/interpreter/[vm_forks, gas_costs], ./errors,
|
||||||
./constants, ./db/[db_chain, accounts_cache],
|
./constants, ./db/[db_chain, accounts_cache],
|
||||||
./utils, json, vm_types, vm/transaction_tracer,
|
./utils, json, vm_types, vm/transaction_tracer,
|
||||||
./config
|
./config, ../stateless/[multi_keys, witness_from_tree, witness_types]
|
||||||
|
|
||||||
proc newAccessLogs*: AccessLogs =
|
proc newAccessLogs*: AccessLogs =
|
||||||
AccessLogs(reads: initTable[string, string](), writes: initTable[string, string]())
|
AccessLogs(reads: initTable[string, string](), writes: initTable[string, string]())
|
||||||
@ -26,6 +26,8 @@ proc `$`*(vmState: BaseVMState): string =
|
|||||||
else:
|
else:
|
||||||
result = &"VMState {vmState.name}:\n header: {vmState.blockHeader}\n chaindb: {vmState.chaindb}"
|
result = &"VMState {vmState.name}:\n header: {vmState.blockHeader}\n chaindb: {vmState.chaindb}"
|
||||||
|
|
||||||
|
proc getMinerAddress(vmState: BaseVMState): EthAddress
|
||||||
|
|
||||||
proc init*(self: BaseVMState, prevStateRoot: Hash256, header: BlockHeader,
|
proc init*(self: BaseVMState, prevStateRoot: Hash256, header: BlockHeader,
|
||||||
chainDB: BaseChainDB, tracerFlags: set[TracerFlags] = {}) =
|
chainDB: BaseChainDB, tracerFlags: set[TracerFlags] = {}) =
|
||||||
self.prevHeaders = @[]
|
self.prevHeaders = @[]
|
||||||
@ -37,12 +39,20 @@ proc init*(self: BaseVMState, prevStateRoot: Hash256, header: BlockHeader,
|
|||||||
self.logEntries = @[]
|
self.logEntries = @[]
|
||||||
self.accountDb = AccountsCache.init(chainDB.db, prevStateRoot, chainDB.pruneTrie)
|
self.accountDb = AccountsCache.init(chainDB.db, prevStateRoot, chainDB.pruneTrie)
|
||||||
self.touchedAccounts = initHashSet[EthAddress]()
|
self.touchedAccounts = initHashSet[EthAddress]()
|
||||||
|
{.gcsafe.}:
|
||||||
|
self.minerAddress = self.getMinerAddress()
|
||||||
|
|
||||||
proc newBaseVMState*(prevStateRoot: Hash256, header: BlockHeader,
|
proc newBaseVMState*(prevStateRoot: Hash256, header: BlockHeader,
|
||||||
chainDB: BaseChainDB, tracerFlags: set[TracerFlags] = {}): BaseVMState =
|
chainDB: BaseChainDB, tracerFlags: set[TracerFlags] = {}): BaseVMState =
|
||||||
new result
|
new result
|
||||||
result.init(prevStateRoot, header, chainDB, tracerFlags)
|
result.init(prevStateRoot, header, chainDB, tracerFlags)
|
||||||
|
|
||||||
|
proc newBaseVMState*(prevStateRoot: Hash256,
|
||||||
|
chainDB: BaseChainDB, tracerFlags: set[TracerFlags] = {}): BaseVMState =
|
||||||
|
new result
|
||||||
|
var header: BlockHeader
|
||||||
|
result.init(prevStateRoot, header, chainDB, tracerFlags)
|
||||||
|
|
||||||
proc setupTxContext*(vmState: BaseVMState, origin: EthAddress, gasPrice: GasInt, forkOverride=none(Fork)) =
|
proc setupTxContext*(vmState: BaseVMState, origin: EthAddress, gasPrice: GasInt, forkOverride=none(Fork)) =
|
||||||
## this proc will be called each time a new transaction
|
## this proc will be called each time a new transaction
|
||||||
## is going to be executed
|
## is going to be executed
|
||||||
@ -55,11 +65,63 @@ proc setupTxContext*(vmState: BaseVMState, origin: EthAddress, gasPrice: GasInt,
|
|||||||
vmState.chainDB.config.toFork(vmState.blockHeader.blockNumber)
|
vmState.chainDB.config.toFork(vmState.blockHeader.blockNumber)
|
||||||
vmState.gasCosts = vmState.fork.forkToSchedule
|
vmState.gasCosts = vmState.fork.forkToSchedule
|
||||||
|
|
||||||
|
proc consensusEnginePoA*(vmState: BaseVMState): bool =
|
||||||
|
let chainId = PublicNetwork(vmState.chainDB.config.chainId)
|
||||||
|
# PoA consensus engine have no reward for miner
|
||||||
|
result = chainId in {GoerliNet, RinkebyNet, KovanNet}
|
||||||
|
|
||||||
|
proc getSignature(bytes: openArray[byte], output: var Signature): bool =
|
||||||
|
let sig = Signature.fromRaw(bytes)
|
||||||
|
if sig.isOk:
|
||||||
|
output = sig[]
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
|
proc headerHashOriExtraData(vmState: BaseVMState): Hash256 =
|
||||||
|
var tmp = vmState.blockHeader
|
||||||
|
tmp.extraData.setLen(tmp.extraData.len-65)
|
||||||
|
result = keccak256.digest(rlp.encode(tmp))
|
||||||
|
|
||||||
|
proc calcMinerAddress(sigRaw: openArray[byte], vmState: BaseVMState, output: var EthAddress): bool =
|
||||||
|
var sig: Signature
|
||||||
|
if sigRaw.getSignature(sig):
|
||||||
|
let headerHash = headerHashOriExtraData(vmState)
|
||||||
|
let pubkey = recover(sig, headerHash)
|
||||||
|
if pubkey.isOk:
|
||||||
|
output = pubkey[].toCanonicalAddress()
|
||||||
|
result = true
|
||||||
|
|
||||||
|
proc getMinerAddress(vmState: BaseVMState): EthAddress =
|
||||||
|
if not vmState.consensusEnginePoA:
|
||||||
|
return vmState.blockHeader.coinbase
|
||||||
|
|
||||||
|
template data: untyped =
|
||||||
|
vmState.blockHeader.extraData
|
||||||
|
|
||||||
|
let len = data.len
|
||||||
|
doAssert(len >= 65)
|
||||||
|
|
||||||
|
var miner: EthAddress
|
||||||
|
if calcMinerAddress(data.toOpenArray(len - 65, len-1), vmState, miner):
|
||||||
|
result = miner
|
||||||
|
else:
|
||||||
|
raise newException(ValidationError, "Could not derive miner address from header extradata")
|
||||||
|
|
||||||
|
proc updateBlockHeader*(vmState: BaseVMState, header: BlockHeader) =
|
||||||
|
vmState.blockHeader = header
|
||||||
|
vmState.touchedAccounts.clear()
|
||||||
|
vmState.suicides.clear()
|
||||||
|
if EnableTracing in vmState.tracer.flags:
|
||||||
|
vmState.tracer.initTracer(vmState.tracer.flags)
|
||||||
|
vmState.logEntries = @[]
|
||||||
|
vmState.receipts = @[]
|
||||||
|
vmState.minerAddress = vmState.getMinerAddress()
|
||||||
|
|
||||||
method blockhash*(vmState: BaseVMState): Hash256 {.base, gcsafe.} =
|
method blockhash*(vmState: BaseVMState): Hash256 {.base, gcsafe.} =
|
||||||
vmState.blockHeader.hash
|
vmState.blockHeader.hash
|
||||||
|
|
||||||
method coinbase*(vmState: BaseVMState): EthAddress {.base, gcsafe.} =
|
method coinbase*(vmState: BaseVMState): EthAddress {.base, gcsafe.} =
|
||||||
vmState.blockHeader.coinbase
|
vmState.minerAddress
|
||||||
|
|
||||||
method timestamp*(vmState: BaseVMState): EthTime {.base, gcsafe.} =
|
method timestamp*(vmState: BaseVMState): EthTime {.base, gcsafe.} =
|
||||||
vmState.blockHeader.timestamp
|
vmState.blockHeader.timestamp
|
||||||
@ -75,6 +137,9 @@ method difficulty*(vmState: BaseVMState): UInt256 {.base, gcsafe.} =
|
|||||||
method gasLimit*(vmState: BaseVMState): GasInt {.base, gcsafe.} =
|
method gasLimit*(vmState: BaseVMState): GasInt {.base, gcsafe.} =
|
||||||
vmState.blockHeader.gasLimit
|
vmState.blockHeader.gasLimit
|
||||||
|
|
||||||
|
when defined(geth):
|
||||||
|
import db/geth_db
|
||||||
|
|
||||||
method getAncestorHash*(vmState: BaseVMState, blockNumber: BlockNumber): Hash256 {.base, gcsafe.} =
|
method getAncestorHash*(vmState: BaseVMState, blockNumber: BlockNumber): Hash256 {.base, gcsafe.} =
|
||||||
var ancestorDepth = vmState.blockHeader.blockNumber - blockNumber - 1
|
var ancestorDepth = vmState.blockHeader.blockNumber - blockNumber - 1
|
||||||
if ancestorDepth >= constants.MAX_PREV_HEADER_DEPTH:
|
if ancestorDepth >= constants.MAX_PREV_HEADER_DEPTH:
|
||||||
@ -82,7 +147,10 @@ method getAncestorHash*(vmState: BaseVMState, blockNumber: BlockNumber): Hash256
|
|||||||
if blockNumber >= vmState.blockHeader.blockNumber:
|
if blockNumber >= vmState.blockHeader.blockNumber:
|
||||||
return
|
return
|
||||||
|
|
||||||
result = vmState.chainDB.getBlockHash(blockNumber)
|
when defined(geth):
|
||||||
|
result = vmState.chainDB.headerHash(blockNumber.truncate(uint64))
|
||||||
|
else:
|
||||||
|
result = vmState.chainDB.getBlockHash(blockNumber)
|
||||||
#TODO: should we use deque here?
|
#TODO: should we use deque here?
|
||||||
# someday we may revive this code when
|
# someday we may revive this code when
|
||||||
# we already have working miner
|
# we already have working miner
|
||||||
@ -143,3 +211,12 @@ proc generateWitness*(vmState: BaseVMState): bool {.inline.} =
|
|||||||
proc `generateWitness=`*(vmState: BaseVMState, status: bool) =
|
proc `generateWitness=`*(vmState: BaseVMState, status: bool) =
|
||||||
if status: vmState.flags.incl GenerateWitness
|
if status: vmState.flags.incl GenerateWitness
|
||||||
else: vmState.flags.excl GenerateWitness
|
else: vmState.flags.excl GenerateWitness
|
||||||
|
|
||||||
|
proc buildWitness*(vmState: BaseVMState): seq[byte] =
|
||||||
|
let rootHash = vmState.accountDb.rootHash
|
||||||
|
let mkeys = vmState.accountDb.makeMultiKeys()
|
||||||
|
let flags = if vmState.fork >= FKSpurious: {wfEIP170} else: {}
|
||||||
|
|
||||||
|
# build witness from tree
|
||||||
|
var wb = initWitnessBuilder(vmState.chainDB.db, rootHash, flags)
|
||||||
|
result = wb.buildWitness(mkeys)
|
||||||
|
@ -19,6 +19,7 @@ type
|
|||||||
VMFlag* = enum
|
VMFlag* = enum
|
||||||
ExecutionOK
|
ExecutionOK
|
||||||
GenerateWitness
|
GenerateWitness
|
||||||
|
ClearCache
|
||||||
|
|
||||||
BaseVMState* = ref object of RootObj
|
BaseVMState* = ref object of RootObj
|
||||||
prevHeaders* : seq[BlockHeader]
|
prevHeaders* : seq[BlockHeader]
|
||||||
@ -38,6 +39,7 @@ type
|
|||||||
txGasPrice* : GasInt
|
txGasPrice* : GasInt
|
||||||
gasCosts* : GasCosts
|
gasCosts* : GasCosts
|
||||||
fork* : Fork
|
fork* : Fork
|
||||||
|
minerAddress* : EthAddress
|
||||||
|
|
||||||
AccessLogs* = ref object
|
AccessLogs* = ref object
|
||||||
reads*: Table[string, string]
|
reads*: Table[string, string]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import stint, os, parseopt, strutils
|
import stint, os, parseopt, strutils
|
||||||
from ../nimbus/config import getDefaultDataDir, ConfigStatus, processInteger
|
from ../nimbus/config import getDefaultDataDir, ConfigStatus, processInteger, PublicNetwork
|
||||||
|
|
||||||
export ConfigStatus
|
export ConfigStatus
|
||||||
|
|
||||||
@ -9,6 +9,7 @@ type
|
|||||||
head*: Uint256
|
head*: Uint256
|
||||||
maxBlocks*: int
|
maxBlocks*: int
|
||||||
numCommits*: int
|
numCommits*: int
|
||||||
|
netId*: PublicNetwork
|
||||||
|
|
||||||
var premixConfig {.threadvar.}: PremixConfiguration
|
var premixConfig {.threadvar.}: PremixConfiguration
|
||||||
|
|
||||||
@ -23,6 +24,7 @@ proc initConfiguration(): PremixConfiguration =
|
|||||||
result.head = 0.u256
|
result.head = 0.u256
|
||||||
result.maxBlocks = 0
|
result.maxBlocks = 0
|
||||||
result.numCommits = 128
|
result.numCommits = 128
|
||||||
|
result.netId = MainNet
|
||||||
|
|
||||||
proc getConfiguration*(): PremixConfiguration =
|
proc getConfiguration*(): PremixConfiguration =
|
||||||
if isNil(premixConfig):
|
if isNil(premixConfig):
|
||||||
@ -36,6 +38,15 @@ proc processU256(val: string, o: var Uint256): ConfigStatus =
|
|||||||
o = parse(val, Uint256)
|
o = parse(val, Uint256)
|
||||||
result = Success
|
result = Success
|
||||||
|
|
||||||
|
proc processNetId(val: string, o: var PublicNetwork): ConfigStatus =
|
||||||
|
case val.toLowerAscii()
|
||||||
|
of "main": o = MainNet
|
||||||
|
of "morden": o = MordenNet
|
||||||
|
of "ropsten": o = RopstenNet
|
||||||
|
of "rinkeby": o = RinkebyNet
|
||||||
|
of "goerli": o = GoerliNet
|
||||||
|
of "kovan": o = KovanNet
|
||||||
|
|
||||||
template checkArgument(fun, o: untyped) =
|
template checkArgument(fun, o: untyped) =
|
||||||
## Checks if arguments got processed successfully
|
## Checks if arguments got processed successfully
|
||||||
var res = (fun)(value, o)
|
var res = (fun)(value, o)
|
||||||
@ -72,6 +83,8 @@ proc processArguments*(msg: var string): ConfigStatus =
|
|||||||
of "numcommits":
|
of "numcommits":
|
||||||
checkArgument processInteger, config.numCommits
|
checkArgument processInteger, config.numCommits
|
||||||
config.numCommits = max(config.numCommits, 512)
|
config.numCommits = max(config.numCommits, 512)
|
||||||
|
of "netid":
|
||||||
|
checkArgument processNetId, config.netId
|
||||||
else:
|
else:
|
||||||
msg = "Unknown option " & key
|
msg = "Unknown option " & key
|
||||||
if value.len > 0: msg = msg & " : " & value
|
if value.len > 0: msg = msg & " : " & value
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
import
|
import
|
||||||
eth/[common, rlp], stint,
|
eth/[common, rlp], stint,
|
||||||
chronicles, downloader, configuration,
|
chronicles, downloader, configuration,
|
||||||
../nimbus/errors
|
../nimbus/[errors, config]
|
||||||
|
|
||||||
import
|
import
|
||||||
eth/trie/[hexary, db],
|
eth/trie/[hexary, db],
|
||||||
@ -34,10 +34,10 @@ proc main() =
|
|||||||
# 52029 first block with receipts logs
|
# 52029 first block with receipts logs
|
||||||
# 66407 failed transaction
|
# 66407 failed transaction
|
||||||
|
|
||||||
let conf = getConfiguration()
|
let conf = configuration.getConfiguration()
|
||||||
let db = newChainDb(conf.dataDir)
|
let db = newChainDb(conf.dataDir)
|
||||||
let trieDB = trieDB db
|
let trieDB = trieDB db
|
||||||
let chainDB = newBaseChainDB(trieDB, false)
|
let chainDB = newBaseChainDB(trieDB, false, conf.netId)
|
||||||
|
|
||||||
# move head to block number ...
|
# move head to block number ...
|
||||||
if conf.head != 0.u256:
|
if conf.head != 0.u256:
|
||||||
@ -93,7 +93,7 @@ when isMainModule:
|
|||||||
var message: string
|
var message: string
|
||||||
|
|
||||||
## Processing command line arguments
|
## Processing command line arguments
|
||||||
if processArguments(message) != Success:
|
if configuration.processArguments(message) != Success:
|
||||||
echo message
|
echo message
|
||||||
quit(QuitFailure)
|
quit(QuitFailure)
|
||||||
else:
|
else:
|
||||||
|
@ -18,7 +18,7 @@ import
|
|||||||
../nimbus/utils/header,
|
../nimbus/utils/header,
|
||||||
../nimbus/p2p/[executor, dao],
|
../nimbus/p2p/[executor, dao],
|
||||||
../nimbus/config,
|
../nimbus/config,
|
||||||
../stateless/[multi_keys, tree_from_witness, witness_from_tree, witness_types]
|
../stateless/[tree_from_witness, witness_types]
|
||||||
|
|
||||||
type
|
type
|
||||||
SealEngine = enum
|
SealEngine = enum
|
||||||
@ -283,13 +283,9 @@ proc parseTester(fixture: JsonNode, testStatusIMPL: var TestStatus): Tester =
|
|||||||
|
|
||||||
proc blockWitness(vmState: BaseVMState, fork: Fork, chainDB: BaseChainDB) =
|
proc blockWitness(vmState: BaseVMState, fork: Fork, chainDB: BaseChainDB) =
|
||||||
let rootHash = vmState.accountDb.rootHash
|
let rootHash = vmState.accountDb.rootHash
|
||||||
let mkeys = vmState.accountDb.makeMultiKeys()
|
let witness = vmState.buildWitness()
|
||||||
let flags = if fork >= FKSpurious: {wfEIP170} else: {}
|
let flags = if fork >= FKSpurious: {wfEIP170} else: {}
|
||||||
|
|
||||||
# build witness from tree
|
|
||||||
var wb = initWitnessBuilder(chainDB.db, rootHash, flags)
|
|
||||||
let witness = wb.buildWitness(mkeys)
|
|
||||||
|
|
||||||
# build tree from witness
|
# build tree from witness
|
||||||
var db = newMemoryDB()
|
var db = newMemoryDB()
|
||||||
when defined(useInputStream):
|
when defined(useInputStream):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user