istanbul

package
v0.0.0-...-f5c8f65 Latest Latest
Warning

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

Go to latest
Published: Apr 3, 2020 License: GPL-3.0 Imports: 18 Imported by: 0

Documentation

Index

Constants

View Source
const (
	MsgPreprepare uint64 = iota
	MsgPrepare
	MsgCommit
	MsgRoundChange
)

Variables

View Source
var (
	// ErrUnauthorizedAddress is returned when given address cannot be found in
	// current validator set.
	ErrUnauthorizedAddress = errors.New("not an elected validator")
	// ErrInvalidSigner is returned if a message's signature does not correspond to the address in msg.Address
	ErrInvalidSigner = errors.New("signed by incorrect validator")
	// ErrStoppedEngine is returned if the engine is stopped
	ErrStoppedEngine = errors.New("stopped engine")
	// ErrStartedEngine is returned if the engine is already started
	ErrStartedEngine = errors.New("started engine")
	// ErrStoppedAnnounce is returned if announce is stopped
	ErrStoppedAnnounce = errors.New("stopped announce")
	// ErrStartedAnnounce is returned if announce is already started
	ErrStartedAnnounce = errors.New("started announce")
	// ErrStoppedVPHThread is returned if validator peer handler thread is stopped
	ErrStoppedVPHThread = errors.New("stopped validator peer handler thread")
	// ErrStartedVPHThread is returned if validator peer handler thread is already started
	ErrStartedVPHThread = errors.New("started validator peer handler thread")
)
View Source
var DefaultConfig = &Config{
	RequestTimeout:                 3000,
	TimeoutBackoffFactor:           1000,
	MinResendRoundChangeTimeout:    15 * 1000,
	MaxResendRoundChangeTimeout:    2 * 60 * 1000,
	BlockPeriod:                    1,
	ProposerPolicy:                 ShuffledRoundRobin,
	Epoch:                          30000,
	LookbackWindow:                 12,
	ValidatorEnodeDBPath:           "validatorenodes",
	VersionCertificateDBPath:       "versioncertificates",
	RoundStateDBPath:               "roundstates",
	Proxy:                          false,
	Proxied:                        false,
	AnnounceQueryEnodeGossipPeriod: 300,
	AnnounceAggressiveQueryEnodeGossipOnEnablement: true,
	AnnounceAdditionalValidatorsToGossip:           10,
}

Functions

func CheckValidatorSignature

func CheckValidatorSignature(valSet ValidatorSet, data []byte, sig []byte) (common.Address, error)

func CompareValidatorPublicKeySlices

func CompareValidatorPublicKeySlices(valSet1 []blscrypto.SerializedPublicKey, valSet2 []blscrypto.SerializedPublicKey) bool

func CompareValidatorSlices

func CompareValidatorSlices(valSet1 []common.Address, valSet2 []common.Address) bool

This function assumes that valSet1 and valSet2 are ordered in the same way

func ConvertPublicKeysToStringSlice

func ConvertPublicKeysToStringSlice(publicKeys []blscrypto.SerializedPublicKey) []string

func GetEpochFirstBlockNumber

func GetEpochFirstBlockNumber(epochNumber uint64, epochSize uint64) (uint64, error)

func GetEpochLastBlockNumber

func GetEpochLastBlockNumber(epochNumber uint64, epochSize uint64) uint64

func GetEpochNumber

func GetEpochNumber(number uint64, epochSize uint64) uint64

Retrieves the epoch number given the block number. There is a special case if the number == 0 (the genesis block). That block will be in the 1st epoch.

func GetNodeID

func GetNodeID(enodeURL string) (*enode.ID, error)

func GetNumberWithinEpoch

func GetNumberWithinEpoch(number uint64, epochSize uint64) uint64

Retrieves the block number within an epoch. The return value will be 1-based. There is a special case if the number == 0. It is basically the last block of the 0th epoch, and should have a value of epochSize

func GetSignatureAddress

func GetSignatureAddress(data []byte, sig []byte) (common.Address, error)

GetSignatureAddress gets the signer address from the signature

func GetValScoreTallyFirstBlockNumber

func GetValScoreTallyFirstBlockNumber(epochNumber uint64, epochSize uint64, lookbackWindowSize uint64) uint64

func GetValScoreTallyLastBlockNumber

