Skip to content
Permalink
Browse files

Tracker Factory for dependency injection (#1327)

* Tracker Factory for dependency injection

Allow callers of NewFromConfig to supply a tracker factory.

* Factory documentation

* tracker.New -> NewSynchronous
  • Loading branch information...
gdbelvin committed Jul 19, 2019
1 parent f3ee35a commit 3c05089a642c48dbccc4d1c6512d7132afc08605
@@ -25,6 +25,8 @@ import (
"time"

"github.com/google/keytransparency/core/client"
"github.com/google/keytransparency/core/client/tracker"
"github.com/google/keytransparency/core/client/verifier"
"github.com/google/keytransparency/impl/authentication"

"github.com/google/trillian"
@@ -39,6 +41,7 @@ import (
"google.golang.org/grpc/credentials/oauth"

pb "github.com/google/keytransparency/core/api/v1/keytransparency_go_proto"
tclient "github.com/google/trillian/client"
)

var (
@@ -219,7 +222,9 @@ func GetClient(ctx context.Context) (*client.Client, error) {
return nil, fmt.Errorf("config: %v", err)
}

return client.NewFromConfig(ktCli, config)
return client.NewFromConfig(ktCli, config,
func(lv *tclient.LogVerifier) verifier.LogTracker { return tracker.NewSynchronous(lv) },
)
}

// config selects a source for and returns the client configuration.
@@ -114,8 +114,9 @@ type Client struct {
}

// NewFromConfig creates a new client from a config
func NewFromConfig(ktClient pb.KeyTransparencyClient, config *pb.Directory) (*Client, error) {
ktVerifier, err := verifier.NewFromDirectory(config)
func NewFromConfig(ktClient pb.KeyTransparencyClient, config *pb.Directory,
trackerFactory verifier.LogTrackerFactory) (*Client, error) {
ktVerifier, err := verifier.NewFromDirectory(config, trackerFactory)
if err != nil {
return nil, err
}
@@ -29,12 +29,15 @@ import (

"github.com/google/keytransparency/core/client"
"github.com/google/keytransparency/core/client/multi"
"github.com/google/keytransparency/core/client/tracker"
"github.com/google/keytransparency/core/client/verifier"

"github.com/benlaurie/objecthash/go/objecthash"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"

pb "github.com/google/keytransparency/core/api/v1/keytransparency_go_proto"
tclient "github.com/google/trillian/client"
)

var (
@@ -107,7 +110,9 @@ func AddKtServer(ktURL string, insecureTLS bool, ktTLSCertPEM []byte, directoryI
}
}

client, err := client.NewFromConfig(ktClient, config)
client, err := client.NewFromConfig(ktClient, config,
func(lv *tclient.LogVerifier) verifier.LogTracker { return tracker.NewSynchronous(lv) },
)
if err != nil {
return fmt.Errorf("error adding the KtServer: %v", err)
}
@@ -28,8 +28,11 @@ import (
"google.golang.org/grpc"

"github.com/google/keytransparency/core/client"
"github.com/google/keytransparency/core/client/tracker"
"github.com/google/keytransparency/core/client/verifier"

pb "github.com/google/keytransparency/core/api/v1/keytransparency_go_proto"
tclient "github.com/google/trillian/client"
)

// DialFunc returns a connected grpc client for Key Transparency.
@@ -200,7 +203,9 @@ func (h *Hammer) newWorkers(n int) ([]worker, error) {
workers := make([]worker, 0, n)
for i := 0; i < n; i++ {
// Give each worker its own client.
client, err := client.NewFromConfig(h.ktCli, h.directory)
client, err := client.NewFromConfig(h.ktCli, h.directory,
func(lv *tclient.LogVerifier) verifier.LogTracker { return tracker.NewSynchronous(lv) },
)
if err != nil {
return nil, err
}
@@ -46,8 +46,8 @@ type LogTracker struct {
mu sync.RWMutex
}

// New creates a log tracker from no trusted root.
func New(lv LogRootVerifier) *LogTracker {
// NewSynchronous creates a log tracker from no trusted root.
func NewSynchronous(lv LogRootVerifier) *LogTracker {
return NewFromSaved(lv, types.LogRootV1{})
}

@@ -28,7 +28,6 @@ import (
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

"github.com/google/keytransparency/core/client/tracker"
"github.com/google/keytransparency/core/crypto/commitments"
"github.com/google/keytransparency/core/crypto/vrf"
"github.com/google/keytransparency/core/crypto/vrf/p256"
@@ -53,6 +52,10 @@ type LogTracker interface {
VerifyLogRoot(state *pb.LogRootRequest, newRoot *pb.LogRoot) (*types.LogRootV1, error)
}

// LogTrackerFactory allows the caller of NewFromDirectory to supply different
// tracker implementations. eg. no-op, single-synchronous-head, and multi-head tracking.
type LogTrackerFactory func(*tclient.LogVerifier) LogTracker

// Verifier is a client helper library for verifying requests and responses.
type Verifier struct {
vrf vrf.PublicKey
@@ -77,7 +80,7 @@ func New(vrf vrf.PublicKey,
}

// NewFromDirectory creates a new instance of the client verifier from a config.
func NewFromDirectory(config *pb.Directory) (*Verifier, error) {
func NewFromDirectory(config *pb.Directory, f LogTrackerFactory) (*Verifier, error) {
logVerifier, err := tclient.NewLogVerifierFromTree(config.GetLog())
if err != nil {
return nil, err
@@ -94,7 +97,9 @@ func NewFromDirectory(config *pb.Directory) (*Verifier, error) {
return nil, fmt.Errorf("error parsing vrf public key: %v", err)
}

return New(vrfPubKey, mapVerifier, logVerifier, tracker.New(logVerifier)), nil
tracker := f(logVerifier)

return New(vrfPubKey, mapVerifier, logVerifier, tracker), nil
}

// Index computes the index from a VRF proof.
@@ -22,6 +22,7 @@ import (
"github.com/google/trillian/types"

tpb "github.com/google/keytransparency/core/testdata/transcript_go_proto"
tclient "github.com/google/trillian/client"
)

// Test vectors in core/testdata are generated by running
@@ -43,7 +44,9 @@ func TestTranscripts(t *testing.T) {
func RunTranscriptTest(t *testing.T, transcript *tpb.Transcript) {
t.Helper()

v, err := NewFromDirectory(transcript.Directory)
v, err := NewFromDirectory(transcript.Directory,
func(lv *tclient.LogVerifier) LogTracker { return tracker.NewSynchronous(lv) },
)
if err != nil {
t.Fatal(err)
}
@@ -23,11 +23,9 @@ import (
"testing"
"time"

"github.com/golang/protobuf/ptypes"
"github.com/google/keytransparency/core/client"
"github.com/google/keytransparency/core/client/tracker"
"github.com/google/keytransparency/core/client/verifier"
"github.com/google/keytransparency/core/crypto/vrf/p256"
"github.com/google/keytransparency/core/sequencer"
"github.com/google/keytransparency/core/testutil"
"github.com/google/trillian/types"
@@ -171,48 +169,23 @@ func TestBatchUpdate(ctx context.Context, env *Env, t *testing.T) []*tpb.Action
return nil
}

func NewClientWithTracker(t *testing.T, env *Env) (*client.Client, *tracker.LogTracker) {
t.Helper()

config := env.Directory
logVerifier, err := tclient.NewLogVerifierFromTree(config.GetLog())
if err != nil {
t.Fatal(err)
}

mapVerifier, err := tclient.NewMapVerifierFromTree(config.GetMap())
if err != nil {
t.Fatal(err)
}

// VRF key
vrfPubKey, err := p256.NewVRFVerifierFromRawKey(config.GetVrf().GetDer())
if err != nil {
t.Fatal(err)
}

logTracker := tracker.New(logVerifier)

verifier := verifier.New(vrfPubKey, mapVerifier, logVerifier, logTracker)

minInterval, err := ptypes.Duration(config.MinInterval)
if err != nil {
t.Fatal(err)
}

cli := client.New(env.Cli, config.DirectoryId, minInterval, verifier)
return cli, logTracker
}

// TestEmptyGetAndUpdate verifies set/get semantics.
func TestEmptyGetAndUpdate(ctx context.Context, env *Env, t *testing.T) []*tpb.Action {
go runSequencer(ctx, t, env.Directory.DirectoryId, env)

cli, logTracker := NewClientWithTracker(t, env)
logTracker.SetUpdatePredicate(func(_, newRoot types.LogRootV1) bool {
// Only update occasionally in order to produce interesting consistency proofs.
return newRoot.TreeSize%5 == 1
})
cli, err := client.NewFromConfig(env.Cli, env.Directory,
func(lv *tclient.LogVerifier) verifier.LogTracker {
t := tracker.NewSynchronous(lv)
t.SetUpdatePredicate(func(_, newRoot types.LogRootV1) bool {
// Only update occasionally in order to produce interesting consistency proofs.
return newRoot.TreeSize%5 == 1
})
return t
},
)
if err != nil {
t.Fatal(err)
}

// Create lists of signers.
signers1 := testutil.SignKeysetsFromPEMs(testPrivKey1)
@@ -353,11 +326,19 @@ func TestBatchGetUser(ctx context.Context, env *Env, t *testing.T) []*tpb.Action
authorizedKeys1 := testutil.VerifyKeysetFromPEMs(testPubKey1)
transcript := []*tpb.Action{}

cli, logTracker := NewClientWithTracker(t, env)
logTracker.SetUpdatePredicate(func(_, newRoot types.LogRootV1) bool {
// Only update occasionally in order to produce interesting consistency proofs.
return newRoot.TreeSize%5 == 1
})
cli, err := client.NewFromConfig(env.Cli, env.Directory,
func(lv *tclient.LogVerifier) verifier.LogTracker {
t := tracker.NewSynchronous(lv)
t.SetUpdatePredicate(func(_, newRoot types.LogRootV1) bool {
// Only update occasionally in order to produce interesting consistency proofs.
return newRoot.TreeSize%5 == 1
})
return t
},
)
if err != nil {
t.Fatal(err)
}

users := []*client.User{
{
@@ -21,6 +21,8 @@ import (

"github.com/golang/glog"
"github.com/google/keytransparency/core/client"
"github.com/google/keytransparency/core/client/tracker"
"github.com/google/keytransparency/core/client/verifier"
"github.com/google/keytransparency/core/monitorstorage"
"github.com/google/trillian"
"github.com/google/trillian/types"
@@ -49,7 +51,9 @@ func NewFromDirectory(cli pb.KeyTransparencyClient,
return nil, fmt.Errorf("could not initialize map verifier: %v", err)
}

ktClient, err := client.NewFromConfig(cli, config)
ktClient, err := client.NewFromConfig(cli, config,
func(lv *tclient.LogVerifier) verifier.LogTracker { return tracker.NewSynchronous(lv) },
)
if err != nil {
return nil, fmt.Errorf("could not create kt client: %v", err)
}
@@ -31,6 +31,8 @@ import (

"github.com/google/keytransparency/core/adminserver"
"github.com/google/keytransparency/core/client"
"github.com/google/keytransparency/core/client/tracker"
"github.com/google/keytransparency/core/client/verifier"
"github.com/google/keytransparency/core/integration"
"github.com/google/keytransparency/core/keyserver"
"github.com/google/keytransparency/core/mutator/entry"
@@ -46,6 +48,7 @@ import (

pb "github.com/google/keytransparency/core/api/v1/keytransparency_go_proto"
spb "github.com/google/keytransparency/core/sequencer/sequencer_go_proto"
tclient "github.com/google/trillian/client"
ttest "github.com/google/trillian/testonly/integration"

_ "github.com/google/trillian/merkle/coniks" // Register hasher
@@ -198,7 +201,9 @@ func NewEnv(ctx context.Context) (*Env, error) {
go gsvr.Serve(lis)

ktClient := pb.NewKeyTransparencyClient(cc)
client, err := client.NewFromConfig(ktClient, directoryPB)
client, err := client.NewFromConfig(ktClient, directoryPB,
func(lv *tclient.LogVerifier) verifier.LogTracker { return tracker.NewSynchronous(lv) },
)
if err != nil {
return nil, fmt.Errorf("error reading config: %v", err)
}

0 comments on commit 3c05089

Please sign in to comment.
You can’t perform that action at this time.