-
Notifications
You must be signed in to change notification settings - Fork 756
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
Add trie.del
#3486
Add trie.del
#3486
Changes from 3 commits
bf2e879
634b1db
084ddb3
2ba791c
021402e
564d576
df15d50
380beec
8be9ee3
256e19b
0efa9c5
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 |
---|---|---|
|
@@ -14,7 +14,7 @@ import { loadVerkleCrypto } from 'verkle-cryptography-wasm' | |
import { CheckpointDB } from './db/checkpoint.js' | ||
import { InternalNode } from './node/internalNode.js' | ||
import { LeafNode } from './node/leafNode.js' | ||
import { type VerkleNode } from './node/types.js' | ||
import { VerkleLeafNodeValue, type VerkleNode, createDeletedLeafValue } from './node/types.js' | ||
import { decodeNode, isLeafNode } from './node/util.js' | ||
import { | ||
type Proof, | ||
|
@@ -250,11 +250,28 @@ export class VerkleTree { | |
) | ||
} | ||
} else { | ||
if (equalsBytes(value, createDeletedLeafValue())) { | ||
// Special case for when the deleted leaf value is passed to `put` | ||
// You can't delete a value on a leaf node that doesn't exist | ||
this.DEBUG && | ||
this.debug(`Leaf node with stem: ${bytesToHex(stem)} not found in trie`, ['DEL']) | ||
return | ||
} | ||
// Leaf node doesn't exist, create a new one | ||
leafNode = await LeafNode.create(stem, this.verkleCrypto) | ||
this.DEBUG && this.debug(`Creating new leaf node at stem: ${bytesToHex(stem)}`, ['PUT']) | ||
} | ||
// Update value in leaf node and push to putStack | ||
if (equalsBytes(value, createDeletedLeafValue())) { | ||
// Special case for when the deleted leaf value is passed to `put` | ||
// Writing the deleted leaf value to the suffix indicated in the key | ||
this.DEBUG && | ||
this.debug( | ||
`Deleting value at suffix: ${suffix} in leaf node with stem: ${bytesToHex(stem)}`, | ||
['DEL'] | ||
) | ||
leafNode.setValue(suffix, VerkleLeafNodeValue.Deleted) | ||
} | ||
leafNode.setValue(suffix, value) | ||
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. Isn't line 268 overwriting what has been done in line 266 within the if block? 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. Indeed. Will address in the next commit. |
||
this.DEBUG && | ||
this.debug( | ||
|
@@ -319,6 +336,12 @@ export class VerkleTree { | |
await this.saveStack(putStack) | ||
} | ||
|
||
async del(key: Uint8Array): Promise<void> { | ||
const stem = key.slice(0, 31) | ||
const suffix = key[key.length - 1] | ||
this.DEBUG && this.debug(`Stem: ${bytesToHex(stem)}; Suffix: ${suffix}`, ['DEL']) | ||
await this.put(key, createDeletedLeafValue()) | ||
} | ||
/** | ||
* Helper method for updating or creating the parent internal node for a given leaf node | ||
* @param leafNode the child leaf node that will be referenced by the new/updated internal node | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -211,7 +211,7 @@ describe('Verkle tree', () => { | |
assert.deepEqual(val2, hexToBytes(values[2]), 'confirm values[2] can be retrieved from trie') | ||
}) | ||
|
||
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. We could also add a test for the expected behavior when attempting to delete a value that does not exist? Left a related comment in the other file (i.e. should this throw or return?) |
||
it('should put values and find them', async () => { | ||
it('should put, find, delete, and the put values (again)', async () => { | ||
acolytec3 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const keys = [ | ||
// Two keys with the same stem but different suffixes | ||
'0x318dea512b6f3237a2d4763cf49bf26de3b617fb0cabe38a97807a5549df4d01', | ||
|
@@ -241,5 +241,11 @@ describe('Verkle tree', () => { | |
assert.deepEqual(await trie.get(hexToBytes(keys[0])), hexToBytes(values[0])) | ||
assert.deepEqual(await trie.get(hexToBytes(keys[2])), hexToBytes(values[2])) | ||
assert.deepEqual(await trie.get(hexToBytes(keys[3])), hexToBytes(values[3])) | ||
|
||
await trie.del(hexToBytes(keys[0])) | ||
assert.deepEqual(await trie.get(hexToBytes(keys[0])), undefined) | ||
|
||
await trie.put(hexToBytes(keys[0]), hexToBytes(values[0])) | ||
assert.deepEqual(await trie.get(hexToBytes(keys[0])), hexToBytes(values[0])) | ||
}) | ||
}) |
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.
Should this not throw an error instead of silently returning?
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.
Now that I've re-read the spec, I'm not sure what the expected behavior is. If it's just writing
0
to the trie, then this behavior is actually invalid and we should just let it create a new leaf node and write what I'm calling thedeleted leaf value
here. Will ask kevThere 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.
My instinct here is that we should actually just create a new leaf node and write zeroes to it. There is no "deletion" in verkle tries so writing zeroes to a leaf value is the same as "deleting" a value in the trie. Will update this section of code accordingly (i.e. just remove this special handling and allow `trie.del to write zeroes)