func GetValScoreTallyLastBlockNumber(epochNumber uint64, epochSize uint64) uint64

func IsFirstBlockOfEpoch

func IsFirstBlockOfEpoch(number uint64, epochSize uint64) bool

func IsLastBlockOfEpoch

func IsLastBlockOfEpoch(number uint64, epochSize uint64) bool

func MapMessagesToSenders

func MapMessagesToSenders(messages []Message) []common.Address

MapMessagesToSenders map a list of Messages to the list of the sender addresses

func MapValidatorsToAddresses

func MapValidatorsToAddresses(validators []Validator) []common.Address

MapValidatorsToAddresses maps a slice of validator to a slice of addresses

func NewIstLogger

func NewIstLogger(fn func() *big.Int, ctx ...interface{}) log.Logger

NewIstLogger creates an Istanbul Logger with custom logic for exposing logs

func RLPHash

func RLPHash(v interface{}) (h common.Hash)

func SeparateValidatorDataIntoIstanbulExtra

func SeparateValidatorDataIntoIstanbulExtra(validators []ValidatorData) ([]common.Address, []blscrypto.SerializedPublicKey)

Types

type BLSMessageSignerFn

type BLSMessageSignerFn func(accounts.Account, []byte, []byte) (blscrypto.SerializedSignature, error)

BLSMessageSignerFn is a signer callback function to request a raw message to be signed by a backing account.

type BLSSignerFn

type BLSSignerFn func(accounts.Account, []byte) (blscrypto.SerializedSignature, error)

BLSSignerFn is a signer callback function to request a hash to be signed by a backing account using BLS.

type Backend

type Backend interface {
	// Address returns the owner's address
	Address() common.Address

	// Validators returns the validator set
	Validators(proposal Proposal) ValidatorSet
	NextBlockValidators(proposal Proposal) (ValidatorSet, error)

	// EventMux returns the event mux in backend
	EventMux() *event.TypeMux

	// BroadcastConsensusMsg sends a message to all validators (include self)
	BroadcastConsensusMsg(validators []common.Address, payload []byte) error

	// Multicast sends a message to it's connected nodes filtered on the 'addresses' parameter (where each address
	// is associated with those node's signing key)
	// If that parameter is nil, then it will send the message to all it's connected peers.
	Multicast(addresses []common.Address, payload []byte, ethMsgCode uint64) error

	// Commit delivers an approved proposal to backend.
	// The delivered proposal will be put into blockchain.
	Commit(proposal Proposal, aggregatedSeal types.IstanbulAggregatedSeal, aggregatedEpochValidatorSetSeal types.IstanbulEpochValidatorSetSeal) error

	// Verify verifies the proposal. If a consensus.ErrFutureBlock error is returned,
	// the time difference of the proposal and current time is also returned.
	Verify(Proposal) (time.Duration, error)

	// Sign signs input data with the backend's private key
	Sign([]byte) ([]byte, error)
	SignBlockHeader([]byte) (blscrypto.SerializedSignature, error)
	SignBLSWithCompositeHash([]byte) (blscrypto.SerializedSignature, error)

	// CheckSignature verifies the signature by checking if it's signed by
	// the given validator
	CheckSignature(data []byte, addr common.Address, sig []byte) error

	// GetCurrentHeadBlock retrieves the last block
	GetCurrentHeadBlock() Proposal

	// GetCurrentHeadBlockAndAuthor retrieves the last block alongside the author for that block
	GetCurrentHeadBlockAndAuthor() (Proposal, common.Address)

	// LastSubject retrieves latest committed subject (view and digest)
	LastSubject() (Subject, error)

	// HasBlock checks if the combination of the given hash and height matches any existing blocks
	HasBlock(hash common.Hash, number *big.Int) bool

	// AuthorForBlock returns the proposer of the given block height
	AuthorForBlock(number uint64) common.Address

	// ParentBlockValidators returns the validator set of the given proposal's parent block
	ParentBlockValidators(proposal Proposal) ValidatorSet

	// RefreshValPeers will connect with all the validators in the validator connection set and disconnect validator peers that are not in the set
	RefreshValPeers() error

	// Authorize injects a private key into the consensus engine.
	Authorize(address common.Address, publicKey *ecdsa.PublicKey, decryptFn DecryptFn, signFn SignerFn, signHashBLSFn BLSSignerFn, signMessageBLSFn BLSMessageSignerFn)
}

