add statediff to traceTransaction

This commit is contained in:
andri lim 2018-12-11 16:53:05 +07:00 committed by zah
parent 9d6dbceefc
commit 403e12b91f
1 changed files with 40 additions and 2 deletions

View File

@ -1,7 +1,7 @@
import import
db/[db_chain, state_db, capturedb], eth_common, utils, json, db/[db_chain, state_db, capturedb], eth_common, utils, json,
constants, vm_state, vm_types, transaction, p2p/executor, constants, vm_state, vm_types, transaction, p2p/executor,
eth_trie/db, nimcrypto eth_trie/db, nimcrypto, strutils, ranges, ./utils/addresses
proc getParentHeader(self: BaseChainDB, header: BlockHeader): BlockHeader = proc getParentHeader(self: BaseChainDB, header: BlockHeader): BlockHeader =
self.getBlockHeader(header.parentHash) self.getBlockHeader(header.parentHash)
@ -9,6 +9,34 @@ proc getParentHeader(self: BaseChainDB, header: BlockHeader): BlockHeader =
proc prefixHex(x: openArray[byte]): string = proc prefixHex(x: openArray[byte]): string =
"0x" & toHex(x, true) "0x" & toHex(x, true)
proc toJson(db: AccountStateDB, address: EthAddress, name: string): JsonNode =
result = newJObject()
result["name"] = %name
result["address"] = %($address)
let account = db.getAccount(address)
result["nonce"] = %(account.nonce.toHex)
result["balance"] = %(account.balance.toHex)
let code = db.getCode(address)
result["codeHash"] = %($account.codeHash)
result["code"] = %(toHex(code.toOpenArray, true))
result["storageRoot"] = %($account.storageRoot)
var storage = newJObject()
for key, value in db.storage(address):
storage[key.dumpHex] = %(value.dumpHex)
result["storage"] = storage
proc captureStateAccount(n: JsonNode, db: AccountStateDB, sender: EthAddress, header: BlockHeader, tx: Transaction) =
n.add toJson(db, sender, "sender")
n.add toJson(db, header.coinbase, "miner")
if tx.isContractCreation:
let contractAddress = generateAddress(sender, tx.accountNonce)
n.add toJson(db, contractAddress, "contract")
else:
n.add toJson(db, tx.to, "recipient")
proc traceTransaction*(db: BaseChainDB, header: BlockHeader, proc traceTransaction*(db: BaseChainDB, header: BlockHeader,
body: BlockBody, txIndex: int, tracerFlags: set[TracerFlags] = {}): JsonNode = body: BlockBody, txIndex: int, tracerFlags: set[TracerFlags] = {}): JsonNode =
let let
@ -26,22 +54,32 @@ proc traceTransaction*(db: BaseChainDB, header: BlockHeader,
assert(body.transactions.calcTxRoot == header.txRoot) assert(body.transactions.calcTxRoot == header.txRoot)
assert(body.transactions.len != 0) assert(body.transactions.len != 0)
var gasUsed: GasInt var
gasUsed: GasInt
before = newJObject()
after = newJObject()
stateDiff = %{"before": before, "after": after}
for idx, tx in body.transactions: for idx, tx in body.transactions:
var sender: EthAddress var sender: EthAddress
if tx.getSender(sender): if tx.getSender(sender):
if idx == txIndex: if idx == txIndex:
vmState.enableTracing() vmState.enableTracing()
before.captureStateAccount(stateDb, sender, header, tx)
let txFee = processTransaction(stateDb, tx, sender, vmState) let txFee = processTransaction(stateDb, tx, sender, vmState)
gasUsed = (txFee div tx.gasPrice.u256).truncate(GasInt) gasUsed = (txFee div tx.gasPrice.u256).truncate(GasInt)
if idx == txIndex: if idx == txIndex:
vmState.disableTracing() vmState.disableTracing()
after.captureStateAccount(stateDb, sender, header, tx)
break break
else: else:
assert(false, "Could not get sender") assert(false, "Could not get sender")
result = vmState.getTracingResult() result = vmState.getTracingResult()
result["gas"] = %gasUsed result["gas"] = %gasUsed
result["statediff"] = stateDiff
# now we dump captured state db # now we dump captured state db
if TracerFlags.DisableState notin tracerFlags: if TracerFlags.DisableState notin tracerFlags: