-
Notifications
You must be signed in to change notification settings - Fork 776
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
Clean-up state-manager.touched #287
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -248,7 +248,6 @@ module.exports = function (opts, cb) { | |
if (results.exceptionError) { | ||
delete results.gasRefund | ||
delete results.selfdestruct | ||
self.stateManager.touched = [] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi Matthew, I am just doing a second review on this before we put this out on npm as a release. Just for my understanding: why is this here not needed anymore? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only way There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, thanks. |
||
} | ||
|
||
if (err && err.error !== ERROR.REVERT) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,7 +69,6 @@ module.exports = function (opts, cb) { | |
|
||
if (tx.to.toString('hex') !== '') { | ||
accounts.add(tx.to.toString('hex')) | ||
self.stateManager.touched.push(tx.to) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same for this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm trying to remember; I think this one is just logically superfluous. Any operation that modifies the empty-ness of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, just seeing that the |
||
} | ||
|
||
if (opts.populateCache === false) { | ||
|
@@ -148,53 +147,50 @@ module.exports = function (opts, cb) { | |
} | ||
|
||
results.amountSpent = results.gasUsed.mul(new BN(tx.gasPrice)) | ||
// refund the leftover gas amount | ||
fromAccount.balance = new BN(tx.gasLimit).sub(results.gasUsed) | ||
.mul(new BN(tx.gasPrice)) | ||
.add(new BN(fromAccount.balance)) | ||
|
||
self.stateManager.cache.put(tx.from, fromAccount) | ||
self.stateManager.touched.push(tx.from) | ||
|
||
var minerAccount = self.stateManager.cache.get(block.header.coinbase) | ||
// add the amount spent on gas to the miner's account | ||
minerAccount.balance = new BN(minerAccount.balance) | ||
.add(results.amountSpent) | ||
|
||
// save the miner's account | ||
if (!(new BN(minerAccount.balance).isZero())) { | ||
self.stateManager.cache.put(block.header.coinbase, minerAccount) | ||
|
||
async.series([ | ||
updateFromAccount, | ||
updateMinerAccount, | ||
cleanupAccounts | ||
], cb) | ||
|
||
function updateFromAccount (next) { | ||
// refund the leftover gas amount | ||
var finalFromBalance = new BN(tx.gasLimit).sub(results.gasUsed) | ||
.mul(new BN(tx.gasPrice)) | ||
.add(new BN(fromAccount.balance)) | ||
fromAccount.balance = finalFromBalance | ||
|
||
self.stateManager.putAccountBalance(utils.toBuffer(tx.from), finalFromBalance, next) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. |
||
} | ||
|
||
if (!results.vm.selfdestruct) { | ||
results.vm.selfdestruct = {} | ||
function updateMinerAccount (next) { | ||
var minerAccount = self.stateManager.cache.get(block.header.coinbase) | ||
// add the amount spent on gas to the miner's account | ||
minerAccount.balance = new BN(minerAccount.balance) | ||
.add(results.amountSpent) | ||
|
||
// save the miner's account | ||
if (!(new BN(minerAccount.balance).isZero())) { | ||
self.stateManager.cache.put(block.header.coinbase, minerAccount) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason that this stays on acting on the cache directly and not switch to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not that I can think of. I was just refactoring and didn't change it. We should probably have a separate ticket to clean up all these direct cache writes There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, probably, have added a note to #268. |
||
} | ||
|
||
next(null) | ||
} | ||
|
||
var keys = Object.keys(results.vm.selfdestruct) | ||
|
||
keys.forEach(function (s) { | ||
self.stateManager.cache.del(Buffer.from(s, 'hex')) | ||
}) | ||
|
||
// delete all touched accounts | ||
var touched = self.stateManager.touched | ||
async.forEach(touched, function (address, next) { | ||
self.stateManager.accountIsEmpty(address, function (err, empty) { | ||
if (err) { | ||
next(err) | ||
return | ||
} | ||
|
||
if (empty) { | ||
self.stateManager.cache.del(address) | ||
} | ||
next(null) | ||
function cleanupAccounts (next) { | ||
if (!results.vm.selfdestruct) { | ||
results.vm.selfdestruct = {} | ||
} | ||
|
||
var keys = Object.keys(results.vm.selfdestruct) | ||
|
||
keys.forEach(function (s) { | ||
self.stateManager.cache.del(Buffer.from(s, 'hex')) | ||
}) | ||
}, | ||
function () { | ||
self.stateManager.touched = [] | ||
cb() | ||
}) | ||
|
||
self.stateManager.cleanupTouchedAccounts(next) | ||
} | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,7 +28,7 @@ function StateManager (opts) { | |
self.trie = trie | ||
self._storageTries = {} // the storage trie cache | ||
self.cache = new Cache(trie) | ||
self.touched = [] | ||
self._touched = new Set() | ||
} | ||
|
||
var proto = StateManager.prototype | ||
|
@@ -47,14 +47,13 @@ proto.exists = function (address, cb) { | |
} | ||
|
||
// saves the account | ||
proto._putAccount = function (address, account, cb) { | ||
proto.putAccount = function (address, account, cb) { | ||
var self = this | ||
var addressHex = Buffer.from(address, 'hex') | ||
// TODO: dont save newly created accounts that have no balance | ||
// if (toAccount.balance.toString('hex') === '00') { | ||
// if they have money or a non-zero nonce or code, then write to tree | ||
self.cache.put(addressHex, account) | ||
self.touched.push(address) | ||
self.cache.put(address, account) | ||
self._touched.add(address.toString('hex')) | ||
// self.trie.put(addressHex, account.serialize(), cb) | ||
cb() | ||
} | ||
|
@@ -82,7 +81,7 @@ proto.putAccountBalance = function (address, balance, cb) { | |
} | ||
|
||
account.balance = balance | ||
self._putAccount(address, account, cb) | ||
self.putAccount(address, account, cb) | ||
}) | ||
} | ||
|
||
|
@@ -98,7 +97,7 @@ proto.putContractCode = function (address, value, cb) { | |
if (err) { | ||
return cb(err) | ||
} | ||
self._putAccount(address, account, cb) | ||
self.putAccount(address, account, cb) | ||
}) | ||
}) | ||
} | ||
|
@@ -180,8 +179,8 @@ proto.putContractStorage = function (address, key, value, cb) { | |
// update contract stateRoot | ||
var contract = self.cache.get(address) | ||
contract.stateRoot = storageTrie.root | ||
self._putAccount(address, contract, cb) | ||
self.touched.push(address) | ||
self.putAccount(address, contract, cb) | ||
self._touched.add(address.toString('hex')) | ||
} | ||
}) | ||
} | ||
|
@@ -204,6 +203,7 @@ proto.commitContracts = function (cb) { | |
proto.revertContracts = function () { | ||
var self = this | ||
self._storageTries = {} | ||
self._touched.clear() | ||
} | ||
|
||
// | ||
|
@@ -325,3 +325,26 @@ proto.accountIsEmpty = function (address, cb) { | |
cb(null, account.nonce.toString('hex') === '' && account.balance.toString('hex') === '' && account.codeHash.toString('hex') === utils.SHA3_NULL_S) | ||
}) | ||
} | ||
|
||
proto.cleanupTouchedAccounts = function (cb) { | ||
var self = this | ||
var touchedArray = Array.from(self._touched) | ||
async.forEach(touchedArray, function (addressHex, next) { | ||
var address = Buffer.from(addressHex, 'hex') | ||
self.accountIsEmpty(address, function (err, empty) { | ||
if (err) { | ||
next(err) | ||
return | ||
} | ||
|
||
if (empty) { | ||
self.cache.del(address) | ||
} | ||
next(null) | ||
}) | ||
}, | ||
function () { | ||
self._touched.clear() | ||
cb() | ||
}) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, this looks good. |
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.
Up to here, I think changes are functionally equivalent to the old version.