Skip to content

Commit

Permalink
Unify dumpAccounts implementation for tools and debugging
Browse files Browse the repository at this point in the history
  • Loading branch information
jangko committed Oct 19, 2023
1 parent 87fbc43 commit 20db418
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 111 deletions.
42 changes: 8 additions & 34 deletions nimbus/utils/debug.nim
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@
# according to those terms.

import
std/[options, json, strutils],
std/[options, json],
../common/common,
stew/byteutils,
../vm_state,
../vm_types,
../db/accounts_cache,
./utils
./utils,
./state_dump

proc `$`(hash: Hash256): string =
hash.data.toHex
Expand Down Expand Up @@ -60,51 +61,24 @@ proc debug*(h: BlockHeader): string =
result.add "beaconRoot : " & $h.parentBeaconBlockRoot.get() & "\n"
result.add "blockHash : " & $blockHash(h) & "\n"

proc dumpAccount(stateDB: AccountsCache, address: EthAddress): JsonNode =
var storage = newJObject()
for k, v in stateDB.cachedStorage(address):
storage[k.toHex] = %v.toHex

result = %{
"nonce": %toHex(stateDB.getNonce(address)),
"balance": %stateDB.getBalance(address).toHex(),
"codehash": %($stateDB.getCodeHash(address)),
"storageRoot": %($stateDB.getStorageRoot(address)),
"storage": storage
}

proc dumpAccounts*(vmState: BaseVMState): JsonNode =
result = newJObject()
for ac in vmState.stateDB.addresses:
result[ac.toHex] = dumpAccount(vmState.stateDB, ac)
%dumpAccounts(vmState.stateDB)

proc debugAccounts*(stateDB: AccountsCache, addresses: openArray[string]): string =
var
accounts = newJObject()
accountList = newSeq[EthAddress]()

var accountList = newSeq[EthAddress]()
for address in addresses:
accountList.add hexToByteArray[20](address)

for ac in accountList:
accounts[ac.toHex] = dumpAccount(stateDB, ac)

accounts.pretty
(%dumpAccounts(stateDB, accountList)).pretty

proc debugAccounts*(vmState: BaseVMState): string =
var
accounts = newJObject()
accountList = newSeq[EthAddress]()

var accountList = newSeq[EthAddress]()
for address in vmState.stateDB.addresses:
accountList.add address

for i, ac in accountList:
accounts[ac.toHex] = dumpAccount(vmState.stateDB, ac)

let res = %{
"rootHash": %($vmState.readOnlyStateDB.rootHash),
"accounts": accounts
"accounts": %dumpAccounts(vmState.stateDB, accountList),
}

res.pretty
Expand Down
98 changes: 98 additions & 0 deletions nimbus/utils/state_dump.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Nimbus
# Copyright (c) 2023 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
# http:https://www.apache.org/licenses/LICENSE-2.0)
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
# http:https://opensource.org/licenses/MIT)
# at your option. This file may not be copied, modified, or distributed except
# according to those terms.

import
std/[json, tables, strutils],
stint,
eth/common/eth_types,
stew/byteutils,
../db/accounts_cache

type
DumpAccount = ref object
balance : UInt256
nonce : AccountNonce
root : Hash256
codeHash: Hash256
code : Blob
key : Hash256
storage : Table[UInt256, UInt256]

StateDump* = ref object
root: Hash256
accounts: Table[EthAddress, DumpAccount]

proc `%`*(x: UInt256): JsonNode =
%("0x" & x.toHex)

proc `%`*(x: Blob): JsonNode =
%("0x" & x.toHex)

proc `%`*(x: Hash256): JsonNode =
%("0x" & x.data.toHex)

proc `%`*(x: AccountNonce): JsonNode =
%("0x" & x.toHex)

proc `%`*(x: Table[UInt256, UInt256]): JsonNode =
result = newJObject()
for k, v in x:
result["0x" & k.toHex] = %(v)

proc `%`*(x: DumpAccount): JsonNode =
result = %{
"balance" : %(x.balance),
"nonce" : %(x.nonce),
"root" : %(x.root),
"codeHash": %(x.codeHash),
"code" : %(x.code),
"key" : %(x.key)
}
if x.storage.len > 0:
result["storage"] = %(x.storage)

proc `%`*(x: Table[EthAddress, DumpAccount]): JsonNode =
result = newJObject()
for k, v in x:
result["0x" & k.toHex] = %(v)

proc `%`*(x: StateDump): JsonNode =
result = %{
"root": %(x.root),
"accounts": %(x.accounts)
}

proc dumpAccount*(db: AccountsCache, acc: EthAddress): DumpAccount =
result = DumpAccount(
balance : db.getBalance(acc),
nonce : db.getNonce(acc),
root : db.getStorageRoot(acc),
codeHash: db.getCodeHash(acc),
code : db.getCode(acc),
key : keccakHash(acc)
)
for k, v in db.cachedStorage(acc):
result.storage[k] = v

