Skip to content

Commit

Permalink
Convert compact.NodeID to Suffix directly
Browse files Browse the repository at this point in the history
  • Loading branch information
pav-kv committed Mar 13, 2021
1 parent 74e8305 commit 9ee2417
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 27 deletions.
25 changes: 13 additions & 12 deletions storage/cache/log_tile.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package cache

import (
"encoding/binary"
"fmt"

"github.com/google/trillian/merkle/compact"
Expand Down Expand Up @@ -61,28 +62,21 @@ func PopulateLogTile(st *storagepb.SubtreeProto, hasher hashers.LogHasher) error
// Don't put leaves into the internal map and only update if we're rebuilding internal
// nodes. If the subtree was saved with internal nodes then we don't touch the map.
if id.Level > 0 && len(st.Leaves) == maxLeaves {
subDepth := logStrataDepth - int(id.Level)
// TODO(Martin2112): See if we can possibly avoid the expense hiding inside NewNodeIDFromPrefix.
nodeID := tree.NewNodeIDFromPrefix(st.Prefix, subDepth, int64(id.Index), logStrataDepth, maxLogDepth)
sfx := nodeID.Suffix(len(st.Prefix), int(st.Depth))
sfxKey := sfx.String()
st.InternalNodes[sfxKey] = hash
st.InternalNodes[toSuffix(id)] = hash
}
}

fact := compact.RangeFactory{Hash: hasher.HashChildren}
cr := fact.NewEmptyRange(0)

// We need to update the subtree root hash regardless of whether it's fully populated
for leafIndex := int64(0); leafIndex < int64(len(st.Leaves)); leafIndex++ {
nodeID := tree.NewNodeIDFromPrefix(st.Prefix, logStrataDepth, leafIndex, logStrataDepth, maxLogDepth)
sfx := nodeID.Suffix(len(st.Prefix), int(st.Depth))
sfxKey := sfx.String()
for leafIndex := uint64(0); leafIndex < uint64(len(st.Leaves)); leafIndex++ {
sfxKey := toSuffix(compact.NewNodeID(0, leafIndex))
h := st.Leaves[sfxKey]
if h == nil {
return fmt.Errorf("unexpectedly got nil for subtree leaf suffix %s", sfx)
return fmt.Errorf("unexpectedly got nil for subtree leaf suffix %s", sfxKey)
}
if size, expected := int64(cr.End()), leafIndex; size != expected {
if size, expected := cr.End(), leafIndex; size != expected {
return fmt.Errorf("got size of %d, but expected %d", size, expected)
}
if err := cr.Append(h, store); err != nil {
Expand Down Expand Up @@ -135,3 +129,10 @@ func prepareLogTile(st *storagepb.SubtreeProto) error {
}
return nil
}

func toSuffix(id compact.NodeID) string {
depth := logStrataDepth - int(id.Level)
var index [8]byte
binary.BigEndian.PutUint64(index[:], id.Index<<(maxLogDepth-depth))
return tree.NewSuffix(uint8(depth), index[:]).String()
}
8 changes: 2 additions & 6 deletions storage/cache/subtree_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,7 @@ func TestRepopulateLogSubtree(t *testing.T) {
t.Fatalf("merkle tree update failed: %v", err)
}

nodeID := tree.NewNodeIDFromPrefix(s.Prefix, logStrataDepth, numLeaves-1, logStrataDepth, maxLogDepth)
_, sfx := nodeID.Split(len(s.Prefix), int(s.Depth))
sfxKey := sfx.String()
sfxKey := toSuffix(compact.NewNodeID(0, uint64(numLeaves)-1))
s.Leaves[sfxKey] = leafHash
if numLeaves == 1<<uint(defaultLogStrata[0]) {
s.InternalNodeCount = uint32(len(cmtStorage.InternalNodes))
Expand Down Expand Up @@ -285,9 +283,7 @@ func BenchmarkRepopulateLogSubtree(b *testing.B) {
for i := 0; i < 256; i++ {
leaf := []byte(fmt.Sprintf("leaf %d", i))
hash := hasher.HashLeaf(leaf)
nodeID := tree.NewNodeIDFromPrefix(s.Prefix, logStrataDepth, int64(i), logStrataDepth, maxLogDepth)
_, sfx := nodeID.Split(len(s.Prefix), int(s.Depth))
s.Leaves[sfx.String()] = hash
s.Leaves[toSuffix(compact.NewNodeID(0, uint64(i)))] = hash
}

for n := 0; n < b.N; n++ {
Expand Down
20 changes: 11 additions & 9 deletions storage/tree/suffix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,21 @@ func TestParseSuffix(t *testing.T) {

func TestSplitParseSuffixRoundtrip(t *testing.T) {
for _, tc := range []struct {
prefix []byte
leafIndex int64
wantPath []byte
prefix []byte
index int64
level int
wantPath []byte
}{
// Because we're using logStrataDepth below we'll always get a one byte
// suffix path.
{h2b(""), 1, h2b("01")},
{h2b("00"), 1, h2b("01")},
{h2b("abcd"), 99, h2b("63")},
{h2b("98765432"), 27, h2b("1b")},
{h2b("12345678"), 253, h2b("fd")},
{prefix: h2b(""), index: 1, wantPath: h2b("01")},
{prefix: h2b("00"), index: 1, wantPath: h2b("01")},
{prefix: h2b("00"), level: 4, index: 10, wantPath: h2b("a0")},
{prefix: h2b("abcd"), index: 99, wantPath: h2b("63")},
{prefix: h2b("98765432"), index: 27, wantPath: h2b("1b")},
{prefix: h2b("12345678"), index: 253, wantPath: h2b("fd")},
} {
nodeID := NewNodeIDFromPrefix(tc.prefix, logStrataDepth, tc.leafIndex, logStrataDepth, maxLogDepth)
nodeID := NewNodeIDFromPrefix(tc.prefix, logStrataDepth-tc.level, tc.index, logStrataDepth, maxLogDepth)
sfx := nodeID.Suffix(len(tc.prefix), logStrataDepth)
sfxKey := sfx.String()

Expand Down

0 comments on commit 9ee2417

Please sign in to comment.