Backend provides application specific functions for Istanbul core

type CommittedSubject

type CommittedSubject struct {
	Subject               *Subject
	CommittedSeal         []byte
	EpochValidatorSetSeal []byte
}

type Config

type Config struct {
	RequestTimeout              uint64         `toml:",omitempty"` // The timeout for each Istanbul round in milliseconds.
	TimeoutBackoffFactor        uint64         `toml:",omitempty"` // Timeout at subsequent rounds is: RequestTimeout + 2**round * TimeoutBackoffFactor (in milliseconds)
	MinResendRoundChangeTimeout uint64         `toml:",omitempty"` // Minimum interval with which to resend RoundChange messages for same round
	MaxResendRoundChangeTimeout uint64         `toml:",omitempty"` // Maximum interval with which to resend RoundChange messages for same round
	BlockPeriod                 uint64         `toml:",omitempty"` // Default minimum difference between two consecutive block's timestamps in second
	ProposerPolicy              ProposerPolicy `toml:",omitempty"` // The policy for proposer selection
	Epoch                       uint64         `toml:",omitempty"` // The number of blocks after which to checkpoint and reset the pending votes
	LookbackWindow              uint64         `toml:",omitempty"` // The window of blocks in which a validator is forgived from voting
	ValidatorEnodeDBPath        string         `toml:",omitempty"` // The location for the validator enodes DB
	VersionCertificateDBPath    string         `toml:",omitempty"` // The location for the signed announce version DB
	RoundStateDBPath            string         `toml:",omitempty"` // The location for the round states DB

	// Proxy Configs
	Proxy                   bool           `toml:",omitempty"` // Specifies if this node is a proxy
	ProxiedValidatorAddress common.Address `toml:",omitempty"` // The address of the proxied validator

	// Proxied Validator Configs
	Proxied                 bool        `toml:",omitempty"` // Specifies if this node is proxied
	ProxyInternalFacingNode *enode.Node `toml:",omitempty"` // The internal facing node of the proxy that this proxied validator will contect to
	ProxyExternalFacingNode *enode.Node `toml:",omitempty"` // The external facing node of the proxy that the proxied validator will broadcast via the announce message

	// Announce Configs
	AnnounceQueryEnodeGossipPeriod                 uint64 `toml:",omitempty"` // Time duration (in seconds) between gossiped query enode messages
	AnnounceAggressiveQueryEnodeGossipOnEnablement bool   `toml:",omitempty"` // Specifies if this node should aggressively query enodes on announce enablement
	AnnounceAdditionalValidatorsToGossip           int64  `toml:",omitempty"` // Specifies the number of additional non-elected validators to gossip an announce
}

type DecryptFn

type DecryptFn func(accounts.Account, []byte, []byte, []byte) ([]byte, error)

Decrypt is a decrypt callback function to request an ECIES ciphertext to be decrypted

type FinalCommittedEvent

type FinalCommittedEvent struct {
}

FinalCommittedEvent is posted when a proposal is committed

type ForwardMessage

type ForwardMessage struct {
	Code          uint64
	Msg           []byte
	DestAddresses []common.Address
}

type Message

type Message struct {
	Code      uint64
	Msg       []byte
	Address   common.Address // The sender address
	Signature []byte         // Signature of the Message using the private key associated with the "Address" field
}

func (*Message) Copy

func (m *Message) Copy() *Message

func (*Message) Decode

func (m *Message) Decode(val interface{}) error

func (*Message) FromPayload

func (m *Message) FromPayload(b []byte, validateFn func([]byte, []byte) (common.Address, error)) error

func (*Message) Payload

func (m *Message) Payload() ([]byte, error)

func (*Message) PayloadNoSig

func (m *Message) PayloadNoSig() ([]byte, error)

func (*Message) Sign

func (m *Message) Sign(signingFn func(data []byte) ([]byte, error)) error

func (*Message) String

func (m *Message) String() string

type MessageEvent

type MessageEvent struct {
	Payload []byte
}

MessageEvent is posted for Istanbul engine communication

type PreparedCertificate

type PreparedCertificate struct {
	Proposal                Proposal
	PrepareOrCommitMessages []Message
}

