Skip to content

Commit dd87e7f

Browse files
committed
fix stateless proof
1 parent fe3e25c commit dd87e7f

14 files changed

+306
-161
lines changed

empty.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func (Empty) Get([]byte, StatePeriod, NodeResolverFn) ([]byte, error) {
4343
return nil, nil
4444
}
4545

46-
func (Empty) Revive(Stem, [][]byte, StatePeriod, StatePeriod, NodeResolverFn) error {
46+
func (Empty) Revive(Stem, [][]byte, StatePeriod, StatePeriod, bool, NodeResolverFn) error {
4747
return errors.New("cannot revive an empty node")
4848
}
4949

@@ -57,8 +57,8 @@ func (Empty) Commitment() *Point {
5757
return &id
5858
}
5959

60-
func (Empty) GetProofItems(keylist, NodeResolverFn) (*ProofElements, []byte, []Stem, error) {
61-
return nil, nil, nil, errors.New("trying to produce a commitment for an empty subtree")
60+
func (Empty) GetProofItems(keylist, NodeResolverFn, StatePeriod) (*ProofElements, []byte, []Stem, []StatePeriod, error) {
61+
return nil, nil, nil, nil, errors.New("trying to produce a commitment for an empty subtree")
6262
}
6363

6464
func (Empty) Serialize() ([]byte, error) {

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, nil, period0); err == nil {
5555
t.Fatal("get proof items should error")
5656
}
5757

expired_leaf.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func (n *ExpiredLeafNode) Get([]byte, StatePeriod, NodeResolverFn) ([]byte, erro
5454
return nil, errExpired
5555
}
5656

57-
func (n *ExpiredLeafNode) Revive(Stem, [][]byte, StatePeriod, StatePeriod, NodeResolverFn) error {
57+
func (n *ExpiredLeafNode) Revive(Stem, [][]byte, StatePeriod, StatePeriod, bool, NodeResolverFn) error {
5858
return errors.New("cannot revive an expired leaf node directly")
5959
}
6060

@@ -69,7 +69,7 @@ func (n *ExpiredLeafNode) Commitment() *Point {
6969
return n.commitment
7070
}
7171

72-
func (n *ExpiredLeafNode) GetProofItems(keys keylist, resolver NodeResolverFn) (*ProofElements, []byte, []Stem, error) {
72+
func (n *ExpiredLeafNode) GetProofItems(keys keylist, resolver NodeResolverFn, _ StatePeriod) (*ProofElements, []byte, []Stem, []StatePeriod, error) {
7373
var (
7474
pe = &ProofElements{
7575
Vals: make([][]byte, len(keys)),
@@ -87,7 +87,7 @@ func (n *ExpiredLeafNode) GetProofItems(keys keylist, resolver NodeResolverFn) (
8787
poass = append(poass, n.stem)
8888
}
8989

90-
return pe, esses, poass, nil
90+
return pe, esses, poass, []StatePeriod{n.lastPeriod}, nil
9191
}
9292

9393
func (n *ExpiredLeafNode) Serialize() ([]byte, error) {

expired_tree_test.go

Lines changed: 127 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ func TestInsertSameLeafNoExpired(t *testing.T) {
1010
t.Parallel()
1111

1212
root := New()
13-
if err := root.Insert(zeroKeyTest, testValue, 0, nil); err != nil {
13+
if err := root.Insert(zeroKeyTest, testValue, period0, nil); err != nil {
1414
t.Fatalf("error inserting: %v", err)
1515
}
1616

17-
if err := root.Insert(oneKeyTest, testValue, 1, nil); err != nil {
17+
if err := root.Insert(oneKeyTest, testValue, period1, nil); err != nil {
1818
t.Fatalf("error inserting: %v", err)
1919
}
2020

@@ -31,7 +31,7 @@ func TestInsertSameLeafNoExpired(t *testing.T) {
3131
t.Fatalf("expected value %x, got %x", testValue, leaf.values[oneKeyTest[StemSize]])
3232
}
3333

34-
if leaf.lastPeriod != 1 {
34+
if leaf.lastPeriod != period1 {
3535
t.Fatalf("expected last accessed to be 1, got %d", leaf.lastPeriod)
3636
}
3737
}
@@ -40,11 +40,11 @@ func TestInsertSameLeafExpired(t *testing.T) {
4040
t.Parallel()
4141

4242
root := New()
43-
if err := root.Insert(zeroKeyTest, testValue, 0, nil); err != nil {
43+
if err := root.Insert(zeroKeyTest, testValue, period0, nil); err != nil {
4444
t.Fatalf("error inserting: %v", err)
4545
}
4646

47-
err := root.Insert(oneKeyTest, testValue, 2, nil)
47+
err := root.Insert(oneKeyTest, testValue, period2, nil)
4848
if !errors.Is(err, errExpired) {
4949
t.Fatalf("expected period expired error when inserting, got %v", err)
5050
}
@@ -58,7 +58,7 @@ func TestInsertSameLeafExpired(t *testing.T) {
5858
t.Fatalf("expected value %x, got %x", testValue, leaf.values[zeroKeyTest[StemSize]])
5959
}
6060

61-
if leaf.lastPeriod != 0 {
61+
if leaf.lastPeriod != period0 {
6262
t.Fatalf("expected last accessed to be 0, got %d", leaf.lastPeriod)
6363
}
6464
}
@@ -67,11 +67,11 @@ func TestInsertDiffLeaf(t *testing.T) {
6767
t.Parallel()
6868

6969
root := New()
70-
if err := root.Insert(zeroKeyTest, testValue, 0, nil); err != nil {
70+
if err := root.Insert(zeroKeyTest, testValue, period0, nil); err != nil {
7171
t.Fatalf("error inserting: %v", err)
7272
}
7373

74-
if err := root.Insert(ffx32KeyTest, testValue, 2, nil); err != nil {
74+
if err := root.Insert(ffx32KeyTest, testValue, period2, nil); err != nil {
7575
t.Fatalf("error inserting: %v", err)
7676
}
7777

@@ -93,24 +93,63 @@ func TestInsertDiffLeaf(t *testing.T) {
9393
t.Fatalf("expected value %x, got %x", testValue, leaff.values[ffx32KeyTest[StemSize]])
9494
}
9595

96-
if leaf0.lastPeriod != 0 {
96+
if leaf0.lastPeriod != period0 {
9797
t.Fatalf("expected last accessed to be 0, got %d", leaf0.lastPeriod)
9898
}
9999

100-
if leaff.lastPeriod != 2 {
100+
if leaff.lastPeriod != period2 {
101101
t.Fatalf("expected last accessed to be 2, got %d", leaff.lastPeriod)
102102
}
103103
}
104104

105+
func TestInsertExpiredLeafSibling(t *testing.T) {
106+
t.Parallel()
107+
108+
root := New()
109+
if err := root.Insert(zeroKeyTest, testValue, period0, nil); err != nil {
110+
t.Fatalf("error inserting: %v", err)
111+
}
112+
113+
leaf, ok := root.(*InternalNode).children[0].(*LeafNode)
114+
if !ok {
115+
t.Fatalf("expected leaf node, got %T", root.(*InternalNode).children[0])
116+
}
117+
118+
root.(*InternalNode).children[0] = NewExpiredLeafNode(leaf.stem, leaf.lastPeriod, leaf.commitment)
119+
120+
if err := root.Insert(forkOneKeyTest, testValue, period2, nil); err != nil {
121+
t.Fatalf("error inserting: %v", err)
122+
}
123+
124+
c1 := root.Commit()
125+
126+
// Reconstruct a new tree with the same key-values but without the expired leaf node
127+
root2 := New()
128+
if err := root2.Insert(zeroKeyTest, testValue, period0, nil); err != nil {
129+
t.Fatalf("error inserting: %v", err)
130+
}
131+
132+
if err := root2.Insert(forkOneKeyTest, testValue, period2, nil); err != nil {
133+
t.Fatalf("error inserting: %v", err)
134+
}
135+
136+
c2 := root2.Commit()
137+
138+
// The two trees should have the same commitment
139+
if !c1.Equal(c2) {
140+
t.Fatalf("expected commitment to be %x, got %x", c1, c2)
141+
}
142+
}
143+
105144
func TestGetNoExpired(t *testing.T) {
106145
t.Parallel()
107146

108147
root := New()
109-
if err := root.Insert(zeroKeyTest, testValue, 0, nil); err != nil {
148+
if err := root.Insert(zeroKeyTest, testValue, period0, nil); err != nil {
110149
t.Fatalf("error inserting: %v", err)
111150
}
112151

113-
val, err := root.Get(zeroKeyTest, 1, nil)
152+
val, err := root.Get(zeroKeyTest, period1, nil)
114153
if err != nil {
115154
t.Fatalf("error getting: %v", err)
116155
}
@@ -124,7 +163,7 @@ func TestGetNoExpired(t *testing.T) {
124163
t.Fatalf("expected value %x, got %x", testValue, val)
125164
}
126165

127-
if leaf.lastPeriod != 0 {
166+
if leaf.lastPeriod != period0 {
128167
t.Fatalf("expected last accessed to be 0, got %d", leaf.lastPeriod)
129168
}
130169
}
@@ -133,11 +172,11 @@ func TestGetExpired(t *testing.T) {
133172
t.Parallel()
134173

135174
root := New()
136-
if err := root.Insert(zeroKeyTest, testValue, 0, nil); err != nil {
175+
if err := root.Insert(zeroKeyTest, testValue, period0, nil); err != nil {
137176
t.Fatalf("error inserting: %v", err)
138177
}
139178

140-
val, err := root.Get(zeroKeyTest, 2, nil)
179+
val, err := root.Get(zeroKeyTest, period2, nil)
141180
if !errors.Is(err, errExpired) {
142181
t.Fatalf("expected period expired error when getting, got %v", err)
143182
}
@@ -151,7 +190,7 @@ func TestGetExpired(t *testing.T) {
151190
t.Fatalf("expected leaf node, got %T", root.(*InternalNode).children[0])
152191
}
153192

154-
if leaf.lastPeriod != 0 {
193+
if leaf.lastPeriod != period0 {
155194
t.Fatalf("expected last accessed to be 0, got %d", leaf.lastPeriod)
156195
}
157196
}
@@ -160,11 +199,11 @@ func TestDelLeafNoExpired(t *testing.T) {
160199
t.Parallel()
161200

162201
root := New()
163-
if err := root.Insert(zeroKeyTest, testValue, 0, nil); err != nil {
202+
if err := root.Insert(zeroKeyTest, testValue, period0, nil); err != nil {
164203
t.Fatalf("error inserting: %v", err)
165204
}
166205

167-
if _, err := root.Delete(zeroKeyTest, 1, nil); err != nil {
206+
if _, err := root.Delete(zeroKeyTest, period1, nil); err != nil {
168207
t.Fatalf("error deleting: %v", err)
169208
}
170209

@@ -178,11 +217,11 @@ func TestDelLeafExpired(t *testing.T) {
178217
t.Parallel()
179218

180219
root := New()
181-
if err := root.Insert(zeroKeyTest, testValue, 0, nil); err != nil {
220+
if err := root.Insert(zeroKeyTest, testValue, period0, nil); err != nil {
182221
t.Fatalf("error inserting: %v", err)
183222
}
184223

185-
_, err := root.Delete(zeroKeyTest, 2, nil)
224+
_, err := root.Delete(zeroKeyTest, period2, nil)
186225
if !errors.Is(err, errExpired) {
187226
t.Fatalf("expected period expired error when deleting, got %v", err)
188227
}
@@ -192,16 +231,80 @@ func TestDelLeafExpired(t *testing.T) {
192231
t.Fatalf("expected empty node, got %T", root.(*InternalNode).children[0])
193232
}
194233

195-
if leaf.lastPeriod != 0 {
234+
if leaf.lastPeriod != period0 {
196235
t.Fatalf("expected last accessed to be 0, got %d", leaf.lastPeriod)
197236
}
198237
}
199238

239+
func TestReviveExpired(t *testing.T) {
240+
t.Parallel()
241+
242+
root := New()
243+
if err := root.Insert(zeroKeyTest, testValue, period0, nil); err != nil {
244+
t.Fatalf("error inserting: %v", err)
245+
}
246+
247+
leaf, ok := root.(*InternalNode).children[0].(*LeafNode)
248+
if !ok {
249+
t.Fatalf("expected leaf node, got %T", root.(*InternalNode).children[0])
250+
}
251+
252+
expiredLeaf := NewExpiredLeafNode(leaf.stem, leaf.lastPeriod, leaf.commitment)
253+
root.(*InternalNode).children[0] = expiredLeaf
254+
255+
if err := root.Revive(leaf.stem, leaf.values, leaf.lastPeriod, period2, false, nil); err != nil {
256+
t.Fatalf("error reviving: %v", err)
257+
}
258+
259+
rLeaf, ok := root.(*InternalNode).children[0].(*LeafNode)
260+
if !ok {
261+
t.Fatalf("expected leaf node, got %T", root.(*InternalNode).children[0])
262+
}
263+
264+
if rLeaf.lastPeriod != period2 {
265+
t.Fatalf("expected last accessed to be 2, got %d", rLeaf.lastPeriod)
266+
}
267+
}
268+
269+
func TestReviveNoExpired(t *testing.T) {
270+
t.Parallel()
271+
272+
root := New()
273+
if err := root.Insert(zeroKeyTest, testValue, period0, nil); err != nil {
274+
t.Fatalf("error inserting: %v", err)
275+
}
276+
277+
leaf, ok := root.(*InternalNode).children[0].(*LeafNode)
278+
if !ok {
279+
t.Fatalf("expected leaf node, got %T", root.(*InternalNode).children[0])
280+
}
281+
282+
comm := root.Commit()
283+
284+
if err := root.Revive(leaf.stem, leaf.values, leaf.lastPeriod, period0, false, nil); err != nil {
285+
t.Fatalf("error reviving: %v", err)
286+
}
287+
288+
rLeaf, ok := root.(*InternalNode).children[0].(*LeafNode)
289+
if !ok {
290+
t.Fatalf("expected leaf node, got %T", root.(*InternalNode).children[0])
291+
}
292+
293+
if rLeaf.lastPeriod != period0 {
294+
t.Fatalf("expected last accessed to be 0, got %d", rLeaf.lastPeriod)
295+
}
296+
297+
rComm := root.Commit()
298+
if !rComm.Equal(comm) {
299+
t.Fatalf("expected commitment to be %x, got %x", comm, rComm)
300+
}
301+
}
302+
200303
func TestRootCommitExpired(t *testing.T) {
201304
t.Parallel()
202305

203306
root := New()
204-
if err := root.Insert(zeroKeyTest, testValue, 0, nil); err != nil {
307+
if err := root.Insert(zeroKeyTest, testValue, period0, nil); err != nil {
205308
t.Fatalf("error inserting: %v", err)
206309
}
207310

@@ -226,13 +329,13 @@ func TestRootCommitDiffEpoch(t *testing.T) {
226329
t.Parallel()
227330

228331
root1 := New()
229-
if err := root1.Insert(zeroKeyTest, testValue, 0, nil); err != nil {
332+
if err := root1.Insert(zeroKeyTest, testValue, period0, nil); err != nil {
230333
t.Fatalf("error inserting: %v", err)
231334
}
232335
comm1 := root1.Commit()
233336

234337
root2 := New()
235-
if err := root2.Insert(zeroKeyTest, testValue, 2, nil); err != nil {
338+
if err := root2.Insert(zeroKeyTest, testValue, period2, nil); err != nil {
236339
t.Fatalf("error inserting: %v", err)
237340
}
238341
comm2 := root2.Commit()

hashednode.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func (HashedNode) Get([]byte, StatePeriod, NodeResolverFn) ([]byte, error) {
4444
return nil, errors.New("can not read from a hash node")
4545
}
4646

47-
func (HashedNode) Revive(Stem, [][]byte, StatePeriod, StatePeriod, NodeResolverFn) error {
47+
func (HashedNode) Revive(Stem, [][]byte, StatePeriod, StatePeriod, bool, NodeResolverFn) error {
4848
return errors.New("cannot revive a hashed node")
4949
}
5050

@@ -62,8 +62,8 @@ func (HashedNode) Commitment() *Point {
6262
panic("can not get commitment of a hash node")
6363
}
6464

65-
func (HashedNode) GetProofItems(keylist, NodeResolverFn) (*ProofElements, []byte, []Stem, error) {
66-
return nil, nil, nil, errors.New("can not get the full path, and there is no proof of absence")
65+
func (HashedNode) GetProofItems(keylist, NodeResolverFn, StatePeriod) (*ProofElements, []byte, []Stem, []StatePeriod, error) {
66+
return nil, nil, nil, nil, errors.New("can not get the full path, and there is no proof of absence")
6767
}
6868

6969
func (HashedNode) Serialize() ([]byte, error) {

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, nil, period0); err == nil {
5050
t.Fatal("got nil error when getting proof items from a hashed node")
5151
}
5252
if _, err := e.Serialize(); err != errSerializeHashedNode {

period.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ type StatePeriod uint16
88

99
const (
1010
NumActiveEpochs = 2
11-
period0 = 0
11+
period0 = StatePeriod(0)
12+
period1 = StatePeriod(1)
13+
period2 = StatePeriod(2)
1214
)
1315

1416
func IsExpired(prev, cur StatePeriod) bool {

0 commit comments

Comments
 (0)