fix(trace): deletion proof missed path terminated by empty node (#330)

* fix deletion proof issue on empty node

* refine for better implement and fix unittest

* Update version.go

---------

Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
This commit is contained in:
Ho 2023-05-22 15:24:49 +08:00 committed by GitHub
parent 1094569b5b
commit 149419cf09
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 16 additions and 4 deletions

View file

@ -24,7 +24,7 @@ import (
const (
VersionMajor = 3 // Major version component of the current release
VersionMinor = 2 // Minor version component of the current release
VersionPatch = 2 // Patch version component of the current release
VersionPatch = 3 // Patch version component of the current release
VersionMeta = "alpha" // Version metadata to append to the version string
)

View file

@ -244,11 +244,12 @@ func TestProofWithDeletion(t *testing.T) {
// notice the sibling of key `k*32`` is just the leaf of key `m*32`
assert.Equal(t, siblings[0][l-33:l-1], nd)
// no effect
// Marking a key that is currently not hit (but terminated by an empty node)
// also causes it to be added to the deletion proof
proofTracer.MarkDeletion(s_key2.Bytes())
siblings, err = proofTracer.GetDeletionProofs()
assert.NoError(t, err)
assert.Equal(t, 1, len(siblings))
assert.Equal(t, 2, len(siblings))
key3 := bytes.Repeat([]byte("x"), 32)
err = mt.UpdateWord(

View file

@ -28,6 +28,7 @@ type ProofTracer struct {
*ZkTrie
deletionTracer map[zkt.Hash]struct{}
rawPaths map[string][]*zktrie.Node
emptyTermPaths map[string][]*zktrie.Node
}
// NewProofTracer create a proof tracer object
@ -37,6 +38,7 @@ func (t *ZkTrie) NewProofTracer() *ProofTracer {
// always consider 0 is "deleted"
deletionTracer: map[zkt.Hash]struct{}{zkt.HashZero: {}},
rawPaths: make(map[string][]*zktrie.Node),
emptyTermPaths: make(map[string][]*zktrie.Node),
}
}
@ -112,9 +114,13 @@ func (t *ProofTracer) GetDeletionProofs() ([][]byte, error) {
// MarkDeletion mark a key has been involved into deletion
func (t *ProofTracer) MarkDeletion(key []byte) {
if path, existed := t.rawPaths[string(key)]; existed {
if path, existed := t.emptyTermPaths[string(key)]; existed {
// copy empty node terminated path for final scanning
t.rawPaths[string(key)] = path
} else if path, existed = t.rawPaths[string(key)]; existed {
// sanity check
leafNode := path[len(path)-1]
if leafNode.Type != zktrie.NodeTypeLeaf {
panic("all path recorded in proofTrace should be ended with leafNode")
}
@ -143,6 +149,11 @@ func (t *ProofTracer) Prove(key []byte, fromLevel uint, proofDb ethdb.KeyValueWr
}
} else if n.Type == zktrie.NodeTypeParent {
mptPath = append(mptPath, n)
} else if n.Type == zktrie.NodeTypeEmpty {
// empty node is considered as "unhit" but it should be also being added
// into a temporary slot for possibly being marked as deletion later
mptPath = append(mptPath, n)
t.emptyTermPaths[string(key)] = mptPath
}
return proofDb.Put(nodeHash[:], n.Value())