dkg

package
v2.0.5-testnet Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 23, 2024 License: Apache-2.0, MIT Imports: 32 Imported by: 0

Documentation

Index

Constants

View Source
const BoltFileName = "dkg.db"
View Source
const BoltStoreOpenPerm = 0660
View Source
const DirPerm = 0755
View Source
const GenesisDelay = 20 * time.Second
View Source
const ShortSigLength = 8

Variables

View Source
var ErrCannotAcceptProposalWhereJoining = errors.New("you cannot accept a proposal where your node is joining - run the join command instead")
View Source
var ErrCannotAcceptProposalWhereLeaving = errors.New("you cannot accept a proposal where your node is leaving")
View Source
var ErrCannotExecuteIfNotJoinerOrRemainer = errors.New("you cannot start execution if you are not a remainer or joiner to the DKG")
View Source
var ErrCannotJoinIfNotInJoining = errors.New("you cannot join a proposal in which you are not a joiner")
View Source
var ErrCannotLeaveIfNotALeaver = errors.New("you cannot execute leave if you were not included as a leaver in the proposal")
View Source
var ErrCannotProposeAsNonLeader = errors.New("cannot make a proposal where you are not the leader")
View Source
var ErrCannotRejectProposalWhereJoining = errors.New("you cannot reject a proposal where your node is joining (just turn your node off)")
View Source
var ErrCannotRejectProposalWhereLeaving = errors.New("you cannot reject a proposal where your node is leaving")
View Source
var ErrDKGAborted = errors.New("DKG aborted")
View Source
var ErrDKGFailed = errors.New("DKG failed")
View Source
var ErrDuplicateAcceptance = errors.New("this participant already accepted the proposal")
View Source
var ErrDuplicateRejection = errors.New("this participant already rejected the proposal")
View Source
var ErrFinalGroupCannotBeEmpty = errors.New("you cannot complete a DKG with a nil final group")
View Source
var ErrGenesisSeedCannotChange = errors.New("genesis seed cannot change after the first epoch")
View Source
var ErrGenesisTimeNotEqual = errors.New("genesis time cannot be changed after the initial DKG")
View Source
var ErrInvalidAcceptor = errors.New("the node that signed this message is not the one claiming be accepting")
View Source
var ErrInvalidBeaconID = errors.New("BeaconID was invalid")
View Source
var ErrInvalidEpoch = errors.New("the epoch provided was invalid")
View Source
var ErrInvalidRejector = errors.New("the node that signed this message is not the one claiming be rejecting")
View Source
var ErrInvalidScheme = errors.New("the scheme proposed does not exist")
View Source
var ErrJoiningAfterFirstEpochNeedsGroupFile = errors.New("joining after the first epoch requires a previous group file")
View Source
var ErrKeyShareCannotBeEmpty = errors.New("you cannot complete a DKG with a nil key share")
View Source
var ErrLeaderCantJoinAfterFirstEpoch = errors.New("you cannot lead a DKG and join at the same time (unless it is epoch 1)")
View Source
var ErrLeaderNotJoining = errors.New("the leader must join in the first epoch")
View Source
var ErrLeaderNotRemaining = errors.New("you cannot lead a DKG and leave at the same time")
View Source
var ErrMissingNodesInProposal = errors.New("some node(s) in the current epoch are missing from the proposal - they should be remaining or leaving")
View Source
var ErrMissingTerms = errors.New("proposal terms cannot be empty")
View Source
var ErrNoGenesisSeedForFirstEpoch = errors.New("the genesis seed is created during the first epoch, so you can't provide it in the proposal")
View Source
var ErrNoNodesRemaining = errors.New("cannot propose a network without nodes remaining")
View Source
var ErrNodeCountTooLow = errors.New("the new node count cannot be lower than the prior threshold")
View Source
var ErrOnlyJoinersAllowedForFirstEpoch = errors.New("participants can only be joiners for the first epoch")
View Source
var ErrOnlyLeaderCanRemoteAbort = errors.New("only the leader can remotely abort the DKG")
View Source
var ErrOnlyLeaderCanTriggerExecute = errors.New("only the leader can trigger the execution")
View Source
var ErrReceivedAcceptance = errors.New("received acceptance but not during proposal phase")
View Source
var ErrReceivedRejection = errors.New("received rejection but not during proposal phase")
View Source
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")
View Source
var ErrSelfMissingFromProposal = errors.New("you must include yourself in a proposal")
View Source
var ErrThresholdHigherThanNodeCount = errors.New("the threshold cannot be higher than the count of remaining + joining nodes")
View Source
var ErrThresholdTooLow = errors.New("the threshold is below the minimum required to allow effective secret recovery given the node count")
View Source
var ErrTimeout = errors.New("DKG timed out")
View Source
var ErrTimeoutReached = errors.New("timeout has been reached")
View Source
var ErrUnknownAcceptor = errors.New("somebody unknown tried to accept the proposal")
View Source
var ErrUnknownRejector = errors.New("somebody unknown tried to reject the proposal")

