From fdc34a4cf61857d521242b5e8f24647a67ff997e Mon Sep 17 00:00:00 2001 From: andri lim Date: Thu, 14 Feb 2019 22:20:41 +0700 Subject: [PATCH] fixes vmState construction --- nimbus/p2p/chain.nim | 2 +- nimbus/p2p/executor.nim | 13 ------------- nimbus/rpc/p2p.nim | 13 +++++++++---- nimbus/tracer.nim | 6 +++--- nimbus/vm_state.nim | 6 ++++-- premix/debug.nim | 2 +- premix/dumper.nim | 2 +- premix/hunter.nim | 2 +- tests/macro_assembler.nim | 2 +- tests/test_generalstate_json.nim | 6 +++--- tests/test_opcode.nim | 2 +- tests/test_precompiles.nim | 2 +- tests/test_rpc.nim | 2 +- tests/test_vm_json.nim | 2 +- 14 files changed, 28 insertions(+), 34 deletions(-) diff --git a/nimbus/p2p/chain.nim b/nimbus/p2p/chain.nim index 01e1fde8d..df054ec1d 100644 --- a/nimbus/p2p/chain.nim +++ b/nimbus/p2p/chain.nim @@ -42,7 +42,7 @@ method persistBlocks*(c: Chain, headers: openarray[BlockHeader], bodies: openarr trace "Persisting blocks", fromBlock = headers[0].blockNumber, toBlock = headers[^1].blockNumber for i in 0 ..< headers.len: let head = c.db.getCanonicalHead() - let vmState = newBaseVMState(head, c.db) + let vmState = newBaseVMState(head.stateRoot, headers[i], c.db) let validationResult = processBlock(c.db, head, headers[i], bodies[i], vmState) when not defined(release): diff --git a/nimbus/p2p/executor.nim b/nimbus/p2p/executor.nim index c38cee179..d2bea1102 100644 --- a/nimbus/p2p/executor.nim +++ b/nimbus/p2p/executor.nim @@ -140,17 +140,6 @@ proc makeReceipt(vmState: BaseVMState, cumulativeGasUsed: GasInt, fork = FkFront result.logs = vmState.getAndClearLogEntries() result.bloom = logsBloom(result.logs).value.toByteArrayBE -proc prepareVMState(vmState: BaseVMState, header: BlockHeader) = - # TODO: move this proc to somewhere else if it already complete - - # blockNumber returned from VM should be current block number - # and not something else - vmState.blockHeader.blockNumber = header.blockNumber - - # time stamp? - # gas limit? - # etc? - proc processBlock*(chainDB: BaseChainDB, head, header: BlockHeader, body: BlockBody, vmState: BaseVMState): ValidationResult = let blockReward = 5.u256 * pow(10.u256, 18) # 5 ETH @@ -158,8 +147,6 @@ proc processBlock*(chainDB: BaseChainDB, head, header: BlockHeader, body: BlockB debug "Mismatched txRoot", blockNumber=header.blockNumber return ValidationResult.Error - prepareVMState(vmState, header) - var stateDb = vmState.accountDb if header.txRoot != BLANK_ROOT_HASH: if body.transactions.len == 0: diff --git a/nimbus/rpc/p2p.nim b/nimbus/rpc/p2p.nim index b2a5842c7..67db5acfe 100644 --- a/nimbus/rpc/p2p.nim +++ b/nimbus/rpc/p2p.nim @@ -82,7 +82,8 @@ proc setupEthRpc*(node: EthereumNode, chain: BaseChainDB, rpcsrv: RpcServer) = func getAccountDb(header: BlockHeader): ReadOnlyStateDB = ## Retrieves the account db from canonical head - let vmState = newBaseVMState(header, chain) + # TODO: header.stateRoot to prevStateRoot + let vmState = newBaseVMState(header.stateRoot, header, chain) result = vmState.readOnlyStateDB() proc accountDbFromTag(tag: string, readOnly = true): ReadOnlyStateDB = @@ -293,7 +294,8 @@ proc setupEthRpc*(node: EthereumNode, chain: BaseChainDB, rpcsrv: RpcServer) = ## Returns the return value of executed contract. let header = headerFromTag(chain, quantityTag) var - vmState = newBaseVMState(header, chain) + # TODO: header.stateRoot to prevStateRoot + vmState = newBaseVMState(header.stateRoot, header, chain) gasLimit = if call.gas.isSome: call.gas.get else: 0.GasInt @@ -330,7 +332,8 @@ proc setupEthRpc*(node: EthereumNode, chain: BaseChainDB, rpcsrv: RpcServer) = ## Returns the amount of gas used. var header = chain.headerFromTag(quantityTag) - vmState = newBaseVMState(header, chain) + # TODO: header.stateRoot to prevStateRoot? + vmState = newBaseVMState(header.stateRoot, header, chain) let gasLimit = if call.gas.isSome and call.gas.get > 0.GasInt: call.gas.get @@ -411,11 +414,13 @@ proc setupEthRpc*(node: EthereumNode, chain: BaseChainDB, rpcsrv: RpcServer) = ## Returns BlockObject or nil when no block was found. let header = chain.headerFromTag(quantityTag) + result = some(populateBlockObject(header, getBlockBody(header.hash))) proc populateTransactionObject(transaction: Transaction, txIndex: int64, blockHeader: BlockHeader, blockHash: Hash256): TransactionObject = let - vmState = newBaseVMState(blockHeader, chain) + # TODO: header.stateRoot to prevStateRoot? + vmState = newBaseVMState(blockHeader.stateRoot, blockHeader, chain) accountDb = vmState.readOnlyStateDB() address = transaction.getSender() txCount = accountDb.getNonce(address) diff --git a/nimbus/tracer.nim b/nimbus/tracer.nim index 62c1ebd0c..abf201fc2 100644 --- a/nimbus/tracer.nim +++ b/nimbus/tracer.nim @@ -86,7 +86,7 @@ proc traceTransaction*(db: BaseChainDB, header: BlockHeader, captureDB = newCaptureDB(db.db, memoryDB) captureTrieDB = trieDB captureDB captureChainDB = newBaseChainDB(captureTrieDB, false) # prune or not prune? - vmState = newBaseVMState(parent, captureChainDB, tracerFlags + {EnableAccount}) + vmState = newBaseVMState(parent.stateRoot, header, captureChainDB, tracerFlags + {EnableAccount}) var stateDb = vmState.accountDb @@ -151,7 +151,7 @@ proc dumpBlockState*(db: BaseChainDB, header: BlockHeader, body: BlockBody, dump captureTrieDB = trieDB captureDB captureChainDB = newBaseChainDB(captureTrieDB, false) # we only need stack dump if we want to scan for internal transaction address - vmState = newBaseVMState(parent, captureChainDB, {EnableTracing, DisableMemory, DisableStorage, EnableAccount}) + vmState = newBaseVMState(parent.stateRoot, header, captureChainDB, {EnableTracing, DisableMemory, DisableStorage, EnableAccount}) var before = newJArray() @@ -206,7 +206,7 @@ proc traceBlock*(db: BaseChainDB, header: BlockHeader, body: BlockBody, tracerFl captureDB = newCaptureDB(db.db, memoryDB) captureTrieDB = trieDB captureDB captureChainDB = newBaseChainDB(captureTrieDB, false) - vmState = newBaseVMState(parent, captureChainDB, tracerFlags + {EnableTracing}) + vmState = newBaseVMState(parent.stateRoot, header, captureChainDB, tracerFlags + {EnableTracing}) if header.txRoot == BLANK_ROOT_HASH: return newJNull() assert(body.transactions.calcTxRoot == header.txRoot) diff --git a/nimbus/vm_state.nim b/nimbus/vm_state.nim index 006f1d62a..bf2d55206 100644 --- a/nimbus/vm_state.nim +++ b/nimbus/vm_state.nim @@ -24,7 +24,8 @@ proc `$`*(vmState: BaseVMState): string = else: result = &"VMState {vmState.name}:\n header: {vmState.blockHeader}\n chaindb: {vmState.chaindb}" -proc newBaseVMState*(header: BlockHeader, chainDB: BaseChainDB, tracerFlags: set[TracerFlags] = {}): BaseVMState = +proc newBaseVMState*(prevStateRoot: Hash256, header: BlockHeader, + chainDB: BaseChainDB, tracerFlags: set[TracerFlags] = {}): BaseVMState = new result result.prevHeaders = @[] result.name = "BaseVM" @@ -34,7 +35,8 @@ proc newBaseVMState*(header: BlockHeader, chainDB: BaseChainDB, tracerFlags: set result.tracer.initTracer(tracerFlags) result.tracingEnabled = TracerFlags.EnableTracing in tracerFlags result.logEntries = @[] - result.accountDb = newAccountStateDB(chainDB.db, header.stateRoot, chainDB.pruneTrie) + result.blockHeader.stateRoot = prevStateRoot + result.accountDb = newAccountStateDB(chainDB.db, prevStateRoot, chainDB.pruneTrie) proc stateRoot*(vmState: BaseVMState): Hash256 = vmState.blockHeader.stateRoot diff --git a/premix/debug.nim b/premix/debug.nim index 64b815685..15740a1c4 100644 --- a/premix/debug.nim +++ b/premix/debug.nim @@ -22,7 +22,7 @@ proc executeBlock(blockEnv: JsonNode, memoryDB: TrieDatabaseRef, blockNumber: Ui let transaction = memoryDB.beginTransaction() defer: transaction.dispose() let - vmState = newBaseVMState(parent, chainDB) + vmState = newBaseVMState(parent.stateRoot, header, chainDB) validationResult = processBlock(chainDB, parent, header, body, vmState) if validationResult != ValidationResult.OK: diff --git a/premix/dumper.nim b/premix/dumper.nim index e520d6d73..0146b7987 100644 --- a/premix/dumper.nim +++ b/premix/dumper.nim @@ -24,7 +24,7 @@ proc dumpDebug(chainDB: BaseChainDB, blockNumber: Uint256) = header = captureChainDB.getBlockHeader(blockNumber) headerHash = header.blockHash body = captureChainDB.getBlockBody(headerHash) - vmState = newBaseVMState(parent, captureChainDB) + vmState = newBaseVMState(parent.stateRoot, header, captureChainDB) captureChainDB.setHead(parent, true) let validationResult = processBlock(captureChainDB, parent, header, body, vmState) diff --git a/premix/hunter.nim b/premix/hunter.nim index 9037fcc01..5cc9ed3c7 100644 --- a/premix/hunter.nim +++ b/premix/hunter.nim @@ -71,7 +71,7 @@ proc huntProblematicBlock(blockNumber: Uint256): ValidationResult = let transaction = memoryDB.beginTransaction() defer: transaction.dispose() let - vmState = newBaseVMState(parentBlock.header, chainDB) + vmState = newBaseVMState(parentBlock.header.stateRoot, thisBlock.header, chainDB) validationResult = processBlock(chainDB, parentBlock.header, thisBlock.header, thisBlock.body, vmState) if validationResult != ValidationResult.OK: diff --git a/tests/macro_assembler.nim b/tests/macro_assembler.nim index 222497dac..1924fd70a 100644 --- a/tests/macro_assembler.nim +++ b/tests/macro_assembler.nim @@ -225,7 +225,7 @@ proc initComputation(blockNumber: Uint256, chainDB: BaseChainDB, payload, data: header = chainDB.getBlockHeader(blockNumber) headerHash = header.blockHash body = chainDB.getBlockBody(headerHash) - vmState = newBaseVMState(parent, chainDB) + vmState = newBaseVMState(parent.stateRoot, header, chainDB) var tx = body.transactions[0] diff --git a/tests/test_generalstate_json.nim b/tests/test_generalstate_json.nim index 9eebdc8b9..f74978ce9 100644 --- a/tests/test_generalstate_json.nim +++ b/tests/test_generalstate_json.nim @@ -22,12 +22,12 @@ suite "generalstate json tests": jsonTest("GeneralStateTests", testFixture) -proc testFixtureIndexes(header: BlockHeader, pre: JsonNode, transaction: Transaction, sender: EthAddress, expectedHash: string, testStatusIMPL: var TestStatus, fork: Fork) = +proc testFixtureIndexes(prevStateRoot: Hash256, header: BlockHeader, pre: JsonNode, transaction: Transaction, sender: EthAddress, expectedHash: string, testStatusIMPL: var TestStatus, fork: Fork) = when enabledLogLevel <= TRACE: let tracerFlags = {TracerFlags.EnableTracing} else: let tracerFlags: set[TracerFlags] = {} - var vmState = newBaseVMState(header, newBaseChainDB(newMemoryDb()), tracerFlags) + var vmState = newBaseVMState(prevStateRoot, header, newBaseChainDB(newMemoryDb()), tracerFlags) vmState.mutateStateDB: setupStateDB(pre, db) @@ -124,4 +124,4 @@ proc testFixture(fixtures: JsonNode, testStatusIMPL: var TestStatus) = valueIndex = indexes["value"].getInt let transaction = ftrans.getFixtureTransaction(dataIndex, gasIndex, valueIndex) let sender = ftrans.getFixtureTransactionSender - testFixtureIndexes(header, fixture["pre"], transaction, sender, expectedHash, testStatusIMPL, fork) + testFixtureIndexes(emptyRlpHash, header, fixture["pre"], transaction, sender, expectedHash, testStatusIMPL, fork) diff --git a/tests/test_opcode.nim b/tests/test_opcode.nim index bd31cf08d..95517331d 100644 --- a/tests/test_opcode.nim +++ b/tests/test_opcode.nim @@ -18,7 +18,7 @@ from eth/common import GasInt proc testCode(code: string, initialGas: GasInt, blockNum: UInt256): BaseComputation = let header = BlockHeader(blockNumber: blockNum) - var vmState = newBaseVMState(header, newBaseChainDB(newMemoryDb())) + var vmState = newBaseVMState(header.stateRoot, header, newBaseChainDB(newMemoryDb())) # coinbase: "", # difficulty: fixture{"env"}{"currentDifficulty"}.getHexadecimalInt.u256, diff --git a/tests/test_precompiles.nim b/tests/test_precompiles.nim index a41000bd8..99ce29186 100644 --- a/tests/test_precompiles.nim +++ b/tests/test_precompiles.nim @@ -23,7 +23,7 @@ template doTest(fixture: JsonNode, address: byte, action: untyped): untyped = var dataStr = test["input"].getStr data = if dataStr.len > 0: dataStr.hexToSeqByte else: @[] - vmState = newBaseVMState(header, newBaseChainDB(newMemoryDb())) + vmState = newBaseVMState(header.stateRoot, header, newBaseChainDB(newMemoryDb())) gas = 1_000_000.GasInt gasPrice = 1.GasInt sender: EthAddress diff --git a/tests/test_rpc.nim b/tests/test_rpc.nim index f9270ca17..87c5b79b1 100644 --- a/tests/test_rpc.nim +++ b/tests/test_rpc.nim @@ -54,7 +54,7 @@ proc doTests = header = BlockHeader(stateRoot: emptyRlpHash) var chain = newBaseChainDB(newMemoryDb()) - state = newBaseVMState(header, chain) + state = newBaseVMState(emptyRlpHash, header, chain) ethNode.chain = newChain(chain) let diff --git a/tests/test_vm_json.nim b/tests/test_vm_json.nim index ca49b7e99..b854e8f35 100644 --- a/tests/test_vm_json.nim +++ b/tests/test_vm_json.nim @@ -42,7 +42,7 @@ proc testFixture(fixtures: JsonNode, testStatusIMPL: var TestStatus) = stateRoot: emptyRlpHash ) - var vmState = newBaseVMState(header, newBaseChainDB(newMemoryDB())) + var vmState = newBaseVMState(emptyRlpHash, header, newBaseChainDB(newMemoryDB())) let fexec = fixture["exec"] var code: seq[byte] vmState.mutateStateDB: