mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-02-23 17:28:27 +00:00
add debugging caps to gst
This commit is contained in:
parent
5060f4aaca
commit
2bd5c99b27
@ -6,63 +6,100 @@
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import
|
||||
unittest, strformat, strutils, tables, json, ospaths, times,
|
||||
unittest, strformat, strutils, tables, json, ospaths, times, os,
|
||||
byteutils, ranges/typedranges, nimcrypto, options,
|
||||
eth/[rlp, common, keys], eth/trie/db, chronicles,
|
||||
eth/[rlp, common, keys], eth/trie/[db, trie_defs], chronicles,
|
||||
./test_helpers, ../nimbus/p2p/executor,
|
||||
../nimbus/[constants, errors, transaction],
|
||||
../nimbus/[vm_state, vm_types, vm_state_transactions, utils],
|
||||
../nimbus/vm/interpreter,
|
||||
../nimbus/db/[db_chain, state_db]
|
||||
|
||||
proc hashLogEntries(logs: seq[Log]): string =
|
||||
toLowerAscii("0x" & $keccakHash(rlp.encode(logs)))
|
||||
type
|
||||
Tester = object
|
||||
name: string
|
||||
header: BlockHeader
|
||||
pre: JsonNode
|
||||
tx: Transaction
|
||||
expectedHash: string
|
||||
expectedLogs: string
|
||||
fork: Fork
|
||||
debugMode: bool
|
||||
|
||||
proc testFixture(fixtures: JsonNode, testStatusIMPL: var TestStatus)
|
||||
proc dumpAccount(accountDb: ReadOnlyStateDB, address: EthAddress, name: string): JsonNode =
|
||||
result = %{
|
||||
"name": %name,
|
||||
"address": %($address),
|
||||
"nonce": %toHex(accountDb.getNonce(address)),
|
||||
"balance": %accountDb.getBalance(address).toHex(),
|
||||
"codehash": %($accountDb.getCodeHash(address)),
|
||||
"storageRoot": %($accountDb.getStorageRoot(address))
|
||||
}
|
||||
|
||||
suite "generalstate json tests":
|
||||
jsonTest("GeneralStateTests", testFixture)
|
||||
proc dumpDebugData(tester: Tester, vmState: BaseVMState, sender: EthAddress, gasUsed: GasInt) =
|
||||
let recipient = tester.tx.getRecipient()
|
||||
let miner = tester.header.coinbase
|
||||
var accounts = newJObject()
|
||||
|
||||
proc testFixtureIndexes(prevStateRoot: Hash256, header: BlockHeader, pre: JsonNode, tx: Transaction,
|
||||
expectedHash, expectedLogs: string, testStatusIMPL: var TestStatus, fork: Fork) =
|
||||
when enabledLogLevel <= TRACE:
|
||||
let tracerFlags = {TracerFlags.EnableTracing}
|
||||
else:
|
||||
let tracerFlags: set[TracerFlags] = {}
|
||||
var vmState = newBaseVMState(prevStateRoot, header, newBaseChainDB(newMemoryDb()), tracerFlags)
|
||||
accounts[$miner] = dumpAccount(vmState.readOnlyStateDB, miner, "miner")
|
||||
accounts[$sender] = dumpAccount(vmState.readOnlyStateDB, sender, "sender")
|
||||
accounts[$recipient] = dumpAccount(vmState.readOnlyStateDB, recipient, "recipient")
|
||||
|
||||
let accountList = [sender, miner, recipient]
|
||||
var i = 0
|
||||
for ac, _ in tester.pre:
|
||||
let account = ethAddressFromHex(ac)
|
||||
if account notin accountList:
|
||||
accounts[$account] = dumpAccount(vmState.readOnlyStateDB, account, "pre" & $i)
|
||||
inc i
|
||||
|
||||
let debugData = %{
|
||||
"gasUsed": %gasUsed,
|
||||
"structLogs": vmState.getTracingResult(),
|
||||
"accounts": accounts
|
||||
}
|
||||
writeFile("debug_" & tester.name & ".json", debugData.pretty())
|
||||
|
||||
proc testFixtureIndexes(tester: Tester, testStatusIMPL: var TestStatus) =
|
||||
var tracerFlags: set[TracerFlags] = if tester.debugMode: {TracerFlags.EnableTracing} else : {}
|
||||
var vmState = newBaseVMState(emptyRlpHash, tester.header, newBaseChainDB(newMemoryDb()), tracerFlags)
|
||||
vmState.mutateStateDB:
|
||||
setupStateDB(pre, db)
|
||||
setupStateDB(tester.pre, db)
|
||||
|
||||
defer:
|
||||
#echo vmState.readOnlyStateDB.dumpAccount("c94f5374fce5edbc8e2a8697c15331677e6ebf0b")
|
||||
let obtainedHash = "0x" & `$`(vmState.readOnlyStateDB.rootHash).toLowerAscii
|
||||
check obtainedHash == expectedHash
|
||||
check obtainedHash == tester.expectedHash
|
||||
let logEntries = vmState.getAndClearLogEntries()
|
||||
let actualLogsHash = hashLogEntries(logEntries)
|
||||
let expectedLogsHash = toLowerAscii(expectedLogs)
|
||||
let expectedLogsHash = toLowerAscii(tester.expectedLogs)
|
||||
check(expectedLogsHash == actualLogsHash)
|
||||
|
||||
let sender = tx.getSender()
|
||||
if not validateTransaction(vmState, tx, sender):
|
||||
let sender = tester.tx.getSender()
|
||||
if not validateTransaction(vmState, tester.tx, sender):
|
||||
vmState.mutateStateDB:
|
||||
# pre-EIP158 (e.g., Byzantium) should ensure currentCoinbase exists
|
||||
# in later forks, don't create at all
|
||||
db.addBalance(header.coinbase, 0.u256)
|
||||
db.addBalance(tester.header.coinbase, 0.u256)
|
||||
return
|
||||
|
||||
var gasUsed: GasInt
|
||||
vmState.mutateStateDB:
|
||||
let gasUsed = tx.processTransaction(sender, vmState, some(fork))
|
||||
db.addBalance(header.coinbase, gasUsed.u256 * tx.gasPrice.u256)
|
||||
gasUsed = tester.tx.processTransaction(sender, vmState, some(tester.fork))
|
||||
db.addBalance(tester.header.coinbase, gasUsed.u256 * tester.tx.gasPrice.u256)
|
||||
|
||||
proc testFixture(fixtures: JsonNode, testStatusIMPL: var TestStatus) =
|
||||
if tester.debugMode:
|
||||
tester.dumpDebugData(vmState, sender, gasUsed)
|
||||
|
||||
proc testFixture(fixtures: JsonNode, testStatusIMPL: var TestStatus, debugMode = false) =
|
||||
var tester: Tester
|
||||
var fixture: JsonNode
|
||||
for label, child in fixtures:
|
||||
fixture = child
|
||||
tester.name = label
|
||||
break
|
||||
|
||||
let fenv = fixture["env"]
|
||||
var emptyRlpHash = keccak256.digest(rlp.encode(""))
|
||||
let header = BlockHeader(
|
||||
tester.header = BlockHeader(
|
||||
coinbase: fenv["currentCoinbase"].getStr.ethAddressFromHex,
|
||||
difficulty: fromHex(UInt256, fenv{"currentDifficulty"}.getStr),
|
||||
blockNumber: fenv{"currentNumber"}.getHexadecimalInt.u256,
|
||||
@ -71,18 +108,34 @@ proc testFixture(fixtures: JsonNode, testStatusIMPL: var TestStatus) =
|
||||
stateRoot: emptyRlpHash
|
||||
)
|
||||
|
||||
tester.debugMode = debugMode
|
||||
let ftrans = fixture["transaction"]
|
||||
for fork in supportedForks:
|
||||
if fixture["post"].hasKey(forkNames[fork]):
|
||||
# echo "[fork: ", forkNames[fork], "]"
|
||||
for expectation in fixture["post"][forkNames[fork]]:
|
||||
tester.expectedHash = expectation["hash"].getStr
|
||||
tester.expectedLogs = expectation["logs"].getStr
|
||||
let
|
||||
expectedHash = expectation["hash"].getStr
|
||||
expectedLogs = expectation["logs"].getStr
|
||||
indexes = expectation["indexes"]
|
||||
dataIndex = indexes["data"].getInt
|
||||
gasIndex = indexes["gas"].getInt
|
||||
valueIndex = indexes["value"].getInt
|
||||
let transaction = ftrans.getFixtureTransaction(dataIndex, gasIndex, valueIndex)
|
||||
testFixtureIndexes(emptyRlpHash, header, fixture["pre"], transaction,
|
||||
expectedHash, expectedLogs, testStatusIMPL, fork)
|
||||
tester.tx = ftrans.getFixtureTransaction(dataIndex, gasIndex, valueIndex)
|
||||
tester.pre = fixture["pre"]
|
||||
tester.fork = fork
|
||||
testFixtureIndexes(tester, testStatusIMPL)
|
||||
|
||||
proc main() =
|
||||
if paramCount() == 0:
|
||||
# run all test fixtures
|
||||
suite "generalstate json tests":
|
||||
jsonTest("GeneralStateTests", testFixture)
|
||||
else:
|
||||
# execute single test in debug mode
|
||||
let path = "tests" / "fixtures" / "GeneralStateTests"
|
||||
let n = json.parseFile(path / paramStr(1))
|
||||
var testStatusIMPL: TestStatus
|
||||
testFixture(n, testStatusIMPL, true)
|
||||
|
||||
main()
|
||||
|
@ -7,10 +7,10 @@
|
||||
|
||||
import
|
||||
os, macros, json, strformat, strutils, parseutils, ospaths, tables,
|
||||
byteutils, eth/[common, keys], ranges/typedranges,
|
||||
byteutils, eth/[common, keys, rlp], ranges/typedranges,
|
||||
../nimbus/[vm_state, constants],
|
||||
../nimbus/db/[db_chain, state_db],
|
||||
../nimbus/transaction,
|
||||
../nimbus/[transaction, utils],
|
||||
../nimbus/vm/interpreter/[gas_costs, vm_forks],
|
||||
../tests/test_generalstate_failing
|
||||
|
||||
@ -290,3 +290,7 @@ proc getFixtureTransaction*(j: JsonNode, dataIndex, gasIndex, valueIndex: int):
|
||||
result.R = fromBytesBE(Uint256, raw[0..31])
|
||||
result.S = fromBytesBE(Uint256, raw[32..63])
|
||||
result.V = raw[64] + 27.byte
|
||||
|
||||
proc hashLogEntries*(logs: seq[Log]): string =
|
||||
toLowerAscii("0x" & $keccakHash(rlp.encode(logs)))
|
||||
|
@ -16,15 +16,11 @@ import
|
||||
../nimbus/vm/interpreter,
|
||||
../nimbus/db/[db_chain, state_db]
|
||||
|
||||
proc hashLogEntries(logs: seq[Log]): string =
|
||||
toLowerAscii("0x" & $keccakHash(rlp.encode(logs)))
|
||||
|
||||
proc testFixture(fixtures: JsonNode, testStatusIMPL: var TestStatus)
|
||||
|
||||
suite "vm json tests":
|
||||
jsonTest("VMTests", testFixture)
|
||||
|
||||
|
||||
proc testFixture(fixtures: JsonNode, testStatusIMPL: var TestStatus) =
|
||||
var fixture: JsonNode
|
||||
for label, child in fixtures:
|
||||
|
Loading…
x
Reference in New Issue
Block a user