add statediff to traceTransaction
This commit is contained in:
parent
9d6dbceefc
commit
403e12b91f
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue