process

package
v1.1.1 Latest Latest
Warning

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

Go to latest
Published: Mar 19, 2020 License: GPL-3.0 Imports: 15 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// NilMessageType is invalid and must not be used.
	NilMessageType = 0
	// ProposeMessageType is used by messages that propose blocks for consensus.
	ProposeMessageType = 1
	// PrevoteMessageType is used by messages that are prevoting for block
	// hashes (or nil prevoting).
	PrevoteMessageType = 2
	// PrecommitMessageType is used by messages that are precommitting for block
	// hashes (or nil precommitting).
	PrecommitMessageType = 3
	// ResyncMessageType is used by messages that query others for previous
	// messages.
	ResyncMessageType = 4
)

Variables

View Source
var (
	// ErrBlockHashNotProvided is returned when querying the block hash for a
	// message type that does not implement the function.
	ErrBlockHashNotProvided = errors.New("block hash not provided")
)

Functions

func Sign

func Sign(m Message, privKey ecdsa.PrivateKey) error

Sign a message using an ECDSA private key. The resulting signature will be stored inside the message.

func Verify

func Verify(m Message) error

Verify that the signature in a message is from the expected signatory. This is done by checking the `Message.Sig()` against the `Message.SigHash()` and `Message.Signatory()`.

Types

type Blockchain

type Blockchain interface {
	InsertBlockAtHeight(block.Height, block.Block)
	BlockAtHeight(block.Height) (block.Block, bool)
	BlockExistsAtHeight(block.Height) bool
}

A Blockchain defines a storage interface for Blocks that is based around Height.

type Broadcaster

type Broadcaster interface {
	Broadcast(Message)
	Cast(id.Signatory, Message)
}

A Broadcaster sends a Message to a either specific Process or as many Processes in the network as possible.

type Inbox

type Inbox struct {
	// contains filtered or unexported fields
}

An Inbox is storage container for one type message. Any type of message can be stored, but an attempt to store messages of different types in one inbox will cause a panic. Inboxes are used extensively by the consensus algorithm to track how many messages (of particular types) have been received, and under what conditions. For example, inboxes are used to track when `2F+1` prevote messages have been received for a specific block hash for the first time.

func NewInbox

func NewInbox(f int, messageType MessageType) *Inbox

NewInbox returns an inbox for one type of message. It assumes at most `F` adversaries are present.

func (*Inbox) Delete added in v0.4.2

func (inbox *Inbox) Delete(height block.Height)

Delete removes all messages at a given height.

func (*Inbox) F

func (inbox *Inbox) F() int

func (*Inbox) Insert

func (inbox *Inbox) Insert(message Message) (n int, firstTime, firstTimeExceedingF, firstTimeExceeding2F, firstTimeExceeding2FOnBlockHash bool)

Insert a message into the inbox. It returns:

  • `n` the number of unique messages at the height and round of the inserted message (not necessarily for the same block hash),
  • `firstTime` whether, or not, this is the first time this message has been seen,
  • `firstTimeExceedingF` whether, or not, `n` has exceeded `F` for the first time as a result of this message being inserted,
  • `firstTimeExceeding2F` whether, or not, `n` has exceeded `2F` for the first time as a result of this message being inserted, and
  • `firstTimeExceeding2FOnBlockHash` whether, or not, this is the first time that more than `2F` unique messages have been seen for the same block.

This method is used extensively for tracking the different conditions under which the state machine is allowed to transition between various states. Its correctness is fundamental to the correctness of the overall implementation.

func (Inbox) MarshalBinary

func (inbox Inbox) MarshalBinary() ([]byte, error)

MarshalBinary implements the `encoding.BinaryMarshaler` interface for the `Inbox` type.

func (Inbox) MarshalJSON

func (inbox Inbox) MarshalJSON() ([]byte, error)

MarshalJSON implements the `json.Marshaler` interface for the `Inbox` type.

func (*Inbox) MessageType

func (inbox *Inbox) MessageType() MessageType

func (*Inbox) QueryByHeightRound

func (inbox *Inbox) QueryByHeightRound(height block.Height, round block.Round) (n int)