func EmptyPreparedCertificate

func EmptyPreparedCertificate() PreparedCertificate

func (*PreparedCertificate) AsData

func (*PreparedCertificate) DecodeRLP

func (pc *PreparedCertificate) DecodeRLP(s *rlp.Stream) error

DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream.

func (*PreparedCertificate) EncodeRLP

func (pc *PreparedCertificate) EncodeRLP(w io.Writer) error

EncodeRLP serializes b into the Ethereum RLP format.

func (*PreparedCertificate) IsEmpty

func (pc *PreparedCertificate) IsEmpty() bool

func (*PreparedCertificate) Summary

type PreparedCertificateData

type PreparedCertificateData struct {
	Proposal                *types.Block
	PrepareOrCommitMessages []Message
}

type PreparedCertificateSummary

type PreparedCertificateSummary struct {
	ProposalHash   common.Hash      `json:"proposalHash"`
	PrepareSenders []common.Address `json:"prepareSenders"`
	CommitSenders  []common.Address `json:"commitSenders"`
}

type Preprepare

type Preprepare struct {
	View                   *View
	Proposal               Proposal
	RoundChangeCertificate RoundChangeCertificate
}

func (*Preprepare) AsData

func (pp *Preprepare) AsData() *PreprepareData

func (*Preprepare) DecodeRLP

func (pp *Preprepare) DecodeRLP(s *rlp.Stream) error

DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream.

func (*Preprepare) EncodeRLP

func (pp *Preprepare) EncodeRLP(w io.Writer) error

EncodeRLP serializes b into the Ethereum RLP format.

func (*Preprepare) HasRoundChangeCertificate

func (pp *Preprepare) HasRoundChangeCertificate() bool

func (*Preprepare) Summary

func (pp *Preprepare) Summary() *PreprepareSummary

type PreprepareData

type PreprepareData struct {
	View                   *View
	Proposal               *types.Block
	RoundChangeCertificate RoundChangeCertificate
}

type PreprepareSummary

type PreprepareSummary struct {
	View                          *View            `json:"view"`
	ProposalHash                  common.Hash      `json:"proposalHash"`
	RoundChangeCertificateSenders []common.Address `json:"roundChangeCertificateSenders"`
}

type Proposal

type Proposal interface {
	// Number retrieves the sequence number of this proposal.
	Number() *big.Int

	Header() *types.Header

	// Hash retrieves the hash of this block
	Hash() common.Hash

	// ParentHash retrieves the hash of this block's parent
	ParentHash() common.Hash

	EncodeRLP(w io.Writer) error

	DecodeRLP(s *rlp.Stream) error
}

Proposal supports retrieving height and serialized block to be used during Istanbul consensus.

type ProposerPolicy

type ProposerPolicy uint64
const (
	RoundRobin ProposerPolicy = iota
	Sticky
	ShuffledRoundRobin
)

type ProposerSelector

type ProposerSelector func(validatorSet ValidatorSet, lastBlockProposer common.Address, currentRound uint64) Validator

ProposerSelector returns the block proposer for a round given the last proposer, round number, and randomness.

type Request

type Request struct {
	Proposal Proposal
}

func (*Request) DecodeRLP

func (b *Request) DecodeRLP(s *rlp.Stream) error

DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream.

func (*Request) EncodeRLP

func (b *Request) EncodeRLP(w io.Writer) error

EncodeRLP serializes b into the Ethereum RLP format.

type RequestEvent

type RequestEvent struct {
	Proposal Proposal
}

RequestEvent is posted to propose a proposal

type RoundChange

type RoundChange struct {
	View                *View
	PreparedCertificate PreparedCertificate
}

func (*RoundChange) DecodeRLP

func (b *RoundChange) DecodeRLP(s *rlp.Stream) error

DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream.

func (*RoundChange) EncodeRLP

func (b *RoundChange) EncodeRLP(w io.Writer) error

EncodeRLP serializes b into the Ethereum RLP format.

func (*RoundChange) HasPreparedCertificate

func (b *RoundChange) HasPreparedCertificate() bool

type RoundChangeCertificate

type RoundChangeCertificate struct {
	RoundChangeMessages []Message
}

func (*RoundChangeCertificate) IsEmpty

