-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
first fruit of debugging tool, block 49018 statediff result #188
Comments
An uncommitted memory layer sounds like a likely culprit indeed. Perhaps there is an inappropriate exception being triggered somewhere before the call/transaction execution is complete. |
out of curiosity, I poking around one version of block 49018 although not the first block with contract, but it is the first block with contract that modified state trie, it calls here is what I already try to merge the diverged statedb: # in state_db.nim I added this
proc reset*(db: AccountStateDB, root: KeccakHash, pruneTrie: bool) =
db.trie = initSecureHexaryTrie(HexaryTrie(db.trie).db, root, pruneTrie)
# in vm_state_transactions.nim `applyCreateTransaction` proc
....
vmState.blockHeader.stateRoot = db.rootHash # I added this line
var c = newBaseComputation(vmState, vmState.blockNumber, msg)
if execComputation(c):
db.reset(vmState.blockHeader.stateRoot, vmState.chaindb.pruneTrie) # and this one
db.addBalance(contractAddress, t.value)
.... after that modification, nimbus able to sync to block number 49439, then it stopped again. this time, the problem located in proc setCode*(db: var AccountStateDB, address: EthAddress, code: ByteRange) =
var account = db.getAccount(address)
let newCodeHash = keccak256.digest code.toOpenArray
if newCodeHash != account.codeHash:
account.codeHash = newCodeHash
db.accountCodes[newCodeHash] = code
# XXX: this uses the journaldb in py-evm
# db.trie.put(account.codeHash.toByteRange_Unnecessary, code)
db.setAccount(address, account)
proc getCode*(db: AccountStateDB, address: EthAddress): ByteRange =
db.accountCodes.getOrDefault(db.getCodeHash(address)) looks like both when here is code in else:
let code = db.getCode(t.to)
if code.len == 0:
# Value transfer
echo "Transfer ", t.value, " from ", sender, " to ", t.to
db.addBalance(t.to, t.value)
else:
# Contract call
echo "Contract call"
debug "Transaction", sender, to = t.to, value = t.value, hasCode = code.len != 0
let msg = newMessage(t.gasLimit, t.gasPrice, t.to, sender, t.value, t.payload, code.toSeq)
# TODO: Run the vm the TODO looks like need to be implemented if we want to have progress, I will not fix this, I will focus to implement debugging tool, but I think this one is crucial to formulate what is actually needed to implement a good/useful debugging tool. (besides opcode tracing and statediff tracing) |
although I've located the bug, my fix is not entirely correct. there should be only one state trie. have more than one state trie lying around only invites bug. |
I think the solution here is to create a new persistent mapping in the back-end database resolving contract hashes to their corresponding contract codes. You would do this by introducing a new The fancy |
the storage appear at op code trace, but somehow it vanish after transaction execution.
when I try manually insert storage to that address, the block stateRoot now match expected result, problem confirmed.
that problematic account storageRoot seems not updated, very strange. I could not locate the bug in the code. uncommitted memory layer db?
The text was updated successfully, but these errors were encountered: