Documentation ¶
Index ¶
- Constants
- Variables
- func InvalidStateChange(from, to Status) error
- func ValidateProposal(currentState *DBState, terms *drand.ProposalTerms) error
- type BeaconIdentifier
- type BoltStore
- func (s *BoltStore) Close() error
- func (s *BoltStore) GetCurrent(beaconID string) (*DBState, error)
- func (s *BoltStore) GetFinished(beaconID string) (*DBState, error)
- func (s *BoltStore) MigrateFromGroupfile(beaconID string, groupFile *key.Group, share *key.Share) error
- func (s *BoltStore) NukeState(beaconID string) error
- func (s *BoltStore) SaveCurrent(beaconID string, state *DBState) error
- func (s *BoltStore) SaveFinished(beaconID string, state *DBState) error
- type Broadcast
- type Config
- type DBState
- func (d *DBState) Aborted(metadata *drand.GossipMetadata) (*DBState, error)
- func (d *DBState) Accepted(me *drand.Participant) (*DBState, error)
- func (d *DBState) Apply(me *drand.Participant, packet *drand.GossipPacket) (*DBState, error)
- func (d *DBState) Complete(finalGroup *key.Group, share *key.Share) (*DBState, error)
- func (d *DBState) Equals(e *DBState) bool
- func (d *DBState) Executing(me *drand.Participant, metadata *drand.GossipMetadata) (*DBState, error)
- func (d *DBState) Failed() (*DBState, error)
- func (d *DBState) Joined(me *drand.Participant, previousGroup *key.Group) (*DBState, error)
- func (d *DBState) Left(me *drand.Participant) (*DBState, error)
- func (d *DBState) Proposed(me *drand.Participant, terms *drand.ProposalTerms, ...) (*DBState, error)
- func (d *DBState) Proposing(me *drand.Participant, terms *drand.ProposalTerms) (*DBState, error)
- func (d *DBState) ReceivedAcceptance(them *drand.Participant, metadata *drand.GossipMetadata) (*DBState, error)
- func (d *DBState) ReceivedRejection(them *drand.Participant, metadata *drand.GossipMetadata) (*DBState, error)
- func (d *DBState) Rejected(me *drand.Participant) (*DBState, error)
- func (d *DBState) StartAbort() (*DBState, error)
- func (d *DBState) StartExecuting(me *drand.Participant) (*DBState, error)
- func (d *DBState) TOML() DBStateTOML
- func (d *DBState) TimedOut() (*DBState, error)
- type DBStateTOML
- type ExecutionOutput
- type Process
- func (d *Process) BroadcastDKG(ctx context.Context, packet *drand.DKGPacket) (*drand.EmptyDKGResponse, error)
- func (d *Process) Close()
- func (d *Process) Command(ctx context.Context, command *drand.DKGCommand) (*drand.EmptyDKGResponse, error)
- func (d *Process) DKGStatus(ctx context.Context, request *drand.DKGStatusRequest) (*drand.DKGStatusResponse, error)
- func (d *Process) Migrate(beaconID string, groupfile *key.Group, share *key.Share) error
- func (d *Process) Packet(ctx context.Context, packet *drand.GossipPacket) (*drand.EmptyDKGResponse, error)
- func (d *Process) StartAbort(ctx context.Context, beaconID string, current *DBState, _ *drand.AbortOptions) (*DBState, *drand.GossipPacket, error)
- func (d *Process) StartAccept(ctx context.Context, beaconID string, me *drand.Participant, state *DBState, ...) (*DBState, *drand.GossipPacket, error)
- func (d *Process) StartExecute(ctx context.Context, beaconID string, me *drand.Participant, state *DBState, ...) (*DBState, *drand.GossipPacket, error)
- func (d *Process) StartJoin(ctx context.Context, beaconID string, me *drand.Participant, state *DBState, ...) (*DBState, *drand.GossipPacket, error)
- func (d *Process) StartNetwork(ctx context.Context, beaconID string, me *drand.Participant, state *DBState, ...) (*DBState, *drand.GossipPacket, error)
- func (d *Process) StartProposal(ctx context.Context, beaconID string, me *drand.Participant, ...) (*DBState, *drand.GossipPacket, error)
- func (d *Process) StartReject(ctx context.Context, beaconID string, me *drand.Participant, state *DBState, ...) (*DBState, *drand.GossipPacket, error)
- type SharingOutput
- type Status
- type Store
- type TestRunner
- func (r *TestRunner) Abort() error
- func (r *TestRunner) Accept() error
- func (r *TestRunner) JoinDKG() error
- func (r *TestRunner) JoinReshare(oldGroup *key.Group) error
- func (r *TestRunner) StartExecution() error
- func (r *TestRunner) StartNetwork(threshold int, period int, schemeID string, timeout time.Duration, ...) error
- func (r *TestRunner) StartReshare(threshold int, catchupPeriod int, joiners []*drand.Participant, ...) error
- func (r *TestRunner) WaitForDKG(lg log.Logger, epoch uint32, numberOfSeconds int) error
Constants ¶
const BoltFileName = "dkg.db"
const BoltStoreOpenPerm = 0660
const DirPerm = 0755
const GenesisDelay = 20 * time.Second
const ShortSigLength = 8
Variables ¶
var ErrCannotAcceptProposalWhereJoining = errors.New("you cannot accept a proposal where your node is joining - run the join command instead")
var ErrCannotAcceptProposalWhereLeaving = errors.New("you cannot accept a proposal where your node is leaving")
var ErrCannotExecuteIfNotJoinerOrRemainer = errors.New("you cannot start execution if you are not a remainer or joiner to the DKG")
var ErrCannotJoinIfNotInJoining = errors.New("you cannot join a proposal in which you are not a joiner")
var ErrCannotLeaveIfNotALeaver = errors.New("you cannot execute leave if you were not included as a leaver in the proposal")
var ErrCannotProposeAsNonLeader = errors.New("cannot make a proposal where you are not the leader")
var ErrCannotRejectProposalWhereJoining = errors.New("you cannot reject a proposal where your node is joining (just turn your node off)")
var ErrCannotRejectProposalWhereLeaving = errors.New("you cannot reject a proposal where your node is leaving")
var ErrDKGAborted = errors.New("DKG aborted")
var ErrDKGFailed = errors.New("DKG failed")
var ErrDuplicateAcceptance = errors.New("this participant already accepted the proposal")
var ErrDuplicateRejection = errors.New("this participant already rejected the proposal")
var ErrFinalGroupCannotBeEmpty = errors.New("you cannot complete a DKG with a nil final group")
var ErrGenesisSeedCannotChange = errors.New("genesis seed cannot change after the first epoch")
var ErrGenesisTimeNotEqual = errors.New("genesis time cannot be changed after the initial DKG")
var ErrInvalidAcceptor = errors.New("the node that signed this message is not the one claiming be accepting")
var ErrInvalidBeaconID = errors.New("BeaconID was invalid")
var ErrInvalidEpoch = errors.New("the epoch provided was invalid")
var ErrInvalidRejector = errors.New("the node that signed this message is not the one claiming be rejecting")
var ErrInvalidScheme = errors.New("the scheme proposed does not exist")
var ErrJoiningAfterFirstEpochNeedsGroupFile = errors.New("joining after the first epoch requires a previous group file")
var ErrLeaderCantJoinAfterFirstEpoch = errors.New("you cannot lead a DKG and join at the same time (unless it is epoch 1)")
var ErrLeaderNotJoining = errors.New("the leader must join in the first epoch")
var ErrLeaderNotRemaining = errors.New("you cannot lead a DKG and leave at the same time")
var ErrMissingNodesInProposal = errors.New("some node(s) in the current epoch are missing from the proposal - they should be remaining or leaving")
var ErrMissingTerms = errors.New("proposal terms cannot be empty")
var ErrNoGenesisSeedForFirstEpoch = errors.New("the genesis seed is created during the first epoch, so you can't provide it in the proposal")
var ErrNoNodesRemaining = errors.New("cannot propose a network without nodes remaining")
var ErrNodeCountTooLow = errors.New("the new node count cannot be lower than the prior threshold")
var ErrOnlyJoinersAllowedForFirstEpoch = errors.New("participants can only be joiners for the first epoch")
var ErrOnlyLeaderCanRemoteAbort = errors.New("only the leader can remotely abort the DKG")
var ErrOnlyLeaderCanTriggerExecute = errors.New("only the leader can trigger the execution")
var ErrReceivedAcceptance = errors.New("received acceptance but not during proposal phase")
var ErrReceivedRejection = errors.New("received rejection but not during proposal phase")
var ErrRemainingAndLeavingNodesMustExistInCurrentEpoch = errors.New("remaining and leaving nodes contained a node that does not exist in the current epoch - they must be added as joiners")
var ErrSelfMissingFromProposal = errors.New("you must include yourself in a proposal")
var ErrThresholdHigherThanNodeCount = errors.New("the threshold cannot be higher than the count of remaining + joining nodes")
var ErrThresholdTooLow = errors.New("the threshold is below the minimum required to allow effective secret recovery given the node count")
var ErrTimeout = errors.New("DKG timed out")
var ErrTimeoutReached = errors.New("timeout has been reached")
var ErrUnknownAcceptor = errors.New("somebody unknown tried to accept the proposal")
var ErrUnknownRejector = errors.New("somebody unknown tried to reject the proposal")
Functions ¶
func InvalidStateChange ¶
func ValidateProposal ¶
func ValidateProposal(currentState *DBState, terms *drand.ProposalTerms) error
Types ¶
type BeaconIdentifier ¶
BeaconIdentifier is necessary because we need to get our identity on a per-beacon basis from the `DrandDaemon` but that would introduce a circular dependency
type BoltStore ¶
type BoltStore struct {
// contains filtered or unexported fields
}
func (*BoltStore) MigrateFromGroupfile ¶
func (*BoltStore) SaveCurrent ¶
type Broadcast ¶
type Broadcast interface { dkg.Board BroadcastDKG(ctx context.Context, p *pdkg.DKGPacket) error Stop() }
Broadcast is an interface that represents the minimum functionality required by drand to both (1) be the interface between drand and the dkg logic and (2) implement the broadcasting mechanism.
type Config ¶
type Config struct { // the length of time after which this node will abort a DKG Timeout time.Duration // the length of time the phaser should use when moving between DKG phases TimeBetweenDKGPhases time.Duration // the length of time a node should wait before broadcasting DKG packets in the execution phase // to allow other nodes to set up their echo broadcast to prevent race conditions KickoffGracePeriod time.Duration // whether or not to skip verifying the cryptographic material in the DKG... almost certainly should be false SkipKeyVerification bool }
type DBState ¶
type DBState struct { BeaconID string Epoch uint32 State Status Threshold uint32 Timeout time.Time SchemeID string GenesisTime time.Time GenesisSeed []byte CatchupPeriod time.Duration BeaconPeriod time.Duration Leader *drand.Participant Remaining []*drand.Participant Joining []*drand.Participant Leaving []*drand.Participant Acceptors []*drand.Participant Rejectors []*drand.Participant FinalGroup *key.Group }
DBState !!! if you add a field, make sure you add it to DBStateTOML AND the FromTOML()/TOML() functions too !!!
func NewFreshState ¶
func (*DBState) Aborted ¶
func (d *DBState) Aborted(metadata *drand.GossipMetadata) (*DBState, error)
func (*DBState) Apply ¶
func (d *DBState) Apply(me *drand.Participant, packet *drand.GossipPacket) (*DBState, error)
func (*DBState) Executing ¶
func (d *DBState) Executing(me *drand.Participant, metadata *drand.GossipMetadata) (*DBState, error)
func (*DBState) Proposed ¶
func (d *DBState) Proposed(me *drand.Participant, terms *drand.ProposalTerms, metadata *drand.GossipMetadata) (*DBState, error)
Proposed is used by non-leader nodes to set their own state when they receive a proposal
func (*DBState) Proposing ¶
func (d *DBState) Proposing(me *drand.Participant, terms *drand.ProposalTerms) (*DBState, error)
Proposing is used by the leader to set their own local state when proposing a DKG to the network
func (*DBState) ReceivedAcceptance ¶
func (d *DBState) ReceivedAcceptance(them *drand.Participant, metadata *drand.GossipMetadata) (*DBState, error)
ReceivedAcceptance is used by nodes when they receive a gossiped acceptance packet they needn't necessarily collect _all_ acceptances for executing, but it gives them some insight into the state of the DKG when they run the status command
func (*DBState) ReceivedRejection ¶
func (d *DBState) ReceivedRejection(them *drand.Participant, metadata *drand.GossipMetadata) (*DBState, error)
ReceivedRejection is used by nodes when they receive a gossiped rejection packet they may not receive all rejections before executing, but it gives them some insight into the state of the DKG when they run the status command
func (*DBState) StartAbort ¶
func (*DBState) StartExecuting ¶
func (d *DBState) StartExecuting(me *drand.Participant) (*DBState, error)
func (*DBState) TOML ¶
func (d *DBState) TOML() DBStateTOML
type DBStateTOML ¶
type DBStateTOML struct { BeaconID string Epoch uint32 State Status Threshold uint32 Timeout time.Time SchemeID string GenesisTime time.Time GenesisSeed []byte TransitionTime time.Time CatchupPeriod time.Duration BeaconPeriod time.Duration Leader *drand.Participant Remaining []*drand.Participant Joining []*drand.Participant Leaving []*drand.Participant Acceptors []*drand.Participant Rejectors []*drand.Participant FinalGroup *key.GroupTOML }
DBStateTOML is a convenience object for managing de/serialization of DBStates when reading/writing them from/to disk. Don't forget to update it if you update the `DBState` object!!
func (*DBStateTOML) FromTOML ¶
func (d *DBStateTOML) FromTOML() (*DBState, error)
type ExecutionOutput ¶
type Process ¶
type Process struct { // this is public in order to replace it in the test code to simulate failures Executions map[string]Broadcast // a set of the packets that have been seen already for easy deduping SeenPackets map[string]bool // contains filtered or unexported fields }
func NewDKGProcess ¶
func NewDKGProcess( store Store, beaconIdentifier BeaconIdentifier, completedDKGs *util.FanOutChan[SharingOutput], dkgClient net.DKGClient, protocolClient net.ProtocolClient, config Config, l log.Logger, ) *Process
func (*Process) BroadcastDKG ¶
func (d *Process) BroadcastDKG(ctx context.Context, packet *drand.DKGPacket) (*drand.EmptyDKGResponse, error)
BroadcastDKG gossips internal DKG protocol messages to other nodes (i.e. any messages encapsulated in the Kyber DKG)
func (*Process) Command ¶
func (d *Process) Command(ctx context.Context, command *drand.DKGCommand) (*drand.EmptyDKGResponse, error)
func (*Process) DKGStatus ¶
func (d *Process) DKGStatus(ctx context.Context, request *drand.DKGStatusRequest) (*drand.DKGStatusResponse, error)
func (*Process) Migrate ¶
Migrate takes an existing groupfile and keyshare, and creates a first epoch DKG state for them. It will fail if DKG state already exists for the given beaconID Deprecated: will only exist in 2.0.0 for migration from v1.5.* to 2.0.0
func (*Process) Packet ¶
func (d *Process) Packet(ctx context.Context, packet *drand.GossipPacket) (*drand.EmptyDKGResponse, error)
func (*Process) StartAbort ¶
func (*Process) StartAccept ¶
func (d *Process) StartAccept( ctx context.Context, beaconID string, me *drand.Participant, state *DBState, _ *drand.AcceptOptions, ) (*DBState, *drand.GossipPacket, error)
func (*Process) StartExecute ¶
func (d *Process) StartExecute( ctx context.Context, beaconID string, me *drand.Participant, state *DBState, _ *drand.ExecutionOptions, ) (*DBState, *drand.GossipPacket, error)
func (*Process) StartJoin ¶
func (d *Process) StartJoin( ctx context.Context, beaconID string, me *drand.Participant, state *DBState, options *drand.JoinOptions, ) (*DBState, *drand.GossipPacket, error)
func (*Process) StartNetwork ¶
func (d *Process) StartNetwork( ctx context.Context, beaconID string, me *drand.Participant, state *DBState, options *drand.FirstProposalOptions, ) (*DBState, *drand.GossipPacket, error)
func (*Process) StartProposal ¶
func (d *Process) StartProposal( ctx context.Context, beaconID string, me *drand.Participant, currentState *DBState, options *drand.ProposalOptions, ) (*DBState, *drand.GossipPacket, error)
func (*Process) StartReject ¶
func (d *Process) StartReject( ctx context.Context, beaconID string, me *drand.Participant, state *DBState, _ *drand.RejectOptions, ) (*DBState, *drand.GossipPacket, error)
type SharingOutput ¶
type Status ¶
type Status uint32
const ( // Fresh is the state all nodes start in - both pre-genesis, and if the network is running but they aren't // yet participating Fresh Status = iota // Proposed implies somebody else has sent me a proposal Proposed // Proposing implies I have sent the others in the network a proposal Proposing // Accepted means I have accepted a proposal received from somebody else // note Joiners do not accept/reject proposals Accepted // Rejected means I have rejected a proposal received from somebody else // it doesn't automatically abort the DKG, but the leader is advised to abort and suggest some new terms Rejected // Aborted means the leader has told the network to abort the proposal; a node may have rejected, // they may have found an error in the proposal, or any other reason could have occurred Aborted // Executing means the leader has reviewed accepts/rejects and decided to go ahead with the DKG // this implies that the Kyber DKG process has been started Executing // Complete means the DKG has finished and a new group file has been created successfully Complete // TimedOut means the proposal timeout has been reached without entering the `Executing` state // any node can trigger this for themselves should they identify timeout has been reached // it does _not_ guarantee that other nodes have also timed out - a network error or something else // could have occurred. If the rest of the network continues, our node will likely transition to `Evicted` TimedOut // Joined is the state a new proposed group member enters when they have been proposed a DKG and they run the // `join` DKG command to signal their acceptance to join the network Joined // Left is used when a node has left the network by their own choice after a DKG. It's not entirely necessary, // an operator could just turn their node off. It's used to determine if an existing state is the current state // of the network, or whether epochs have happened in between times Left // Failed signals that a key sharing execution was attempted, but this node did not see it complete successfully. // This could be either due to it being evicted or the DKG not completing for the whole network. Operators should // check the node and network status, and manually transition the node to `Left` or create a new proposal depending // on the outcome of the DKG Failed )
type Store ¶
type Store interface { // GetCurrent returns the current DKG information, finished DKG information or fresh DKG information, // depending on the state of the world GetCurrent(beaconID string) (*DBState, error) // GetFinished returns the last completed DKG state (i.e. completed or aborted), or nil if one has not been finished GetFinished(beaconID string) (*DBState, error) // SaveCurrent stores a DKG packet for an ongoing DKG SaveCurrent(beaconID string, state *DBState) error // SaveFinished stores a completed, successful DKG and overwrites the current packet SaveFinished(beaconID string, state *DBState) error // Close closes and cleans up any database handles Close() error // MigrateFromGroupfile takes an existing groupfile and keyshare, and creates a first epoch DKG state for them. // It will fail if DKG state already exists for the given beaconID // Deprecated: will only exist in 2.0.0 for migration from v1.5.* to 2.0.0 MigrateFromGroupfile(beaconID string, groupFile *key.Group, share *key.Share) error }
type TestRunner ¶
type TestRunner struct { Client drand.DKGControlClient BeaconID string Clock clockwork.Clock }
TestRunner is a convenience struct for running DKG tests
func (*TestRunner) Abort ¶
func (r *TestRunner) Abort() error
func (*TestRunner) Accept ¶
func (r *TestRunner) Accept() error
func (*TestRunner) JoinDKG ¶
func (r *TestRunner) JoinDKG() error
func (*TestRunner) JoinReshare ¶
func (r *TestRunner) JoinReshare(oldGroup *key.Group) error
func (*TestRunner) StartExecution ¶
func (r *TestRunner) StartExecution() error
func (*TestRunner) StartNetwork ¶
func (r *TestRunner) StartNetwork( threshold int, period int, schemeID string, timeout time.Duration, catchupPeriod int, joiners []*drand.Participant, ) error
func (*TestRunner) StartReshare ¶
func (r *TestRunner) StartReshare( threshold int, catchupPeriod int, joiners []*drand.Participant, remainers []*drand.Participant, leavers []*drand.Participant, ) error