Functions

func InvalidStateChange

func InvalidStateChange(from, to Status) error

func ValidateProposal

func ValidateProposal(currentState *DBState, terms *drand.ProposalTerms) error

Types

type BeaconIdentifier

type BeaconIdentifier interface {
	KeypairFor(beaconID string) (*key.Pair, error)
}

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 NewDKGStore

func NewDKGStore(baseFolder string, options *bolt.Options) (*BoltStore, error)

func (*BoltStore) Close

func (s *BoltStore) Close() error

func (*BoltStore) GetCurrent

func (s *BoltStore) GetCurrent(beaconID string) (*DBState, error)

func (*BoltStore) GetFinished

func (s *BoltStore) GetFinished(beaconID string) (*DBState, error)

func (*BoltStore) MigrateFromGroupfile

func (s *BoltStore) MigrateFromGroupfile(beaconID string, groupFile *key.Group, share *key.Share) error

func (*BoltStore) NukeState

func (s *BoltStore) NukeState(beaconID string) error

func (*BoltStore) SaveCurrent

func (s *BoltStore) SaveCurrent(beaconID string, state *DBState) error

func (*BoltStore) SaveFinished

func (s *BoltStore) SaveFinished(beaconID string, state *DBState) error

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
	KeyShare   *key.Share
}

DBState !!! if you add a field, make sure you add it to DBStateTOML AND the FromTOML()/TOML() functions too !!!

func NewFreshState

func NewFreshState(beaconID string) *DBState

func (*DBState) Aborted

func (d *DBState) Aborted(metadata *drand.GossipMetadata) (*DBState, error)

func (*DBState) Accepted

func (d *DBState) Accepted(me *drand.Participant) (*DBState, error)

func (*DBState) Apply

func (d *DBState) Apply(me *drand.Participant, packet *drand.GossipPacket) (*DBState, error)

func (*DBState) Complete

func (d *DBState) Complete(finalGroup *key.Group, share *key.Share) (*DBState, error)

func (*DBState) Equals

func (d *DBState) Equals(e *DBState) bool

Equals does a deep equal comparison on all the values in the `DBState`

func (*DBState) Executing

func (d *DBState) Executing(me *drand.Participant, metadata *drand.GossipMetadata) (*DBState, error)

func (*DBState) Failed

func (d *DBState) Failed() (*DBState, error)

func (*DBState) Joined

func (d *DBState) Joined(me *drand.Participant, previousGroup *key.Group) (*DBState, error)

func (*DBState) Left

func (d *DBState) Left(me *drand.Participant) (*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) Rejected

func (d *DBState) Rejected(me *drand.Participant) (*DBState, error)

func (*DBState) StartAbort

func (d *DBState) StartAbort() (*DBState, error)

func (*DBState) StartExecuting

func (d *DBState) StartExecuting(me *drand.Participant) (*DBState, error)

func (*DBState) TOML

func (d *DBState) TOML() DBStateTOML

func (*DBState) TimedOut

func (d *DBState) TimedOut() (*DBState, error)

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
	KeyShare   *key.ShareTOML
}

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 ExecutionOutput struct {
	FinalGroup *key.Group
	KeyShare   *key.Share
}

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) Close

func (d *Process) Close()

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

func (d *Process) Migrate(beaconID string, groupfile *key.Group, share *key.Share) error

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 (d *Process) StartAbort(
	ctx context.Context,
	beaconID string,
	current *DBState,
	_ *drand.AbortOptions,
) (*DBState, *drand.GossipPacket, error)

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 SharingOutput struct {
	BeaconID string
	Old      *DBState
	New      DBState
}

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
)

func (Status) String

func (s Status) String() string

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

func (*TestRunner) WaitForDKG

func (r *TestRunner) WaitForDKG(lg log.Logger, epoch uint32, numberOfSeconds int) error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL