aboutsummaryrefslogtreecommitdiff
path: root/sth.go
diff options
context:
space:
mode:
authorRasmus Dahlberg <rasmus.dahlberg@kau.se>2021-02-25 14:36:35 +0100
committerRasmus Dahlberg <rasmus.dahlberg@kau.se>2021-02-25 14:36:35 +0100
commitc05c22ddbc771e7713849cae40f9d91bfafa0503 (patch)
treeb97d11ab2a914806e6f671f9aff1cab9767b2eab /sth.go
parentc9b4b43654f0ff26207cc63449f13298cd3c56e8 (diff)
major refactor based on README.md and TODOs
Updated types, improved units tests, isolated most test data to have it in one place, renamed and created new files to improve readability, and fixed a bunch of minor TODOs.
Diffstat (limited to 'sth.go')
-rw-r--r--sth.go90
1 files changed, 49 insertions, 41 deletions
diff --git a/sth.go b/sth.go
index 58b5c35..30ba965 100644
--- a/sth.go
+++ b/sth.go
@@ -9,21 +9,22 @@ import (
"github.com/golang/glog"
"github.com/google/certificate-transparency-go/schedule"
"github.com/google/trillian"
- "github.com/google/trillian/types"
+ ttypes "github.com/google/trillian/types"
+ "github.com/system-transparency/stfe/types"
)
// SthSource provides access to the log's STHs.
type SthSource interface {
// Latest returns the most reccent signed_tree_head_v*.
- Latest(context.Context) (*StItem, error)
+ Latest(context.Context) (*types.StItem, error)
// Stable returns the most recent signed_tree_head_v* that is stable for
// some period of time, e.g., 10 minutes.
- Stable(context.Context) (*StItem, error)
+ Stable(context.Context) (*types.StItem, error)
// Cosigned returns the most recent cosigned_tree_head_v*.
- Cosigned(context.Context) (*StItem, error)
+ Cosigned(context.Context) (*types.StItem, error)
// AddCosignature attempts to add a cosignature to the stable STH. The
// passed cosigned_tree_head_v* must have a single verified cosignature.
- AddCosignature(context.Context, *StItem) error
+ AddCosignature(context.Context, *types.StItem) error
// Run keeps the STH source updated until cancelled
Run(context.Context)
}
@@ -33,9 +34,9 @@ type SthSource interface {
type ActiveSthSource struct {
client trillian.TrillianLogClient
logParameters *LogParameters
- currCosth *StItem // current cosigned_tree_head_v1 (already finalized)
- nextCosth *StItem // next cosigned_tree_head_v1 (under preparation)
- cosignatureFrom map[string]bool // track who we got cosignatures from in nextCosth
+ currCosth *types.StItem // current cosigned_tree_head_v1 (already finalized)
+ nextCosth *types.StItem // next cosigned_tree_head_v1 (under preparation)
+ cosignatureFrom map[[types.NamespaceFingerprintSize]byte]bool // track who we got cosignatures from in nextCosth
mutex sync.RWMutex
}
@@ -51,10 +52,11 @@ func NewActiveSthSource(cli trillian.TrillianLogClient, lp *LogParameters) (*Act
if err != nil {
return nil, fmt.Errorf("Latest: %v", err)
}
+
// TODO: load persisted cosigned STH?
- s.currCosth = NewCosignedTreeHeadV1(sth.SignedTreeHeadV1, nil)
- s.nextCosth = NewCosignedTreeHeadV1(sth.SignedTreeHeadV1, nil)
- s.cosignatureFrom = make(map[string]bool)
+ s.currCosth = types.NewCosignedTreeHeadV1(sth.SignedTreeHeadV1, nil)
+ s.nextCosth = types.NewCosignedTreeHeadV1(sth.SignedTreeHeadV1, nil)
+ s.cosignatureFrom = make(map[[types.NamespaceFingerprintSize]byte]bool)
return &s, nil
}
@@ -70,78 +72,84 @@ func (s *ActiveSthSource) Run(ctx context.Context) {
// rotate
s.mutex.Lock()
defer s.mutex.Unlock()
- s.rotate(sth)
+ if err := s.rotate(sth); err != nil {
+ glog.Warningf("rotate failed: %v", err)
+ }
// TODO: persist cosigned STH?
})
}
-func (s *ActiveSthSource) Latest(ctx context.Context) (*StItem, error) {
+func (s *ActiveSthSource) Latest(ctx context.Context) (*types.StItem, error) {
trsp, err := s.client.GetLatestSignedLogRoot(ctx, &trillian.GetLatestSignedLogRootRequest{
LogId: s.logParameters.TreeId,
})
- var lr types.LogRootV1
+ var lr ttypes.LogRootV1
if errInner := checkGetLatestSignedLogRoot(s.logParameters, trsp, err, &lr); errInner != nil {
return nil, fmt.Errorf("invalid signed log root response: %v", errInner)
}
- return s.logParameters.genV1Sth(NewTreeHeadV1(&lr))
+ return s.logParameters.SignTreeHeadV1(NewTreeHeadV1FromLogRoot(&lr))
}
-func (s *ActiveSthSource) Stable(_ context.Context) (*StItem, error) {
+func (s *ActiveSthSource) Stable(_ context.Context) (*types.StItem, error) {
s.mutex.RLock()
defer s.mutex.RUnlock()
if s.nextCosth == nil {
return nil, fmt.Errorf("no stable sth available")
}
- return &StItem{
- Format: StFormatSignedTreeHeadV1,
- SignedTreeHeadV1: &s.nextCosth.CosignedTreeHeadV1.SignedTreeHeadV1,
- }, nil
+ return types.NewSignedTreeHeadV1(&s.nextCosth.CosignedTreeHeadV1.SignedTreeHead.TreeHead, &s.nextCosth.CosignedTreeHeadV1.SignedTreeHead.Signature), nil
}
-func (s *ActiveSthSource) Cosigned(_ context.Context) (*StItem, error) {
+func (s *ActiveSthSource) Cosigned(_ context.Context) (*types.StItem, error) {
s.mutex.RLock()
defer s.mutex.RUnlock()
- if s.currCosth == nil || len(s.currCosth.CosignedTreeHeadV1.SignatureV1) == 0 {
+ if s.currCosth == nil || len(s.currCosth.CosignedTreeHeadV1.Cosignatures) == 0 {
return nil, fmt.Errorf("no cosigned sth available")
}
return s.currCosth, nil
}
-func (s *ActiveSthSource) AddCosignature(_ context.Context, costh *StItem) error {
+func (s *ActiveSthSource) AddCosignature(_ context.Context, costh *types.StItem) error {
s.mutex.Lock()
defer s.mutex.Unlock()
- if !reflect.DeepEqual(s.nextCosth.CosignedTreeHeadV1.SignedTreeHeadV1, costh.CosignedTreeHeadV1.SignedTreeHeadV1) {
+ if !reflect.DeepEqual(s.nextCosth.CosignedTreeHeadV1.SignedTreeHead, costh.CosignedTreeHeadV1.SignedTreeHead) {
return fmt.Errorf("cosignature covers a different tree head")
}
- witness := costh.CosignedTreeHeadV1.SignatureV1[0].Namespace.String()
- if _, ok := s.cosignatureFrom[witness]; ok {
+ witness, err := costh.CosignedTreeHeadV1.Cosignatures[0].Namespace.Fingerprint()
+ if err != nil {
+ return fmt.Errorf("namespace without fingerprint: %v", err)
+ }
+ if _, ok := s.cosignatureFrom[*witness]; ok {
return nil // duplicate
}
- s.cosignatureFrom[witness] = true
- s.nextCosth.CosignedTreeHeadV1.SignatureV1 = append(s.nextCosth.CosignedTreeHeadV1.SignatureV1, costh.CosignedTreeHeadV1.SignatureV1[0])
+ s.cosignatureFrom[*witness] = true
+ s.nextCosth.CosignedTreeHeadV1.Cosignatures = append(s.nextCosth.CosignedTreeHeadV1.Cosignatures, costh.CosignedTreeHeadV1.Cosignatures[0])
return nil
}
// rotate rotates the log's cosigned and stable STH. The caller must aquire the
// source's read-write lock if there are concurrent reads and/or writes.
-func (s *ActiveSthSource) rotate(fixedSth *StItem) {
+func (s *ActiveSthSource) rotate(fixedSth *types.StItem) error {
// rotate stable -> cosigned
- if reflect.DeepEqual(&s.currCosth.CosignedTreeHeadV1.SignedTreeHeadV1, &s.nextCosth.CosignedTreeHeadV1.SignedTreeHeadV1) {
- for _, sigv1 := range s.currCosth.CosignedTreeHeadV1.SignatureV1 {
- witness := sigv1.Namespace.String()
- if _, ok := s.cosignatureFrom[witness]; !ok {
- s.cosignatureFrom[witness] = true
- s.nextCosth.CosignedTreeHeadV1.SignatureV1 = append(s.nextCosth.CosignedTreeHeadV1.SignatureV1, sigv1)
+ if reflect.DeepEqual(&s.currCosth.CosignedTreeHeadV1.SignedTreeHead, &s.nextCosth.CosignedTreeHeadV1.SignedTreeHead) {
+ for _, sigv1 := range s.currCosth.CosignedTreeHeadV1.Cosignatures {
+ witness, err := sigv1.Namespace.Fingerprint()
+ if err != nil {
+ return fmt.Errorf("namespace without fingerprint: %v", err)
+ }
+ if _, ok := s.cosignatureFrom[*witness]; !ok {
+ s.cosignatureFrom[*witness] = true
+ s.nextCosth.CosignedTreeHeadV1.Cosignatures = append(s.nextCosth.CosignedTreeHeadV1.Cosignatures, sigv1)
}
}
}
- s.currCosth.CosignedTreeHeadV1.SignedTreeHeadV1 = s.nextCosth.CosignedTreeHeadV1.SignedTreeHeadV1
- s.currCosth.CosignedTreeHeadV1.SignatureV1 = make([]SignatureV1, len(s.nextCosth.CosignedTreeHeadV1.SignatureV1))
- copy(s.currCosth.CosignedTreeHeadV1.SignatureV1, s.nextCosth.CosignedTreeHeadV1.SignatureV1)
+ s.currCosth.CosignedTreeHeadV1.SignedTreeHead = s.nextCosth.CosignedTreeHeadV1.SignedTreeHead
+ s.currCosth.CosignedTreeHeadV1.Cosignatures = make([]types.SignatureV1, len(s.nextCosth.CosignedTreeHeadV1.Cosignatures))
+ copy(s.currCosth.CosignedTreeHeadV1.Cosignatures, s.nextCosth.CosignedTreeHeadV1.Cosignatures)
// rotate new stable -> stable
- if !reflect.DeepEqual(&s.nextCosth.CosignedTreeHeadV1.SignedTreeHeadV1, fixedSth.SignedTreeHeadV1) {
- s.nextCosth = NewCosignedTreeHeadV1(fixedSth.SignedTreeHeadV1, nil)
- s.cosignatureFrom = make(map[string]bool)
+ if !reflect.DeepEqual(&s.nextCosth.CosignedTreeHeadV1.SignedTreeHead, fixedSth.SignedTreeHeadV1) {
+ s.nextCosth = types.NewCosignedTreeHeadV1(fixedSth.SignedTreeHeadV1, nil)
+ s.cosignatureFrom = make(map[[types.NamespaceFingerprintSize]byte]bool)
}
+ return nil
}