@@ -49,7 +49,7 @@ func Inclusion(index, size uint64) (Nodes, error) {
4949 if index >= size {
5050 return Nodes {}, fmt .Errorf ("index %d out of bounds for tree size %d" , index , size )
5151 }
52- return nodes (index , 0 , size ), nil
52+ return nodes (index , 0 , size ). skipFirst () , nil
5353}
5454
5555// Consistency returns the information on how to fetch and construct a
@@ -72,22 +72,10 @@ func Consistency(size1, size2 uint64) (Nodes, error) {
7272 // into this node in the tree of size2.
7373 p := nodes (index , level , size2 )
7474
75- // Handle the case when size1 is not a power of 2.
76- if index != 0 {
77- // Prepend the earlier computed node to the proof.
78- // TODO(pavelkalinnikov): This code path is invoked almost always. Avoid
79- // the extra allocation that append does.
80- p .IDs = append (p .IDs , compact.NodeID {})
81- copy (p .IDs [1 :], p .IDs )
82- p .IDs [0 ] = compact .NewNodeID (level , index )
83-
84- // Fixup the indices into the IDs slice.
85- if p .begin < p .end {
86- p .begin ++
87- p .end ++
88- }
75+ // Handle the case when size1 is a power of 2.
76+ if index == 0 {
77+ return p .skipFirst (), nil
8978 }
90-
9179 return p , nil
9280}
9381
@@ -111,15 +99,16 @@ func nodes(index uint64, level uint, size uint64) Nodes {
11199 left := compact .RangeSize (0 , begin )
112100 right := compact .RangeSize (end , size )
113101
102+ node := compact .NewNodeID (level , index )
114103 // Pre-allocate the exact number of nodes for the proof, in order:
104+ // - The seed node for which we are building the proof.
115105 // - The `inner` nodes at each level up to the fork node.
116106 // - The `right` nodes, comprising the ephemeral node.
117107 // - The `left` nodes, completing the coverage of the whole [0, size) range.
118- nodes := make ([]compact.NodeID , 0 , inner + right + left )
108+ nodes := append ( make ([]compact.NodeID , 0 , 1 + inner + right + left ), node )
119109
120110 // The first portion of the proof consists of the siblings for nodes of the
121111 // path going up to the level at which the ephemeral node appears.
122- node := compact .NewNodeID (level , index )
123112 for ; node .Level < fork .Level ; node = node .Parent () {
124113 nodes = append (nodes , node .Sibling ())
125114 }
@@ -146,7 +135,7 @@ func nodes(index uint64, level uint, size uint64) Nodes {
146135 len1 , len2 = 0 , 0
147136 }
148137
149- return Nodes {IDs : nodes , begin : len1 , end : len2 , ephem : node .Sibling ()}
138+ return Nodes {IDs : nodes , begin : len1 , end : len2 , ephem : fork .Sibling ()}
150139}
151140
152141// Ephem returns the ephemeral node, and indices begin and end, such that
@@ -186,6 +175,16 @@ func (n Nodes) Rehash(h [][]byte, hc func(left, right []byte) []byte) ([][]byte,
186175 return h [:cursor ], nil
187176}
188177
178+ func (n Nodes ) skipFirst () Nodes {
179+ n .IDs = n .IDs [1 :]
180+ // Fixup the indices into the IDs slice.
181+ if n .begin < n .end {
182+ n .begin --
183+ n .end --
184+ }
185+ return n
186+ }
187+
189188func reverse (ids []compact.NodeID ) {
190189 for i , j := 0 , len (ids )- 1 ; i < j ; i , j = i + 1 , j - 1 {
191190 ids [i ], ids [j ] = ids [j ], ids [i ]
0 commit comments