Skip to content
Snippets Groups Projects
Unverified Commit befbcc04 authored by Lily Sturmann's avatar Lily Sturmann Committed by GitHub
Browse files

Require tlog_id when inactive shard config file is passed in (#739)


tlog_id specifes the active shard and is kept for backwards compatibility.
To avoid replicating information, the shard config file is used only to
specify inactive shards and must be used in conjunction with a tlog_id flag.
Together, these build the logRanges type in the sharding module.

Signed-off-by: default avatarLily Sturmann <lsturman@redhat.com>
parent 4a34ec50
No related branches found
No related tags found
No related merge requests found
...@@ -106,7 +106,7 @@ var serveCmd = &cobra.Command{ ...@@ -106,7 +106,7 @@ var serveCmd = &cobra.Command{
// Update logRangeMap if flag was passed in // Update logRangeMap if flag was passed in
shardingConfig := viper.GetString("trillian_log_server.sharding_config") shardingConfig := viper.GetString("trillian_log_server.sharding_config")
treeID := viper.GetString("trillian_log_server.tlog_id") treeID := viper.GetUint("trillian_log_server.tlog_id")
ranges, err := sharding.NewLogRanges(shardingConfig, treeID) ranges, err := sharding.NewLogRanges(shardingConfig, treeID)
if err != nil { if err != nil {
......
...@@ -87,8 +87,7 @@ func NewAPI(ranges sharding.LogRanges) (*API, error) { ...@@ -87,8 +87,7 @@ func NewAPI(ranges sharding.LogRanges) (*API, error) {
} }
tLogID = t.TreeId tLogID = t.TreeId
} }
// append the active treeID to the API's logRangeMap for lookups ranges.SetActive(tLogID)
ranges.AppendRange(sharding.LogRange{TreeID: tLogID})
rekorSigner, err := signer.New(ctx, viper.GetString("rekor_server.signer")) rekorSigner, err := signer.New(ctx, viper.GetString("rekor_server.signer"))
if err != nil { if err != nil {
......
...@@ -42,7 +42,7 @@ func GetLogInfoHandler(params tlog.GetLogInfoParams) middleware.Responder { ...@@ -42,7 +42,7 @@ func GetLogInfoHandler(params tlog.GetLogInfoParams) middleware.Responder {
// for each inactive shard, get the loginfo // for each inactive shard, get the loginfo
var inactiveShards []*models.InactiveShardLogInfo var inactiveShards []*models.InactiveShardLogInfo
for _, shard := range tc.ranges.GetRanges() { for _, shard := range tc.ranges.GetInactive() {
if shard.TreeID == tc.ranges.ActiveTreeID() { if shard.TreeID == tc.ranges.ActiveTreeID() {
break break
} }
......
...@@ -16,18 +16,28 @@ package sharding ...@@ -16,18 +16,28 @@ package sharding
// VirtualLogIndex returns the virtual log index for a given leaf index // VirtualLogIndex returns the virtual log index for a given leaf index
func VirtualLogIndex(leafIndex int64, tid int64, ranges LogRanges) int64 { func VirtualLogIndex(leafIndex int64, tid int64, ranges LogRanges) int64 {
// if we have no ranges, we have just one log! return the leafIndex as is // if we have no inactive ranges, we have just one log! return the leafIndex as is
if ranges.Empty() { // as long as it matches the active tree ID
return leafIndex if ranges.NoInactive() {
if ranges.GetActive() == tid {
return leafIndex
}
return -1
} }
var virtualIndex int64 var virtualIndex int64
for _, r := range ranges.GetRanges() { for _, r := range ranges.GetInactive() {
if r.TreeID == tid { if r.TreeID == tid {
return virtualIndex + leafIndex return virtualIndex + leafIndex
} }
virtualIndex += r.TreeLength virtualIndex += r.TreeLength
} }
// this should never happen
// If no TreeID in Inactive matches the tid, the virtual index should be the active tree
if ranges.GetActive() == tid {
return virtualIndex + leafIndex
}
// Otherwise, the tid is invalid
return -1 return -1
} }
...@@ -33,50 +33,48 @@ func TestVirtualLogIndex(t *testing.T) { ...@@ -33,50 +33,48 @@ func TestVirtualLogIndex(t *testing.T) {
expectedIndex: 5, expectedIndex: 5,
}, },
// Log 100: 0 1 2 3 4 // Log 100: 0 1 2 3 4
// Log 300: 5 6 7 // Log 300: 5 6 7...
{ {
description: "two shards", description: "two shards",
leafIndex: 2, leafIndex: 2,
tid: 300, tid: 300,
ranges: LogRanges{ ranges: LogRanges{
ranges: []LogRange{ inactive: []LogRange{
{ {
TreeID: 100, TreeID: 100,
TreeLength: 5, TreeLength: 5,
}, { }},
TreeID: 300, active: 300,
},
},
}, },
expectedIndex: 7, expectedIndex: 7,
}, { },
// Log 100: 0 1 2 3 4
// Log 300: 5 6 7 8
// Log 400: ...
{
description: "three shards", description: "three shards",
leafIndex: 1, leafIndex: 1,
tid: 300, tid: 300,
ranges: LogRanges{ ranges: LogRanges{
ranges: []LogRange{ inactive: []LogRange{
{ {
TreeID: 100, TreeID: 100,
TreeLength: 5, TreeLength: 5,
}, { }, {
TreeID: 300, TreeID: 300,
TreeLength: 4, TreeLength: 4,
}, { }},
TreeID: 400, active: 400,
},
},
}, },
expectedIndex: 6, expectedIndex: 6,
}, { },
description: "ranges is empty but not-nil", // Log 30: 1 2 3...
{
description: "only active tree",
leafIndex: 2, leafIndex: 2,
tid: 30, tid: 30,
ranges: LogRanges{ ranges: LogRanges{
ranges: []LogRange{ active: 30,
{
TreeID: 30,
},
},
}, },
expectedIndex: 2, expectedIndex: 2,
}, { }, {
...@@ -84,11 +82,7 @@ func TestVirtualLogIndex(t *testing.T) { ...@@ -84,11 +82,7 @@ func TestVirtualLogIndex(t *testing.T) {
leafIndex: 2, leafIndex: 2,
tid: 4, tid: 4,
ranges: LogRanges{ ranges: LogRanges{
ranges: []LogRange{ active: 30,
{
TreeID: 30,
},
},
}, },
expectedIndex: -1, expectedIndex: -1,
}, },
......
...@@ -18,7 +18,6 @@ package sharding ...@@ -18,7 +18,6 @@ package sharding
import ( import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"strconv"
"strings" "strings"
"github.com/ghodss/yaml" "github.com/ghodss/yaml"
...@@ -26,7 +25,8 @@ import ( ...@@ -26,7 +25,8 @@ import (
) )
type LogRanges struct { type LogRanges struct {
ranges Ranges inactive Ranges
active int64
} }
type Ranges []LogRange type Ranges []LogRange
...@@ -36,13 +36,12 @@ type LogRange struct { ...@@ -36,13 +36,12 @@ type LogRange struct {
TreeLength int64 `yaml:"treeLength"` TreeLength int64 `yaml:"treeLength"`
} }
func NewLogRanges(path string, treeID string) (LogRanges, error) { func NewLogRanges(path string, treeID uint) (LogRanges, error) {
if path == "" { if path == "" {
return LogRanges{}, nil return LogRanges{}, nil
} }
id, err := strconv.Atoi(treeID) if treeID == 0 {
if err != nil { return LogRanges{}, errors.New("non-zero tlog_id required when passing in shard config filepath; please set the active tree ID via the `--trillian_log_server.tlog_id` flag")
return LogRanges{}, errors.Wrapf(err, "%s is not a valid int64", treeID)
} }
// otherwise, try to read contents of the sharding config // otherwise, try to read contents of the sharding config
var ranges Ranges var ranges Ranges
...@@ -53,59 +52,68 @@ func NewLogRanges(path string, treeID string) (LogRanges, error) { ...@@ -53,59 +52,68 @@ func NewLogRanges(path string, treeID string) (LogRanges, error) {
if err := yaml.Unmarshal(contents, &ranges); err != nil { if err := yaml.Unmarshal(contents, &ranges); err != nil {
return LogRanges{}, err return LogRanges{}, err
} }
ranges = append(ranges, LogRange{TreeID: int64(id)})
return LogRanges{ return LogRanges{
ranges: ranges, inactive: ranges,
active: int64(treeID),
}, nil }, nil
} }
func (l *LogRanges) ResolveVirtualIndex(index int) (int64, int64) { func (l *LogRanges) ResolveVirtualIndex(index int) (int64, int64) {
indexLeft := index indexLeft := index
for _, l := range l.ranges { for _, l := range l.inactive {
if indexLeft < int(l.TreeLength) { if indexLeft < int(l.TreeLength) {
return l.TreeID, int64(indexLeft) return l.TreeID, int64(indexLeft)
} }
indexLeft -= int(l.TreeLength) indexLeft -= int(l.TreeLength)
} }
// Return the last one! // If index not found in inactive trees, return the active tree
return l.ranges[len(l.ranges)-1].TreeID, int64(indexLeft) return l.active, int64(indexLeft)
} }
// ActiveTreeID returns the active shard index, always the last shard in the range
func (l *LogRanges) ActiveTreeID() int64 { func (l *LogRanges) ActiveTreeID() int64 {
return l.ranges[len(l.ranges)-1].TreeID return l.active
} }
func (l *LogRanges) Empty() bool { func (l *LogRanges) NoInactive() bool {
return l.ranges == nil return l.inactive == nil
} }
// TotalLength returns the total length across all shards // TotalInactiveLength returns the total length across all inactive shards;
func (l *LogRanges) TotalLength() int64 { // we don't know the length of the active shard.
func (l *LogRanges) TotalInactiveLength() int64 {
var total int64 var total int64
for _, r := range l.ranges { for _, r := range l.inactive {
total += r.TreeLength total += r.TreeLength
} }
return total return total
} }
func (l *LogRanges) SetRanges(r []LogRange) { func (l *LogRanges) SetInactive(r []LogRange) {
l.ranges = r l.inactive = r
}
func (l *LogRanges) GetInactive() []LogRange {
return l.inactive
}
func (l *LogRanges) AppendInactive(r LogRange) {
l.inactive = append(l.inactive, r)
} }
func (l *LogRanges) GetRanges() []LogRange { func (l *LogRanges) SetActive(i int64) {
return l.ranges l.active = i
} }
func (l *LogRanges) AppendRange(r LogRange) { func (l *LogRanges) GetActive() int64 {
l.ranges = append(l.ranges, r) return l.active
} }
func (l *LogRanges) String() string { func (l *LogRanges) String() string {
ranges := []string{} ranges := []string{}
for _, r := range l.ranges { for _, r := range l.inactive {
ranges = append(ranges, fmt.Sprintf("%d=%d", r.TreeID, r.TreeLength)) ranges = append(ranges, fmt.Sprintf("%d=%d", r.TreeID, r.TreeLength))
} }
ranges = append(ranges, fmt.Sprintf("active=%d", l.active))
return strings.Join(ranges, ",") return strings.Join(ranges, ",")
} }
...@@ -32,19 +32,17 @@ func TestNewLogRanges(t *testing.T) { ...@@ -32,19 +32,17 @@ func TestNewLogRanges(t *testing.T) {
if err := ioutil.WriteFile(file, []byte(contents), 0644); err != nil { if err := ioutil.WriteFile(file, []byte(contents), 0644); err != nil {
t.Fatal(err) t.Fatal(err)
} }
treeID := "45" treeID := uint(45)
expected := LogRanges{ expected := LogRanges{
ranges: []LogRange{ inactive: []LogRange{
{ {
TreeID: 1, TreeID: 1,
TreeLength: 3, TreeLength: 3,
}, { }, {
TreeID: 2, TreeID: 2,
TreeLength: 4, TreeLength: 4,
}, { }},
TreeID: 45, active: int64(45),
},
},
} }
got, err := NewLogRanges(file, treeID) got, err := NewLogRanges(file, treeID)
if err != nil { if err != nil {
...@@ -53,19 +51,18 @@ func TestNewLogRanges(t *testing.T) { ...@@ -53,19 +51,18 @@ func TestNewLogRanges(t *testing.T) {
if expected.ActiveTreeID() != got.ActiveTreeID() { if expected.ActiveTreeID() != got.ActiveTreeID() {
t.Fatalf("expected tree id %d got %d", expected.ActiveTreeID(), got.ActiveTreeID()) t.Fatalf("expected tree id %d got %d", expected.ActiveTreeID(), got.ActiveTreeID())
} }
if !reflect.DeepEqual(expected.GetRanges(), got.GetRanges()) { if !reflect.DeepEqual(expected.GetInactive(), got.GetInactive()) {
t.Fatalf("expected %v got %v", expected.GetRanges(), got.GetRanges()) t.Fatalf("expected %v got %v", expected.GetInactive(), got.GetInactive())
} }
} }
func TestLogRanges_ResolveVirtualIndex(t *testing.T) { func TestLogRanges_ResolveVirtualIndex(t *testing.T) {
lrs := LogRanges{ lrs := LogRanges{
ranges: []LogRange{ inactive: []LogRange{
{TreeID: 1, TreeLength: 17}, {TreeID: 1, TreeLength: 17},
{TreeID: 2, TreeLength: 1}, {TreeID: 2, TreeLength: 1},
{TreeID: 3, TreeLength: 100}, {TreeID: 3, TreeLength: 100}},
{TreeID: 4}, active: 4,
},
} }
for _, tt := range []struct { for _, tt := range []struct {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment