From d21d0814c69070e3a9c81f7164fe2456df5f8bcb Mon Sep 17 00:00:00 2001 From: andri lim Date: Fri, 22 Feb 2019 15:52:53 +0700 Subject: [PATCH] add getAncestorHash to hunter tool --- nimbus/vm_state.nim | 24 ++++++++++++++---------- premix/downloader.nim | 8 +++++--- premix/hunter.nim | 31 +++++++++++++++++++++++++++++-- 3 files changed, 48 insertions(+), 15 deletions(-) diff --git a/nimbus/vm_state.nim b/nimbus/vm_state.nim index f3326e206..5e1b457d1 100644 --- a/nimbus/vm_state.nim +++ b/nimbus/vm_state.nim @@ -24,19 +24,23 @@ proc `$`*(vmState: BaseVMState): string = else: result = &"VMState {vmState.name}:\n header: {vmState.blockHeader}\n chaindb: {vmState.chaindb}" +proc init*(self: BaseVMState, prevStateRoot: Hash256, header: BlockHeader, + chainDB: BaseChainDB, tracerFlags: set[TracerFlags] = {}) = + self.prevHeaders = @[] + self.name = "BaseVM" + self.accessLogs = newAccessLogs() + self.blockHeader = header + self.chaindb = chainDB + self.tracer.initTracer(tracerFlags) + self.tracingEnabled = TracerFlags.EnableTracing in tracerFlags + self.logEntries = @[] + self.blockHeader.stateRoot = prevStateRoot + self.accountDb = newAccountStateDB(chainDB.db, prevStateRoot, chainDB.pruneTrie) + proc newBaseVMState*(prevStateRoot: Hash256, header: BlockHeader, chainDB: BaseChainDB, tracerFlags: set[TracerFlags] = {}): BaseVMState = new result - result.prevHeaders = @[] - result.name = "BaseVM" - result.accessLogs = newAccessLogs() - result.blockHeader = header - result.chaindb = chainDB - result.tracer.initTracer(tracerFlags) - result.tracingEnabled = TracerFlags.EnableTracing in tracerFlags - result.logEntries = @[] - result.blockHeader.stateRoot = prevStateRoot - result.accountDb = newAccountStateDB(chainDB.db, prevStateRoot, chainDB.pruneTrie) + result.init(prevStateRoot, header, chainDB, tracerFlags) proc stateRoot*(vmState: BaseVMState): Hash256 = vmState.blockHeader.stateRoot diff --git a/premix/downloader.nim b/premix/downloader.nim index ffebace6f..ce5050bdb 100644 --- a/premix/downloader.nim +++ b/premix/downloader.nim @@ -72,12 +72,14 @@ proc requestTxTraces(n: JsonNode): JsonNode = raise newException(ValueError, "Error when retrieving transaction trace") result.add txTrace -proc requestBlock*(blockNumber: BlockNumber, flags: set[DownloadFlags] = {}): Block = - var header = request("eth_getBlockByNumber", %[%blockNumber.prefixHex, %true]) - if header.kind == JNull: +proc requestHeader*(blockNumber: BlockNumber): JsonNode = + result = request("eth_getBlockByNumber", %[%blockNumber.prefixHex, %true]) + if result.kind == JNull: error "requested block not available", blockNumber=blockNumber raise newException(ValueError, "Error when retrieving block header") +proc requestBlock*(blockNumber: BlockNumber, flags: set[DownloadFlags] = {}): Block = + let header = requestHeader(blockNumber) result.jsonData = header result.header = parseBlockHeader(header) result.body = requestBlockBody(header, blockNumber) diff --git a/premix/hunter.nim b/premix/hunter.nim index 52066dd44..3b099a5d4 100644 --- a/premix/hunter.nim +++ b/premix/hunter.nim @@ -2,7 +2,8 @@ import json, downloader, stint, strutils, byteutils, parser, nimcrypto, chronicles, ../nimbus/tracer, eth/trie/[trie_defs, db], ../nimbus/vm_state, ../nimbus/db/[db_chain, state_db], ../nimbus/p2p/executor, premixcore, - eth/common, configuration + eth/common, configuration, tables, ../nimbus/vm_types, hashes, + ../nimbus/utils/header const emptyCodeHash = blankStringHash @@ -55,6 +56,31 @@ proc prepareBlockEnv(parent: BlockHeader, thisBlock: Block): TrieDatabaseRef = result = memoryDB +type + HunterVMState = ref object of BaseVMState + headers: Table[BlockNumber, BlockHeader] + +proc hash*(x: Uint256): Hash = + result = hash(x.toByteArrayBE) + +proc newHunterVMState(prevStateRoot: Hash256, header: BlockHeader, chainDB: BaseChainDB): HunterVMState = + new result + result.init(prevStateRoot, header, chainDB) + result.headers = initTable[BlockNumber, BlockHeader]() + +method getAncestorHash*(vmState: HunterVMState, blockNumber: BlockNumber): Hash256 {.gcsafe.} = + if blockNumber in vmState.headers: + result = vmState.headers[blockNumber].hash + else: + let data = requestHeader(blockNumber) + let header = parseBlockHeader(data) + result = header.hash + vmState.headers[blockNumber] = header + +proc putAncestorsIntoDB(vmState: HunterVMState, db: BaseChainDB) = + for header in vmState.headers.values: + db.addBlockNumberToHashLookup(header) + proc huntProblematicBlock(blockNumber: Uint256): ValidationResult = let # prepare needed state from previous block @@ -71,11 +97,12 @@ proc huntProblematicBlock(blockNumber: Uint256): ValidationResult = let transaction = memoryDB.beginTransaction() defer: transaction.dispose() let - vmState = newBaseVMState(parentBlock.header.stateRoot, thisBlock.header, chainDB) + vmState = newHunterVMState(parentBlock.header.stateRoot, thisBlock.header, chainDB) validationResult = processBlock(chainDB, parentBlock.header, thisBlock.header, thisBlock.body, vmState) if validationResult != ValidationResult.OK: transaction.rollback() + putAncestorsIntoDB(vmState, chainDB) dumpDebuggingMetaData(chainDB, thisBlock.header, thisBlock.body, vmState, false) result = validationResult