Unify dumpAccounts implementation for tools and debugging
This commit is contained in:
parent
87fbc43867
commit
20db41878d
|
@ -9,13 +9,14 @@
|
||||||
# according to those terms.
|
# according to those terms.
|
||||||
|
|
||||||
import
|
import
|
||||||
std/[options, json, strutils],
|
std/[options, json],
|
||||||
../common/common,
|
../common/common,
|
||||||
stew/byteutils,
|
stew/byteutils,
|
||||||
../vm_state,
|
../vm_state,
|
||||||
../vm_types,
|
../vm_types,
|
||||||
../db/accounts_cache,
|
../db/accounts_cache,
|
||||||
./utils
|
./utils,
|
||||||
|
./state_dump
|
||||||
|
|
||||||
proc `$`(hash: Hash256): string =
|
proc `$`(hash: Hash256): string =
|
||||||
hash.data.toHex
|
hash.data.toHex
|
||||||
|
@ -60,51 +61,24 @@ proc debug*(h: BlockHeader): string =
|
||||||
result.add "beaconRoot : " & $h.parentBeaconBlockRoot.get() & "\n"
|
result.add "beaconRoot : " & $h.parentBeaconBlockRoot.get() & "\n"
|
||||||
result.add "blockHash : " & $blockHash(h) & "\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 =
|
proc dumpAccounts*(vmState: BaseVMState): JsonNode =
|
||||||
result = newJObject()
|
%dumpAccounts(vmState.stateDB)
|
||||||
for ac in vmState.stateDB.addresses:
|
|
||||||
result[ac.toHex] = dumpAccount(vmState.stateDB, ac)
|
|
||||||
|
|
||||||
proc debugAccounts*(stateDB: AccountsCache, addresses: openArray[string]): string =
|
proc debugAccounts*(stateDB: AccountsCache, addresses: openArray[string]): string =
|
||||||
var
|
var accountList = newSeq[EthAddress]()
|
||||||
accounts = newJObject()
|
|
||||||
accountList = newSeq[EthAddress]()
|
|
||||||
|
|
||||||
for address in addresses:
|
for address in addresses:
|
||||||
accountList.add hexToByteArray[20](address)
|
accountList.add hexToByteArray[20](address)
|
||||||
|
|
||||||
for ac in accountList:
|
(%dumpAccounts(stateDB, accountList)).pretty
|
||||||
accounts[ac.toHex] = dumpAccount(stateDB, ac)
|
|
||||||
|
|
||||||
accounts.pretty
|
|
||||||
|
|
||||||
proc debugAccounts*(vmState: BaseVMState): string =
|
proc debugAccounts*(vmState: BaseVMState): string =
|
||||||
var
|
var accountList = newSeq[EthAddress]()
|
||||||
accounts = newJObject()
|
|
||||||
accountList = newSeq[EthAddress]()
|
|
||||||
|
|
||||||
for address in vmState.stateDB.addresses:
|
for address in vmState.stateDB.addresses:
|
||||||
accountList.add address
|
accountList.add address
|
||||||
|
|
||||||
for i, ac in accountList:
|
|
||||||
accounts[ac.toHex] = dumpAccount(vmState.stateDB, ac)
|
|
||||||
|
|
||||||
let res = %{
|
let res = %{
|
||||||
"rootHash": %($vmState.readOnlyStateDB.rootHash),
|
"rootHash": %($vmState.readOnlyStateDB.rootHash),
|
||||||
"accounts": accounts
|
"accounts": %dumpAccounts(vmState.stateDB, accountList),
|
||||||
}
|
}
|
||||||
|
|
||||||
res.pretty
|
res.pretty
|
||||||
|
|
|
@ -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://www.apache.org/licenses/LICENSE-2.0)
|
||||||
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
|
||||||
|
# http://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)
|
||||||
|
|
|
@ -22,6 +22,7 @@ import
|
||||||
../../nimbus/common/common,
|
../../nimbus/common/common,
|
||||||
../../nimbus/evm/tracer/json_tracer,
|
../../nimbus/evm/tracer/json_tracer,
|
||||||
../../nimbus/core/eip4844,
|
../../nimbus/core/eip4844,
|
||||||
|
../../nimbus/utils/state_dump,
|
||||||
../common/helpers as chp,
|
../common/helpers as chp,
|
||||||
"."/[config, helpers],
|
"."/[config, helpers],
|
||||||
../common/state_clearing
|
../common/state_clearing
|
||||||
|
@ -41,19 +42,6 @@ type
|
||||||
error: string
|
error: string
|
||||||
trustedSetupLoaded: bool
|
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
|
StateResult = object
|
||||||
name : string
|
name : string
|
||||||
pass : bool
|
pass : bool
|
||||||
|
@ -93,46 +81,6 @@ proc verifyResult(ctx: var StateContext, vmState: BaseVMState) =
|
||||||
[($actualLogsHash).toLowerAscii, $ctx.expectedLogs]
|
[($actualLogsHash).toLowerAscii, $ctx.expectedLogs]
|
||||||
return
|
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]) =
|
proc writeResultToStdout(stateRes: seq[StateResult]) =
|
||||||
var n = newJArray()
|
var n = newJArray()
|
||||||
for res in stateRes:
|
for res in stateRes:
|
||||||
|
@ -150,26 +98,6 @@ proc writeResultToStdout(stateRes: seq[StateResult]) =
|
||||||
stdout.write(n.pretty)
|
stdout.write(n.pretty)
|
||||||
stdout.write("\n")
|
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) =
|
proc writeRootHashToStderr(vmState: BaseVMState) =
|
||||||
let stateRoot = %{
|
let stateRoot = %{
|
||||||
"stateRoot": %(vmState.readOnlyStateDB.rootHash)
|
"stateRoot": %(vmState.readOnlyStateDB.rootHash)
|
||||||
|
@ -213,12 +141,12 @@ proc runExecution(ctx: var StateContext, conf: StateConf, pre: JsonNode): StateR
|
||||||
result = StateResult(
|
result = StateResult(
|
||||||
name : ctx.name,
|
name : ctx.name,
|
||||||
pass : ctx.error.len == 0,
|
pass : ctx.error.len == 0,
|
||||||
root : vmState.stateDB.rootHash,
|
root : vmState.readOnlyStateDB.rootHash,
|
||||||
fork : ctx.forkStr,
|
fork : ctx.forkStr,
|
||||||
error: ctx.error
|
error: ctx.error
|
||||||
)
|
)
|
||||||
if conf.dumpEnabled:
|
if conf.dumpEnabled:
|
||||||
result.state = dumpState(vmState)
|
result.state = dumpState(vmState.stateDB)
|
||||||
if conf.jsonEnabled:
|
if conf.jsonEnabled:
|
||||||
writeRootHashToStderr(vmState)
|
writeRootHashToStderr(vmState)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue