augment debug tool: fix, compile, update report page, iterate
This commit is contained in:
parent
78367bf10a
commit
66ae0145f0
|
@ -252,6 +252,7 @@ function headerRenderer(nimbus, geth) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let container = $('#headerContainer').empty();
|
let container = $('#headerContainer').empty();
|
||||||
|
$('#headerTitle').text('Block #' + parseInt(geth.block.number, 16));
|
||||||
|
|
||||||
let ncs = deepCopy(nimbus.stateDump.after);
|
let ncs = deepCopy(nimbus.stateDump.after);
|
||||||
let gcs = deepCopy(geth.accounts);
|
let gcs = deepCopy(geth.accounts);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import
|
import
|
||||||
json, os, stint, eth_trie/db, byteutils, eth_common,
|
json, os, stint, eth_trie/db, byteutils, eth_common,
|
||||||
../nimbus/db/[db_chain], chronicles, ../nimbus/vm_state,
|
../nimbus/db/[db_chain], chronicles, ../nimbus/vm_state,
|
||||||
../nimbus/p2p/executor
|
../nimbus/p2p/executor, premixcore, prestate, ../nimbus/tracer
|
||||||
|
|
||||||
proc prepareBlockEnv(node: JsonNode, memoryDB: TrieDatabaseRef) =
|
proc prepareBlockEnv(node: JsonNode, memoryDB: TrieDatabaseRef) =
|
||||||
let state = node["state"]
|
let state = node["state"]
|
||||||
|
@ -11,7 +11,7 @@ proc prepareBlockEnv(node: JsonNode, memoryDB: TrieDatabaseRef) =
|
||||||
let value = hexToSeqByte(v.getStr())
|
let value = hexToSeqByte(v.getStr())
|
||||||
memoryDB.put(key, value)
|
memoryDB.put(key, value)
|
||||||
|
|
||||||
proc executeBlock(memoryDB: TrieDatabaseRef, blockNumber: Uint256) =
|
proc executeBlock(blockEnv: JsonNode, memoryDB: TrieDatabaseRef, blockNumber: Uint256) =
|
||||||
let
|
let
|
||||||
parentNumber = blockNumber - 1
|
parentNumber = blockNumber - 1
|
||||||
chainDB = newBaseChainDB(memoryDB, false)
|
chainDB = newBaseChainDB(memoryDB, false)
|
||||||
|
@ -28,6 +28,21 @@ proc executeBlock(memoryDB: TrieDatabaseRef, blockNumber: Uint256) =
|
||||||
else:
|
else:
|
||||||
info "block validation success", validationResult, blockNumber
|
info "block validation success", validationResult, blockNumber
|
||||||
|
|
||||||
|
dumpDebuggingMetaData(chainDB, header, body, vmState.receipts, false)
|
||||||
|
let
|
||||||
|
fileName = "debug" & $blockNumber & ".json"
|
||||||
|
nimbus = json.parseFile(fileName)
|
||||||
|
geth = blockEnv["geth"]
|
||||||
|
|
||||||
|
processNimbusData(nimbus)
|
||||||
|
|
||||||
|
# premix data goes to report page
|
||||||
|
generatePremixData(nimbus, geth)
|
||||||
|
|
||||||
|
# prestate data goes to debug tool and contains data
|
||||||
|
# needed to execute single block
|
||||||
|
generatePrestate(nimbus, geth, blockNumber, parent, header, body)
|
||||||
|
|
||||||
proc main() =
|
proc main() =
|
||||||
if paramCount() == 0:
|
if paramCount() == 0:
|
||||||
echo "usage: debug blockxxx.json"
|
echo "usage: debug blockxxx.json"
|
||||||
|
@ -39,6 +54,6 @@ proc main() =
|
||||||
blockNumber = UInt256.fromHex(blockEnv["blockNumber"].getStr())
|
blockNumber = UInt256.fromHex(blockEnv["blockNumber"].getStr())
|
||||||
|
|
||||||
prepareBlockEnv(blockEnv, memoryDB)
|
prepareBlockEnv(blockEnv, memoryDB)
|
||||||
executeBlock(memoryDB, blockNumber)
|
executeBlock(blockEnv, memoryDB, blockNumber)
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -108,7 +108,7 @@
|
||||||
<!-- Header Page -->
|
<!-- Header Page -->
|
||||||
<div class="uk-section-small uk-section-default">
|
<div class="uk-section-small uk-section-default">
|
||||||
<div class="uk-container uk-container-medium">
|
<div class="uk-container uk-container-medium">
|
||||||
<h3>Header Post State Accounts</h3>
|
<h3>Header Post State Accounts <span id="headerTitle" class="uk-text-primary uk-text-small">Block #</span></h3>
|
||||||
<div id="headerContainer">
|
<div id="headerContainer">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,22 +2,7 @@ import
|
||||||
json, downloader, stint, strutils, os,
|
json, downloader, stint, strutils, os,
|
||||||
../nimbus/tracer, chronicles, prestate,
|
../nimbus/tracer, chronicles, prestate,
|
||||||
js_tracer, eth_common, byteutils, parser,
|
js_tracer, eth_common, byteutils, parser,
|
||||||
nimcrypto
|
nimcrypto, premixcore
|
||||||
|
|
||||||
proc fakeAlloc(n: JsonNode) =
|
|
||||||
const
|
|
||||||
chunk = repeat('0', 64)
|
|
||||||
|
|
||||||
for i in 1 ..< n.len:
|
|
||||||
if not n[i].hasKey("memory"): return
|
|
||||||
let
|
|
||||||
prevMem = n[i-1]["memory"]
|
|
||||||
currMem = n[i]["memory"]
|
|
||||||
|
|
||||||
if currMem.len > prevMem.len:
|
|
||||||
let diff = currMem.len - prevMem.len
|
|
||||||
for _ in 0 ..< diff:
|
|
||||||
prevMem.add %chunk
|
|
||||||
|
|
||||||
proc jsonTracer(tracer: string): JsonNode =
|
proc jsonTracer(tracer: string): JsonNode =
|
||||||
result = %{ "tracer": %tracer }
|
result = %{ "tracer": %tracer }
|
||||||
|
@ -99,32 +84,6 @@ proc requestBlockState(postState: JsonNode, thisBlock: Block) =
|
||||||
for x in trace["storageProof"]:
|
for x in trace["storageProof"]:
|
||||||
account["storage"][x["key"].getStr] = padding(x["value"].getStr())
|
account["storage"][x["key"].getStr] = padding(x["value"].getStr())
|
||||||
|
|
||||||
proc copyAccount(acc: JsonNode): JsonNode =
|
|
||||||
result = newJObject()
|
|
||||||
if acc.hasKey("name"):
|
|
||||||
result["name"] = newJString(acc["name"].getStr)
|
|
||||||
result["balance"] = newJString(acc["balance"].getStr)
|
|
||||||
result["nonce"] = newJString(acc["nonce"].getStr)
|
|
||||||
result["code"] = newJString(acc["code"].getStr)
|
|
||||||
var storage = newJObject()
|
|
||||||
for k, v in acc["storage"]:
|
|
||||||
storage[k] = newJString(v.getStr)
|
|
||||||
result["storage"] = storage
|
|
||||||
result["storageRoot"] = newJString(acc["storageRoot"].getStr)
|
|
||||||
result["codeHash"] = newJString(acc["codeHash"].getStr)
|
|
||||||
|
|
||||||
proc updateAccount(a, b: JsonNode) =
|
|
||||||
if b.hasKey("name"):
|
|
||||||
a["name"] = newJString(b["name"].getStr)
|
|
||||||
a["balance"] = newJString(b["balance"].getStr)
|
|
||||||
a["nonce"] = newJString(b["nonce"].getStr)
|
|
||||||
a["code"] = newJString(b["code"].getStr)
|
|
||||||
var storage = a["storage"]
|
|
||||||
for k, v in b["storage"]:
|
|
||||||
storage[k] = newJString(v.getStr)
|
|
||||||
a["storageRoot"] = newJString(b["storageRoot"].getStr)
|
|
||||||
a["codeHash"] = newJString(b["codeHash"].getStr)
|
|
||||||
|
|
||||||
proc processPostState(postState: JsonNode): JsonNode =
|
proc processPostState(postState: JsonNode): JsonNode =
|
||||||
var accounts = newJObject()
|
var accounts = newJObject()
|
||||||
|
|
||||||
|
@ -137,17 +96,6 @@ proc processPostState(postState: JsonNode): JsonNode =
|
||||||
|
|
||||||
result = accounts
|
result = accounts
|
||||||
|
|
||||||
proc removePostStateDup(nimbus: JsonNode) =
|
|
||||||
let postState = nimbus["stateDump"]["after"]
|
|
||||||
var accounts = newJObject()
|
|
||||||
for acc in postState:
|
|
||||||
let address = acc["address"].getStr
|
|
||||||
if accounts.hasKey(address):
|
|
||||||
updateAccount(accounts[address], acc)
|
|
||||||
else:
|
|
||||||
accounts[address] = copyAccount(acc)
|
|
||||||
nimbus["stateDump"]["after"] = accounts
|
|
||||||
|
|
||||||
proc requestPostState(thisBlock: Block): JsonNode =
|
proc requestPostState(thisBlock: Block): JsonNode =
|
||||||
let postState = requestPostState(thisBlock.jsonData, postStateTracer, thisBlock)
|
let postState = requestPostState(thisBlock.jsonData, postStateTracer, thisBlock)
|
||||||
requestBlockState(postState, thisBlock)
|
requestBlockState(postState, thisBlock)
|
||||||
|
@ -159,15 +107,11 @@ proc requestPostState(thisBlock: Block): JsonNode =
|
||||||
requestBlockState(postState, thisBlock, addresses)
|
requestBlockState(postState, thisBlock, addresses)
|
||||||
processPostState(postState)
|
processPostState(postState)
|
||||||
|
|
||||||
proc generatePremixData(nimbus: JsonNode, blockNumber: Uint256, thisBlock: Block, accounts: JsonNode) =
|
proc generateGethData(thisBlock: Block, blockNumber: Uint256, accounts: JsonNode): JsonNode =
|
||||||
let
|
let
|
||||||
receipts = toJson(thisBlock.receipts)
|
receipts = toJson(thisBlock.receipts)
|
||||||
txTraces = nimbus["txTraces"]
|
|
||||||
|
|
||||||
for trace in txTraces:
|
let geth = %{
|
||||||
trace["structLogs"].fakeAlloc()
|
|
||||||
|
|
||||||
var geth = %{
|
|
||||||
"blockNumber": %blockNumber.toHex,
|
"blockNumber": %blockNumber.toHex,
|
||||||
"txTraces": thisBlock.traces,
|
"txTraces": thisBlock.traces,
|
||||||
"receipts": receipts,
|
"receipts": receipts,
|
||||||
|
@ -175,13 +119,7 @@ proc generatePremixData(nimbus: JsonNode, blockNumber: Uint256, thisBlock: Block
|
||||||
"accounts": accounts
|
"accounts": accounts
|
||||||
}
|
}
|
||||||
|
|
||||||
var premixData = %{
|
result = geth
|
||||||
"nimbus": nimbus,
|
|
||||||
"geth": geth
|
|
||||||
}
|
|
||||||
|
|
||||||
var data = "var premixData = " & premixData.pretty & "\n"
|
|
||||||
writeFile("premixData.js", data)
|
|
||||||
|
|
||||||
proc printDebugInstruction(blockNumber: Uint256) =
|
proc printDebugInstruction(blockNumber: Uint256) =
|
||||||
var text = """
|
var text = """
|
||||||
|
@ -206,17 +144,18 @@ proc main() =
|
||||||
blockNumber = UInt256.fromHex(nimbus["blockNumber"].getStr())
|
blockNumber = UInt256.fromHex(nimbus["blockNumber"].getStr())
|
||||||
thisBlock = downloader.requestBlock(blockNumber, {DownloadReceipts, DownloadTxTrace})
|
thisBlock = downloader.requestBlock(blockNumber, {DownloadReceipts, DownloadTxTrace})
|
||||||
accounts = requestPostState(thisBlock)
|
accounts = requestPostState(thisBlock)
|
||||||
|
geth = generateGethData(thisBlock, blockNumber, accounts)
|
||||||
|
parentNumber = blockNumber - 1.u256
|
||||||
|
parentBlock = requestBlock(parentNumber)
|
||||||
|
|
||||||
# remove duplicate accounts with same address
|
processNimbusData(nimbus)
|
||||||
# and only take newest one
|
|
||||||
removePostStateDup(nimbus)
|
|
||||||
|
|
||||||
# premix data goes to report page
|
# premix data goes to report page
|
||||||
generatePremixData(nimbus, blockNumber, thisBlock, accounts)
|
generatePremixData(nimbus, geth)
|
||||||
|
|
||||||
# prestate data goes to debug tool and contains data
|
# prestate data goes to debug tool and contains data
|
||||||
# needed to execute single block
|
# needed to execute single block
|
||||||
generatePrestate(nimbus, blockNumber, thisBlock)
|
generatePrestate(nimbus, geth, blockNumber, parentBlock.header, thisBlock.header, thisBlock.body)
|
||||||
|
|
||||||
printDebugInstruction(blockNumber)
|
printDebugInstruction(blockNumber)
|
||||||
except:
|
except:
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
import json, strutils
|
||||||
|
|
||||||
|
proc fakeAlloc(n: JsonNode) =
|
||||||
|
const
|
||||||
|
chunk = repeat('0', 64)
|
||||||
|
|
||||||
|
for i in 1 ..< n.len:
|
||||||
|
if not n[i].hasKey("memory"): return
|
||||||
|
let
|
||||||
|
prevMem = n[i-1]["memory"]
|
||||||
|
currMem = n[i]["memory"]
|
||||||
|
|
||||||
|
if currMem.len > prevMem.len:
|
||||||
|
let diff = currMem.len - prevMem.len
|
||||||
|
for _ in 0 ..< diff:
|
||||||
|
prevMem.add %chunk
|
||||||
|
|
||||||
|
proc copyAccount*(acc: JsonNode): JsonNode =
|
||||||
|
result = newJObject()
|
||||||
|
if acc.hasKey("name"):
|
||||||
|
result["name"] = newJString(acc["name"].getStr)
|
||||||
|
result["balance"] = newJString(acc["balance"].getStr)
|
||||||
|
result["nonce"] = newJString(acc["nonce"].getStr)
|
||||||
|
result["code"] = newJString(acc["code"].getStr)
|
||||||
|
var storage = newJObject()
|
||||||
|
for k, v in acc["storage"]:
|
||||||
|
storage[k] = newJString(v.getStr)
|
||||||
|
result["storage"] = storage
|
||||||
|
result["storageRoot"] = newJString(acc["storageRoot"].getStr)
|
||||||
|
result["codeHash"] = newJString(acc["codeHash"].getStr)
|
||||||
|
|
||||||
|
proc updateAccount*(a, b: JsonNode) =
|
||||||
|
if b.hasKey("name"):
|
||||||
|
a["name"] = newJString(b["name"].getStr)
|
||||||
|
a["balance"] = newJString(b["balance"].getStr)
|
||||||
|
a["nonce"] = newJString(b["nonce"].getStr)
|
||||||
|
a["code"] = newJString(b["code"].getStr)
|
||||||
|
var storage = a["storage"]
|
||||||
|
for k, v in b["storage"]:
|
||||||
|
storage[k] = newJString(v.getStr)
|
||||||
|
a["storageRoot"] = newJString(b["storageRoot"].getStr)
|
||||||
|
a["codeHash"] = newJString(b["codeHash"].getStr)
|
||||||
|
|
||||||
|
proc removePostStateDup(nimbus: JsonNode) =
|
||||||
|
let postState = nimbus["stateDump"]["after"]
|
||||||
|
var accounts = newJObject()
|
||||||
|
for acc in postState:
|
||||||
|
let address = acc["address"].getStr
|
||||||
|
if accounts.hasKey(address):
|
||||||
|
updateAccount(accounts[address], acc)
|
||||||
|
else:
|
||||||
|
accounts[address] = copyAccount(acc)
|
||||||
|
nimbus["stateDump"]["after"] = accounts
|
||||||
|
|
||||||
|
proc processNimbusData*(nimbus: JsonNode) =
|
||||||
|
# remove duplicate accounts with same address
|
||||||
|
# and only take newest one
|
||||||
|
removePostStateDup(nimbus)
|
||||||
|
|
||||||
|
let txTraces = nimbus["txTraces"]
|
||||||
|
|
||||||
|
for trace in txTraces:
|
||||||
|
trace["structLogs"].fakeAlloc()
|
||||||
|
|
||||||
|
proc generatePremixData*(nimbus, geth: JsonNode) =
|
||||||
|
var premixData = %{
|
||||||
|
"nimbus": nimbus,
|
||||||
|
"geth": geth
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = "var premixData = " & premixData.pretty & "\n"
|
||||||
|
writeFile("premixData.js", data)
|
|
@ -3,39 +3,35 @@ import
|
||||||
../nimbus/db/[db_chain, storage_types], rlp, eth_common,
|
../nimbus/db/[db_chain, storage_types], rlp, eth_common,
|
||||||
../nimbus/p2p/chain, ../nimbus/tracer
|
../nimbus/p2p/chain, ../nimbus/tracer
|
||||||
|
|
||||||
proc generatePrestate*(nimbus: JsonNode, blockNumber: Uint256, thisBlock: Block) =
|
proc generatePrestate*(nimbus, geth: JsonNode, blockNumber: Uint256, parent, header: BlockHeader, body: BlockBody) =
|
||||||
let
|
let
|
||||||
state = nimbus["state"]
|
state = nimbus["state"]
|
||||||
parentNumber = blockNumber - 1.u256
|
headerHash = rlpHash(header)
|
||||||
parentBlock = requestBlock(parentNumber)
|
#parentNumber = parent.blockNumber
|
||||||
headerHash = rlpHash(thisBlock.header)
|
|
||||||
|
|
||||||
var
|
var
|
||||||
memoryDB = newMemoryDB()
|
memoryDB = newMemoryDB()
|
||||||
chainDB = newBaseChainDB(memoryDB, false)
|
chainDB = newBaseChainDB(memoryDB, false)
|
||||||
|
|
||||||
chainDB.setHead(parentBlock.header, true)
|
chainDB.setHead(parent, true)
|
||||||
chainDB.persistTransactions(blockNumber, thisBlock.body.transactions)
|
chainDB.persistTransactions(blockNumber, body.transactions)
|
||||||
discard chainDB.persistUncles(thisBlock.body.uncles)
|
discard chainDB.persistUncles(body.uncles)
|
||||||
|
|
||||||
memoryDB.put(genericHashKey(headerHash).toOpenArray, rlp.encode(thisBlock.header))
|
memoryDB.put(genericHashKey(headerHash).toOpenArray, rlp.encode(header))
|
||||||
chainDB.addBlockNumberToHashLookup(thisBlock.header)
|
chainDB.addBlockNumberToHashLookup(header)
|
||||||
|
|
||||||
for k, v in state:
|
for k, v in state:
|
||||||
let key = hexToSeqByte(k)
|
let key = hexToSeqByte(k)
|
||||||
let value = hexToSeqByte(v.getStr())
|
let value = hexToSeqByte(v.getStr())
|
||||||
memoryDB.put(key, value)
|
memoryDB.put(key, value)
|
||||||
|
|
||||||
let
|
#discard chainDB.getBlockHeader(parentNumber)
|
||||||
chain = newChain(chainDB)
|
#discard chainDB.getBlockHeader(blockNumber)
|
||||||
parent = chainDB.getBlockHeader(parentNumber)
|
#discard chainDB.getBlockBody(headerHash)
|
||||||
header = chainDB.getBlockHeader(blockNumber)
|
|
||||||
body = chainDB.getBlockBody(headerHash)
|
|
||||||
headers = @[header]
|
|
||||||
bodies = @[body]
|
|
||||||
|
|
||||||
var metaData = %{
|
var metaData = %{
|
||||||
"blockNumber": %blockNumber.toHex
|
"blockNumber": %blockNumber.toHex,
|
||||||
|
"geth": geth
|
||||||
}
|
}
|
||||||
|
|
||||||
metaData.dumpMemoryDB(memoryDB)
|
metaData.dumpMemoryDB(memoryDB)
|
||||||
|
|
Loading…
Reference in New Issue