-
Notifications
You must be signed in to change notification settings - Fork 679
Fix forked transaction trace storage so it returns the correct data and doesn't modify the root trie #398
Conversation
|
||
callback(); | ||
}); | ||
BlockchainDouble.prototype.initialize.call(self, accounts, callback); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reason for change: we don't need to call patchVm
since it already gets called within createVMFromStateTrie
.
@@ -107,7 +101,7 @@ ForkedBlockchain.prototype.createGenesisBlock = function(callback) { | |||
|
|||
// Update the relevant block numbers | |||
self.forkBlockNumber = self.options.fork_block_number = blockNumber; | |||
self.stateTrie.forkBlockNumber = blockNumber; | |||
self.stateTrie.forkBlockNumber = self.stateTrie.options.forkBlockNumber = blockNumber; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reason for change: The stateTrie
is now copy
ed instead of created via new ForkedStorageTrie
(this aligns with how the merkle patricia trie does it internally). When copying we need to also copy the options object, so here I am making sure the forkBlockNumber is set on the object.
return callback(null, this.storageTrieCache[address]); | ||
} | ||
ForkedBlockchain.prototype.getLookupStorageTrie = function(stateTrie, lookupAccount) { | ||
lookupAccount = lookupAccount || this.getLookupAccount(stateTrie); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reason for change: getLookupStorageTrie
is usually called when the ephemeralVm is created; when that happens, we already have a lookupAccount
fn generated, so we used that. There are other ways to call getLookupStorageTrie and those don't have (easy) access to a valid lookupAccount
fn. So sometimes we have to create it.
ForkedBlockchain.prototype.getLookupStorageTrie = function(stateTrie, lookupAccount) { | ||
lookupAccount = lookupAccount || this.getLookupAccount(stateTrie); | ||
return (address, callback) => { | ||
const storageTrie = stateTrie.copy(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reason for change: DRY and in-line with the way the MPT lib does it.
lookupAccount = lookupAccount || this.getLookupAccount(stateTrie); | ||
return (address, callback) => { | ||
const storageTrie = stateTrie.copy(); | ||
storageTrie.address = address; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reason for change: ForkedStorageTrie
needs the address
.
lib/utils/forkedblockchain.js
Outdated
@@ -161,7 +145,8 @@ ForkedBlockchain.prototype.isFallbackBlock = function(value, callback) { | |||
}; | |||
|
|||
ForkedBlockchain.prototype.isBlockHash = function(value) { | |||
return typeof value === "string" && value.indexOf("0x") === 0 && value.length > 42; | |||
const isHash = typeof value === "string" && value.indexOf("0x") === 0 && value.length > 42; | |||
return isHash || (Buffer.isBuffer(value) && value.byteLength > 20); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reason for change: Sometimes the value is a Buffer and we obviously should check the buffer to see if it big enough to be a blockhash.
@@ -171,6 +156,10 @@ ForkedBlockchain.prototype.isFallbackBlockHash = function(value, callback) { | |||
return callback(null, false); | |||
} | |||
|
|||
if (Buffer.isBuffer(value)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reason for change: blockHashes.get
, below, only allows hex strings.
var self = this; | ||
|
||
this.isFallbackBlockHash(number, function(err, isFallbackBlockHash) { | ||
let checkFn; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reason for change: simplifying some of the code, which also eliminates from duplicate checks.
}); | ||
}; | ||
|
||
ForkedBlockchain.prototype.getStorage = function(address, key, number, callback) { | ||
this.lookupStorageTrie(address, function(err, trie) { | ||
this.getLookupStorageTrie(this.stateTrie)(address, (err, trie) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reason for change: Make sure we use the new and improved storage trie instead of the old and busted one (which has been removed)
return trie; | ||
}; | ||
|
||
ForkedBlockchain.prototype.lookupStorageTrie = function(address, callback) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reason for change: we have a better one now. And the cache is mostly unnecessary as it complicates things (like when the stateTrie root is from a previous block but the cache contains data from a newer block) and the cache is already properly handled in the VM, which most of the calls to this fn come from.
lib/utils/forkedblockchain.js
Outdated
@@ -327,6 +303,28 @@ ForkedBlockchain.prototype.getCode = function(address, number, callback) { | |||
}); | |||
}; | |||
|
|||
ForkedBlockchain.prototype.getLookupAccount = function(trie) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reason for change: we needed to be able to lookup an account based on a trie, not a block number.
@@ -640,33 +638,4 @@ ForkedBlockchain.prototype.getBlockLogs = function(number, callback) { | |||
}); | |||
}; | |||
|
|||
ForkedBlockchain.prototype._checkpointTrie = function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reason for change: These don't get used.
@@ -70,12 +58,14 @@ ForkedStorageTrie.prototype.get = function(key, blockNumber, callback) { | |||
callback(null, account.serialize()); | |||
}); | |||
} else { | |||
if (to.number(blockNumber) > to.number(self.forkBlockNumber)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reason for change: Whenever we go to the main chain we shouldn't use a block number after we forked because that data is not valid for us.
// Note: For some reason, naming this function checkpoint() | ||
// -- overriding the default function -- prevents it from | ||
// being called. | ||
ForkedStorageTrie.prototype.customCheckpoint = function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reason for change: These were never used.
var utils = require("ethereumjs-util"); | ||
var inherits = require("util").inherits; | ||
var Web3 = require("web3"); | ||
var to = require("./to.js"); | ||
|
||
inherits(ForkedStorageTrie, MerklePatriciaTree); | ||
inherits(ForkedStorageBaseTrie, BaseTrie); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reason for change:
Most of these changes are just code reorg. We now have a "Base" trie and our normal trie. This is just to align with the MPT implementation. I wanted to use the copy
mechanism, but couldn't do so without this small refactor... because of reasons (things crashed).
We don't use to.hex since we check/know the type is buffer and so we can reduce the overhead by converting to hex string directly.
3371016
to
73e5982
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't quite had the bandwidth to give this the type of review it may require, but I have read through a few times and everything seems to LGTM! Happy to approve for now, we can talk more if you're not feeling 💯 about any part of this otherwise !
This should fix /issues/439 and #362.