@ -73,7 +73,7 @@ var (
// Tree defines the struct that implements the MerkleTree functionalities
type Tree struct {
sync . RW Mutex
sync . Mutex
db db . Database
maxLevels int
@ -659,11 +659,12 @@ func (t *Tree) GenProofWithTx(rTx db.ReadTx, k []byte) ([]byte, []byte, []byte,
}
// PackSiblings packs the siblings into a byte array.
// [ 1 byte | L bytes | S * N bytes ]
// [ bitmap length (L) | bitmap | N non-zero siblings ]
// [ 2 byte | 2 byte | L bytes | S * N bytes ]
// [ full length | bitmap length (L) | bitmap | N non-zero siblings ]
// Where the bitmap indicates if the sibling is 0 or a value from the siblings
// array. And S is the size of the output of the hash function used for the
// Tree.
// Tree. The 2 2-byte that define the full length and bitmap length, are
// encoded in little-endian.
func PackSiblings ( hashFunc HashFunction , siblings [ ] [ ] byte ) [ ] byte {
var b [ ] byte
var bitmap [ ] bool
@ -680,19 +681,28 @@ func PackSiblings(hashFunc HashFunction, siblings [][]byte) []byte {
bitmapBytes := bitmapToBytes ( bitmap )
l := len ( bitmapBytes )
res := make ( [ ] byte , l + 1 + len ( b ) )
res [ 0 ] = byte ( l ) // set the bitmapBytes length
copy ( res [ 1 : 1 + l ] , bitmapBytes )
copy ( res [ 1 + l : ] , b )
fullLen := 4 + l + len ( b ) //nolint:gomnd
res := make ( [ ] byte , fullLen )
binary . LittleEndian . PutUint16 ( res [ 0 : 2 ] , uint16 ( fullLen ) ) // set full length
binary . LittleEndian . PutUint16 ( res [ 2 : 4 ] , uint16 ( l ) ) // set the bitmapBytes length
copy ( res [ 4 : 4 + l ] , bitmapBytes )
copy ( res [ 4 + l : ] , b )
return res
}
// UnpackSiblings unpacks the siblings from a byte array.
func UnpackSiblings ( hashFunc HashFunction , b [ ] byte ) ( [ ] [ ] byte , error ) {
l := b [ 0 ]
bitmapBytes := b [ 1 : 1 + l ]
fullLen := binary . LittleEndian . Uint16 ( b [ 0 : 2 ] )
l := binary . LittleEndian . Uint16 ( b [ 2 : 4 ] ) // bitmap bytes length
if len ( b ) != int ( fullLen ) {
return nil ,
fmt . Errorf ( "error unpacking siblings. Expected len: %d, current len: %d" ,
fullLen , len ( b ) )
}
bitmapBytes := b [ 4 : 4 + l ]
bitmap := bytesToBitmap ( bitmapBytes )
siblingsBytes := b [ 1 + l : ]
siblingsBytes := b [ 4 + l : ]
iSibl := 0
emptySibl := make ( [ ] byte , hashFunc . Len ( ) )
var siblings [ ] [ ] byte
@ -845,9 +855,6 @@ func (t *Tree) GetNLeafsWithTx(rTx db.ReadTx) (int, error) {
// Snapshot returns a read-only copy of the Tree from the given root
func ( t * Tree ) Snapshot ( fromRoot [ ] byte ) ( * Tree , error ) {
t . RLock ( )
defer t . RUnlock ( )
// allow to define which root to use
if fromRoot == nil {
var err error