QueryByHeightRound returns the number of unique messages that have been received at the specified height and round. The specific block hash of the messages are ignored and might be different from each other.

func (*Inbox) QueryByHeightRoundBlockHash

func (inbox *Inbox) QueryByHeightRoundBlockHash(height block.Height, round block.Round, blockHash id.Hash) (n int)

QueryByHeightRoundBlockHash returns the number of unique messages that have been received at the specified height and round. Only messages that reference the specified block hash are considered.

func (*Inbox) QueryByHeightRoundSignatory

func (inbox *Inbox) QueryByHeightRoundSignatory(height block.Height, round block.Round, sig id.Signatory) Message

QueryByHeightRoundSignatory the message (or nil) sent by a specific signatory at a specific height and round.

func (*Inbox) QueryMessagesByHeightRound added in v0.3.2

func (inbox *Inbox) QueryMessagesByHeightRound(height block.Height, round block.Round) []Message

QueryMessagesByHeightRound returns all unique messages that have been received at the specified height and round. The specific block hash of the messages are ignored and might be different from each other.

func (*Inbox) QueryMessagesByHeightWithHighestRound added in v0.3.2

func (inbox *Inbox) QueryMessagesByHeightWithHighestRound(height block.Height) []Message

QueryMessagesByHeightWithHighestRound returns all unique messages that have been received at the specified height and at the heighest round observed (for the specified height). The specific block hash of the messages are ignored and might be different from each other.

func (*Inbox) Reset

func (inbox *Inbox) Reset(height block.Height)

Reset the inbox to a specific height. All messages for height lower than the specified height are dropped. This is necessary to ensure that, over time, the storage space of the inbox is bounded.

func (*Inbox) UnmarshalBinary

func (inbox *Inbox) UnmarshalBinary(data []byte) error

UnmarshalBinary implements the `encoding.BinaryUnmarshaler` interface for the `Inbox` type. See the `UnmarshalJSON` method for more information.

func (*Inbox) UnmarshalJSON

func (inbox *Inbox) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the `json.Unmarshaler` interface for the `Inbox` type. Before unmarshaling into an inbox, you must initialise it. Unmarshaling will panic if the inbox in not initialised, or if it is initialised with the wrong message type.

type LatestCommit

type LatestCommit struct {
	Block      block.Block
	Precommits []Precommit
}

The LatestCommit can be attached to a proposal. It stores the latest committed block, and a set of precommits that prove this block was committed. This is useful for allowing processes that have fallen out-of-sync to fast forward. See https://github.com/renproject/hyperdrive/wiki/Consensus for more information about fast fowarding.

type Message

type Message interface {
	fmt.Stringer
	json.Marshaler
	json.Unmarshaler
	encoding.BinaryMarshaler
	encoding.BinaryUnmarshaler

	// The Signatory that sent the message.
	Signatory() id.Signatory
	// The SigHash that is expected to by signed by the signatory. This is used
	// to authenticate the claimed signatory.
	SigHash() id.Hash
	// The Signature produced by the signatory signing the sighash. This is used
	// to authenticate the claimed signatory.
	Sig() id.Signature

	// The Height of the blockchain in which this message was broadcast.
	Height() block.Height
	// The Round of consensus in which this message was broadcast.
	Round() block.Round
	// The BlockHash of the block to this message concerns. Proposals will be
	// proposing the block identified  by this hash, prevotes will be prevoting
	// for the block identified by this hash (nil prevotes will use
	// `InvalidBlockHash`), and precommits will be precommitting for block
	// identified by this hash (nil precommits will also use
	// `InvalidBlockHash`).
	BlockHash() id.Hash

	// Type returns the message type of this message. This is useful for
	// marshaling/unmarshaling when type information is elided.
	Type() MessageType
}

The Message interface defines the common behaviour of all messages that are broadcast throughout the network during consensus rounds.

type MessageType

type MessageType uint64

MessageType distinguished between the three valid (and one invalid) messages types that are supported during consensus rounds.

type Messages

type Messages []Message

Messages is a wrapper around the `[]Message` type.

type NilReasons added in v0.3.2

