Documentation ¶
Overview ¶
Package agreement implements Algorand's agreement protocol, which enables all nodes to consistently update the state of the system.
The Service establishes a consensus on the ordering of Blocks. This ordering is defined by a Round number, which indexes into the ordered log of Blocks.
Clients instantiate an Service by providing it several parameters:
Ledger represents a data store which supports the reading and writing of data stored within Blocks.
BlockFactory produces Blocks for a given round.
BlockValidator validates Blocks for a given round.
KeyManager holds the participation keys necessary to participate in the protocol.
Network provides an abstraction over the underlying network.
timers.Clock provides timekeeping services for timeouts.
db.Accessor provides persistent storage for internal state.
Blocks for which consensus is completed are written using Ledger.EnsureBlock alongside Certificate objects, which are cryptographic proofs that a Block was confirmed for a given round.
If Ledger and db.Accessor provide crash-safe storage, agreement will also recover safely after crashes.
Index ¶
- Variables
- func DeadlineTimeout() time.Duration
- func FilterTimeout(p period, v protocol.ConsensusVersion) time.Duration
- func ParamsRound(rnd basics.Round) basics.Round
- type AsyncVoteVerifier
- type Autopsy
- type AutopsyBounds
- type AutopsyFilter
- type BlockFactory
- type BlockValidator
- type CadaverMetadata
- type Certificate
- func (c Certificate) Authenticate(e bookkeeping.Block, l LedgerReader, avv *AsyncVoteVerifier) (err error)
- func (_ *Certificate) CanMarshalMsg(z interface{}) bool
- func (_ *Certificate) CanUnmarshalMsg(z interface{}) bool
- func (z *Certificate) MarshalMsg(b []byte) (o []byte)
- func (z *Certificate) MsgIsZero() bool
- func (z *Certificate) Msgsize() (s int)
- func (z *Certificate) UnmarshalMsg(bts []byte) (o []byte, err error)
- type ConsensusVersionView
- type EventsProcessingMonitor
- type KeyManager
- type Ledger
- type LedgerDroppedRoundError
- type LedgerReader
- type LedgerWriter
- type Message
- type MessageHandle
- type Network
- type Parameters
- type RandomSource
- type Service
- type ValidatedBlock
Constants ¶
This section is empty.
Variables ¶
var ErrAssembleBlockRoundStale = errors.New("requested round for AssembleBlock is stale")
ErrAssembleBlockRoundStale is returned by AssembleBlock when the requested round number is not the one that matches the ledger last committed round + 1.
Functions ¶
func DeadlineTimeout ¶
DeadlineTimeout is the duration of the second agreement step.
func FilterTimeout ¶
func FilterTimeout(p period, v protocol.ConsensusVersion) time.Duration
FilterTimeout is the duration of the first agreement step.
Types ¶
type AsyncVoteVerifier ¶
type AsyncVoteVerifier struct {
// contains filtered or unexported fields
}
AsyncVoteVerifier uses workers to verify agreement protocol votes and writes the results on an output channel specified by the user.
func MakeAsyncVoteVerifier ¶
func MakeAsyncVoteVerifier(verificationPool execpool.BacklogPool) *AsyncVoteVerifier
MakeAsyncVoteVerifier creates an AsyncVoteVerifier with workers as the number of CPUs
func (*AsyncVoteVerifier) Parallelism ¶
func (avv *AsyncVoteVerifier) Parallelism() int
Parallelism gives the maximum parallelism of the vote verifier.
func (*AsyncVoteVerifier) Quit ¶
func (avv *AsyncVoteVerifier) Quit()
Quit tells the AsyncVoteVerifier to shutdown and waits until all workers terminate.
type Autopsy ¶
An Autopsy is a trace of the ordered input events and output actions as seen by the agreement state machine.
Functions depending on autopsies are not guaranteed to be supported as the agreement protocol changes.
func PrepareAutopsy ¶
func PrepareAutopsy(cadaverBaseFilename string, nextBounds func(int, AutopsyBounds), done func(int, error)) (*Autopsy, error)
PrepareAutopsy prepares an autopsy from a cadaver filename.
nextBounds is called with a sequence number for each new invocation of a cadaver-generating process (a "run").
done is called with the total number of runs and any error encountered while performing the autopsy.
func PrepareAutopsyFromStream ¶
func PrepareAutopsyFromStream(stream io.ReadCloser, nextBounds func(int, AutopsyBounds), done func(int, error)) (*Autopsy, error)
PrepareAutopsyFromStream prepares an autopsy from a given ReadCloser.
nextBounds is called with a sequence number for each new invocation of a cadaver-generating process (a "run").
done is called with the total number of runs and any error encountered while performing the autopsy.
func (*Autopsy) DumpMessagePack ¶
func (a *Autopsy) DumpMessagePack(filter AutopsyFilter, w0 io.WriteCloser) (version string)
DumpMessagePack dumps a msgpack representation of the AutopsiedCdvs to the given io.Writer.
func (*Autopsy) DumpString ¶
func (a *Autopsy) DumpString(filter AutopsyFilter, w0 io.Writer) (version string)
DumpString dumps a textual representation of the AutopsyCdvs to the given io.Writer.
type AutopsyBounds ¶
type AutopsyBounds struct { // Start and End are inclusive here. StartRound uint64 StartPeriod uint64 EndRound uint64 EndPeriod uint64 }
AutopsyBounds defines the range of rounds and periods spanned by a single invocation of a cadaver-generating process.
type AutopsyFilter ¶
type AutopsyFilter struct { Enabled bool // do not filter if this is false First basics.Round // first round to emit output for; inclusive Last basics.Round // last round to emit output for; inclusive }
AutopsyFilter represents a window of rounds to be filtered from the autopsy output.
type BlockFactory ¶
type BlockFactory interface { // AssembleBlock produces a new ValidatedBlock which is suitable for proposal // at a given Round. The time argument specifies a target deadline by // which the block should be produced. Specifically, the deadline can // cause the factory to add fewer transactions to the block in question // than might otherwise be possible. // // AssembleBlock should produce a ValidatedBlock for which the corresponding // BlockValidator validates (i.e. for which BlockValidator.Validate // returns true). If an insufficient number of nodes can assemble valid // entries, the agreement protocol may lose liveness. // // AssembleBlock may return an error if the BlockFactory is unable to // produce a ValidatedBlock for the given round. If an insufficient number of // nodes on the network can assemble entries, the agreement protocol may // lose liveness. AssembleBlock(basics.Round, time.Time) (ValidatedBlock, error) }
An BlockFactory produces an Block which is suitable for proposal for a given Round.
type BlockValidator ¶
type BlockValidator interface { // Validate must return an error if a given Block cannot be determined // to be valid as applied to the agreement state; otherwise, it returns // nil. // // The correctness of Validate is essential to the correctness of the // protocol. If Validate accepts an invalid Block (i.e., a false // positive), the agreement protocol may fork, or the system state may // even become undefined. If Validate rejects a valid Block (i.e., a // false negative), the agreement protocol may even lose // liveness. Validate should therefore be conservative in which Entries // it accepts. // // TODO There should probably be a second Round argument here. Validate(context.Context, bookkeeping.Block) (ValidatedBlock, error) }
An BlockValidator validates that a given Block may correctly be appended to the sequence of Entries agreed upon by the protocol so far.
type CadaverMetadata ¶
CadaverMetadata contains informational metadata written to the top of every cadaver file
type Certificate ¶
type Certificate unauthenticatedBundle
A Certificate contains a cryptographic proof that agreement was reached on a given block in a given round.
When a client first joins the network or has fallen behind and needs to catch up, certificates allow the client to verify that a block someone gives them is the real one.
func (Certificate) Authenticate ¶
func (c Certificate) Authenticate(e bookkeeping.Block, l LedgerReader, avv *AsyncVoteVerifier) (err error)
Authenticate returns nil if the Certificate authenticates the given Block; otherwise, it returns an error.
Callers may want to cache the result of this check, as it is relatively expensive.
func (*Certificate) CanMarshalMsg ¶
func (_ *Certificate) CanMarshalMsg(z interface{}) bool
func (*Certificate) CanUnmarshalMsg ¶
func (_ *Certificate) CanUnmarshalMsg(z interface{}) bool
func (*Certificate) MarshalMsg ¶
func (z *Certificate) MarshalMsg(b []byte) (o []byte)
MarshalMsg implements msgp.Marshaler
func (*Certificate) MsgIsZero ¶
func (z *Certificate) MsgIsZero() bool
MsgIsZero returns whether this is a zero value
func (*Certificate) Msgsize ¶
func (z *Certificate) Msgsize() (s int)
Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (*Certificate) UnmarshalMsg ¶
func (z *Certificate) UnmarshalMsg(bts []byte) (o []byte, err error)
UnmarshalMsg implements msgp.Unmarshaler
type ConsensusVersionView ¶
type ConsensusVersionView struct { Err serializableError Version protocol.ConsensusVersion }
A ConsensusVersionView is a view of the consensus version as read from a LedgerReader, associated with some round.
type EventsProcessingMonitor ¶
EventsProcessingMonitor is an abstraction over the inner queues of the agreement service. It allows an external client to monitor the activity of the various events queues.
type KeyManager ¶
type KeyManager interface { // VotingKeys returns an immutable array of voting keys that are // valid for the provided votingRound, and were available at // keysRound. VotingKeys(votingRound, keysRound basics.Round) []account.Participation }
A KeyManager stores and deletes participation keys.
type Ledger ¶
type Ledger interface { LedgerReader LedgerWriter }
A Ledger represents the sequence of Entries agreed upon by the protocol. The Ledger consists of two parts: a LedgerReader and a LedgerWriter, which provide read and write access to the ledger, respectively.
Ledger must be safe for concurrent use.
Once a method of Ledger succeeds, it must always succeed and become idempotent. (That is, all future calls to that method must return the same result, and multiple calls to a method must produce the same state as a single call.)
type LedgerDroppedRoundError ¶
type LedgerDroppedRoundError struct {
Err error
}
LedgerDroppedRoundError is a wrapper error for when the ledger cannot return a Lookup query because the entry is old and was dropped from the ledger. The purpose of this wrapper is to help the agreement differentiate between a malicious vote and a vote that it cannot verify
func (*LedgerDroppedRoundError) Error ¶
func (e *LedgerDroppedRoundError) Error() string
func (*LedgerDroppedRoundError) Unwrap ¶
func (e *LedgerDroppedRoundError) Unwrap() error
type LedgerReader ¶
type LedgerReader interface { // NextRound returns the first round for which no Block has been // confirmed. NextRound() basics.Round // Wait returns a channel which fires when the specified round // completes and is durably stored on disk. Wait(basics.Round) chan struct{} // Seed returns the VRF seed that was agreed upon in a given round. // // The Seed is a source of cryptographic entropy which has bounded // bias. It is used to select committees for participation in // sortition. // // This method returns an error if the given Round has not yet been // confirmed. It may also return an error if the given Round is // unavailable by the storage device. In that case, the agreement // protocol may lose liveness. Seed(basics.Round) (committee.Seed, error) // Lookup returns the AccountData associated with some Address // at the conclusion of a given round. // // This method returns an error if the given Round has not yet been // confirmed. It may also return an error if the given Round is // unavailable by the storage device. In that case, the agreement // protocol may lose liveness. Lookup(basics.Round, basics.Address) (basics.AccountData, error) // Circulation returns the total amount of money in circulation at the // conclusion of a given round. // // This method returns an error if the given Round has not yet been // confirmed. It may also return an error if the given Round is // unavailable by the storage device. In that case, the agreement // protocol may lose liveness. Circulation(basics.Round) (basics.MicroAlgos, error) // LookupDigest returns the Digest of the entry that was agreed on in a // given round. // // Recent Entry Digests are periodically used when computing the Seed. // This prevents some subtle attacks. // // This method returns an error if the given Round has not yet been // confirmed. It may also return an error if the given Round is // unavailable by the storage device. In that case, the agreement // protocol may lose liveness. // // A LedgerReader need only keep track of the digest from the most // recent multiple of (config.Protocol.BalLookback/2). All other // digests may be forgotten without hurting liveness. LookupDigest(basics.Round) (crypto.Digest, error) // ConsensusParams returns the consensus parameters that are correct // for the given round. // // This method returns an error if the given Round has not yet been // confirmed. It may also return an error if the given Round is // unavailable by the storage device. In that case, the agreement // protocol may lose liveness. // // TODO replace with ConsensusVersion ConsensusParams(basics.Round) (config.ConsensusParams, error) // ConsensusVersion returns the consensus version that is correct // for the given round. // // This method returns an error if the given Round has not yet been // confirmed. It may also return an error if the given Round is // unavailable by the storage device. In that case, the agreement // protocol may lose liveness. ConsensusVersion(basics.Round) (protocol.ConsensusVersion, error) }
A LedgerReader provides read access to observe the state of the ledger.
type LedgerWriter ¶
type LedgerWriter interface { // EnsureBlock adds a Block, along with a Certificate authenticating // its contents, to the ledger. // // The Ledger must guarantee that after this method returns, any Seed, // Record, or Circulation call reflects the contents of this Block. // // EnsureBlock will never be called twice for two entries e1 and e2 // where e1.Round() == e2.Round() but e1.Digest() != e2.Digest(). If // this is the case, the behavior of Ledger is undefined. // (Implementations are encouraged to panic or otherwise fail loudly in // this case, because it means that a fork has occurred.) // // EnsureBlock does not wait until the block is written to disk; use // Wait() for that. EnsureBlock(bookkeeping.Block, Certificate) // EnsureValidatedBlock is an optimized version of EnsureBlock that // works on a ValidatedBlock, but otherwise has the same semantics // as above. EnsureValidatedBlock(ValidatedBlock, Certificate) // EnsureDigest signals the Ledger to attempt to fetch a Block matching // the given Certificate. EnsureDigest does not wait for the block to // be written to disk; use Wait() if needed. // // The Ledger must guarantee that after this method returns, any Seed, // Record, or Circulation call reflects the contents of the Block // authenticated by the given Certificate. // // EnsureDigest will never be called twice for two certificates c1 and // c2 where c1 authenticates the block e1 and c2 authenticates the block // e2, but e1.Round() == e2.Round() and e1.Digest() != e2.Digest(). If // this is the case, the behavior of Ledger is undefined. // (Implementations are encouraged to panic or otherwise fail loudly in // this case, because it means that a fork has occurred.) EnsureDigest(Certificate, *AsyncVoteVerifier) }
A LedgerWriter allows writing entries to the ledger.
type Message ¶
type Message struct { MessageHandle Data []byte }
Message encapsulates a MessageHandle and its payload.
type MessageHandle ¶
type MessageHandle interface{}
MessageHandle is an ID referring to a specific message.
A MessageHandle of nil denotes that a message is "sourceless".
type Network ¶
type Network interface { // Messages returns a channel of Messages which corresponds to a given // protocol.Tag. Messages(protocol.Tag) <-chan Message // Broadcast attempts to send a slice of bytes under some protocol.Tag // to all neighbors. // // Broadcast represents a best-effort, ordered delivery mechanism. In // other words, sends to any given peer may fail due to disconnection or // network congestion. However, the Network should try to transmit // messages in the order identical to the ordering of Broadcast calls. // // Calls to Broadcast by the agreement package are currently guaranteed // to be serialized. // // If the broadcasting of the message have failed or is not possible, the // method returns a non-nil error describing the underlaying error. // otherwise, a nil is returned. Broadcast(protocol.Tag, []byte) error // Relay attempts to send a slice of bytes under some protocol.Tag to // all neighbors, except for the neighbor associated with the given // MessageHandle. // // The behavior of Relay is otherwise identical to Broadcast. // // Passing a MessageHandle value of nil to Relay should produce behavior // identical to calling Broadcast. In other words, the calls // Broadcast(tag, data) and Relay(nil, tag, data) should cause identical // behavior. // // If the relaying of the message have failed or is not possible, the // method returns a non-nil error describing the underlaying error. // otherwise, a nil is returned. Relay(MessageHandle, protocol.Tag, []byte) error // Disconnect sends the Network a hint to disconnect to the peer // associated with the given MessageHandle. Disconnect(MessageHandle) // Start notifies the network that the agreement service is ready // to start receiving messages. Start() }
Network is an abstraction over the interface expected by the agreement protocol.
type Parameters ¶
type Parameters struct { Ledger Network KeyManager BlockValidator BlockFactory RandomSource EventsProcessingMonitor timers.Clock db.Accessor logging.Logger config.Local execpool.BacklogPool }
Parameters holds the parameters necessary to run the agreement protocol.
type RandomSource ¶
type RandomSource interface { // Uint64 returns a pseudo-random 64-bit value as a uint64. Uint64() uint64 }
RandomSource is an abstraction over the random number generator. The agreement protocol use it to determine the duration of which different nodes would wait on steps 5 and above.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service represents an instance of an execution of Algorand's agreement protocol.
func MakeService ¶
func MakeService(p Parameters) *Service
MakeService creates a new Agreement Service instance given a set of Parameters.
Call Start to start execution and Shutdown to finish execution.
func (*Service) SetTracerFilename ¶
SetTracerFilename updates the tracer filename used.
type ValidatedBlock ¶
type ValidatedBlock interface { // WithSeed creates a copy of this ValidatedBlock with its // cryptographically random seed set to the given value. // // Calls to Seed() or to Digest() on the copy's Block must // reflect the value of the new seed. WithSeed(committee.Seed) ValidatedBlock // Block returns the underlying block that has been validated. Block() bookkeeping.Block }
A ValidatedBlock represents an Block that has been successfuly validated and can now be recorded in the ledger. This is an optimized version of calling EnsureBlock() on the Ledger.
Source Files ¶
- abstractions.go
- actions.go
- actiontype_string.go
- actor.go
- agreeInstall.go
- asyncVoteVerifier.go
- autopsy.go
- bundle.go
- cadaver.go
- certificate.go
- coservice.go
- coservicetype_string.go
- cryptoRequestContext.go
- cryptoVerifier.go
- demux.go
- doc.go
- errors.go
- events.go
- eventtype_string.go
- listener.go
- message.go
- msgp_gen.go
- params.go
- persistence.go
- player.go
- playerContract.go
- proposal.go
- proposalManager.go
- proposalManagerContract.go
- proposalStore.go
- proposalStoreContract.go
- proposalTable.go
- proposalTracker.go
- proposalTrackerContract.go
- pseudonode.go
- router.go
- selector.go
- service.go
- statemachinetag_string.go
- trace.go
- traceTime.go
- types.go
- vote.go
- voteAggregator.go
- voteAggregatorContract.go
- voteAuxiliary.go
- voteAuxiliaryContract.go
- voteTracker.go
- voteTrackerContract.go
Directories ¶
Path | Synopsis |
---|---|
Package agreementtest produces useful functions for testing code.
|
Package agreementtest produces useful functions for testing code. |
Package gossip adapts the interface of network.GossipNode to agreement.Network.
|
Package gossip adapts the interface of network.GossipNode to agreement.Network. |