diff --git a/storage/cache/log_tile.go b/storage/cache/log_tile.go index 356b7f9991..2def12312e 100644 --- a/storage/cache/log_tile.go +++ b/storage/cache/log_tile.go @@ -15,6 +15,7 @@ package cache import ( + "encoding/binary" "fmt" "github.com/google/trillian/merkle/compact" @@ -61,12 +62,7 @@ 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 } } @@ -74,15 +70,13 @@ func PopulateLogTile(st *storagepb.SubtreeProto, hasher hashers.LogHasher) error 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 { @@ -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() +} diff --git a/storage/cache/subtree_cache_test.go b/storage/cache/subtree_cache_test.go index a70e5b6752..2b6a764660 100644 --- a/storage/cache/subtree_cache_test.go +++ b/storage/cache/subtree_cache_test.go @@ -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<