type NilReasons map[string][]byte

NilReasons can be used to provide contextual information alongside an error upon validating blocks.

func (NilReasons) MarshalBinary added in v0.3.2

func (nilReasons NilReasons) MarshalBinary() ([]byte, error)

MarshalBinary implements the `encoding.BinaryMarshaler` interface for the `NilReasons` type.

func (*NilReasons) UnmarshalBinary added in v0.3.2

func (nilReasons *NilReasons) UnmarshalBinary(data []byte) error

UnmarshalBinary implements the `encoding.BinaryUnmarshaler` interface for the `NilReasons` type.

type Observer

type Observer interface {
	DidCommitBlock(block.Height)
	DidReceiveSufficientNilPrevotes(messages Messages, f int)
}

An Observer is notified when note-worthy events happen for the first time.

type Precommit

type Precommit struct {
	// contains filtered or unexported fields
}

Precommit a block hash.

func NewPrecommit

func NewPrecommit(height block.Height, round block.Round, blockHash id.Hash) *Precommit

func (*Precommit) BlockHash

func (precommit *Precommit) BlockHash() id.Hash

func (*Precommit) Height

func (precommit *Precommit) Height() block.Height

func (Precommit) MarshalBinary

func (precommit Precommit) MarshalBinary() ([]byte, error)

MarshalBinary implements the `encoding.BinaryMarshaler` interface for the `Precommit` type.

func (Precommit) MarshalJSON

func (precommit Precommit) MarshalJSON() ([]byte, error)

MarshalJSON implements the `json.Marshaler` interface for the `Precommit` type.

func (*Precommit) Round

func (precommit *Precommit) Round() block.Round

func (*Precommit) Sig

func (precommit *Precommit) Sig() id.Signature

func (*Precommit) SigHash

func (precommit *Precommit) SigHash() id.Hash

func (*Precommit) Signatory

func (precommit *Precommit) Signatory() id.Signatory

func (*Precommit) String

func (precommit *Precommit) String() string

func (*Precommit) Type

func (precommit *Precommit) Type() MessageType

func (*Precommit) UnmarshalBinary

func (precommit *Precommit) UnmarshalBinary(data []byte) error

UnmarshalBinary implements the `encoding.BinaryUnmarshaler` interface for the `Precommit` type.

func (*Precommit) UnmarshalJSON

func (precommit *Precommit) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the `json.Unmarshaler` interface for the `Precommit` type.

type Precommits

type Precommits []Precommit

Precommits is a wrapper around the `[]Precommit` type.

type Prevote

type Prevote struct {
	// contains filtered or unexported fields
}

Prevote for a block hash.

func NewPrevote

func NewPrevote(height block.Height, round block.Round, blockHash id.Hash, nilReasons NilReasons) *Prevote

func (*Prevote) BlockHash

func (prevote *Prevote) BlockHash() id.Hash

func (*Prevote) Height

func (prevote *Prevote) Height() block.Height

func (Prevote) MarshalBinary

func (prevote Prevote) MarshalBinary() ([]byte, error)

MarshalBinary implements the `encoding.BinaryMarshaler` interface for the `Prevote` type.

func (Prevote) MarshalJSON

func (prevote Prevote) MarshalJSON() ([]byte, error)

MarshalJSON implements the `json.Marshaler` interface for the `Prevote` type.

func (*Prevote) NilReasons added in v0.3.2

func (prevote *Prevote) NilReasons() NilReasons

func (*Prevote) Round

func (prevote *Prevote) Round() block.Round

func (*Prevote) Sig

func (prevote *Prevote) Sig() id.Signature

func (*Prevote) SigHash

func (prevote *Prevote) SigHash() id.Hash

func (*Prevote) Signatory

func (prevote *Prevote) Signatory() id.Signatory

func (*Prevote) String

func (prevote *Prevote) String() string

func (*Prevote) Type

func (prevote *Prevote) Type() MessageType

func (*Prevote) UnmarshalBinary

func (prevote *Prevote) UnmarshalBinary(data []byte) error

UnmarshalBinary implements the `encoding.BinaryUnmarshaler` interface for the `Prevote` type.