func (b *RoundChangeCertificate) IsEmpty() bool

type SignerFn

type SignerFn func(accounts.Account, string, []byte) ([]byte, error)

SignerFn is a signer callback function to request a header to be signed by a backing account.

type Subject

type Subject struct {
	View   *View
	Digest common.Hash
}

func (*Subject) String

func (s *Subject) String() string

type Uptime

type Uptime struct {
	LatestBlock uint64
	Entries     []UptimeEntry
}

Uptime contains the latest block for which uptime metrics were accounted for. It also contains an array of Entries where the `i`th entry represents the uptime statistics of the `i`th validator in the validator set for that epoch

type UptimeEntry

type UptimeEntry struct {
	ScoreTally      uint64
	LastSignedBlock uint64
}

UptimeEntry contains the uptime score of a validator during an epoch as well as the last block they signed on

func (*UptimeEntry) String

func (u *UptimeEntry) String() string

type Validator

type Validator interface {
	fmt.Stringer

	// Address returns address
	Address() common.Address

	BLSPublicKey() blscrypto.SerializedPublicKey

	// Serialize returns binary reprenstation of the Validator
	// can be use used to instantiate a validator with DeserializeValidator()
	Serialize() ([]byte, error)

	// AsData returns Validator representation as ValidatorData
	AsData() *ValidatorData
}

type ValidatorData

type ValidatorData struct {
	Address      common.Address
	BLSPublicKey blscrypto.SerializedPublicKey
}

func CombineIstanbulExtraToValidatorData

func CombineIstanbulExtraToValidatorData(addrs []common.Address, blsPublicKeys []blscrypto.SerializedPublicKey) ([]ValidatorData, error)

func ValidatorSetDiff

func ValidatorSetDiff(oldValSet []ValidatorData, newValSet []ValidatorData) ([]ValidatorData, *big.Int)

type ValidatorSet

type ValidatorSet interface {
	fmt.Stringer

	// Sets the randomness for use in the proposer policy.
	// This is injected into the ValidatorSet when we call `getOrderedValidators`
	SetRandomness(seed common.Hash)
	// Sets the randomness for use in the proposer policy
	GetRandomness() common.Hash

	// Return the validator size
	Size() int
	// Get the maximum number of faulty nodes
	F() int
	// Get the minimum quorum size
	MinQuorumSize() int

	// List returns all the validators
	List() []Validator
	// Return the validator index
	GetIndex(addr common.Address) int
	// Get validator by index
	GetByIndex(i uint64) Validator
	// Get validator by given address
	GetByAddress(addr common.Address) (int, Validator)
	// CointainByAddress indicates if a validator with the given address is present
	ContainsByAddress(add common.Address) bool

	// Add validators
	AddValidators(validators []ValidatorData) bool
	// Remove validators
	RemoveValidators(removedValidators *big.Int) bool
	// Copy validator set
	Copy() ValidatorSet

	// Serialize returns binary reprentation of the ValidatorSet
	// can be use used to instantiate a validator with DeserializeValidatorSet()
	Serialize() ([]byte, error)
}

type ValidatorSetData

type ValidatorSetData struct {
	Validators []ValidatorData
	Randomness common.Hash
}

type ValidatorsDataByAddress

type ValidatorsDataByAddress []ValidatorData

func (ValidatorsDataByAddress) Len

func (a ValidatorsDataByAddress) Len() int

func (ValidatorsDataByAddress) Less

func (a ValidatorsDataByAddress) Less(i, j int) bool

func (ValidatorsDataByAddress) Swap

func (a ValidatorsDataByAddress) Swap(i, j int)

type View

type View struct {
	Round    *big.Int
	Sequence *big.Int
}

View includes a round number and a sequence number. Sequence is the block number we'd like to commit. Each round has a number and is composed by 3 steps: preprepare, prepare and commit.

If the given block is not accepted by validators, a round change will occur and the validators start a new round with round+1.

func (*View) Cmp

func (v *View) Cmp(y *View) int

Cmp compares v and y and returns:

-1 if v <  y
 0 if v == y
+1 if v >  y

func (*View) String

func (v *View) String() string

Directories

Path Synopsis
random
Package random implements a language independent method of producing random validator orderings.
Package random implements a language independent method of producing random validator orderings.

Jump to

Keyboard shortcuts

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