Skip to content

Commit 546eedd

Browse files
committed
support stateless proof
revert unnecessary changes
1 parent a5c3119 commit 546eedd

17 files changed

+401
-118
lines changed

conversion.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ func (n *InternalNode) InsertMigratedLeaves(leaves []LeafNode, curTs AccessTimes
104104

105105
// We first mark all children of the subtreess that we'll update in parallel,
106106
// so the subtree updating doesn't produce a concurrent access to n.cowChild(...).
107-
lastChildrenIdx := -1
107+
var lastChildrenIdx = -1
108108
for i := range leaves {
109109
if int(leaves[i].stem[0]) != lastChildrenIdx {
110110
lastChildrenIdx = int(leaves[i].stem[0])

doc.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,13 @@ var (
3838
errUnknownNodeType = errors.New("unknown node type detected")
3939
errMissingNodeInStateless = errors.New("trying to access a node that is missing from the stateless view")
4040
errIsPOAStub = errors.New("trying to read/write a proof of absence leaf node")
41-
errEpochExpired = errors.New("trying to access an expired leaf node")
41+
errExpired = errors.New("trying to access an expired leaf node")
4242
)
4343

4444
const (
4545
// Extension status
4646
extStatusAbsentEmpty = byte(iota) // missing child node along the path
4747
extStatusAbsentOther // path led to a node with a different stem
4848
extStatusPresent // stem was present
49+
extStatusExpired // stem was present but expired
4950
)

empty.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func (Empty) Commitment() *Point {
5353
return &id
5454
}
5555

56-
func (Empty) GetProofItems(keylist, NodeResolverFn) (*ProofElements, []byte, []Stem, error) {
56+
func (Empty) GetProofItems(keylist, AccessTimestamp, NodeResolverFn) (*ProofElements, []byte, []Stem, error) {
5757
return nil, nil, nil, errors.New("trying to produce a commitment for an empty subtree")
5858
}
5959

empty_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func TestEmptyFuncs(t *testing.T) {
5151
t.Fatal("commitment and commit mismatch")
5252
}
5353

54-
if _, _, _, err := e.GetProofItems(nil, nil); err == nil {
54+
if _, _, _, err := e.GetProofItems(nil, 0, nil); err == nil {
5555
t.Fatal("get proof items should error")
5656
}
5757

encoding.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func ParseNode(serializedNode []byte, depth byte) (VerkleNode, error) {
9898
case singleSlotType:
9999
return parseSingleSlotNode(serializedNode, depth)
100100
case expiredLeafType:
101-
return parseExpiredLeafNode(serializedNode)
101+
return parseExpiredLeafNode(serializedNode, depth)
102102
default:
103103
return nil, ErrInvalidNodeEncoding
104104
}
@@ -203,9 +203,10 @@ func parseSingleSlotNode(serialized []byte, depth byte) (VerkleNode, error) {
203203
return ln, nil
204204
}
205205

206-
func parseExpiredLeafNode(serialized []byte) (VerkleNode, error) {
206+
func parseExpiredLeafNode(serialized []byte, depth byte) (VerkleNode, error) {
207207
l := &ExpiredLeafNode{}
208208
l.stem = serialized[leafStemOffset : leafStemOffset+StemSize]
209+
l.setDepth(depth)
209210
l.commitment = new(Point)
210211
if err := l.commitment.SetBytesUncompressed(serialized[leafStemOffset+StemSize:], true); err != nil {
211212
return nil, fmt.Errorf("setting commitment: %w", err)

expired_leaf.go

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,41 +28,58 @@ package verkle
2828
type ExpiredLeafNode struct {
2929
stem Stem
3030
commitment *Point
31+
depth byte // used for proof only, not commitment calculation
3132
}
3233

3334
func NewExpiredLeafNode(stem Stem, commitment *Point) *ExpiredLeafNode {
3435
return &ExpiredLeafNode{stem: stem, commitment: commitment}
3536
}
3637

37-
func (ExpiredLeafNode) Insert([]byte, []byte, AccessTimestamp, NodeResolverFn) error {
38-
return errEpochExpired
38+
func (n *ExpiredLeafNode) Insert([]byte, []byte, AccessTimestamp, NodeResolverFn) error {
39+
return errExpired
3940
}
4041

41-
func (ExpiredLeafNode) Delete([]byte, AccessTimestamp, NodeResolverFn) (bool, error) {
42-
return false, errEpochExpired
42+
func (n *ExpiredLeafNode) Delete([]byte, AccessTimestamp, NodeResolverFn) (bool, error) {
43+
return false, errExpired
4344
}
4445

45-
func (ExpiredLeafNode) Get([]byte, AccessTimestamp, NodeResolverFn) ([]byte, error) {
46-
return nil, errEpochExpired
46+
func (n *ExpiredLeafNode) Get([]byte, AccessTimestamp, NodeResolverFn) ([]byte, error) {
47+
return nil, errExpired
4748
}
4849

49-
func (n ExpiredLeafNode) Commit() *Point {
50+
func (n *ExpiredLeafNode) Commit() *Point {
5051
if n.commitment == nil {
5152
panic("nil commitment")
5253
}
5354
return n.commitment
5455
}
5556

56-
func (n ExpiredLeafNode) Commitment() *Point {
57+
func (n *ExpiredLeafNode) Commitment() *Point {
5758
return n.commitment
5859
}
5960

60-
// TODO(weiihann): prove that something was expired, for the block to be able to execute statelessly.
61-
func (n ExpiredLeafNode) GetProofItems(keylist, NodeResolverFn) (*ProofElements, []byte, []Stem, error) {
62-
return nil, nil, nil, errEpochExpired
61+
func (n *ExpiredLeafNode) GetProofItems(keys keylist, curTs AccessTimestamp, resolver NodeResolverFn) (*ProofElements, []byte, []Stem, error) {
62+
var (
63+
pe = &ProofElements{
64+
Vals: make([][]byte, len(keys)),
65+
ByPath: map[string]*Point{},
66+
}
67+
esses []byte = nil
68+
poass []Stem
69+
)
70+
71+
for i := range keys {
72+
pe.ByPath[string(keys[i][:n.depth])] = n.commitment
73+
pe.Vals[i] = nil
74+
75+
esses = append(esses, extStatusExpired|(n.depth<<3))
76+
poass = append(poass, n.stem)
77+
}
78+
79+
return pe, esses, poass, nil
6380
}
6481

65-
func (n ExpiredLeafNode) Serialize() ([]byte, error) {
82+
func (n *ExpiredLeafNode) Serialize() ([]byte, error) {
6683
cBytes := n.commitment.BytesUncompressedTrusted()
6784

6885
var buf [expiredLeafSize]byte
@@ -74,10 +91,11 @@ func (n ExpiredLeafNode) Serialize() ([]byte, error) {
7491
return result, nil
7592
}
7693

77-
func (n ExpiredLeafNode) Copy() VerkleNode {
94+
func (n *ExpiredLeafNode) Copy() VerkleNode {
7895
l := &ExpiredLeafNode{}
7996
l.stem = make(Stem, len(n.stem))
80-
97+
l.depth = n.depth
98+
copy(l.stem, n.stem)
8199
if n.commitment != nil {
82100
l.commitment = new(Point)
83101
l.commitment.Set(n.commitment)
@@ -86,15 +104,15 @@ func (n ExpiredLeafNode) Copy() VerkleNode {
86104
return l
87105
}
88106

89-
func (n ExpiredLeafNode) toDot(string, string) string {
107+
func (n *ExpiredLeafNode) toDot(string, string) string {
90108
return ""
91109
}
92110

93-
func (n ExpiredLeafNode) setDepth(_ byte) {
94-
panic("should not be try to set the depth of an ExpiredLeafNode node")
111+
func (n *ExpiredLeafNode) setDepth(d byte) {
112+
n.depth = d
95113
}
96114

97-
func (n ExpiredLeafNode) Hash() *Fr {
115+
func (n *ExpiredLeafNode) Hash() *Fr {
98116
var hash Fr
99117
n.commitment.MapToScalarField(&hash)
100118
return &hash

expired_leaf_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@ func TestExpiredLeafBasic(t *testing.T) {
1414
leaf := NewExpiredLeafNode(zeroKeyTest[:StemSize], &comm)
1515

1616
err := leaf.Insert(zeroKeyTest, zeroKeyTest, 0, nil)
17-
if !errors.Is(err, errEpochExpired) {
17+
if !errors.Is(err, errExpired) {
1818
t.Fatalf("expected epoch expired error when inserting, got %v", err)
1919
}
2020

2121
_, err = leaf.Delete(zeroKeyTest, 0, nil)
22-
if !errors.Is(err, errEpochExpired) {
22+
if !errors.Is(err, errExpired) {
2323
t.Fatalf("expected epoch expired error when deleting, got %v", err)
2424
}
2525

2626
v, err := leaf.Get(zeroKeyTest, 0, nil)
27-
if !errors.Is(err, errEpochExpired) {
27+
if !errors.Is(err, errExpired) {
2828
t.Fatalf("expected epoch expired error when getting, got %v", err)
2929
}
3030
if v != nil {

expired_tree_test.go

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func TestInsertSameLeafExpired(t *testing.T) {
4545
}
4646

4747
err := root.Insert(oneKeyTest, testValue, 2, nil)
48-
if !errors.Is(err, errEpochExpired) {
48+
if !errors.Is(err, errExpired) {
4949
t.Fatalf("expected epoch expired error when inserting, got %v", err)
5050
}
5151

@@ -138,7 +138,7 @@ func TestGetExpired(t *testing.T) {
138138
}
139139

140140
val, err := root.Get(zeroKeyTest, 2, nil)
141-
if !errors.Is(err, errEpochExpired) {
141+
if !errors.Is(err, errExpired) {
142142
t.Fatalf("expected epoch expired error when getting, got %v", err)
143143
}
144144

@@ -156,7 +156,7 @@ func TestGetExpired(t *testing.T) {
156156
}
157157
}
158158

159-
func TestDelLeafNoExpired(t *testing.T) { // skipcq: GO-R1005
159+
func TestDelLeafNoExpired(t *testing.T) {
160160
t.Parallel()
161161

162162
root := New()
@@ -174,7 +174,7 @@ func TestDelLeafNoExpired(t *testing.T) { // skipcq: GO-R1005
174174
}
175175
}
176176

177-
func TestDelLeafExpired(t *testing.T) { // skipcq: GO-R1005
177+
func TestDelLeafExpired(t *testing.T) {
178178
t.Parallel()
179179

180180
root := New()
@@ -183,7 +183,7 @@ func TestDelLeafExpired(t *testing.T) { // skipcq: GO-R1005
183183
}
184184

185185
_, err := root.Delete(zeroKeyTest, 2, nil)
186-
if !errors.Is(err, errEpochExpired) {
186+
if !errors.Is(err, errExpired) {
187187
t.Fatalf("expected epoch expired error when deleting, got %v", err)
188188
}
189189

@@ -221,3 +221,23 @@ func TestRootCommitExpired(t *testing.T) {
221221
t.Fatalf("expected commitment to be %x, got %x", &init, comm)
222222
}
223223
}
224+
225+
func TestRootCommitDiffTimestamp(t *testing.T) {
226+
t.Parallel()
227+
228+
root1 := New()
229+
if err := root1.Insert(zeroKeyTest, testValue, 0, nil); err != nil {
230+
t.Fatalf("error inserting: %v", err)
231+
}
232+
comm1 := root1.Commit()
233+
234+
root2 := New()
235+
if err := root2.Insert(zeroKeyTest, testValue, 2, nil); err != nil {
236+
t.Fatalf("error inserting: %v", err)
237+
}
238+
comm2 := root2.Commit()
239+
240+
if comm1.Equal(comm2) {
241+
t.Fatalf("expected different commitments, got %x", comm1)
242+
}
243+
}

hashednode.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func (HashedNode) Commitment() *Point {
5858
panic("can not get commitment of a hash node")
5959
}
6060

61-
func (HashedNode) GetProofItems(keylist, NodeResolverFn) (*ProofElements, []byte, []Stem, error) {
61+
func (HashedNode) GetProofItems(keylist, AccessTimestamp, NodeResolverFn) (*ProofElements, []byte, []Stem, error) {
6262
return nil, nil, nil, errors.New("can not get the full path, and there is no proof of absence")
6363
}
6464

hashednode_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func TestHashedNodeFuncs(t *testing.T) {
4646
if v != nil {
4747
t.Fatal("non-nil get from a hashed node")
4848
}
49-
if _, _, _, err := e.GetProofItems(nil, nil); err == nil {
49+
if _, _, _, err := e.GetProofItems(nil, 0, nil); err == nil {
5050
t.Fatal("got nil error when getting proof items from a hashed node")
5151
}
5252
if _, err := e.Serialize(); err != errSerializeHashedNode {

0 commit comments

Comments
 (0)