func (*Prevote) UnmarshalJSON

func (prevote *Prevote) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the `json.Unmarshaler` interface for the `Prevote` type.

type Prevotes

type Prevotes []Prevote

Prevotes is a wrapper around the `[]Prevote` type.

type Process

type Process struct {
	// contains filtered or unexported fields
}

A Process defines a state machine in the distributed replicated state machine. See https://arxiv.org/pdf/1807.04938.pdf for more information.

func New

func New(logger logrus.FieldLogger, signatory id.Signatory, blockchain Blockchain, state State, proposer Proposer, validator Validator, observer Observer, broadcaster Broadcaster, scheduler Scheduler, timer Timer) *Process

New Process initialised to the default state, starting in the first round.

func (*Process) HandleMessage

func (p *Process) HandleMessage(m Message)

HandleMessage is safe for concurrent use. See https://arxiv.org/pdf/1807.04938.pdf for more information.

func (Process) MarshalBinary

func (p Process) MarshalBinary() ([]byte, error)

MarshalBinary implements the `encoding.BinaryMarshaler` interface for the Process type, by marshaling its isolated State.

func (Process) MarshalJSON

func (p Process) MarshalJSON() ([]byte, error)

MarshalJSON implements the `json.Marshaler` interface for the Process type, by marshaling its isolated State.

func (*Process) Start

func (p *Process) Start()

Start the process.

func (*Process) StartRound

func (p *Process) StartRound(round block.Round)

StartRound is safe for concurrent use. See https://arxiv.org/pdf/1807.04938.pdf for more information.

func (*Process) UnmarshalBinary

func (p *Process) UnmarshalBinary(data []byte) error

UnmarshalBinary implements the `encoding.BinaryUnmarshaler` interface for the Process type, by unmarshaling its isolated State.

func (*Process) UnmarshalJSON

func (p *Process) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the `json.Unmarshaler` interface for the Process type, by unmarshaling its isolated State.

type Processes

type Processes []Process

Processes defines a wrapper type around the []Process type.

type Propose

type Propose struct {
	// contains filtered or unexported fields
}

Propose a block for committment.

func NewPropose

func NewPropose(height block.Height, round block.Round, block block.Block, validRound block.Round) *Propose

func (*Propose) Block

func (propose *Propose) Block() block.Block

func (*Propose) BlockHash

func (propose *Propose) BlockHash() id.Hash

func (*Propose) Height

func (propose *Propose) Height() block.Height

func (Propose) MarshalBinary

func (propose Propose) MarshalBinary() ([]byte, error)

MarshalBinary implements the `encoding.BinaryMarshaler` interface for the `Propose` type.

func (Propose) MarshalJSON

func (propose Propose) MarshalJSON() ([]byte, error)

MarshalJSON implements the `json.Marshaler` interface for the `Propose` type.

func (*Propose) Round

func (propose *Propose) Round() block.Round

func (*Propose) Sig

func (propose *Propose) Sig() id.Signature

func (*Propose) SigHash

func (propose *Propose) SigHash() id.Hash

func (*Propose) Signatory

func (propose *Propose) Signatory() id.Signatory

func (*Propose) String

func (propose *Propose) String() string

func (*Propose) Type

func (propose *Propose) Type() MessageType

func (*Propose) UnmarshalBinary

func (propose *Propose) UnmarshalBinary(data []byte) error

UnmarshalBinary implements the `encoding.BinaryUnmarshaler` interface for the `Propose` type.

func (*Propose) UnmarshalJSON

func (propose *Propose) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the `json.Unmarshaler` interface for the `Propose` type.

func (*Propose) ValidRound

func (propose *Propose) ValidRound() block.Round

type Proposer

type Proposer interface {
	BlockProposal(block.Height, block.Round) block.Block
}

A Proposer builds a `block.Block` for proposals.

type Proposes

type Proposes []Propose

Proposes is a wrapper around the `[]Propose` type.

type Resync added in v0.4.2

type Resync struct {
	// contains filtered or unexported fields
}

Resync previous messages.

func NewResync added in v0.4.2

