-
Notifications
You must be signed in to change notification settings - Fork 765
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
Clean-up state-manager.touched #287
Conversation
lib/runCall.js
Outdated
var newBalance = new BN(toAccount.balance).add(txValue) | ||
toAccount.balance = newBalance | ||
// _putAccount as the nonce may have changed for contract creation | ||
stateManager._putAccount(ethUtil.toBuffer(toAddress), toAccount, cb) |
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.
The functions with an underscore would be internal functions of the StateManager
and should not be called from outside. (It may be the case at the moment in some places but that should be fixed.)
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.
Agreed. The only way of achieving this write in the current codebase is to either manipulate the cache directly (which I feel should also be a no-no) or to call _putAccount
. My preference would be to make _putAccount
public (rename to putAccount
) but I didn't want to change the interface in this way without checking first. Would you be ok with this?
@mattdean-digicatapult thank you for the PR and I am sorry that this has languished without a response (we are very busy!). I like the changes here and think they improve code readability. I don't fully understand the solution described in #267 :
Otherwise, I feel like this PR addresses the issue well. Would like to here @axic and @holgerd77 's opinions before we merge this. P.s. @mattdean-digicatapult please rebase this branch. |
62f0d19
to
66af9d3
Compare
Thanks. Rebased as requested |
@mattdean-digicatapult Thanks. Looks like we are having some issues with the CircleCI job (I think it might have to do with your branch being located on your personal fork of ethereumjs-vm). We have another PR that updates the Circle config to the latest format. I would like to see if that helps with the issue at all. If you could also please squash the two commits in this PR into one. Thanks |
Please rebase this again. |
66af9d3
to
5327e6f
Compare
Rebased, squashed and circle is now happy 😃 |
@holgerd77 do you also want to have a look at this? Probably it didn't break anything, just to be sure before a release. |
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.
Generally really beautiful and clean PR, just have two or three questions for my own understanding.
@@ -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 comment
The 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 comment
The reason will be displayed to describe this comment to others. Learn more.
The only way exceptionError
can be truthy is if err
is truthy. In this case stateManager.revertContracts()
will have been called on ln 233. That method clears _touched
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.
Ok, thanks.
@@ -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 comment
The 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 comment
The 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 to
address will necessarily add that address to the touched set. Therefore there's no need to do it here as part of cache population.
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.
Ah, just seeing that the toAccount
(also the newly created one from loadToAccount
) is added in runCall.addTxValue()
through stateManager.putAccount()
. So this should be fine.
var newBalance = new BN(toAccount.balance).add(txValue) | ||
toAccount.balance = newBalance | ||
// putAccount as the nonce may have changed for contract creation | ||
stateManager.putAccount(ethUtil.toBuffer(toAddress), toAccount, cb) |
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.
.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 comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
|
||
// 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 comment
The 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 putAccount
or putAccountBalance
?
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.
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 comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, probably, have added a note to #268.
self._touched.clear() | ||
cb() | ||
}) | ||
} |
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.
Ok, this looks good.
Handle signatures for chainIds greater than 110
Fixes #267
I'm looking to contribute on this project a bit, especially with the aim of cleaning up the
StateManager
interface, and thought I'd start here.I've taken a different approach to that in the issue description so feel free to criticise if there was a particular reason for suggesting turning the
StateManager
into anEventEmitter
. I just felt that would be externalising state that should instead be encapsulated inStateManager
itself.Instead the approach I've taken is to move all mutations of
StateManager.touched
intoStateManager
such thattouched
can be considered private. This involved adding a new method to theStateManager
interface in order to tidy up touched accounts. I would have preferred to include this as part of a commit phase but couldn't find somewhere sensible to do so without changing a lot of code.I've also had to include one usage of the private method
StateManager._putAccount
which I feel should probably be public in the long run anyway.Finally some methods have been made asynchronous in order to allow using
StateManager
methods instead of directly manipulatingStateManager.cache
. This makes the diff look a little worse than it really is.