-
Notifications
You must be signed in to change notification settings - Fork 107
/
api.go
95 lines (74 loc) · 3.08 KB
/
api.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// Package api implements the Oasis timekeeping API and common types.
package api
import (
"context"
"fmt"
"github.com/oasisprotocol/oasis-core/go/common/pubsub"
"github.com/oasisprotocol/oasis-core/go/oasis-node/cmd/common/flags"
)
// ModuleName is a unique module name for the epochtime module.
const ModuleName = "epochtime"
// EpochTime is the number of intervals (epochs) since a fixed instant
// in time (epoch date).
type EpochTime uint64
// EpochInvalid is the placeholder invalid epoch.
const EpochInvalid EpochTime = 0xffffffffffffffff // ~50 quadrillion years away.
// Backend is a timekeeping implementation.
type Backend interface {
// GetBaseEpoch returns the base epoch.
GetBaseEpoch(context.Context) (EpochTime, error)
// GetEpoch returns the epoch number at the specified block height.
// Calling this method with height `0`, should return the
// epoch of latest known block.
GetEpoch(context.Context, int64) (EpochTime, error)
// GetEpochBlock returns the block height at the start of the said
// epoch.
GetEpochBlock(context.Context, EpochTime) (int64, error)
// WatchEpochs returns a channel that produces a stream of messages
// on epoch transitions.
//
// Upon subscription the current epoch is sent immediately.
WatchEpochs() (<-chan EpochTime, *pubsub.Subscription)
// WatchLatestEpoch returns a channel that produces a stream of messages on
// epoch transitions. If an epoch transition hapens before previous epoch
// is read from channel, the old epochs is overwritten.
//
// Upon subscription the current epoch is sent immediately.
WatchLatestEpoch() (<-chan EpochTime, *pubsub.Subscription)
// StateToGenesis returns the genesis state at the specified block height.
StateToGenesis(ctx context.Context, height int64) (*Genesis, error)
}
// SetableBackend is a Backend that supports setting the current epoch.
type SetableBackend interface {
Backend
// SetEpoch sets the current epoch.
SetEpoch(context.Context, EpochTime) error
}
// Genesis is the initial genesis state for allowing configurable timekeeping.
type Genesis struct {
// Parameters are the epochtime consensus parameters.
Parameters ConsensusParameters `json:"params"`
// Base is the starting epoch.
Base EpochTime `json:"base"`
}
// ConsensusParameters are the epochtime consensus parameters.
type ConsensusParameters struct {
// Interval is the epoch interval (in blocks).
Interval int64 `json:"interval"`
// DebugMockBackend is flag for enabling mock epochtime backend.
DebugMockBackend bool `json:"debug_mock_backend,omitempty"`
}
// SanityCheck does basic sanity checking on the genesis state.
func (g *Genesis) SanityCheck() error {
unsafeFlags := g.Parameters.DebugMockBackend
if unsafeFlags && !flags.DebugDontBlameOasis() {
return fmt.Errorf("epochtime: sanity check failed: one or more unsafe debug flags set")
}
if g.Parameters.Interval <= 0 && !g.Parameters.DebugMockBackend {
return fmt.Errorf("epochtime: sanity check failed: epoch interval must be > 0")
}
if g.Base == EpochInvalid {
return fmt.Errorf("epochtime: sanity check failed: starting epoch is invalid")
}
return nil
}