-
Notifications
You must be signed in to change notification settings - Fork 790
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
Trie: new deleteFromDB option (default: false) #1219
Conversation
Codecov Report
Flags with carried forward coverage won't be shown. Click here to find out more. |
type: 'del', | ||
key: hashRoot, | ||
}) | ||
} |
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.
Note that this change is also changing the semantics of this conditional clause. Before if - when using a CheckpointTrie
- being not within a checkpoint the remove
calls would have been transitioned into a put
operation. I am not seeing the logic of this and would assume this is falsy behaviour with no side effects (or maybe with side effects, not 100% sure), since the node references are removed from the trie anyhow (so it has no effect if the value is saved (again) in the DB. I wouldn't exclude the possibility though that I am overlooking something here.
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.
that is a good observation and indeed weird
this is looking good to me. should we add a test setting the stateRoot back and accessing a "deleted" value? then it will succeed with deleteFromDb=false and fail (return null?) with deleteFromDb=true |
@ryanio test addition was a great suggestion since this revealed that this fix is actually not fixing the problem. I added a test here d7d7c38 and this is - against assumption - also returning I tracked a bit with First-thought alternative suggestion to fix would therefore be to add a |
991e498
to
84e7fe4
Compare
Ok, I would now open this up for review. 😄 As discussed in the call we now keep (respectively: set) the no-delete option as I've now found out why the tests failed, this is due to this Overall this PR has the following properties: I followed all the potential delete paths on the Trie methods, so various entry points which lead to either On the other hand the operations on the This makes me think respectively remember: we do the following direct DB operation in the async putContractCode(address: Address, value: Buffer): Promise<void> {
const codeHash = keccak256(value)
if (codeHash.equals(KECCAK256_NULL)) {
return
}
await this._trie.db.put(codeHash, value)
const account = await this.getAccount(address)
account.codeHash = codeHash
await this.putAccount(address, account)
} Is this still something dangerous in this context, e.g. when a numm value is passed? I have to say I am generally not understanding this code part and why the DB is accessed directly in this context and this is not done through the higher level Trie interface. |
Regarding I am wondering if we change from Regarding the I found on eth.wiki it says:
|
@ryanio are there any code changes/updates you would recommend me to do derived from the last comment you made ( |
@holgerd77 hm, thinking about it more, putContractCode must use the underlying db so it doesn't format the nodes via
The last sentence explains why we use the underlying db instead of formatting the trie, so I think the current code is correct. The greater-than-32 check also seems correct to me and doesn't need any code changes. |
84e7fe4
to
f02c8fe
Compare
Rebased the branch on master. |
As mentioned on Discord, this PR doesn't fix the bug, at least not in Balancer's codebase. This repo can be used as a test. You need to check out the To use the latest/released version of the state manager, just run To try with a local build of the vm, run Update on this comment (from @holgerd77): we have re-analyzed and this comment is outdated, bug has been fixed and confirmed. |
Ok, I've now pushed a last update on the TODO comment with the suggestions from Ryan. I guess with the latest analysis done by @alcuadrado and @ryanio we can now merge here and do a release? 😄 Can someone please review and approve? |
@jochem-brouwer @ryanio Can this get a final review please? 😄 |
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.
Yup this looks great!
I would still like to remove this TODO before merging: #1219 (comment) |
@ryanio could you do? I am somewhat on family holidays during the next days until Monday. |
resolve TODO note for rlpNode.length >= 32
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.
lgtm!
Fixes #1210
I am coming more and more to the conclusion that this might be the only change we need. We shouldn't comment out stuff (or remove) directly in the DB manager to let people the freedom to delete themselves if they wish, this is what would be expected from the direct DB class.
Some historical reference in between:
_formatNode
has been moved fromCheckpointTrie
toBaseTrie
here.All Trie delete operations - both from
del()
and frombatch()
- are routed through this_formatNode
method, so this should shield all possible high-level trie deletes.I am unsure about the default setting of a potential new option
deleteFromDB
. My tendency is to switch to this keep-behavior to shield users from an unwanted delete behavior. However I am not sure about the side effects. This will lead to larger state growth - also e.g. in our client - if used for continuous trie operations. This would be an argument to start with remaining the delete-behavior (so setdeleteFromDB
totrue
by default) but then instantiate the default trie in the VM withfalse
.Hmm, very much unsure about these decisions.
Nevertheless this is my proposal what I would currently have a tendency towards.