Skip to content

Commit eaf6ab9

Browse files
committed
Refactor FindSubtrees to return (Subtree, Subtree, error) directly
Update FindSubtrees in proof/proof.go to return two Subtree structs by value instead of allocating a []Subtree slice. TAG=agy CONV=1f76bf92-7d8b-43a5-942a-a4bd88025626
1 parent 6ffb78f commit eaf6ab9

3 files changed

Lines changed: 23 additions & 25 deletions

File tree

proof/proof.go

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -285,15 +285,15 @@ type Subtree struct {
285285
// - If the provided subtree has a size <= 1, then this function returns that subtree and an empty subtree.
286286
// - If the provided [start, end) range is already a valid subtree, then it is still split into two smaller subtrees.
287287
// - The 2nd subtree, if not empty, is adjacent to the first, and may not be a perfect subtree.
288-
// - The returned subtree(s) fully cover the [start, end) range.
288+
// - The returned subtrees fully cover the [start, end) range.
289289
// - There are no "extra" entries covered past end, but there may be covered entries prior to start.
290290
// - The number of entries covered before start is always less than half the size of the first returned subtree.
291-
func FindSubtrees(start, end uint64) ([]Subtree, error) {
291+
func FindSubtrees(start, end uint64) (Subtree, Subtree, error) {
292292
if start > end {
293-
return nil, fmt.Errorf("start %d must be less than or equal to end %d", start, end)
293+
return Subtree{}, Subtree{}, fmt.Errorf("start %d must be less than or equal to end %d", start, end)
294294
}
295295
if end-start <= 1 {
296-
return []Subtree{{Start: start, End: end}, {Start: end, End: end}}, nil
296+
return Subtree{Start: start, End: end}, Subtree{Start: end, End: end}, nil
297297
}
298298
last := end - 1
299299
// Find where start and last's tree paths diverge.
@@ -304,10 +304,7 @@ func FindSubtrees(start, end uint64) ([]Subtree, error) {
304304
// Maximize the left endpoint.
305305
leftSplit := bits.Len64(^start & mask)
306306
leftStart := start & ^((uint64(1) << leftSplit) - 1)
307-
return []Subtree{
308-
{Start: leftStart, End: mid},
309-
{Start: mid, End: end},
310-
}, nil
307+
return Subtree{Start: leftStart, End: mid}, Subtree{Start: mid, End: end}, nil
311308
}
312309

313310
// isSubtreeValid returns whether a subtree covers a valid range.

proof/proof_test.go

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -825,25 +825,26 @@ func inclusion(t *testing.T, index, size uint64) Nodes {
825825
func TestFindSubtrees(t *testing.T) {
826826
for _, tc := range []struct {
827827
start, end uint64
828-
want []Subtree
828+
wantLeft Subtree
829+
wantRight Subtree
829830
wantErr bool
830831
}{
831-
// Already-valid subtrees are returned as-is.
832832
// Single entry subtrees:
833-
{start: 0, end: 1, want: []Subtree{{Start: 0, End: 1}, {Start: 1, End: 1}}},
834-
{start: 3, end: 4, want: []Subtree{{Start: 3, End: 4}, {Start: 4, End: 4}}},
833+
{start: 0, end: 1, wantLeft: Subtree{Start: 0, End: 1}, wantRight: Subtree{Start: 1, End: 1}},
834+
{start: 3, end: 4, wantLeft: Subtree{Start: 3, End: 4}, wantRight: Subtree{Start: 4, End: 4}},
835835
// Perfectly aligned subtrees:
836-
{start: 4, end: 6, want: []Subtree{{Start: 4, End: 5}, {Start: 5, End: 6}}},
837-
{start: 16, end: 32, want: []Subtree{{Start: 16, End: 24}, {Start: 24, End: 32}}},
836+
{start: 4, end: 6, wantLeft: Subtree{Start: 4, End: 5}, wantRight: Subtree{Start: 5, End: 6}},
837+
{start: 16, end: 32, wantLeft: Subtree{Start: 16, End: 24}, wantRight: Subtree{Start: 24, End: 32}},
838838
// Non-perfect trees are split into two:
839-
{start: 5, end: 13, want: []Subtree{{Start: 4, End: 8}, {Start: 8, End: 13}}},
840-
{start: 7, end: 9, want: []Subtree{{Start: 7, End: 8}, {Start: 8, End: 9}}},
839+
{start: 5, end: 13, wantLeft: Subtree{Start: 4, End: 8}, wantRight: Subtree{Start: 8, End: 13}},
840+
{start: 7, end: 9, wantLeft: Subtree{Start: 7, End: 8}, wantRight: Subtree{Start: 8, End: 9}},
841+
// Empty subtrees.
842+
{start: 5, end: 5, wantLeft: Subtree{Start: 5, End: 5}, wantRight: Subtree{Start: 5, End: 5}},
841843
// Invalid inputs:
842-
{start: 5, end: 5, want: []Subtree{{Start: 5, End: 5}, {Start: 5, End: 5}}},
843844
{start: 6, end: 5, wantErr: true},
844845
} {
845846
t.Run(fmt.Sprintf("%d:%d", tc.start, tc.end), func(t *testing.T) {
846-
got, err := FindSubtrees(tc.start, tc.end)
847+
gotLeft, gotRight, err := FindSubtrees(tc.start, tc.end)
847848
if tc.wantErr {
848849
if err == nil {
849850
t.Fatal("expected error, got nil")
@@ -853,8 +854,11 @@ func TestFindSubtrees(t *testing.T) {
853854
if err != nil {
854855
t.Fatalf("FindSubtrees: %v", err)
855856
}
856-
if diff := cmp.Diff(tc.want, got); diff != "" {
857-
t.Errorf("FindSubtrees mismatch (-want +got):\n%s", diff)
857+
if diff := cmp.Diff(tc.wantLeft, gotLeft); diff != "" {
858+
t.Errorf("FindSubtrees left mismatch (-want +got):\n%s", diff)
859+
}
860+
if diff := cmp.Diff(tc.wantRight, gotRight); diff != "" {
861+
t.Errorf("FindSubtrees right mismatch (-want +got):\n%s", diff)
858862
}
859863
})
860864
}

testonly/vectors_test.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,11 @@ func TestSubtreeCoveringVectors(t *testing.T) {
130130
h := sha256.New()
131131
for end := range subtreeVectorMax + 1 {
132132
for start := range end + 1 {
133-
subtrees, err := proof.FindSubtrees(start, end)
133+
left, right, err := proof.FindSubtrees(start, end)
134134
if err != nil {
135135
t.Fatalf("FindSubtrees(%d, %d): %v", start, end, err)
136136
}
137-
if l := len(subtrees); l != 2 {
138-
t.Fatalf("FindSubtrees(%d, %d) returned unexpected number of subtrees: %d", start, end, l)
139-
}
140-
if _, err := fmt.Fprintf(h, "[%d, %d) [%d, %d)\n", subtrees[0].Start, subtrees[0].End, subtrees[1].Start, subtrees[1].End); err != nil {
137+
if _, err := fmt.Fprintf(h, "[%d, %d) [%d, %d)\n", left.Start, left.End, right.Start, right.End); err != nil {
141138
t.Fatalf("fmt.Fprintf: %v", err)
142139
}
143140
}

0 commit comments

Comments
 (0)