proc dumpAccounts*(db: AccountsCache): Table[EthAddress, DumpAccount] =
for acc in db.addresses():
result[acc] = dumpAccount(db, acc)

proc dumpState*(db: AccountsCache): StateDump =
StateDump(
root: db.rootHash,
accounts: dumpAccounts(db)
)

proc dumpAccounts*(stateDB: AccountsCache, addresses: openArray[EthAddress]): JsonNode =
result = newJObject()
for ac in addresses:
result[ac.toHex] = %dumpAccount(stateDB, ac)

82 changes: 5 additions & 77 deletions tools/evmstate/evmstate.nim
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import
../../nimbus/common/common,
../../nimbus/evm/tracer/json_tracer,
../../nimbus/core/eip4844,
../../nimbus/utils/state_dump,
../common/helpers as chp,
"."/[config, helpers],
../common/state_clearing
Expand All @@ -41,19 +42,6 @@ type
error: string
trustedSetupLoaded: bool

DumpAccount = ref object
balance : UInt256
nonce : AccountNonce
root : Hash256
codeHash: Hash256
code : Blob
key : Hash256
storage : Table[UInt256, UInt256]

StateDump = ref object
root: Hash256
accounts: Table[EthAddress, DumpAccount]

StateResult = object
name : string
pass : bool
Expand Down Expand Up @@ -93,46 +81,6 @@ proc verifyResult(ctx: var StateContext, vmState: BaseVMState) =
[($actualLogsHash).toLowerAscii, $ctx.expectedLogs]
return

proc `%`(x: UInt256): JsonNode =
%("0x" & x.toHex)

proc `%`(x: Blob): JsonNode =
%("0x" & x.toHex)

proc `%`(x: Hash256): JsonNode =
%("0x" & x.data.toHex)

proc `%`(x: AccountNonce): JsonNode =
%("0x" & x.toHex)

proc `%`(x: Table[UInt256, UInt256]): JsonNode =
result = newJObject()
for k, v in x:
result["0x" & k.toHex] = %(v)

proc `%`(x: DumpAccount): JsonNode =
result = %{
"balance" : %(x.balance),
"nonce" : %(x.nonce),
"root" : %(x.root),
"codeHash": %(x.codeHash),
"code" : %(x.code),
"key" : %(x.key)
}
if x.storage.len > 0:
result["storage"] = %(x.storage)

proc `%`(x: Table[EthAddress, DumpAccount]): JsonNode =
result = newJObject()
for k, v in x:
result["0x" & k.toHex] = %(v)

proc `%`(x: StateDump): JsonNode =
result = %{
"root": %(x.root),
"accounts": %(x.accounts)
}

proc writeResultToStdout(stateRes: seq[StateResult]) =
var n = newJArray()
for res in stateRes:
Expand All @@ -150,26 +98,6 @@ proc writeResultToStdout(stateRes: seq[StateResult]) =
stdout.write(n.pretty)
stdout.write("\n")

proc dumpAccounts(db: AccountsCache): Table[EthAddress, DumpAccount] =
for accAddr in db.addresses():
let acc = DumpAccount(
balance : db.getBalance(accAddr),
nonce : db.getNonce(accAddr),
root : db.getStorageRoot(accAddr),
codeHash: db.getCodeHash(accAddr),
code : db.getCode(accAddr),
key : keccakHash(accAddr)
)
for k, v in db.storage(accAddr):
acc.storage[k] = v
result[accAddr] = acc

proc dumpState(vmState: BaseVMState): StateDump =
StateDump(
root: vmState.readOnlyStateDB.rootHash,
accounts: dumpAccounts(vmState.stateDB)
)

proc writeRootHashToStderr(vmState: BaseVMState) =
let stateRoot = %{
"stateRoot": %(vmState.readOnlyStateDB.rootHash)
Expand All @@ -191,9 +119,9 @@ proc runExecution(ctx: var StateContext, conf: StateConf, pre: JsonNode): StateR
let res = loadKzgTrustedSetup()
if res.isErr:
echo "FATAL: ", res.error
quit(QuitFailure)
quit(QuitFailure)
ctx.trustedSetupLoaded = true

let vmState = TestVMState()
vmState.init(
parent = ctx.parent,
Expand All @@ -213,12 +141,12 @@ proc runExecution(ctx: var StateContext, conf: StateConf, pre: JsonNode): StateR
result = StateResult(
name : ctx.name,
pass : ctx.error.len == 0,
root : vmState.stateDB.rootHash,
root : vmState.readOnlyStateDB.rootHash,
fork : ctx.forkStr,
error: ctx.error
)
if conf.dumpEnabled:
result.state = dumpState(vmState)
result.state = dumpState(vmState.stateDB)
if conf.jsonEnabled:
writeRootHashToStderr(vmState)

Expand Down

0 comments on commit 20db418

Please sign in to comment.