You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
86 lines
2.7 KiB
86 lines
2.7 KiB
// Package testkit builds DateKeys test material: known Quicknet releases,
|
|
// offline release sources, capsules with arbitrary structural defects, and age
|
|
// files with edited headers whose MAC is still valid.
|
|
//
|
|
// It is internal and exists for tests and fixture generation only.
|
|
package testkit
|
|
|
|
import (
|
|
"context"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"time"
|
|
|
|
datekeys "g.activething.com/go/DateKeys"
|
|
"g.activething.com/go/DateKeys/profile"
|
|
"g.activething.com/go/DateKeys/provider"
|
|
)
|
|
|
|
// Published Quicknet signatures. They are public data obtained from drand
|
|
// relays; tests never trust them blindly but verify them with provider.Verify
|
|
// against the pinned public key.
|
|
var signatures = map[uint64]string{
|
|
1000: "b44679b9a59af2ec876b1a6b1ad52ea9b1615fc3982b19576350f93447cb1125e342b73a8dd2bacbe47e4b6b63ed5e39",
|
|
1001: "b33bf3667cbd5a82de3a24b4e0e9fe5513cc1a0e840368c6e31f5fcfa79bea03f73896b25883abf2853d10337fb8fa41",
|
|
2000: "b6cb8f482a0b15d45936a4c4ea08e98a087e71787caee3f4d07a8a9843b1bc5423c6b3c22f446488b3137eaca799c77e",
|
|
}
|
|
|
|
// Rounds with a known release, in increasing order.
|
|
var Rounds = []uint64{1000, 1001, 2000}
|
|
|
|
// Release returns the published release of round; it panics for rounds
|
|
// without a known signature.
|
|
func Release(round uint64) provider.Release {
|
|
s, ok := signatures[round]
|
|
if !ok {
|
|
panic(fmt.Sprintf("testkit: no known release for round %d", round))
|
|
}
|
|
b, err := hex.DecodeString(s)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return provider.Release{Round: round, Signature: b}
|
|
}
|
|
|
|
// Source serves the given releases by round and reports every other round as
|
|
// unavailable. It counts the requests it receives.
|
|
type Source struct {
|
|
Releases map[uint64]provider.Release
|
|
Calls int
|
|
}
|
|
|
|
// NewSource returns a Source with the given releases.
|
|
func NewSource(releases ...provider.Release) *Source {
|
|
s := &Source{Releases: map[uint64]provider.Release{}}
|
|
for _, r := range releases {
|
|
s.Releases[r.Round] = r
|
|
}
|
|
return s
|
|
}
|
|
|
|
// Fetch implements provider.ReleaseSource.
|
|
func (s *Source) Fetch(_ context.Context, _ *profile.Profile, c provider.Condition) (provider.Release, error) {
|
|
s.Calls++
|
|
r, ok := s.Releases[c.Round]
|
|
if !ok {
|
|
return provider.Release{}, fmt.Errorf("testkit: round %d: %w", c.Round, datekeys.ErrReleaseUnavailable)
|
|
}
|
|
return r, nil
|
|
}
|
|
|
|
// Fixed returns a clock stopped at t.
|
|
func Fixed(t time.Time) func() time.Time { return func() time.Time { return t } }
|
|
|
|
// Genesis returns the Quicknet genesis instant, a convenient "now" for
|
|
// encrypting to rounds that are already published.
|
|
func Genesis() time.Time { return time.Unix(profile.QuicknetGenesisTime, 0).UTC() }
|
|
|
|
// Registry returns the default registry or panics.
|
|
func Registry() profile.Registry {
|
|
r, err := profile.Default()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return r
|
|
}
|