func NewResync(height block.Height, round block.Round) *Resync

func (*Resync) BlockHash added in v0.4.2

func (resync *Resync) BlockHash() id.Hash

func (*Resync) Height added in v0.4.2

func (resync *Resync) Height() block.Height

func (Resync) MarshalBinary added in v1.1.0

func (resync Resync) MarshalBinary() ([]byte, error)

MarshalBinary implements the `encoding.BinaryMarshaler` interface for the `Resync` type.

func (Resync) MarshalJSON added in v1.1.0

func (resync Resync) MarshalJSON() ([]byte, error)

MarshalJSON implements the `json.Marshaler` interface for the `Resync` type.

func (*Resync) Round added in v0.4.2

func (resync *Resync) Round() block.Round

func (*Resync) Sig added in v0.4.2

func (resync *Resync) Sig() id.Signature

func (*Resync) SigHash added in v0.4.2

func (resync *Resync) SigHash() id.Hash

func (*Resync) Signatory added in v0.4.2

func (resync *Resync) Signatory() id.Signatory

func (*Resync) String added in v0.4.2

func (resync *Resync) String() string

func (*Resync) Type added in v0.4.2

func (resync *Resync) Type() MessageType

func (*Resync) UnmarshalBinary added in v1.1.0

func (resync *Resync) UnmarshalBinary(data []byte) error

UnmarshalBinary implements the `encoding.BinaryUnmarshaler` interface for the `Resync` type.

func (*Resync) UnmarshalJSON added in v1.1.0

func (resync *Resync) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the `json.Unmarshaler` interface for the `Resync` type.

type Resyncs added in v0.4.2

type Resyncs []Resync

Resyncs is a wrapper around the `[]Resync` type.

type Scheduler

type Scheduler interface {
	Schedule(block.Height, block.Round) id.Signatory
}

A Scheduler determines which `id.Signatory` should be broadcasting proposals in at a given `block.Height` and `block.Round`.

type State

type State struct {
	CurrentHeight block.Height `json:"currentHeight"`
	CurrentRound  block.Round  `json:"currentRound"`
	CurrentStep   Step         `json:"currentStep"`

	LockedBlock block.Block `json:"lockedBlock"` // the most recent block for which a precommit message has been sent
	LockedRound block.Round `json:"lockedRound"` // the last round in which the process sent a precommit message that is not nil.
	ValidBlock  block.Block `json:"validBlock"`  // store the most recent possible decision value
	ValidRound  block.Round `json:"validRound"`  // is the last round in which valid value is updated

	Proposals  *Inbox `json:"proposals"`
	Prevotes   *Inbox `json:"prevotes"`
	Precommits *Inbox `json:"precommits"`
}

The State of a Process. It is isolated from the Process so that it can be easily marshaled to/from JSON.

func DefaultState

func DefaultState(f int) State

DefaultState returns a State with all values set to the default. See https://arxiv.org/pdf/1807.04938.pdf for more information.

func (*State) Equal

func (state *State) Equal(other State) bool

Equal compares one State with another.

func (State) MarshalBinary

func (state State) MarshalBinary() ([]byte, error)

MarshalBinary implements the `encoding.BinaryMarshaler` interface for the `State` type.

func (*State) Reset

func (state *State) Reset(height block.Height)

Reset the State (not all values are reset). See https://arxiv.org/pdf/1807.04938.pdf for more information.

func (*State) UnmarshalBinary

func (state *State) UnmarshalBinary(data []byte) error

UnmarshalBinary implements the `encoding.BinaryUnmarshaler` interface for the `State` type.

type Step

type Step uint8

Step in the consensus algorithm.

const (
	StepNil Step = iota
	StepPropose
	StepPrevote
	StepPrecommit
)

Define all Steps.

type Timer

type Timer interface {
	Timeout(step Step, round block.Round) time.Duration
}

A Timer determines the timeout duration at a given Step and `block.Round`.

type Validator

type Validator interface {
	IsBlockValid(block block.Block, checkHistory bool) (NilReasons, error)
}

A Validator validates a `block.Block` that has been proposed.

Jump to

Keyboard shortcuts

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