mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-23 18:49:57 +00:00
fixes vmState construction
This commit is contained in:
parent
c53e7fa07c
commit
fdc34a4cf6
@ -42,7 +42,7 @@ method persistBlocks*(c: Chain, headers: openarray[BlockHeader], bodies: openarr
|
|||||||
trace "Persisting blocks", fromBlock = headers[0].blockNumber, toBlock = headers[^1].blockNumber
|
trace "Persisting blocks", fromBlock = headers[0].blockNumber, toBlock = headers[^1].blockNumber
|
||||||
for i in 0 ..< headers.len:
|
for i in 0 ..< headers.len:
|
||||||
let head = c.db.getCanonicalHead()
|
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)
|
let validationResult = processBlock(c.db, head, headers[i], bodies[i], vmState)
|
||||||
|
|
||||||
when not defined(release):
|
when not defined(release):
|
||||||
|
@ -140,17 +140,6 @@ proc makeReceipt(vmState: BaseVMState, cumulativeGasUsed: GasInt, fork = FkFront
|
|||||||
result.logs = vmState.getAndClearLogEntries()
|
result.logs = vmState.getAndClearLogEntries()
|
||||||
result.bloom = logsBloom(result.logs).value.toByteArrayBE
|
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 =
|
proc processBlock*(chainDB: BaseChainDB, head, header: BlockHeader, body: BlockBody, vmState: BaseVMState): ValidationResult =
|
||||||
let blockReward = 5.u256 * pow(10.u256, 18) # 5 ETH
|
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
|
debug "Mismatched txRoot", blockNumber=header.blockNumber
|
||||||
return ValidationResult.Error
|
return ValidationResult.Error
|
||||||
|
|
||||||
prepareVMState(vmState, header)
|
|
||||||
|
|
||||||
var stateDb = vmState.accountDb
|
var stateDb = vmState.accountDb
|
||||||
if header.txRoot != BLANK_ROOT_HASH:
|
if header.txRoot != BLANK_ROOT_HASH:
|
||||||
if body.transactions.len == 0:
|
if body.transactions.len == 0:
|
||||||
|
@ -82,7 +82,8 @@ proc setupEthRpc*(node: EthereumNode, chain: BaseChainDB, rpcsrv: RpcServer) =
|
|||||||
|
|
||||||
func getAccountDb(header: BlockHeader): ReadOnlyStateDB =
|
func getAccountDb(header: BlockHeader): ReadOnlyStateDB =
|
||||||
## Retrieves the account db from canonical head
|
## 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()
|
result = vmState.readOnlyStateDB()
|
||||||
|
|
||||||
proc accountDbFromTag(tag: string, readOnly = true): 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.
|
## Returns the return value of executed contract.
|
||||||
let header = headerFromTag(chain, quantityTag)
|
let header = headerFromTag(chain, quantityTag)
|
||||||
var
|
var
|
||||||
vmState = newBaseVMState(header, chain)
|
# TODO: header.stateRoot to prevStateRoot
|
||||||
|
vmState = newBaseVMState(header.stateRoot, header, chain)
|
||||||
gasLimit =
|
gasLimit =
|
||||||
if call.gas.isSome: call.gas.get
|
if call.gas.isSome: call.gas.get
|
||||||
else: 0.GasInt
|
else: 0.GasInt
|
||||||
@ -330,7 +332,8 @@ proc setupEthRpc*(node: EthereumNode, chain: BaseChainDB, rpcsrv: RpcServer) =
|
|||||||
## Returns the amount of gas used.
|
## Returns the amount of gas used.
|
||||||
var
|
var
|
||||||
header = chain.headerFromTag(quantityTag)
|
header = chain.headerFromTag(quantityTag)
|
||||||
vmState = newBaseVMState(header, chain)
|
# TODO: header.stateRoot to prevStateRoot?
|
||||||
|
vmState = newBaseVMState(header.stateRoot, header, chain)
|
||||||
let
|
let
|
||||||
gasLimit = if
|
gasLimit = if
|
||||||
call.gas.isSome and call.gas.get > 0.GasInt: call.gas.get
|
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.
|
## Returns BlockObject or nil when no block was found.
|
||||||
let
|
let
|
||||||
header = chain.headerFromTag(quantityTag)
|
header = chain.headerFromTag(quantityTag)
|
||||||
|
|
||||||
result = some(populateBlockObject(header, getBlockBody(header.hash)))
|
result = some(populateBlockObject(header, getBlockBody(header.hash)))
|
||||||
|
|
||||||
proc populateTransactionObject(transaction: Transaction, txIndex: int64, blockHeader: BlockHeader, blockHash: Hash256): TransactionObject =
|
proc populateTransactionObject(transaction: Transaction, txIndex: int64, blockHeader: BlockHeader, blockHash: Hash256): TransactionObject =
|
||||||
let
|
let
|
||||||
vmState = newBaseVMState(blockHeader, chain)
|
# TODO: header.stateRoot to prevStateRoot?
|
||||||
|
vmState = newBaseVMState(blockHeader.stateRoot, blockHeader, chain)
|
||||||
accountDb = vmState.readOnlyStateDB()
|
accountDb = vmState.readOnlyStateDB()
|
||||||
address = transaction.getSender()
|
address = transaction.getSender()
|
||||||
txCount = accountDb.getNonce(address)
|
txCount = accountDb.getNonce(address)
|
||||||
|
@ -86,7 +86,7 @@ proc traceTransaction*(db: BaseChainDB, header: BlockHeader,
|
|||||||
captureDB = newCaptureDB(db.db, memoryDB)
|
captureDB = newCaptureDB(db.db, memoryDB)
|
||||||
captureTrieDB = trieDB captureDB
|
captureTrieDB = trieDB captureDB
|
||||||
captureChainDB = newBaseChainDB(captureTrieDB, false) # prune or not prune?
|
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
|
var stateDb = vmState.accountDb
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ proc dumpBlockState*(db: BaseChainDB, header: BlockHeader, body: BlockBody, dump
|
|||||||
captureTrieDB = trieDB captureDB
|
captureTrieDB = trieDB captureDB
|
||||||
captureChainDB = newBaseChainDB(captureTrieDB, false)
|
captureChainDB = newBaseChainDB(captureTrieDB, false)
|
||||||
# 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, captureChainDB, {EnableTracing, DisableMemory, DisableStorage, EnableAccount})
|
vmState = newBaseVMState(parent.stateRoot, header, captureChainDB, {EnableTracing, DisableMemory, DisableStorage, EnableAccount})
|
||||||
|
|
||||||
var
|
var
|
||||||
before = newJArray()
|
before = newJArray()
|
||||||
@ -206,7 +206,7 @@ proc traceBlock*(db: BaseChainDB, header: BlockHeader, body: BlockBody, tracerFl
|
|||||||
captureDB = newCaptureDB(db.db, memoryDB)
|
captureDB = newCaptureDB(db.db, memoryDB)
|
||||||
captureTrieDB = trieDB captureDB
|
captureTrieDB = trieDB captureDB
|
||||||
captureChainDB = newBaseChainDB(captureTrieDB, false)
|
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()
|
if header.txRoot == BLANK_ROOT_HASH: return newJNull()
|
||||||
assert(body.transactions.calcTxRoot == header.txRoot)
|
assert(body.transactions.calcTxRoot == header.txRoot)
|
||||||
|
@ -24,7 +24,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 newBaseVMState*(header: BlockHeader, chainDB: BaseChainDB, tracerFlags: set[TracerFlags] = {}): BaseVMState =
|
proc newBaseVMState*(prevStateRoot: Hash256, header: BlockHeader,
|
||||||
|
chainDB: BaseChainDB, tracerFlags: set[TracerFlags] = {}): BaseVMState =
|
||||||
new result
|
new result
|
||||||
result.prevHeaders = @[]
|
result.prevHeaders = @[]
|
||||||
result.name = "BaseVM"
|
result.name = "BaseVM"
|
||||||
@ -34,7 +35,8 @@ proc newBaseVMState*(header: BlockHeader, chainDB: BaseChainDB, tracerFlags: set
|
|||||||
result.tracer.initTracer(tracerFlags)
|
result.tracer.initTracer(tracerFlags)
|
||||||
result.tracingEnabled = TracerFlags.EnableTracing in tracerFlags
|
result.tracingEnabled = TracerFlags.EnableTracing in tracerFlags
|
||||||
result.logEntries = @[]
|
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 =
|
proc stateRoot*(vmState: BaseVMState): Hash256 =
|
||||||
vmState.blockHeader.stateRoot
|
vmState.blockHeader.stateRoot
|
||||||
|
@ -22,7 +22,7 @@ proc executeBlock(blockEnv: JsonNode, memoryDB: TrieDatabaseRef, blockNumber: Ui
|
|||||||
let transaction = memoryDB.beginTransaction()
|
let transaction = memoryDB.beginTransaction()
|
||||||
defer: transaction.dispose()
|
defer: transaction.dispose()
|
||||||
let
|
let
|
||||||
vmState = newBaseVMState(parent, chainDB)
|
vmState = newBaseVMState(parent.stateRoot, header, chainDB)
|
||||||
validationResult = processBlock(chainDB, parent, header, body, vmState)
|
validationResult = processBlock(chainDB, parent, header, body, vmState)
|
||||||
|
|
||||||
if validationResult != ValidationResult.OK:
|
if validationResult != ValidationResult.OK:
|
||||||
|
@ -24,7 +24,7 @@ proc dumpDebug(chainDB: BaseChainDB, blockNumber: Uint256) =
|
|||||||
header = captureChainDB.getBlockHeader(blockNumber)
|
header = captureChainDB.getBlockHeader(blockNumber)
|
||||||
headerHash = header.blockHash
|
headerHash = header.blockHash
|
||||||
body = captureChainDB.getBlockBody(headerHash)
|
body = captureChainDB.getBlockBody(headerHash)
|
||||||
vmState = newBaseVMState(parent, captureChainDB)
|
vmState = newBaseVMState(parent.stateRoot, header, captureChainDB)
|
||||||
|
|
||||||
captureChainDB.setHead(parent, true)
|
captureChainDB.setHead(parent, true)
|
||||||
let validationResult = processBlock(captureChainDB, parent, header, body, vmState)
|
let validationResult = processBlock(captureChainDB, parent, header, body, vmState)
|
||||||
|
@ -71,7 +71,7 @@ proc huntProblematicBlock(blockNumber: Uint256): ValidationResult =
|
|||||||
let transaction = memoryDB.beginTransaction()
|
let transaction = memoryDB.beginTransaction()
|
||||||
defer: transaction.dispose()
|
defer: transaction.dispose()
|
||||||
let
|
let
|
||||||
vmState = newBaseVMState(parentBlock.header, chainDB)
|
vmState = newBaseVMState(parentBlock.header.stateRoot, thisBlock.header, chainDB)
|
||||||
validationResult = processBlock(chainDB, parentBlock.header, thisBlock.header, thisBlock.body, vmState)
|
validationResult = processBlock(chainDB, parentBlock.header, thisBlock.header, thisBlock.body, vmState)
|
||||||
|
|
||||||
if validationResult != ValidationResult.OK:
|
if validationResult != ValidationResult.OK:
|
||||||
|
@ -225,7 +225,7 @@ proc initComputation(blockNumber: Uint256, chainDB: BaseChainDB, payload, data:
|
|||||||
header = chainDB.getBlockHeader(blockNumber)
|
header = chainDB.getBlockHeader(blockNumber)
|
||||||
headerHash = header.blockHash
|
headerHash = header.blockHash
|
||||||
body = chainDB.getBlockBody(headerHash)
|
body = chainDB.getBlockBody(headerHash)
|
||||||
vmState = newBaseVMState(parent, chainDB)
|
vmState = newBaseVMState(parent.stateRoot, header, chainDB)
|
||||||
|
|
||||||
var
|
var
|
||||||
tx = body.transactions[0]
|
tx = body.transactions[0]
|
||||||
|
@ -22,12 +22,12 @@ suite "generalstate json tests":
|
|||||||
jsonTest("GeneralStateTests", testFixture)
|
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:
|
when enabledLogLevel <= TRACE:
|
||||||
let tracerFlags = {TracerFlags.EnableTracing}
|
let tracerFlags = {TracerFlags.EnableTracing}
|
||||||
else:
|
else:
|
||||||
let tracerFlags: set[TracerFlags] = {}
|
let tracerFlags: set[TracerFlags] = {}
|
||||||
var vmState = newBaseVMState(header, newBaseChainDB(newMemoryDb()), tracerFlags)
|
var vmState = newBaseVMState(prevStateRoot, header, newBaseChainDB(newMemoryDb()), tracerFlags)
|
||||||
vmState.mutateStateDB:
|
vmState.mutateStateDB:
|
||||||
setupStateDB(pre, db)
|
setupStateDB(pre, db)
|
||||||
|
|
||||||
@ -124,4 +124,4 @@ proc testFixture(fixtures: JsonNode, testStatusIMPL: var TestStatus) =
|
|||||||
valueIndex = indexes["value"].getInt
|
valueIndex = indexes["value"].getInt
|
||||||
let transaction = ftrans.getFixtureTransaction(dataIndex, gasIndex, valueIndex)
|
let transaction = ftrans.getFixtureTransaction(dataIndex, gasIndex, valueIndex)
|
||||||
let sender = ftrans.getFixtureTransactionSender
|
let sender = ftrans.getFixtureTransactionSender
|
||||||
testFixtureIndexes(header, fixture["pre"], transaction, sender, expectedHash, testStatusIMPL, fork)
|
testFixtureIndexes(emptyRlpHash, header, fixture["pre"], transaction, sender, expectedHash, testStatusIMPL, fork)
|
||||||
|
@ -18,7 +18,7 @@ from eth/common import GasInt
|
|||||||
|
|
||||||
proc testCode(code: string, initialGas: GasInt, blockNum: UInt256): BaseComputation =
|
proc testCode(code: string, initialGas: GasInt, blockNum: UInt256): BaseComputation =
|
||||||
let header = BlockHeader(blockNumber: blockNum)
|
let header = BlockHeader(blockNumber: blockNum)
|
||||||
var vmState = newBaseVMState(header, newBaseChainDB(newMemoryDb()))
|
var vmState = newBaseVMState(header.stateRoot, header, newBaseChainDB(newMemoryDb()))
|
||||||
|
|
||||||
# coinbase: "",
|
# coinbase: "",
|
||||||
# difficulty: fixture{"env"}{"currentDifficulty"}.getHexadecimalInt.u256,
|
# difficulty: fixture{"env"}{"currentDifficulty"}.getHexadecimalInt.u256,
|
||||||
|
@ -23,7 +23,7 @@ template doTest(fixture: JsonNode, address: byte, action: untyped): untyped =
|
|||||||
var
|
var
|
||||||
dataStr = test["input"].getStr
|
dataStr = test["input"].getStr
|
||||||
data = if dataStr.len > 0: dataStr.hexToSeqByte else: @[]
|
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
|
gas = 1_000_000.GasInt
|
||||||
gasPrice = 1.GasInt
|
gasPrice = 1.GasInt
|
||||||
sender: EthAddress
|
sender: EthAddress
|
||||||
|
@ -54,7 +54,7 @@ proc doTests =
|
|||||||
header = BlockHeader(stateRoot: emptyRlpHash)
|
header = BlockHeader(stateRoot: emptyRlpHash)
|
||||||
var
|
var
|
||||||
chain = newBaseChainDB(newMemoryDb())
|
chain = newBaseChainDB(newMemoryDb())
|
||||||
state = newBaseVMState(header, chain)
|
state = newBaseVMState(emptyRlpHash, header, chain)
|
||||||
ethNode.chain = newChain(chain)
|
ethNode.chain = newChain(chain)
|
||||||
|
|
||||||
let
|
let
|
||||||
|
@ -42,7 +42,7 @@ proc testFixture(fixtures: JsonNode, testStatusIMPL: var TestStatus) =
|
|||||||
stateRoot: emptyRlpHash
|
stateRoot: emptyRlpHash
|
||||||
)
|
)
|
||||||
|
|
||||||
var vmState = newBaseVMState(header, newBaseChainDB(newMemoryDB()))
|
var vmState = newBaseVMState(emptyRlpHash, header, newBaseChainDB(newMemoryDB()))
|
||||||
let fexec = fixture["exec"]
|
let fexec = fixture["exec"]
|
||||||
var code: seq[byte]
|
var code: seq[byte]
|
||||||
vmState.mutateStateDB:
|
vmState.mutateStateDB:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user