diff --git a/debug.go b/debug.go index 40127d9..4c854d0 100644 --- a/debug.go +++ b/debug.go @@ -42,12 +42,11 @@ type ( C [32]byte `json:"commitment"` C1 [32]byte `json:"c1"` C2 [32]byte `json:"c2"` - LastPeriod StatePeriod `json:"last_period"` + Period StatePeriod `json:"period"` } ExportableExpiredLeafNode struct { Stem Stem `json:"stem"` - LastPeriod StatePeriod `json:"last_period"` Commitment [32]byte `json:"commitment"` } ) diff --git a/doc.go b/doc.go index 295ad0a..6aa2d55 100644 --- a/doc.go +++ b/doc.go @@ -43,6 +43,7 @@ var ( errReviveValuesMismatch = errors.New("values mismatch in revive") errReviveStemMismatch = errors.New("stem mismatch in revive") errRevivePeriodMismatch = errors.New("period mismatch in revive") + errRevivePeriodOlderThanNew = errors.New("revive old period is older than the new period") ) const ( @@ -50,5 +51,4 @@ const ( extStatusAbsentEmpty = byte(iota) // missing child node along the path extStatusAbsentOther // path led to a node with a different stem extStatusPresent // stem was present - extStatusExpired // stem was present but expired ) diff --git a/empty.go b/empty.go index 4529bc7..342baa0 100644 --- a/empty.go +++ b/empty.go @@ -57,7 +57,7 @@ func (Empty) Commitment() *Point { return &id } -func (Empty) GetProofItems(keylist, NodeResolverFn, StatePeriod) (*ProofElements, []byte, []Stem, []StatePeriod, error) { +func (Empty) GetProofItems(keylist, NodeResolverFn) (*ProofElements, []byte, []Stem, []StatePeriod, error) { return nil, nil, nil, nil, errors.New("trying to produce a commitment for an empty subtree") } diff --git a/empty_test.go b/empty_test.go index 8f2177b..c4a2eef 100644 --- a/empty_test.go +++ b/empty_test.go @@ -51,7 +51,7 @@ func TestEmptyFuncs(t *testing.T) { t.Fatal("commitment and commit mismatch") } - if _, _, _, _, err := e.GetProofItems(nil, nil, period0); err == nil { + if _, _, _, _, err := e.GetProofItems(nil, nil); err == nil { t.Fatal("get proof items should error") } diff --git a/encoding.go b/encoding.go index f5e83fa..063657e 100644 --- a/encoding.go +++ b/encoding.go @@ -62,7 +62,7 @@ const ( leafValueIndexSize = 1 singleSlotLeafSize = nodeTypeSize + StemSize + 2*banderwagon.UncompressedSize + leafValueIndexSize + leafSlotSize + periodSize eoaLeafSize = nodeTypeSize + StemSize + 2*banderwagon.UncompressedSize + leafBasicDataSize + periodSize - expiredLeafSize = nodeTypeSize + StemSize + periodSize + banderwagon.UncompressedSize + expiredLeafSize = nodeTypeSize + StemSize + banderwagon.UncompressedSize ) func bit(bitlist []byte, nr int) bool { @@ -77,9 +77,9 @@ var errSerializedPayloadTooShort = errors.New("verkle payload is too short") // ParseNode deserializes a node into its proper VerkleNode instance. // The serialized bytes have the format: // - Internal nodes: -// - Leaf nodes: -// - EoA nodes: -// - single slot node: +// - Leaf nodes: +// - EoA nodes: +// - single slot node: // - Expired leaf nodes: func ParseNode(serializedNode []byte, depth byte) (VerkleNode, error) { // Check that the length of the serialized node is at least the smallest possible serialized node. @@ -200,9 +200,8 @@ func parseExpiredLeafNode(serialized []byte, depth byte) (VerkleNode, error) { l := &ExpiredLeafNode{} l.setDepth(depth) l.stem = serialized[leafStemOffset : leafStemOffset+StemSize] - l.lastPeriod = StatePeriodFromBytes(serialized[leafStemOffset+StemSize:leafStemOffset+StemSize+periodSize]) l.commitment = new(Point) - if err := l.commitment.SetBytesUncompressed(serialized[leafStemOffset+StemSize+periodSize:], true); err != nil { + if err := l.commitment.SetBytesUncompressed(serialized[leafStemOffset+StemSize:], true); err != nil { return nil, fmt.Errorf("setting commitment: %w", err) } return l, nil diff --git a/encoding_test.go b/encoding_test.go index 87b241e..0c7cec9 100644 --- a/encoding_test.go +++ b/encoding_test.go @@ -198,7 +198,7 @@ func TestParseExpiredLeaf(t *testing.T) { comm := srs[0] stem := ffx32KeyTest[:StemSize] - el := NewExpiredLeafNode(stem, period2, &comm) + el := NewExpiredLeafNode(stem, &comm) serialized, err := el.Serialize() if err != nil { @@ -222,8 +222,4 @@ func TestParseExpiredLeaf(t *testing.T) { if !el2.commitment.Equal(&comm) { t.Fatalf("invalid commitment, got %x, expected %x", el2.commitment, comm) } - - if el2.lastPeriod != period2 { - t.Fatalf("invalid last period, got %d, expected %d", el2.lastPeriod, period2) - } } diff --git a/expired_leaf.go b/expired_leaf.go index 14e1afb..8581bce 100644 --- a/expired_leaf.go +++ b/expired_leaf.go @@ -28,18 +28,16 @@ package verkle import ( "fmt" "errors" - "encoding/binary" ) type ExpiredLeafNode struct { stem Stem - lastPeriod StatePeriod commitment *Point depth byte // used for proof only, not commitment calculation } -func NewExpiredLeafNode(stem Stem, lastPeriod StatePeriod, commitment *Point) *ExpiredLeafNode { - return &ExpiredLeafNode{stem: stem, lastPeriod: lastPeriod, commitment: commitment} +func NewExpiredLeafNode(stem Stem, commitment *Point) *ExpiredLeafNode { + return &ExpiredLeafNode{stem: stem, commitment: commitment} } func (n *ExpiredLeafNode) Insert([]byte, []byte, StatePeriod, NodeResolverFn) error { @@ -69,25 +67,8 @@ func (n *ExpiredLeafNode) Commitment() *Point { return n.commitment } -func (n *ExpiredLeafNode) GetProofItems(keys keylist, resolver NodeResolverFn, _ StatePeriod) (*ProofElements, []byte, []Stem, []StatePeriod, error) { - var ( - pe = &ProofElements{ - Vals: make([][]byte, len(keys)), - ByPath: map[string]*Point{}, - } - esses []byte = nil - poass []Stem - ) - - for i := range keys { - pe.ByPath[string(keys[i][:n.depth])] = n.commitment - pe.Vals[i] = nil - - esses = append(esses, extStatusExpired|(n.depth<<3)) - poass = append(poass, n.stem) - } - - return pe, esses, poass, []StatePeriod{n.lastPeriod}, nil +func (n *ExpiredLeafNode) GetProofItems(keylist, NodeResolverFn) (*ProofElements, []byte, []Stem, []StatePeriod, error) { + return nil, nil, nil, nil, errors.New("cannot get proof items from expired leaf node") } func (n *ExpiredLeafNode) Serialize() ([]byte, error) { @@ -97,11 +78,7 @@ func (n *ExpiredLeafNode) Serialize() ([]byte, error) { result := buf[:] result[0] = expiredLeafType copy(result[leafStemOffset:], n.stem[:StemSize]) - - lastPeriod := make([]byte, periodSize) - binary.BigEndian.PutUint16(lastPeriod, uint16(n.lastPeriod)) - copy(result[leafStemOffset+StemSize:], lastPeriod) - copy(result[leafStemOffset+StemSize+periodSize:], cBytes[:]) + copy(result[leafStemOffset+StemSize:], cBytes[:]) return result, nil } diff --git a/expired_leaf_test.go b/expired_leaf_test.go index f25494f..f25dc35 100644 --- a/expired_leaf_test.go +++ b/expired_leaf_test.go @@ -11,7 +11,7 @@ func TestExpiredLeafBasic(t *testing.T) { cfg := GetConfig() srs := cfg.conf.SRS comm := srs[0] - leaf := NewExpiredLeafNode(zeroKeyTest[:StemSize], period0, &comm) + leaf := NewExpiredLeafNode(zeroKeyTest[:StemSize], &comm) err := leaf.Insert(zeroKeyTest, zeroKeyTest, 0, nil) if !errors.Is(err, errExpired) { diff --git a/expired_tree_test.go b/expired_tree_test.go index 9bfb7a5..46e7fb0 100644 --- a/expired_tree_test.go +++ b/expired_tree_test.go @@ -31,8 +31,8 @@ func TestInsertSameLeafNoExpired(t *testing.T) { t.Fatalf("expected value %x, got %x", testValue, leaf.values[oneKeyTest[StemSize]]) } - if leaf.lastPeriod != period1 { - t.Fatalf("expected last accessed to be 1, got %d", leaf.lastPeriod) + if leaf.period != period1 { + t.Fatalf("expected last accessed to be 1, got %d", leaf.period) } } @@ -58,8 +58,8 @@ func TestInsertSameLeafExpired(t *testing.T) { t.Fatalf("expected value %x, got %x", testValue, leaf.values[zeroKeyTest[StemSize]]) } - if leaf.lastPeriod != period0 { - t.Fatalf("expected last accessed to be 0, got %d", leaf.lastPeriod) + if leaf.period != period0 { + t.Fatalf("expected last accessed to be 0, got %d", leaf.period) } } @@ -93,12 +93,12 @@ func TestInsertDiffLeaf(t *testing.T) { t.Fatalf("expected value %x, got %x", testValue, leaff.values[ffx32KeyTest[StemSize]]) } - if leaf0.lastPeriod != period0 { - t.Fatalf("expected last accessed to be 0, got %d", leaf0.lastPeriod) + if leaf0.period != period0 { + t.Fatalf("expected last accessed to be 0, got %d", leaf0.period) } - if leaff.lastPeriod != period2 { - t.Fatalf("expected last accessed to be 2, got %d", leaff.lastPeriod) + if leaff.period != period2 { + t.Fatalf("expected last accessed to be 2, got %d", leaff.period) } } @@ -115,7 +115,7 @@ func TestInsertExpiredLeafSibling(t *testing.T) { t.Fatalf("expected leaf node, got %T", root.(*InternalNode).children[0]) } - root.(*InternalNode).children[0] = NewExpiredLeafNode(leaf.stem, leaf.lastPeriod, leaf.commitment) + root.(*InternalNode).children[0] = NewExpiredLeafNode(leaf.stem, leaf.commitment) if err := root.Insert(forkOneKeyTest, testValue, period2, nil); err != nil { t.Fatalf("error inserting: %v", err) @@ -163,8 +163,8 @@ func TestGetNoExpired(t *testing.T) { t.Fatalf("expected value %x, got %x", testValue, val) } - if leaf.lastPeriod != period0 { - t.Fatalf("expected last accessed to be 0, got %d", leaf.lastPeriod) + if leaf.period != period0 { + t.Fatalf("expected last accessed to be 0, got %d", leaf.period) } } @@ -190,8 +190,8 @@ func TestGetExpired(t *testing.T) { t.Fatalf("expected leaf node, got %T", root.(*InternalNode).children[0]) } - if leaf.lastPeriod != period0 { - t.Fatalf("expected last accessed to be 0, got %d", leaf.lastPeriod) + if leaf.period != period0 { + t.Fatalf("expected last accessed to be 0, got %d", leaf.period) } } @@ -231,8 +231,28 @@ func TestDelLeafExpired(t *testing.T) { t.Fatalf("expected empty node, got %T", root.(*InternalNode).children[0]) } - if leaf.lastPeriod != period0 { - t.Fatalf("expected last accessed to be 0, got %d", leaf.lastPeriod) + if leaf.period != period0 { + t.Fatalf("expected last accessed to be 0, got %d", leaf.period) + } +} + +func TestUpdatePeriod(t *testing.T) { + values := make([][]byte, NodeWidth) + values[0] = testValue + leaf1, err := NewLeafNode(zeroKeyTest, values, period1) + if err != nil { + t.Fatalf("error creating leaf node: %v", err) + } + + leaf1.updatePeriod(period2) + + leaf2, err := NewLeafNode(zeroKeyTest, values, period2) + if err != nil { + t.Fatalf("error creating leaf node: %v", err) + } + + if !leaf1.Commitment().Equal(leaf2.Commitment()) { + t.Fatalf("expected commitment to be %x, got %x", leaf1.Commitment(), leaf2.Commitment()) } } @@ -244,25 +264,30 @@ func TestReviveExpired(t *testing.T) { t.Fatalf("error inserting: %v", err) } - leaf, ok := root.(*InternalNode).children[0].(*LeafNode) - if !ok { - t.Fatalf("expected leaf node, got %T", root.(*InternalNode).children[0]) - } - - expiredLeaf := NewExpiredLeafNode(leaf.stem, leaf.lastPeriod, leaf.commitment) + leaf := root.(*InternalNode).children[0].(*LeafNode) + expiredLeaf := NewExpiredLeafNode(leaf.stem, new(Point).Set(leaf.commitment)) + expiredLeaf.setDepth(1) root.(*InternalNode).children[0] = expiredLeaf - if err := root.Revive(leaf.stem, leaf.values, leaf.lastPeriod, period2, false, nil); err != nil { + if err := root.Revive(leaf.stem, leaf.values, leaf.period, period2, false, nil); err != nil { t.Fatalf("error reviving: %v", err) } + comm1 := root.Commit() - rLeaf, ok := root.(*InternalNode).children[0].(*LeafNode) - if !ok { - t.Fatalf("expected leaf node, got %T", root.(*InternalNode).children[0]) + rLeaf := root.(*InternalNode).children[0].(*LeafNode) + if rLeaf.period != period2 { + t.Fatalf("expected last accessed to be 2, got %d", rLeaf.period) + } + + // Create a new root and insert the same key-value with the post-revive period + root2 := New() + if err := root2.Insert(zeroKeyTest, testValue, period2, nil); err != nil { + t.Fatalf("error inserting: %v", err) } + comm2 := root2.Commit() - if rLeaf.lastPeriod != period2 { - t.Fatalf("expected last accessed to be 2, got %d", rLeaf.lastPeriod) + if !comm1.Equal(comm2) { + t.Fatalf("expected commitment to be %x, got %x", comm1, comm2) } } @@ -281,7 +306,7 @@ func TestReviveNoExpired(t *testing.T) { comm := root.Commit() - if err := root.Revive(leaf.stem, leaf.values, leaf.lastPeriod, period0, false, nil); err != nil { + if err := root.Revive(leaf.stem, leaf.values, leaf.period, period0, false, nil); err != nil { t.Fatalf("error reviving: %v", err) } @@ -290,8 +315,8 @@ func TestReviveNoExpired(t *testing.T) { t.Fatalf("expected leaf node, got %T", root.(*InternalNode).children[0]) } - if rLeaf.lastPeriod != period0 { - t.Fatalf("expected last accessed to be 0, got %d", rLeaf.lastPeriod) + if rLeaf.period != period0 { + t.Fatalf("expected last accessed to be 0, got %d", rLeaf.period) } rComm := root.Commit() @@ -316,7 +341,7 @@ func TestRootCommitExpired(t *testing.T) { var init Point init.Set(root.Commit()) - expiredLeaf := NewExpiredLeafNode(leaf.stem, leaf.lastPeriod, leaf.commitment) + expiredLeaf := NewExpiredLeafNode(leaf.stem, leaf.commitment) root.(*InternalNode).children[0] = expiredLeaf comm := root.Commit() @@ -343,4 +368,4 @@ func TestRootCommitDiffEpoch(t *testing.T) { if comm1.Equal(comm2) { t.Fatalf("expected different commitments, got %x", comm1) } -} +} \ No newline at end of file diff --git a/hashednode.go b/hashednode.go index c64a012..4ed7b06 100644 --- a/hashednode.go +++ b/hashednode.go @@ -62,7 +62,7 @@ func (HashedNode) Commitment() *Point { panic("can not get commitment of a hash node") } -func (HashedNode) GetProofItems(keylist, NodeResolverFn, StatePeriod) (*ProofElements, []byte, []Stem, []StatePeriod, error) { +func (HashedNode) GetProofItems(keylist, NodeResolverFn) (*ProofElements, []byte, []Stem, []StatePeriod, error) { return nil, nil, nil, nil, errors.New("can not get the full path, and there is no proof of absence") } diff --git a/hashednode_test.go b/hashednode_test.go index ad79f9b..c4ccece 100644 --- a/hashednode_test.go +++ b/hashednode_test.go @@ -46,7 +46,7 @@ func TestHashedNodeFuncs(t *testing.T) { if v != nil { t.Fatal("non-nil get from a hashed node") } - if _, _, _, _, err := e.GetProofItems(nil, nil, period0); err == nil { + if _, _, _, _, err := e.GetProofItems(nil, nil); err == nil { t.Fatal("got nil error when getting proof items from a hashed node") } if _, err := e.Serialize(); err != errSerializeHashedNode { diff --git a/proof_ipa.go b/proof_ipa.go index 3d3dfb7..8192857 100644 --- a/proof_ipa.go +++ b/proof_ipa.go @@ -110,10 +110,10 @@ type Proof struct { ExtStatus []byte // the extension status of each stem Cs []*Point // commitments, sorted by their path in the tree PoaStems []Stem // stems proving another stem is absent - ExpiryPeriods []StatePeriod // periods of expired stems Keys [][]byte PreValues [][]byte PostValues [][]byte + PrePeriods []StatePeriod } type SuffixStateDiff struct { @@ -127,7 +127,7 @@ type SuffixStateDiffs []SuffixStateDiff type StemStateDiff struct { Stem [StemSize]byte `json:"stem"` SuffixDiffs SuffixStateDiffs `json:"suffixDiffs"` - PeriodExpired *StatePeriod `json:"periodExpired,omitempty"` + PrePeriod StatePeriod `json:"prePeriod,omitempty"` } type StateDiff []StemStateDiff @@ -137,7 +137,7 @@ func (sd StateDiff) Copy() StateDiff { for i := range sd { copy(ret[i].Stem[:], sd[i].Stem[:]) ret[i].SuffixDiffs = make([]SuffixStateDiff, len(sd[i].SuffixDiffs)) - ret[i].PeriodExpired = sd[i].PeriodExpired + ret[i].PrePeriod = sd[i].PrePeriod for j := range sd[i].SuffixDiffs { ret[i].SuffixDiffs[j].Suffix = sd[i].SuffixDiffs[j].Suffix if sd[i].SuffixDiffs[j].CurrentValue != nil { @@ -187,22 +187,22 @@ func (sd StateDiff) Equal(other StateDiff) error { return nil } -func GetCommitmentsForMultiproof(root VerkleNode, keys [][]byte, resolver NodeResolverFn, period StatePeriod) (*ProofElements, []byte, []Stem, []StatePeriod, error) { +func GetCommitmentsForMultiproof(root VerkleNode, keys [][]byte, resolver NodeResolverFn) (*ProofElements, []byte, []Stem, []StatePeriod, error) { sort.Sort(keylist(keys)) - return root.GetProofItems(keylist(keys), resolver, period) + return root.GetProofItems(keylist(keys), resolver) } // getProofElementsFromTree factors the logic that is used both in the proving and verification methods. It takes a pre-state // tree and an optional post-state tree, extracts the proof data from them and returns all the items required to build/verify // a proof. -func getProofElementsFromTree(preroot, postroot VerkleNode, keys [][]byte, prePeriod, postEpoch StatePeriod, resolver NodeResolverFn) (*ProofElements, []byte, []Stem, [][]byte, []StatePeriod, error) { +func getProofElementsFromTree(preroot, postroot VerkleNode, keys [][]byte, postPeriod StatePeriod, resolver NodeResolverFn) (*ProofElements, []byte, []Stem, [][]byte, []StatePeriod, error) { // go-ipa won't accept no key as an input, catch this corner case // and return an empty result. if len(keys) == 0 { return nil, nil, nil, nil, nil, errors.New("no key provided for proof") } - pe, es, poas, eps, err := GetCommitmentsForMultiproof(preroot, keys, resolver, prePeriod) + pe, es, poas, ps, err := GetCommitmentsForMultiproof(preroot, keys, resolver) if err != nil { return nil, nil, nil, nil, nil, fmt.Errorf("error getting pre-state proof data: %w", err) } @@ -214,7 +214,7 @@ func getProofElementsFromTree(preroot, postroot VerkleNode, keys [][]byte, prePe // keys were sorted already in the above GetcommitmentsForMultiproof. // Set the post values, if they are untouched, leave them `nil` for i := range keys { - val, err := postroot.Get(keys[i], postEpoch, resolver) + val, err := postroot.Get(keys[i], postPeriod, resolver) if err != nil { return nil, nil, nil, nil, nil, fmt.Errorf("error getting post-state value for key %x: %w", keys[i], err) } @@ -226,12 +226,12 @@ func getProofElementsFromTree(preroot, postroot VerkleNode, keys [][]byte, prePe // [0:3]: proof elements of the pre-state trie for serialization, // 3: values to be inserted in the post-state trie for serialization - // 4: expiry stems, also included in proof elements for serialization - return pe, es, poas, postvals, eps, nil + // 4: pre-state periods of each stem + return pe, es, poas, postvals, ps, nil } -func MakeVerkleMultiProof(preroot, postroot VerkleNode, keys [][]byte, prePeriod, postEpoch StatePeriod, resolver NodeResolverFn) (*Proof, []*Point, []byte, []*Fr, error) { - pe, es, poas, postvals, eps, err := getProofElementsFromTree(preroot, postroot, keys, prePeriod, postEpoch, resolver) +func MakeVerkleMultiProof(preroot, postroot VerkleNode, keys [][]byte, postPeriod StatePeriod, resolver NodeResolverFn) (*Proof, []*Point, []byte, []*Fr, error) { + pe, es, poas, postvals, ps, err := getProofElementsFromTree(preroot, postroot, keys, postPeriod, resolver) if err != nil { return nil, nil, nil, nil, fmt.Errorf("get commitments for multiproof: %s", err) } @@ -265,17 +265,17 @@ func MakeVerkleMultiProof(preroot, postroot VerkleNode, keys [][]byte, prePeriod Cs: cis, ExtStatus: es, PoaStems: poas, - ExpiryPeriods: eps, Keys: keys, PreValues: pe.Vals, PostValues: postvals, + PrePeriods: ps, } return proof, pe.Cis, pe.Zis, pe.Yis, nil } // verifyVerkleProofWithPreState takes a proof and a trusted tree root and verifies that the proof is valid. -func verifyVerkleProofWithPreState(proof *Proof, preroot VerkleNode, prePeriod StatePeriod) error { - pe, _, _, _, _, err := getProofElementsFromTree(preroot, nil, proof.Keys, prePeriod, period0,nil) +func verifyVerkleProofWithPreState(proof *Proof, preroot VerkleNode) error { + pe, _, _, _, _, err := getProofElementsFromTree(preroot, nil, proof.Keys, period0, nil) if err != nil { return fmt.Errorf("error getting proof elements: %w", err) } @@ -321,20 +321,13 @@ func SerializeProof(proof *Proof) (*VerkleProof, StateDiff, error) { var stemdiff *StemStateDiff var statediff StateDiff - var curExtStatus byte - var checkStemExpiry bool - curExtInd := -1 // index of the current extension status - curExpInd := 0 // index of the current expiry period for i, key := range proof.Keys { stem := KeyToStem(key) if stemdiff == nil || !bytes.Equal(stemdiff.Stem[:], stem) { statediff = append(statediff, StemStateDiff{}) stemdiff = &statediff[len(statediff)-1] copy(stemdiff.Stem[:], stem) - checkStemExpiry = true - curExtInd += 1 - curExtStatus = proof.ExtStatus[curExtInd] } stemdiff.SuffixDiffs = append(stemdiff.SuffixDiffs, SuffixStateDiff{Suffix: key[StemSize]}) @@ -364,13 +357,6 @@ func SerializeProof(proof *Proof) (*VerkleProof, StateDiff, error) { copy(aligned[:valueLen], proof.PostValues[i]) newsd.NewValue = (*[32]byte)(unsafe.Pointer(&aligned[0])) } - - if checkStemExpiry && curExtStatus&3 == extStatusExpired { - checkStemExpiry = false - period := proof.ExpiryPeriods[curExpInd] - stemdiff.PeriodExpired = &period - curExpInd += 1 - } } return &VerkleProof{ @@ -396,7 +382,7 @@ func DeserializeProof(vp *VerkleProof, statediff StateDiff) (*Proof, error) { extStatus []byte commitments []*Point multipoint ipa.MultiProof - expiryPeriods []StatePeriod + prePeriods []StatePeriod ) poaStems = make([]Stem, len(vp.OtherStems)) @@ -453,9 +439,7 @@ func DeserializeProof(vp *VerkleProof, statediff StateDiff) (*Proof, error) { } } - if stemdiff.PeriodExpired != nil { - expiryPeriods = append(expiryPeriods, *stemdiff.PeriodExpired) - } + prePeriods = append(prePeriods, stemdiff.PrePeriod) } proof := Proof{ @@ -463,10 +447,10 @@ func DeserializeProof(vp *VerkleProof, statediff StateDiff) (*Proof, error) { extStatus, commitments, poaStems, - expiryPeriods, keys, prevalues, postvalues, + prePeriods, } return &proof, nil } @@ -503,7 +487,7 @@ func PreStateTreeFromProof(proof *Proof, rootC *Point) (VerkleNode, error) { // paths [][]byte err error poas = proof.PoaStems - eps = proof.ExpiryPeriods + ps = proof.PrePeriods ) // The proof of absence stems must be sorted. If that isn't the case, the proof is invalid. @@ -570,21 +554,12 @@ func PreStateTreeFromProof(proof *Proof, rootC *Point) (VerkleNode, error) { // if bytes.Equal(KeyToStem(k), si.stem) { si.values[k[StemSize]] = proof.PreValues[j] si.has_c1 = si.has_c1 || (k[StemSize] < 128) + si.has_c2 = si.has_c2 || (k[StemSize] >= 128) } } - case extStatusExpired: - // All keys that are part of a proof of expiry, must contain empty - // prestate values. If that isn't the case, the proof is invalid. - for j := range proof.Keys { // TODO: DoS risk, use map or binary search. - if bytes.HasPrefix(proof.Keys[j], stems[i]) && proof.PreValues[j] != nil { - return nil, fmt.Errorf("proof of absence (empty) stem %x has a value", si.stem) - } - } - si.stem = poas[0] - si.period = eps[0] - poas = poas[1:] - eps = eps[1:] + si.period = ps[0] + ps = ps[1:] default: return nil, fmt.Errorf("invalid extension status: %d", si.stemType) } @@ -647,12 +622,8 @@ func PostStateTreeFromStateDiff(preroot VerkleNode, statediff StateDiff, postEpo var stem [StemSize]byte copy(stem[:StemSize], stemstatediff.Stem[:]) - if stemstatediff.PeriodExpired != nil { - if err := postroot.Revive(stem[:], values, *stemstatediff.PeriodExpired, postEpoch, true, nil); err != nil { - return nil, fmt.Errorf("error reviving in post state: %w", err) - } - } else if overwrites { - if err := postroot.(*InternalNode).InsertValuesAtStem(stem[:], values, postEpoch, nil); err != nil { + if overwrites { + if err := postroot.(*InternalNode).InsertValuesAtStem(stem[:], values, postEpoch, true, nil); err != nil { return nil, fmt.Errorf("error overwriting value in post state: %w", err) } } @@ -669,7 +640,7 @@ func (x bytesSlice) Less(i, j int) bool { return bytes.Compare(x[i], x[j]) < 0 } func (x bytesSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] } // Verify is the API function that verifies a verkle proofs as found in a block/execution payload. -func Verify(vp *VerkleProof, preStateRoot []byte, postStateRoot []byte, statediff StateDiff, prePeriod, postPeriod StatePeriod) error { +func Verify(vp *VerkleProof, preStateRoot []byte, postStateRoot []byte, statediff StateDiff, postPeriod StatePeriod) error { proof, err := DeserializeProof(vp, statediff) if err != nil { return fmt.Errorf("verkle proof deserialization error: %w", err) @@ -720,5 +691,5 @@ func Verify(vp *VerkleProof, preStateRoot []byte, postStateRoot []byte, statedif return fmt.Errorf("post tree root mismatch: %x != %x", regeneratedPostTreeRoot, postStateRoot) } - return verifyVerkleProofWithPreState(proof, pretree, prePeriod) + return verifyVerkleProofWithPreState(proof, pretree) } diff --git a/proof_json.go b/proof_json.go index 9b2be63..76e7ebb 100644 --- a/proof_json.go +++ b/proof_json.go @@ -186,14 +186,14 @@ func (vp *VerkleProof) UnmarshalJSON(data []byte) error { type stemStateDiffMarshaller struct { Stem string `json:"stem"` SuffixDiffs SuffixStateDiffs `json:"suffixDiffs"` - PeriodExpired *StatePeriod `json:"periodExpired,omitempty"` + PrePeriod StatePeriod `json:"prePeriod"` } func (ssd StemStateDiff) MarshalJSON() ([]byte, error) { return json.Marshal(&stemStateDiffMarshaller{ Stem: HexToPrefixedString(ssd.Stem[:]), SuffixDiffs: ssd.SuffixDiffs, - PeriodExpired: ssd.PeriodExpired, + PrePeriod: ssd.PrePeriod, }) } @@ -209,7 +209,7 @@ func (ssd *StemStateDiff) UnmarshalJSON(data []byte) error { } *ssd = StemStateDiff{ SuffixDiffs: aux.SuffixDiffs, - PeriodExpired: aux.PeriodExpired, + PrePeriod: aux.PrePeriod, } copy(ssd.Stem[:], stem) return nil diff --git a/proof_test.go b/proof_test.go index 6546d36..58a1d2b 100644 --- a/proof_test.go +++ b/proof_test.go @@ -29,7 +29,6 @@ import ( "crypto/rand" "encoding/hex" "encoding/json" - "errors" "fmt" "reflect" "testing" @@ -43,7 +42,7 @@ func TestProofEmptyTree(t *testing.T) { root := New() root.Commit() - proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{ffx32KeyTest}, period0, period0, nil) + proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{ffx32KeyTest}, period0, nil) cfg := GetConfig() if ok, err := verifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil { t.Fatalf("could not verify verkle proof: %s", ToDot(root)) @@ -65,7 +64,7 @@ func TestProofVerifyTwoLeaves(t *testing.T) { } root.Commit() - proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{ffx32KeyTest}, period0, period0, nil) + proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{ffx32KeyTest}, period0, nil) cfg := GetConfig() if ok, err := verifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil { @@ -92,7 +91,7 @@ func TestProofVerifyMultipleLeaves(t *testing.T) { } root.Commit() - proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{keys[0]}, period0, period0, nil) + proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{keys[0]}, period0, nil) cfg := GetConfig() if ok, err := verifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil { @@ -119,9 +118,9 @@ func TestMultiProofVerifyMultipleLeaves(t *testing.T) { } root.Commit() - proof, _, _, _, _ := MakeVerkleMultiProof(root, nil, keys[0:2], period0, period0, nil) + proof, _, _, _, _ := MakeVerkleMultiProof(root, nil, keys[0:2], period0, nil) - pe, _, _, _, err := GetCommitmentsForMultiproof(root, keys[0:2], nil, period0) + pe, _, _, _, err := GetCommitmentsForMultiproof(root, keys[0:2], nil) if err != nil { t.Fatal(err) } @@ -159,9 +158,9 @@ func TestMultiProofVerifyMultipleLeavesWithAbsentStem(t *testing.T) { absent[3] = 1 // and the stem differs keys = append(keys, absent) - proof, _, _, _, _ := MakeVerkleMultiProof(root, nil, keys, period0, period0, nil) + proof, _, _, _, _ := MakeVerkleMultiProof(root, nil, keys, period0, nil) - pe, _, isabsent, _, err := GetCommitmentsForMultiproof(root, keys, nil, period0) + pe, _, isabsent, _, err := GetCommitmentsForMultiproof(root, keys, nil) if err != nil { t.Fatal(err) } @@ -193,9 +192,9 @@ func TestMultiProofVerifyMultipleLeavesCommitmentRedundancy(t *testing.T) { } root.Commit() - proof, _, _, _, _ := MakeVerkleMultiProof(root, nil, keys, period0, period0, nil) + proof, _, _, _, _ := MakeVerkleMultiProof(root, nil, keys, period0, nil) - pe, _, _, _, err := GetCommitmentsForMultiproof(root, keys, nil, period0) + pe, _, _, _, err := GetCommitmentsForMultiproof(root, keys, nil) if err != nil { t.Fatal(err) } @@ -217,7 +216,7 @@ func TestProofOfAbsenceInternalVerify(t *testing.T) { } root.Commit() - proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{ffx32KeyTest}, period0, period0, nil) + proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{ffx32KeyTest}, period0, nil) cfg := GetConfig() if ok, err := verifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil { @@ -237,7 +236,7 @@ func TestProofOfAbsenceLeafVerify(t *testing.T) { } root.Commit() - proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{oneKeyTest}, period0, period0, nil) + proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{oneKeyTest}, period0, nil) cfg := GetConfig() if ok, err := verifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil { @@ -262,7 +261,7 @@ func TestProofOfAbsenceLeafVerifyOtherSuffix(t *testing.T) { return ret }() - proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{key}, period0, period0, nil) + proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{key}, period0, nil) cfg := GetConfig() if ok, err := verifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil { @@ -284,7 +283,7 @@ func TestProofOfAbsenceStemVerify(t *testing.T) { }() root.Commit() - proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{key}, period0, period0, nil) + proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{key}, period0, nil) cfg := GetConfig() if ok, err := verifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil { @@ -310,7 +309,7 @@ func BenchmarkProofCalculation(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { - if _, _, _, _, err := MakeVerkleMultiProof(root, nil, [][]byte{keys[len(keys)/2]}, period0, period0, nil); err != nil { + if _, _, _, _, err := MakeVerkleMultiProof(root, nil, [][]byte{keys[len(keys)/2]}, period0, nil); err != nil { b.Fatal(err) } } @@ -331,7 +330,7 @@ func BenchmarkProofVerification(b *testing.B) { } root.Commit() - proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{keys[len(keys)/2]}, period0, period0, nil) + proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{keys[len(keys)/2]}, period0, nil) b.ResetTimer() b.ReportAllocs() @@ -362,7 +361,7 @@ func TestProofSerializationNoAbsentStem(t *testing.T) { } } - proof, _, _, _, _ := MakeVerkleMultiProof(root, nil, [][]byte{keys[0]}, period0, period0, nil) + proof, _, _, _, _ := MakeVerkleMultiProof(root, nil, [][]byte{keys[0]}, period0, nil) vp, statediff, err := SerializeProof(proof) if err != nil { @@ -401,7 +400,7 @@ func TestProofSerializationWithAbsentStem(t *testing.T) { absentkey[2] = 2 absentkey[3] = 1 - proof, _, _, _, _ := MakeVerkleMultiProof(root, nil, [][]byte{absentkey[:]}, period0, period0, nil) + proof, _, _, _, _ := MakeVerkleMultiProof(root, nil, [][]byte{absentkey[:]}, period0, nil) vp, statediff, err := SerializeProof(proof) if err != nil { @@ -442,7 +441,7 @@ func TestProofDeserialize(t *testing.T) { absentkey[2] = 2 absentkey[3] = 1 - proof, _, _, _, _ := MakeVerkleMultiProof(root, nil, [][]byte{absentkey[:]}, period0, period0, nil) + proof, _, _, _, _ := MakeVerkleMultiProof(root, nil, [][]byte{absentkey[:]}, period0, nil) vp, statediff, err := SerializeProof(proof) if err != nil { @@ -455,7 +454,7 @@ func TestProofDeserialize(t *testing.T) { } _ = deserialized - pe, _, _, _, err := root.GetProofItems(keylist{absentkey[:]}, nil, period0) + pe, _, _, _, err := root.GetProofItems(keylist{absentkey[:]}, nil) if err != nil { t.Fatal(err) } @@ -472,7 +471,7 @@ func TestProofOfAbsenceEdgeCase(t *testing.T) { root.Commit() ret, _ := hex.DecodeString("0303030303030303030303030303030303030303030303030303030303030303") - proof, cs, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{ret}, period0, period0, nil) + proof, cs, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{ret}, period0, nil) cfg := GetConfig() if ok, err := verifyVerkleProof(proof, cs, zis, yis, cfg); !ok || err != nil { t.Fatal("could not verify proof") @@ -493,7 +492,7 @@ func TestProofOfAbsenceOtherMultipleLeaves(t *testing.T) { ret1, _ := hex.DecodeString("0303030303030303030303030303030303030303030303030303030303030300") ret2, _ := hex.DecodeString("0303030303030303030303030303030303030303030303030303030303030301") - proof, cs, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{ret1, ret2}, period0, period0, nil) + proof, cs, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{ret1, ret2}, period0, nil) cfg := GetConfig() if ok, err := verifyVerkleProof(proof, cs, zis, yis, cfg); !ok || err != nil { t.Fatal("could not verify proof") @@ -555,7 +554,7 @@ func TestProofOfAbsenceNoneMultipleStems(t *testing.T) { ret1, _ := hex.DecodeString("0303030303030303030303030303030303030303030303030303030303030300") ret2, _ := hex.DecodeString("0303030303030303030303030303030303030303030303030303030303030200") - proof, cs, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{ret1, ret2}, period0, period0, nil) + proof, cs, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{ret1, ret2}, period0, nil) cfg := GetConfig() if ok, err := verifyVerkleProof(proof, cs, zis, yis, cfg); !ok || err != nil { t.Fatal("could not verify proof") @@ -626,10 +625,10 @@ func TestStemStateDiffJSONMarshalUn(t *testing.T) { 0xDD, 0xEE, 0xFF, 0x00, }, }}, - PeriodExpired: func() *StatePeriod { p := StatePeriod(100); return &p }(), + PrePeriod: StatePeriod(100), } - expectedJSON := `{"stem":"0x0a000000000000000000000000000000000000000000000000000000000000","suffixDiffs":[{"suffix":65,"currentValue":"0x102030405060708090a0b0c0d0e0f000112233445566778899aabbccddeeff00","newValue":null}],"periodExpired":100}` + expectedJSON := `{"stem":"0x0a000000000000000000000000000000000000000000000000000000000000","suffixDiffs":[{"suffix":65,"currentValue":"0x102030405060708090a0b0c0d0e0f000112233445566778899aabbccddeeff00","newValue":null}],"prePeriod":100}` actualJSON, err := json.Marshal(ssd) if err != nil { t.Errorf("error marshalling SuffixStateDiff to JSON: %v", err) @@ -839,111 +838,6 @@ func TestProofOfAbsenceBorderCaseReversed(t *testing.T) { testSerializeDeserializeProof(t, insertKVs, proveKeys) } -func TestProofOfExpiryOneLeaf(t *testing.T) { - t.Parallel() - - root := New() - if err := root.Insert(zeroKeyTest, zeroKeyTest, period2, nil); err != nil { - t.Fatalf("could not insert key: %v", err) - } - if err := root.Insert(oneKeyTest, zeroKeyTest, period2, nil); err != nil { - t.Fatalf("could not insert key: %v", err) - } - init := root.Commit() - - leaf := root.(*InternalNode).children[0].(*LeafNode) - - expiredLeaf := NewExpiredLeafNode(leaf.stem, leaf.lastPeriod, leaf.commitment) - expiredLeaf.setDepth(1) - root.(*InternalNode).children[0] = expiredLeaf - - comm := root.Commit() - if !comm.Equal(init) { - t.Fatalf("expected commitment to be %x, got %x", init, comm) - } - - proof, cis, zis, yis, err := MakeVerkleMultiProof(root, nil, [][]byte{zeroKeyTest}, period0, period0, nil) - if err != nil { - t.Fatalf("could not make verkle proof: %v", err) - } - - cfg := GetConfig() - if ok, err := verifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil { - t.Fatalf("could not verify verkle proof: %s", ToDot(root)) - } - - deserialized, err := PreStateTreeFromProof(proof, init) - if err != nil { - t.Fatalf("error deserializing %v", err) - } - - _, err = deserialized.Get(zeroKeyTest, period0, nil) - if !errors.Is(err, errExpired) { - t.Fatalf("expected error getting key %x, got %v", zeroKeyTest, err) - } - - if !deserialized.Commit().Equal(init) { - t.Fatalf("expected commitment to be different from %x, got %x", init, deserialized.Commit()) - } -} - -func TestProofOfExpiryMultipleLeaves(t *testing.T) { - t.Parallel() - - root := New() - if err := root.Insert(zeroKeyTest, zeroKeyTest, period2, nil); err != nil { - t.Fatalf("could not insert key: %v", err) - } - if err := root.Insert(ffx32KeyTest, zeroKeyTest, period2, nil); err != nil { - t.Fatalf("could not insert key: %v", err) - } - init := root.Commit() - - leaf0 := root.(*InternalNode).children[0].(*LeafNode) - expiredLeaf0 := NewExpiredLeafNode(leaf0.stem, leaf0.lastPeriod, leaf0.commitment) - expiredLeaf0.setDepth(1) - root.(*InternalNode).children[0] = expiredLeaf0 - - leaff := root.(*InternalNode).children[255].(*LeafNode) - expiredLeaff := NewExpiredLeafNode(leaff.stem, leaff.lastPeriod, leaff.commitment) - expiredLeaff.setDepth(1) - root.(*InternalNode).children[255] = expiredLeaff - - comm := root.Commit() - if !comm.Equal(init) { - t.Fatalf("expected commitment to be %x, got %x", init, comm) - } - - proof, cis, zis, yis, err := MakeVerkleMultiProof(root, nil, [][]byte{zeroKeyTest, ffx32KeyTest}, period0, period0, nil) - if err != nil { - t.Fatalf("could not make verkle proof: %v", err) - } - - cfg := GetConfig() - if ok, err := verifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil { - t.Fatalf("could not verify verkle proof: %s", ToDot(root)) - } - - deserialized, err := PreStateTreeFromProof(proof, init) - if err != nil { - t.Fatalf("error deserializing %v", err) - } - - _, err = deserialized.Get(zeroKeyTest, period0, nil) - if !errors.Is(err, errExpired) { - t.Fatalf("expected error getting key %x, got %v", zeroKeyTest, err) - } - - _, err = deserialized.Get(ffx32KeyTest, period0, nil) - if !errors.Is(err, errExpired) { - t.Fatalf("expected error getting key %x, got %v", ffx32KeyTest, err) - } - - if !deserialized.Commit().Equal(init) { - t.Fatalf("expected commitment to be different from %x, got %x", init, deserialized.Commit()) - } -} - func testSerializeDeserializeProof(t *testing.T, insertKVs map[string][]byte, proveKeys keylist) { t.Helper() @@ -970,7 +864,7 @@ func testSerializeDeserializeProof(t *testing.T, insertKVs map[string][]byte, pr proveKVs[string(key)] = value } - proof, _, _, _, _ := MakeVerkleMultiProof(root, nil, proveKeys, period0, period0, nil) + proof, _, _, _, _ := MakeVerkleMultiProof(root, nil, proveKeys, period0, nil) serialized, statediff, err := SerializeProof(proof) if err != nil { @@ -1119,7 +1013,7 @@ func TestProofVerificationWithPostState(t *testing.T) { // skipcq: GO-R1005 } postroot.Commit() - proof, _, _, _, _ := MakeVerkleMultiProof(root, postroot, data.keystoprove, period0, period0, nil) + proof, _, _, _, _ := MakeVerkleMultiProof(root, postroot, data.keystoprove, period0, nil) keys: for i := range proof.Keys { @@ -1158,7 +1052,7 @@ func TestProofVerificationWithPostState(t *testing.T) { // skipcq: GO-R1005 t.Fatalf("error deserializing proof: %v", err) } - if err = verifyVerkleProofWithPreState(dproof, root, period0); err != nil { + if err = verifyVerkleProofWithPreState(dproof, root); err != nil { t.Fatalf("could not verify verkle proof: %v, original: %s reconstructed: %s", err, ToDot(root), ToDot(postroot)) } @@ -1176,7 +1070,7 @@ func TestProofVerificationWithPostState(t *testing.T) { // skipcq: GO-R1005 t.Fatalf("differing root commitments %x != %x", dpostroot.Commitment().Bytes(), postroot.Commitment().Bytes()) } - if err = verifyVerkleProofWithPreState(dproof, dpreroot, period0); err != nil { + if err = verifyVerkleProofWithPreState(dproof, dpreroot); err != nil { t.Fatalf("could not verify verkle proof: %v, original: %s reconstructed: %s", err, ToDot(dpreroot), ToDot(dpostroot)) } }) @@ -1184,7 +1078,7 @@ func TestProofVerificationWithPostState(t *testing.T) { // skipcq: GO-R1005 } // TODO(weiihann): add more test cases similar to TestProofVerificationWithPostState -func TestProofVerificationPreStateExpiredPostStateResurrected(t *testing.T) { +func TestProofVerificationPreStateExpiredPostStateRevived(t *testing.T) { t.Parallel() prePeriod := period0 @@ -1194,19 +1088,26 @@ func TestProofVerificationPreStateExpiredPostStateResurrected(t *testing.T) { if err := preRoot.Insert(zeroKeyTest, zeroKeyTest, prePeriod, nil); err != nil { t.Fatalf("could not insert key: %v", err) } - rootC := preRoot.Commit() + preReviveRoot := new(Point).Set(preRoot.Commit()) leaf := preRoot.(*InternalNode).children[0].(*LeafNode) - expiredLeaf := NewExpiredLeafNode(leaf.stem, leaf.lastPeriod, leaf.commitment) + expiredLeaf := NewExpiredLeafNode(leaf.stem, leaf.commitment) expiredLeaf.setDepth(1) preRoot.(*InternalNode).children[0] = expiredLeaf + if err := preRoot.Revive(leaf.stem, leaf.values, prePeriod, postPeriod, true, nil); err != nil { + t.Fatalf("error reviving leaf node: %v", err) + } + postRoot := New() if err := postRoot.Insert(zeroKeyTest, fourtyKeyTest, postPeriod, nil); err != nil { t.Fatalf("could not insert key: %v", err) } - proof, _, _, _, _ := MakeVerkleMultiProof(preRoot, postRoot, keylist{zeroKeyTest}, prePeriod, postPeriod, nil) + proof, _, _, _, err := MakeVerkleMultiProof(preRoot, postRoot, keylist{zeroKeyTest}, postPeriod, nil) + if err != nil { + t.Fatalf("error making proof: %v", err) + } p, diff, err := SerializeProof(proof) if err != nil { @@ -1218,11 +1119,11 @@ func TestProofVerificationPreStateExpiredPostStateResurrected(t *testing.T) { t.Fatalf("error deserializing proof: %v", err) } - if err = verifyVerkleProofWithPreState(dproof, preRoot, prePeriod); err != nil { + if err = verifyVerkleProofWithPreState(dproof, preRoot); err != nil { t.Fatalf("could not verify verkle proof: %v", err) } - dpreroot, err := PreStateTreeFromProof(dproof, rootC) + dpreroot, err := PreStateTreeFromProof(dproof, preReviveRoot) if err != nil { t.Fatalf("error recreating pre tree: %v", err) } @@ -1232,7 +1133,7 @@ func TestProofVerificationPreStateExpiredPostStateResurrected(t *testing.T) { t.Fatalf("error recreating post tree: %v", err) } - if err = verifyVerkleProofWithPreState(dproof, dpreroot, prePeriod); err != nil { + if err = verifyVerkleProofWithPreState(dproof, dpreroot); err != nil { t.Fatalf("could not verify verkle proof: %v, original: %s reconstructed: %s", err, ToDot(dpreroot), ToDot(dpostroot)) } @@ -1259,7 +1160,7 @@ func TestGenerateProofWithOnlyAbsentKeys(t *testing.T) { // Create a proof with a key with the same first byte, but different second byte (i.e: absent). absentKey, _ := hex.DecodeString("4010000000000000000000000000000000000000000000000000000000000000") - proof, cis, zis, yis, err := MakeVerkleMultiProof(root, nil, keylist{absentKey}, period0, period0, nil) + proof, cis, zis, yis, err := MakeVerkleMultiProof(root, nil, keylist{absentKey}, period0, nil) if err != nil { t.Fatal(err) } @@ -1284,7 +1185,7 @@ func TestGenerateProofWithOnlyAbsentKeys(t *testing.T) { } // From the rebuilt tree, validate the proof. - pe, _, _, _, err := GetCommitmentsForMultiproof(droot, keylist{absentKey}, nil, period0) + pe, _, _, _, err := GetCommitmentsForMultiproof(droot, keylist{absentKey}, nil) if err != nil { t.Fatal(err) } @@ -1339,7 +1240,7 @@ func TestDoubleProofOfAbsence(t *testing.T) { // in that leaf node. i.e: two proof of absence in the same leaf node with no proof of presence. key2, _ := hex.DecodeString("0000000000000000000000000000000000000000000000000000000000000100") key3, _ := hex.DecodeString("0000000000000000000000000000000000000000000000000000000000000200") - proof, _, _, _, _ := MakeVerkleMultiProof(root, nil, keylist{key2, key3}, period0, period0, nil) + proof, _, _, _, _ := MakeVerkleMultiProof(root, nil, keylist{key2, key3}, period0, nil) serialized, statediff, err := SerializeProof(proof) if err != nil { @@ -1388,7 +1289,7 @@ func TestProveAbsenceInEmptyHalf(t *testing.T) { key2, _ := hex.DecodeString("0000000000000000000000000000000000000000000000000000000000000100") key3, _ := hex.DecodeString("0000000000000000000000000000000000000000000000000000000000000000") - proof, _, _, _, _ := MakeVerkleMultiProof(root, nil, keylist{key2, key3}, period0, period0, nil) + proof, _, _, _, _ := MakeVerkleMultiProof(root, nil, keylist{key2, key3}, period0, nil) serialized, statediff, err := SerializeProof(proof) if err != nil { diff --git a/tree.go b/tree.go index b17c6c5..3c93e72 100644 --- a/tree.go +++ b/tree.go @@ -91,7 +91,7 @@ type VerkleNode interface { // returns them breadth-first. On top of that, it returns // one "extension status" per stem, and an alternate stem // if the key is missing but another stem has been found. - GetProofItems(keylist, NodeResolverFn, StatePeriod) (*ProofElements, []byte, []Stem, []StatePeriod, error) + GetProofItems(keylist, NodeResolverFn) (*ProofElements, []byte, []Stem, []StatePeriod, error) // Serialize encodes the node to RLP. Serialize() ([]byte, error) @@ -205,7 +205,7 @@ type ( // true in the context of a stateless tree. isPOAStub bool - lastPeriod StatePeriod + period StatePeriod // the last accessed period } ) @@ -230,12 +230,11 @@ func (n *InternalNode) toExportable() *ExportableInternalNode { Values: child.values, C: child.commitment.Bytes(), C1: child.c1.Bytes(), - LastPeriod: child.lastPeriod, + Period: child.period, } case *ExpiredLeafNode: exportable.Children[i] = &ExportableExpiredLeafNode{ Stem: child.stem, - LastPeriod: child.lastPeriod, Commitment: child.commitment.Bytes(), } default: @@ -279,7 +278,7 @@ func NewStatelessInternal(depth byte, comm *Point) VerkleNode { } // New creates a new leaf node -func NewLeafNode(stem Stem, values [][]byte, lastPeriod StatePeriod) (*LeafNode, error) { +func NewLeafNode(stem Stem, values [][]byte, period StatePeriod) (*LeafNode, error) { cfg := GetConfig() // C1. @@ -322,7 +321,7 @@ func NewLeafNode(stem Stem, values [][]byte, lastPeriod StatePeriod) (*LeafNode, return nil, fmt.Errorf("batch mapping to scalar fields: %s", err) } - poly[4].SetUint64(uint64(lastPeriod)) + poly[4].SetUint64(uint64(period)) return &LeafNode{ // depth will be 0, but the commitment calculation @@ -332,20 +331,20 @@ func NewLeafNode(stem Stem, values [][]byte, lastPeriod StatePeriod) (*LeafNode, commitment: cfg.CommitToPoly(poly[:], NodeWidth-5), c1: c1, c2: c2, - lastPeriod: lastPeriod, + period: period, }, nil } // NewLeafNodeWithNoComms create a leaf node but does not compute its // commitments. The created node's commitments are intended to be // initialized with `SetTrustedBytes` in a deserialization context. -func NewLeafNodeWithNoComms(stem Stem, values [][]byte, lastPeriod StatePeriod) *LeafNode { +func NewLeafNodeWithNoComms(stem Stem, values [][]byte, period StatePeriod) *LeafNode { return &LeafNode{ // depth will be 0, but the commitment calculation // does not need it, and so it won't be free. values: values, stem: stem, - lastPeriod: lastPeriod, + period: period, } } @@ -378,10 +377,10 @@ func (n *InternalNode) cowChild(index byte) { func (n *InternalNode) Insert(key []byte, value []byte, curPeriod StatePeriod, resolver NodeResolverFn) error { values := make([][]byte, NodeWidth) values[key[StemSize]] = value - return n.InsertValuesAtStem(KeyToStem(key), values, curPeriod, resolver) + return n.InsertValuesAtStem(KeyToStem(key), values, curPeriod, false,resolver) } -func (n *InternalNode) InsertValuesAtStem(stem Stem, values [][]byte, curPeriod StatePeriod, resolver NodeResolverFn) error { +func (n *InternalNode) InsertValuesAtStem(stem Stem, values [][]byte, curPeriod StatePeriod, skipPeriodCheck bool, resolver NodeResolverFn) error { nChild := offset2key(stem, n.depth) // index of the child pointed by the next byte in the key switch child := n.children[nChild].(type) { @@ -411,7 +410,7 @@ func (n *InternalNode) InsertValuesAtStem(stem Stem, values [][]byte, curPeriod n.cowChild(nChild) // recurse to handle the case of a LeafNode child that // splits. - return n.InsertValuesAtStem(stem, values, curPeriod, resolver) + return n.InsertValuesAtStem(stem, values, curPeriod, skipPeriodCheck, resolver) case *ExpiredLeafNode: // If the stem is the same as the expired leaf node, we can't insert if equalPaths(child.stem, stem) { @@ -427,7 +426,7 @@ func (n *InternalNode) InsertValuesAtStem(stem Stem, values [][]byte, curPeriod nextWordInInsertedKey := offset2key(stem, n.depth+1) if nextWordInInsertedKey == nextWordInExistingKey { - return newBranch.InsertValuesAtStem(stem, values, curPeriod, resolver) + return newBranch.InsertValuesAtStem(stem, values, curPeriod, skipPeriodCheck, resolver) } leaf, err := NewLeafNode(stem, values, curPeriod) @@ -444,7 +443,7 @@ func (n *InternalNode) InsertValuesAtStem(stem Stem, values [][]byte, curPeriod return errIsPOAStub } n.cowChild(nChild) - return child.insertMultiple(stem, values, curPeriod) + return child.insertMultiple(stem, values, curPeriod, skipPeriodCheck) } n.cowChild(nChild) @@ -460,7 +459,7 @@ func (n *InternalNode) InsertValuesAtStem(stem Stem, values [][]byte, curPeriod nextWordInInsertedKey := offset2key(stem, n.depth+1) if nextWordInInsertedKey == nextWordInExistingKey { - return newBranch.InsertValuesAtStem(stem, values, curPeriod, resolver) + return newBranch.InsertValuesAtStem(stem, values, curPeriod, skipPeriodCheck, resolver) } // Next word differs, so this was the last level. @@ -474,7 +473,7 @@ func (n *InternalNode) InsertValuesAtStem(stem Stem, values [][]byte, curPeriod newBranch.children[nextWordInInsertedKey] = leaf case *InternalNode: n.cowChild(nChild) - return child.InsertValuesAtStem(stem, values, curPeriod, resolver) + return child.InsertValuesAtStem(stem, values, curPeriod, skipPeriodCheck, resolver) default: // It should be an UknownNode. return errUnknownNodeType } @@ -482,7 +481,11 @@ func (n *InternalNode) InsertValuesAtStem(stem Stem, values [][]byte, curPeriod return nil } -func (n *InternalNode) Revive(stem Stem, values [][]byte, oldPeriod, curPeriod StatePeriod, skipReviveVerify bool,resolver NodeResolverFn) error { +func (n *InternalNode) Revive(stem Stem, values [][]byte, oldPeriod, curPeriod StatePeriod, skipUpdate bool,resolver NodeResolverFn) error { + if oldPeriod > curPeriod { + return errRevivePeriodOlderThanNew + } + nChild := offset2key(stem, n.depth) switch child := n.children[nChild].(type) { @@ -505,18 +508,8 @@ func (n *InternalNode) Revive(stem Stem, values [][]byte, oldPeriod, curPeriod S } n.children[nChild] = resolved n.cowChild(nChild) - return n.Revive(stem, values, oldPeriod, curPeriod, skipReviveVerify, resolver) + return n.Revive(stem, values, oldPeriod, curPeriod, skipUpdate, resolver) case *ExpiredLeafNode: - if skipReviveVerify { - leaf, err := NewLeafNode(stem, values, curPeriod) - if err != nil { - return err - } - leaf.setDepth(n.depth + 1) - n.children[nChild] = leaf - return nil - } - leaf, err := NewLeafNode(stem, values, oldPeriod) if err != nil { return err @@ -529,12 +522,15 @@ func (n *InternalNode) Revive(stem Stem, values [][]byte, oldPeriod, curPeriod S // Update period and set as child leaf.setDepth(n.depth + 1) - leaf.updatePeriod(curPeriod) + if !skipUpdate { + leaf.updatePeriod(curPeriod) + } n.children[nChild] = leaf - + n.cowChild(nChild) + return nil case *LeafNode: - return child.Revive(stem, values, oldPeriod, curPeriod, skipReviveVerify, resolver) + return child.Revive(stem, values, oldPeriod, curPeriod, skipUpdate, resolver) } return nil @@ -587,6 +583,7 @@ func (n *InternalNode) CreatePath(path []byte, stemInfo stemInfo, comms []*Point commitment: comms[0], stem: stemInfo.stem, values: values, + period: stemInfo.period, depth: n.depth + 1, } n.children[path[0]] = newchild @@ -612,21 +609,6 @@ func (n *InternalNode) CreatePath(path []byte, stemInfo stemInfo, comms []*Point for b, value := range stemInfo.values { newchild.values[b] = value } - case extStatusExpired: - if len(comms) == 0 { - return comms, fmt.Errorf("missing commitment for stem %x", stemInfo.stem) - } - if len(stemInfo.stem) != StemSize { - return comms, fmt.Errorf("invalid stem size %d", len(stemInfo.stem)) - } - newchild := &ExpiredLeafNode{ - commitment: comms[0], - stem: stemInfo.stem, - lastPeriod: stemInfo.period, - depth: n.depth + 1, - } - n.children[path[0]] = newchild - comms = comms[1:] default: return comms, fmt.Errorf("invalid stem type %d", stemInfo.stemType) } @@ -1066,7 +1048,7 @@ func groupKeys(keys keylist, depth byte) []keylist { return groups } -func (n *InternalNode) GetProofItems(keys keylist, resolver NodeResolverFn, curPeriod StatePeriod) (*ProofElements, []byte, []Stem, []StatePeriod, error) { +func (n *InternalNode) GetProofItems(keys keylist, resolver NodeResolverFn) (*ProofElements, []byte, []Stem, []StatePeriod, error) { var ( groups = groupKeys(keys, n.depth) pe = &ProofElements{ @@ -1079,7 +1061,7 @@ func (n *InternalNode) GetProofItems(keys keylist, resolver NodeResolverFn, curP esses []byte = nil // list of extension statuses poass []Stem // list of proof-of-absence stems - expiryPeriods []StatePeriod + ps []StatePeriod ) // fill in the polynomial for this node @@ -1162,7 +1144,7 @@ func (n *InternalNode) GetProofItems(keys keylist, resolver NodeResolverFn, curP continue } - pec, es, other, otherEs, err := n.children[childIdx].GetProofItems(group, resolver, curPeriod) + pec, es, other, otherPs, err := n.children[childIdx].GetProofItems(group, resolver) if err != nil { // TODO: add a test case to cover this scenario. return nil, nil, nil, nil, err @@ -1170,10 +1152,10 @@ func (n *InternalNode) GetProofItems(keys keylist, resolver NodeResolverFn, curP pe.Merge(pec) poass = append(poass, other...) esses = append(esses, es...) - expiryPeriods = append(expiryPeriods, otherEs...) + ps = append(ps, otherPs...) } - return pe, esses, poass, expiryPeriods, nil + return pe, esses, poass, ps, nil } // Serialize returns the serialized form of the internal node. @@ -1293,16 +1275,16 @@ func (n *LeafNode) Insert(key []byte, value []byte, curPeriod StatePeriod, _ Nod } values := make([][]byte, NodeWidth) values[key[StemSize]] = value - return n.insertMultiple(stem, values, curPeriod) + return n.insertMultiple(stem, values, curPeriod, false) } -func (n *LeafNode) insertMultiple(stem Stem, values [][]byte, curPeriod StatePeriod) error { +func (n *LeafNode) insertMultiple(stem Stem, values [][]byte, curPeriod StatePeriod, skipPeriodCheck bool) error { // Sanity check: ensure the stems are the same. if !equalPaths(stem, n.stem) { return errInsertIntoOtherStem } - if n.isExpired(curPeriod) { + if !skipPeriodCheck && n.isExpired(curPeriod) { return errExpired } @@ -1322,7 +1304,7 @@ func (n *LeafNode) updateC(cxIndex int, newC Fr, oldC Fr, curPeriod StatePeriod) var poly [NodeWidth]Fr poly[cxIndex] = deltaC - if n.lastPeriod != curPeriod { + if n.period != curPeriod { poly[4].SetUint64(uint64(curPeriod)) } @@ -1388,7 +1370,7 @@ func (n *LeafNode) updateLeaf(index byte, value []byte, curPeriod StatePeriod) e // If index is in the first NodeWidth/2 elements, we need to update C1. Otherwise, C2. cxIndex := 2 + int(index)/(NodeWidth/2) // [1, stem, -> C1, C2 <-] - n.lastPeriod = curPeriod + n.period = curPeriod n.updateC(cxIndex, frs[0], frs[1], curPeriod) n.values[index] = value @@ -1443,19 +1425,19 @@ func (n *LeafNode) updateMultipleLeaves(values [][]byte, curPeriod StatePeriod) } n.updateC(c1Idx, frs[0], frs[1], curPeriod) n.updateC(c2Idx, frs[2], frs[3], curPeriod) - n.lastPeriod = curPeriod + n.period = curPeriod } else if oldC1 != nil { // Case 2. (C1 touched) if err := banderwagon.BatchMapToScalarField([]*Fr{&frs[0], &frs[1]}, []*Point{n.c1, oldC1}); err != nil { return fmt.Errorf("batch mapping to scalar fields: %s", err) } n.updateC(c1Idx, frs[0], frs[1], curPeriod) - n.lastPeriod = curPeriod + n.period = curPeriod } else if oldC2 != nil { // Case 2. (C2 touched) if err := banderwagon.BatchMapToScalarField([]*Fr{&frs[0], &frs[1]}, []*Point{n.c2, oldC2}); err != nil { return fmt.Errorf("batch mapping to scalar fields: %s", err) } n.updateC(c2Idx, frs[0], frs[1], curPeriod) - n.lastPeriod = curPeriod + n.period = curPeriod } return nil @@ -1536,7 +1518,7 @@ func (n *LeafNode) Delete(k []byte, curPeriod StatePeriod, _ NodeResolverFn) (bo n.commitment.Sub(n.commitment, cfg.CommitToPoly(poly[:], 0)) // TODO(weiihann): can this be done together with the previous? - if n.lastPeriod != curPeriod { + if n.period != curPeriod { n.updatePeriod(curPeriod) } @@ -1586,14 +1568,18 @@ func (n *LeafNode) Get(k []byte, curPeriod StatePeriod, _ NodeResolverFn) ([]byt return n.values[k[StemSize]], nil } -func (n *LeafNode) Revive(stem Stem, values [][]byte, oldPeriod, curPeriod StatePeriod, _ bool, resolver NodeResolverFn) error { +func (n *LeafNode) Revive(stem Stem, values [][]byte, oldPeriod, curPeriod StatePeriod, skipUpdate bool, resolver NodeResolverFn) error { + if oldPeriod > curPeriod { + return errRevivePeriodOlderThanNew + } + // No-op if already in current period - if n.lastPeriod == curPeriod { + if n.period == curPeriod { return nil } // Verify period, stem and values match - if n.lastPeriod != oldPeriod { + if n.period != oldPeriod { return errRevivePeriodMismatch } if !bytes.Equal(n.stem, stem) { @@ -1608,7 +1594,10 @@ func (n *LeafNode) Revive(stem Stem, values [][]byte, oldPeriod, curPeriod State } } - n.updatePeriod(curPeriod) + if !skipUpdate { + n.updatePeriod(curPeriod) + } + return nil } @@ -1634,19 +1623,20 @@ func (n *LeafNode) Commit() *Point { // updatePeriod updates the last period of the leaf node and updates the commitment func (n *LeafNode) updatePeriod(curPeriod StatePeriod) { - // no-op if the period is already the same - if n.lastPeriod == curPeriod { + // no-op if the current period is the same + if curPeriod <= n.period { return } - n.lastPeriod = curPeriod var poly [5]Fr - poly[4].SetUint64(uint64(curPeriod)) + poly[4].SetUint64(uint64(curPeriod - n.period)) n.commitment.Add(n.commitment, cfg.CommitToPoly(poly[:], 0)) + + n.period = curPeriod } func (n *LeafNode) isExpired(cur StatePeriod) bool { - return IsExpired(n.lastPeriod, cur) + return IsExpired(n.period, cur) } // fillSuffixTreePoly takes one of the two suffix tree and @@ -1697,7 +1687,7 @@ func leafToComms(poly []Fr, val []byte) error { return nil } -func (n *LeafNode) GetProofItems(keys keylist, resolver NodeResolverFn, curPeriod StatePeriod) (*ProofElements, []byte, []Stem, []StatePeriod, error) { // skipcq: GO-R1005 +func (n *LeafNode) GetProofItems(keys keylist, resolver NodeResolverFn) (*ProofElements, []byte, []Stem, []StatePeriod, error) { // skipcq: GO-R1005 var ( poly [NodeWidth]Fr // top-level polynomial pe = &ProofElements{ @@ -1711,16 +1701,10 @@ func (n *LeafNode) GetProofItems(keys keylist, resolver NodeResolverFn, curPerio esses []byte = nil // list of extension statuses poass []Stem // list of proof-of-absence + ps []StatePeriod ) - // Leaf node is expired but not yet garbage collected, create a temporary expired leaf node - // and return its proof items. - if n.isExpired(curPeriod) { - expireLeaf := NewExpiredLeafNode(n.stem, n.lastPeriod, n.commitment) - return expireLeaf.GetProofItems(keys, resolver, curPeriod) - } - - // Initialize the top-level polynomial with 1 + stem + C1 + C2 + lastPeriod + // Initialize the top-level polynomial with 1 + stem + C1 + C2 + period poly[0].SetUint64(1) if err := StemFromLEBytes(&poly[1], n.stem); err != nil { return nil, nil, nil, nil, fmt.Errorf("error serializing stem '%x': %w", n.stem, err) @@ -1768,7 +1752,7 @@ func (n *LeafNode) GetProofItems(keys keylist, resolver NodeResolverFn, curPerio pe.Fis = append(pe.Fis, poly[:]) } - poly[4].SetUint64(uint64(n.lastPeriod)) + poly[4].SetUint64(uint64(n.period)) pe.Cis = append(pe.Cis, n.commitment) pe.Zis = append(pe.Zis, 4) @@ -1859,11 +1843,11 @@ func (n *LeafNode) GetProofItems(keys keylist, resolver NodeResolverFn, curPerio pe.ByPath[slotPath] = scomm } - return pe, esses, poass, nil, nil + return pe, esses, poass, ps, nil } // Serialize serializes a LeafNode. -// The format is: +// The format is: func (n *LeafNode) Serialize() ([]byte, error) { cBytes := banderwagon.BatchToBytesUncompressed(n.commitment, n.c1, n.c2) return n.serializeLeafWithUncompressedCommitments(cBytes[0], cBytes[1], cBytes[2]), nil @@ -2114,8 +2098,8 @@ func (n *LeafNode) serializeLeafWithUncompressedCommitments(cBytes, c1Bytes, c2B // Create the serialization. var result []byte - lastPeriod := make([]byte, periodSize) - binary.BigEndian.PutUint16(lastPeriod, uint16(n.lastPeriod)) + period := make([]byte, periodSize) + binary.BigEndian.PutUint16(period, uint16(n.period)) switch { case count == 1: var buf [singleSlotLeafSize]byte @@ -2128,7 +2112,7 @@ func (n *LeafNode) serializeLeafWithUncompressedCommitments(cBytes, c1Bytes, c2B copy(result[leafStemOffset+StemSize:], c2Bytes[:]) } copy(result[leafStemOffset+StemSize+banderwagon.UncompressedSize:], cBytes[:]) - copy(result[leafStemOffset+StemSize+2*banderwagon.UncompressedSize:], lastPeriod) + copy(result[leafStemOffset+StemSize+2*banderwagon.UncompressedSize:], period) result[leafStemOffset+StemSize+2*banderwagon.UncompressedSize+periodSize] = byte(lastIdx) copy(result[leafStemOffset+StemSize+2*banderwagon.UncompressedSize+periodSize+leafValueIndexSize:], n.values[lastIdx][:]) case isEoA: @@ -2138,7 +2122,7 @@ func (n *LeafNode) serializeLeafWithUncompressedCommitments(cBytes, c1Bytes, c2B copy(result[leafStemOffset:], n.stem[:StemSize]) copy(result[leafStemOffset+StemSize:], c1Bytes[:]) copy(result[leafStemOffset+StemSize+banderwagon.UncompressedSize:], cBytes[:]) - copy(result[leafStemOffset+StemSize+2*banderwagon.UncompressedSize:], lastPeriod) + copy(result[leafStemOffset+StemSize+2*banderwagon.UncompressedSize:], period) copy(result[leafStemOffset+StemSize+2*banderwagon.UncompressedSize+periodSize:], n.values[0]) // copy basic data default: result = make([]byte, nodeTypeSize+StemSize+bitlistSize+3*banderwagon.UncompressedSize+periodSize+len(children)) @@ -2148,7 +2132,7 @@ func (n *LeafNode) serializeLeafWithUncompressedCommitments(cBytes, c1Bytes, c2B copy(result[leafCommitmentOffset:], cBytes[:]) copy(result[leafC1CommitmentOffset:], c1Bytes[:]) copy(result[leafC2CommitmentOffset:], c2Bytes[:]) - copy(result[leafLastEpochOffset:], lastPeriod) + copy(result[leafLastEpochOffset:], period) copy(result[leafChildrenOffset:], children) } diff --git a/tree_test.go b/tree_test.go index 840d67d..7d2fd87 100644 --- a/tree_test.go +++ b/tree_test.go @@ -1047,7 +1047,7 @@ func TestEmptyCommitment(t *testing.T) { t.Fatalf("inserting into the original failed: %v", err) } root.Commit() - pe, _, _, _, err := root.GetProofItems(keylist{ffx32KeyTest}, nil, period0) + pe, _, _, _, err := root.GetProofItems(keylist{ffx32KeyTest}, nil) if err != nil { t.Fatal(err) } @@ -1114,7 +1114,7 @@ func TestGetProofItemsNoPoaIfStemPresent(t *testing.T) { key1, _ := hex.DecodeString("ffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") key2, _ := hex.DecodeString("ffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff") - _, esses, poas, _, err := root.GetProofItems(keylist{key1, key2, ffx32KeyTest}, nil, period0) + _, esses, poas, _, err := root.GetProofItems(keylist{key1, key2, ffx32KeyTest}, nil) if err != nil { t.Fatal(err) } @@ -1172,7 +1172,7 @@ func TestInsertStem(t *testing.T) { values[5] = zeroKeyTest values[192] = fourtyKeyTest - if err := root1.(*InternalNode).InsertValuesAtStem(KeyToStem(fourtyKeyTest), values, 0, nil); err != nil { + if err := root1.(*InternalNode).InsertValuesAtStem(KeyToStem(fourtyKeyTest), values, 0, false, nil); err != nil { t.Fatalf("error inserting: %s", err) } r1c := root1.Commit() @@ -1220,7 +1220,7 @@ func TestInsertStemTouchingBothHalves(t *testing.T) { newValues := make([][]byte, NodeWidth) newValues[1] = testValue newValues[NodeWidth-2] = testValue - if err := root.(*InternalNode).InsertValuesAtStem(KeyToStem(zeroKeyTest), newValues, 0, nil); err != nil { + if err := root.(*InternalNode).InsertValuesAtStem(KeyToStem(zeroKeyTest), newValues, 0, false, nil); err != nil { t.Fatalf("error inserting stem: %v", err) } root.Commit() @@ -1369,7 +1369,7 @@ func TestRustBanderwagonBlock48(t *testing.T) { r := tree.Commit() - proof, cis, zis, yis, _ := MakeVerkleMultiProof(tree, nil, keys, period0, period0, nil) + proof, cis, zis, yis, _ := MakeVerkleMultiProof(tree, nil, keys, period0, nil) vp, statediff, err := SerializeProof(proof) if err != nil { t.Fatal(err) @@ -1390,7 +1390,7 @@ func TestRustBanderwagonBlock48(t *testing.T) { if err != nil { t.Fatal(err) } - pe, _, _, _, err := droot.GetProofItems(keylist(keys), nil, period0) + pe, _, _, _, err := droot.GetProofItems(keylist(keys), nil) if err != nil { t.Fatal(err) } @@ -1841,7 +1841,7 @@ func runRandTest(rt randTest) error { continue } root.Commit() - proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, keys, period0, period0, nil) + proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, keys, period0, nil) if ok, err := verifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil { rt[i].err = fmt.Errorf("could not verify verkle proof: %s, err %v", ToDot(root), err) } diff --git a/unknown.go b/unknown.go index 093b673..0c42f26 100644 --- a/unknown.go +++ b/unknown.go @@ -55,7 +55,7 @@ func (UnknownNode) Commitment() *Point { return &id } -func (UnknownNode) GetProofItems(keylist, NodeResolverFn, StatePeriod) (*ProofElements, []byte, []Stem, []StatePeriod, error) { +func (UnknownNode) GetProofItems(keylist, NodeResolverFn) (*ProofElements, []byte, []Stem, []StatePeriod, error) { return nil, nil, nil, nil, errors.New("can't generate proof items for unknown node") } diff --git a/unknown_test.go b/unknown_test.go index d78688b..9e21912 100644 --- a/unknown_test.go +++ b/unknown_test.go @@ -24,7 +24,7 @@ func TestUnknownFuncs(t *testing.T) { if comm := un.Commitment(); !comm.Equal(&identity) { t.Errorf("got %v, want identity", comm) } - if _, _, _, _, err := un.GetProofItems(nil, nil, period0); err == nil { + if _, _, _, _, err := un.GetProofItems(nil, nil); err == nil { t.Errorf("got nil error when getting proof items from a hashed node") } if _, err := un.Serialize(); err == nil {