From b6705968935cafaf6ce12f52f3eb6eafa320b801 Mon Sep 17 00:00:00 2001 From: weiihann Date: Fri, 27 Dec 2024 22:32:40 +0800 Subject: [PATCH] add lastPeriod to ExpiredLeafNode --- config.go | 2 +- debug.go | 1 + encoding.go | 7 ++++--- encoding_test.go | 6 +++++- expired_leaf.go | 12 +++++++++--- expired_leaf_test.go | 2 +- expired_tree_test.go | 2 +- proof_ipa.go | 7 +++++++ proof_test.go | 8 ++++---- tree.go | 4 +++- 10 files changed, 36 insertions(+), 15 deletions(-) diff --git a/config.go b/config.go index 63261ec..57d8fbe 100644 --- a/config.go +++ b/config.go @@ -35,7 +35,7 @@ const ( NodeWidth = 256 NodeBitWidth byte = 8 StemSize = 31 - periodSize = 8 + periodSize = 2 ) func equalPaths(key1, key2 []byte) bool { diff --git a/debug.go b/debug.go index 0e6c53c..40127d9 100644 --- a/debug.go +++ b/debug.go @@ -47,6 +47,7 @@ type ( ExportableExpiredLeafNode struct { Stem Stem `json:"stem"` + LastPeriod StatePeriod `json:"last_period"` Commitment [32]byte `json:"commitment"` } ) diff --git a/encoding.go b/encoding.go index 8b6e81f..f5e83fa 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 + banderwagon.UncompressedSize + expiredLeafSize = nodeTypeSize + StemSize + periodSize + banderwagon.UncompressedSize ) func bit(bitlist []byte, nr int) bool { @@ -198,10 +198,11 @@ func parseSingleSlotNode(serialized []byte, depth byte) (VerkleNode, error) { func parseExpiredLeafNode(serialized []byte, depth byte) (VerkleNode, error) { l := &ExpiredLeafNode{} - l.stem = serialized[leafStemOffset : leafStemOffset+StemSize] 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:], true); err != nil { + if err := l.commitment.SetBytesUncompressed(serialized[leafStemOffset+StemSize+periodSize:], 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 0c7cec9..87b241e 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, &comm) + el := NewExpiredLeafNode(stem, period2, &comm) serialized, err := el.Serialize() if err != nil { @@ -222,4 +222,8 @@ 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 b65479d..5728599 100644 --- a/expired_leaf.go +++ b/expired_leaf.go @@ -28,16 +28,18 @@ 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, commitment *Point) *ExpiredLeafNode { - return &ExpiredLeafNode{stem: stem, commitment: commitment} +func NewExpiredLeafNode(stem Stem, lastPeriod StatePeriod, commitment *Point) *ExpiredLeafNode { + return &ExpiredLeafNode{stem: stem, lastPeriod: lastPeriod, commitment: commitment} } func (n *ExpiredLeafNode) Insert([]byte, []byte, StatePeriod, NodeResolverFn) error { @@ -95,7 +97,11 @@ func (n *ExpiredLeafNode) Serialize() ([]byte, error) { result := buf[:] result[0] = expiredLeafType copy(result[leafStemOffset:], n.stem[:StemSize]) - copy(result[leafStemOffset+StemSize:], cBytes[:]) + + lastPeriod := make([]byte, periodSize) + binary.BigEndian.PutUint16(lastPeriod, uint16(n.lastPeriod)) + copy(result[leafStemOffset+StemSize:], lastPeriod) + copy(result[leafStemOffset+StemSize+periodSize:], cBytes[:]) return result, nil } diff --git a/expired_leaf_test.go b/expired_leaf_test.go index f25dc35..f25494f 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], &comm) + leaf := NewExpiredLeafNode(zeroKeyTest[:StemSize], period0, &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 a74d380..8a490a8 100644 --- a/expired_tree_test.go +++ b/expired_tree_test.go @@ -213,7 +213,7 @@ func TestRootCommitExpired(t *testing.T) { var init Point init.Set(root.Commit()) - expiredLeaf := NewExpiredLeafNode(leaf.stem, leaf.commitment) + expiredLeaf := NewExpiredLeafNode(leaf.stem, leaf.lastPeriod, leaf.commitment) root.(*InternalNode).children[0] = expiredLeaf comm := root.Commit() diff --git a/proof_ipa.go b/proof_ipa.go index c169bf2..a7b1a75 100644 --- a/proof_ipa.go +++ b/proof_ipa.go @@ -105,16 +105,23 @@ func (vp *VerkleProof) Equal(other *VerkleProof) error { return nil } +// TODO(weiihann): add PoeStems for proof of expiry? It should be a list of (stem, lastPeriod) type Proof struct { Multipoint *ipa.MultiProof // multipoint argument 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 + // PoeInfos []PoeInfo // stems proving another stem is expired Keys [][]byte PreValues [][]byte PostValues [][]byte } +type PoeInfo struct { + Stem Stem + Period StatePeriod +} + type SuffixStateDiff struct { Suffix byte `json:"suffix"` CurrentValue *[32]byte `json:"currentValue"` diff --git a/proof_test.go b/proof_test.go index 6e11bb5..a5fe6c6 100644 --- a/proof_test.go +++ b/proof_test.go @@ -858,7 +858,7 @@ func TestProofOfExpiryOneLeaf(t *testing.T) { leaf := root.(*InternalNode).children[0].(*LeafNode) - expiredLeaf := NewExpiredLeafNode(leaf.stem, leaf.commitment) + expiredLeaf := NewExpiredLeafNode(leaf.stem, leaf.lastPeriod, leaf.commitment) expiredLeaf.setDepth(1) root.(*InternalNode).children[0] = expiredLeaf @@ -905,12 +905,12 @@ func TestProofOfExpiryMultipleLeaves(t *testing.T) { init := root.Commit() leaf0 := root.(*InternalNode).children[0].(*LeafNode) - expiredLeaf0 := NewExpiredLeafNode(leaf0.stem, leaf0.commitment) + 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.commitment) + expiredLeaff := NewExpiredLeafNode(leaff.stem, leaff.lastPeriod, leaff.commitment) expiredLeaff.setDepth(1) root.(*InternalNode).children[255] = expiredLeaff @@ -1202,7 +1202,7 @@ func TestProofVerificationPreStateExpiredPostStateResurrected(t *testing.T) { rootC := preRoot.Commit() leaf := preRoot.(*InternalNode).children[0].(*LeafNode) - expiredLeaf := NewExpiredLeafNode(leaf.stem, leaf.commitment) + expiredLeaf := NewExpiredLeafNode(leaf.stem, leaf.lastPeriod, leaf.commitment) expiredLeaf.setDepth(1) preRoot.(*InternalNode).children[0] = expiredLeaf diff --git a/tree.go b/tree.go index 9e355b3..1517a21 100644 --- a/tree.go +++ b/tree.go @@ -235,6 +235,7 @@ func (n *InternalNode) toExportable() *ExportableInternalNode { case *ExpiredLeafNode: exportable.Children[i] = &ExportableExpiredLeafNode{ Stem: child.stem, + LastPeriod: child.lastPeriod, Commitment: child.commitment.Bytes(), } default: @@ -583,6 +584,7 @@ func (n *InternalNode) CreatePath(path []byte, stemInfo stemInfo, comms []*Point if len(stemInfo.stem) != StemSize { return comms, fmt.Errorf("invalid stem size %d", len(stemInfo.stem)) } + // TODO(weiihann): add last period newchild := &ExpiredLeafNode{ commitment: comms[0], stem: stemInfo.stem, @@ -2062,7 +2064,7 @@ func (n *LeafNode) serializeLeafWithUncompressedCommitments(cBytes, c1Bytes, c2B // Create the serialization. var result []byte lastPeriod := make([]byte, periodSize) - binary.BigEndian.PutUint64(lastPeriod, uint64(n.lastPeriod)) + binary.BigEndian.PutUint16(lastPeriod, uint16(n.lastPeriod)) switch { case count == 1: var buf [singleSlotLeafSize]byte