announce

package
v0.0.0-...-697f13e Latest Latest
Warning

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

Go to latest
Published: Nov 7, 2022 License: GPL-3.0 Imports: 24 Imported by: 0

Documentation

Index

Constants

View Source
const (
	QueryEnodeGossipCooldownDuration         = 5 * time.Minute
	VersionCertificateGossipCooldownDuration = 5 * time.Minute
)

Variables

This section is empty.

Functions

func DecryptAndParseEnodeURL

func DecryptAndParseEnodeURL(ecdsa *istanbul.EcdsaInfo, encEnodeURL []byte) (*enode.Node, error)

DecryptAndParseEnodeURL decrypts an encrypted enodeURL with the given ecdsa key pair, and parses the resulting Node.

func NewAnnounceTaskState

func NewAnnounceTaskState(config *istanbul.Config) *announceTaskState

Types

type AddressProvider

type AddressProvider interface {
	SelfNode() *enode.Node
	ValidatorAddress() common.Address
}

AddressProvider provides the different addresses the announce manager needs

type AddressTime

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

func NewAddressTime

func NewAddressTime() *AddressTime

func (*AddressTime) Get

func (a *AddressTime) Get(addr common.Address) (time.Time, bool)

func (*AddressTime) RemoveIf

func (a *AddressTime) RemoveIf(predicate func(common.Address, time.Time) bool)

func (*AddressTime) Set

func (a *AddressTime) Set(addr common.Address, t time.Time)

type AnnounceState

type AnnounceState struct {
	ValEnodeTable           *ValidatorEnodeDB
	VersionCertificateTable *VersionCertificateDB

	LastVersionCertificatesGossiped *AddressTime
	LastQueryEnodeGossiped          *AddressTime
}

func NewAnnounceState

func NewAnnounceState(valEnodeTable *ValidatorEnodeDB, versionCertificateTable *VersionCertificateDB) *AnnounceState

type AnnounceStatePruner

type AnnounceStatePruner interface {
	Prune(*AnnounceState) error
}

func NewAnnounceStatePruner

func NewAnnounceStatePruner(retrieveValidatorConnSetFn func() (map[common.Address]bool, error)) AnnounceStatePruner

type EnodeCertificateMsgGenerator

type EnodeCertificateMsgGenerator interface {
	// GenerateEnodeCertificateMsgs generates a map of enode certificate messages.
	// One certificate message is generated for each external enode this node possesses generated for
	// each external enode this node possesses. A unproxied validator will have one enode, while a
	// proxied validator may have one for each proxy.. Each enode is a key in the returned map, and the
	// value is the certificate message.
	GenerateEnodeCertificateMsgs(ei *istanbul.EcdsaInfo, version uint) (map[enode.ID]*istanbul.EnodeCertMsg, error)
}

type EnodeCertificateMsgHolder

type EnodeCertificateMsgHolder interface {
	// Get gets the most recent enode certificate messages.
	// May be nil if no message was generated as a result of the core not being
	// started, or if a proxy has not received a message from its proxied validator
	Get() map[enode.ID]*istanbul.EnodeCertMsg
	Set(enodeCertMsgMap map[enode.ID]*istanbul.EnodeCertMsg) error
}

func NewLockedHolder

func NewLockedHolder() EnodeCertificateMsgHolder

type EnodeQuery

type EnodeQuery struct {
	RecipientAddress   common.Address
	RecipientPublicKey *ecdsa.PublicKey
	EnodeURL           string
}

type EnodeQueryGossiper

type EnodeQueryGossiper interface {
	// GossipEnodeQueries will generate, encrypt, and gossip through the p2p network a new
	// QueryEnodeMsg with the enodeQueries given.
	GossipEnodeQueries(*istanbul.EcdsaInfo, []*EnodeQuery) (*istanbul.Message, error)
}

func NewEnodeQueryGossiper

func NewEnodeQueryGossiper(announceVersion VersionReader, gossipFn func([]byte) error) EnodeQueryGossiper

type ExternalFacingEnodeGetter

type ExternalFacingEnodeGetter interface {
	// GetEnodeCertNodesAndDestAddresses will retrieve all the external facing external nodes for this validator
	// (one for each of it's proxies, or itself for standalone validators) for the purposes of generating enode certificates
	// for those enodes.  It will also return the destination validators for each enode certificate.  If the destAddress is a
	// `nil` value, then that means that the associated enode certificate should be sent to all of the connected validators.
	GetEnodeCertNodesAndDestAddresses() ([]*enode.Node, map[enode.ID][]common.Address, error)
}

func NewProxiedExternalFacingEnodeGetter

func NewProxiedExternalFacingEnodeGetter(getProxiesAndValAssignmentsFn func() ([]*proxy.Proxy, map[enode.ID][]common.Address, error)) ExternalFacingEnodeGetter

func NewSelfExternalFacingEnodeGetter

func NewSelfExternalFacingEnodeGetter(selfNodeFn func() *enode.Node) ExternalFacingEnodeGetter

type Manager

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

Manager is the facade and entry point for the implementation of the announce protocol. It exposes methods to start and stop the announce Worker, and to handle announce messages.

func NewManager

func NewManager(
	config *istanbul.Config,
	aWallets *atomic.Value,
	network Network, proxyContext ProxyContext,
	addrProvider AddressProvider, state *AnnounceState,
	gossipCache istanbul.GossipCache,
	checker ValidatorChecker,
	ovcp OutboundVersionCertificateProcessor,
	ecertHolder EnodeCertificateMsgHolder,
	vcGossiper VersionCertificateGossiper,
	vpap ValProxyAssigmnentProvider,
	worker Worker) *Manager

NewManager creates a new Manager using the valEnodeTable given. It is the responsibility of the caller to close the valEnodeTable, the Manager will not do it.

func (*Manager) Close

func (m *Manager) Close() error

func (*Manager) GetAnnounceVersion

func (m *Manager) GetAnnounceVersion() uint

GetAnnounceVersion will retrieve the current announce version.

func (*Manager) GetVersionCertificateTableInfo

func (m *Manager) GetVersionCertificateTableInfo() (map[string]*VersionCertificateEntryInfo, error)

func (*Manager) HandleEnodeCertificateMsg

func (m *Manager) HandleEnodeCertificateMsg(_ consensus.Peer, payload []byte) error

HandleEnodeCertificateMsg handles an enode certificate message for proxied and standalone validators.

func (*Manager) HandleQueryEnodeMsg

func (m *Manager) HandleQueryEnodeMsg(addr common.Address, peer consensus.Peer, payload []byte) error

HandleQueryEnodeMsg handles a queryEnodeMsg received by the p2p network, according to the announce protocol spec.

func (*Manager) HandleVersionCertificatesMsg

func (m *Manager) HandleVersionCertificatesMsg(addr common.Address, peer consensus.Peer, payload []byte) error

HandleVersionCertificatesMsg handles a versionCertificates received by the p2p network, according to the announce protocol spec.

func (*Manager) IsAnnounceRunning

func (m *Manager) IsAnnounceRunning() bool

IsAnnounceRunning returns true iff the anounce Worker thread is running, without locking for access.

func (*Manager) RetrieveEnodeCertificateMsgMap

func (m *Manager) RetrieveEnodeCertificateMsgMap() map[enode.ID]*istanbul.EnodeCertMsg

RetrieveEnodeCertificateMsgMap gets the most recent enode certificate messages. May be nil if no message was generated as a result of the core not being started, or if a proxy has not received a message from its proxied validator

func (*Manager) SendVersionCertificateTable

func (m *Manager) SendVersionCertificateTable(peer consensus.Peer) error

SendVersionCertificateTable sends all VersionCertificates this node has to a peer

func (*Manager) SetEnodeCertificateMsgMap

func (m *Manager) SetEnodeCertificateMsgMap(enodeCertMsgMap map[enode.ID]*istanbul.EnodeCertMsg) error

func (*Manager) StartAnnouncing

func (m *Manager) StartAnnouncing(onStart func() error) error

func (*Manager) StopAnnouncing

func (m *Manager) StopAnnouncing(onStop func() error) error

func (*Manager) UpdateAnnounceVersion

func (m *Manager) UpdateAnnounceVersion()

UpdateAnnounceVersion will asynchronously update the announce version.

func (*Manager) Worker

func (m *Manager) Worker() Worker

Worker returns the worker used by this manager.

type Network

type Network interface {
	// Gossip gossips protocol messages
	Gossip(payload []byte, ethMsgCode uint64) error
	// RetrieveValidatorConnSet returns the validator connection set
	RetrieveValidatorConnSet() (map[common.Address]bool, error)
	// Multicast will send the eth message (with the message's payload and msgCode field set to the params
	// payload and ethMsgCode respectively) to the nodes with the signing address in the destAddresses param.
	Multicast(destAddresses []common.Address, payload []byte, ethMsgCode uint64, sendToSelf bool) error
}

Network manages the communication needed for the announce protocol to work.

type OnNewEnodeCertsMsgSentFn

type OnNewEnodeCertsMsgSentFn func(map[enode.ID]*istanbul.EnodeCertMsg) error

type OutboundVersionCertificateProcessor

type OutboundVersionCertificateProcessor interface {
	Process(*AnnounceState, []*istanbul.VersionCertificate, common.Address) error
}

type PeerCounterFn

type PeerCounterFn func(purpose p2p.PurposeFlag) int

type ProxyContext

type ProxyContext interface {
	GetProxiedValidatorEngine() proxy.ProxiedValidatorEngine
}

type QueryEnodeEntryProvider

type QueryEnodeEntryProvider interface {
	GetQueryEnodeValEnodeEntries(enforceRetryBackoff bool, exceptAddress common.Address) ([]*istanbul.AddressEntry, error)
}

func NewQueryEnodeEntryProvider

func NewQueryEnodeEntryProvider(valEnodeTable *ValidatorEnodeDB) QueryEnodeEntryProvider

type QueryEnodeGossipFrequencyState

type QueryEnodeGossipFrequencyState int

QueryEnodeGossipFrequencyState specifies how frequently to gossip query enode messages

const (
	// HighFreqBeforeFirstPeerState will send out a query enode message every 1 minute until the first peer is established
	HighFreqBeforeFirstPeerState QueryEnodeGossipFrequencyState = iota

	// HighFreqAfterFirstPeerState will send out an query enode message every 1 minute for the first 10 query enode messages after the first peer is established.
	// This is on the assumption that when this node first establishes a peer, the p2p network that this node is in may
	// be partitioned with the broader p2p network. We want to give that p2p network some time to connect to the broader p2p network.
	HighFreqAfterFirstPeerState

	// LowFreqState will send out an query every config.AnnounceQueryEnodeGossipPeriod seconds
	LowFreqState
)

type ValEnodeEntryInfo

type ValEnodeEntryInfo struct {
	PublicKey                    string `json:"publicKey"`
	Enode                        string `json:"enode"`
	Version                      uint   `json:"version"`
	HighestKnownVersion          uint   `json:"highestKnownVersion"`
	NumQueryAttemptsForHKVersion uint   `json:"numQueryAttemptsForHKVersion"`
	LastQueryTimestamp           string `json:"lastQueryTimestamp"` // Unix timestamp
}

ValEnodeEntryInfo contains information for an entry of the val enode table

type ValProxyAssigmnentProvider

type ValProxyAssigmnentProvider interface {
	// GetValProxyAssignments returns the remote validator -> external node assignments.
	// If this is a standalone validator, it will set the external node to itself.
	// If this is a proxied validator, it will set external node to the proxy's external node.
	GetValProxyAssignments(valAddresses []common.Address) (map[common.Address]*enode.Node, error)
}

ValProxyAssigmentProvider is responsible for, given a list of validator addresses, returning a mapping <validator address, assigned eNode>, where each validator will be assigned to an external eNode this node. E.g if this node has two proxies: A and B, it is possible to assign A to a set of validators, and B to another set, therefore splitting the load of validator to validator connections through these proxies instances. If this node has no proxy, then all values should be the self eNode.

func NewProxiedValProxyAssigmentProvider

func NewProxiedValProxyAssigmentProvider(proxyAssigmentsFn func([]common.Address) (map[common.Address]*proxy.Proxy, error)) ValProxyAssigmnentProvider

func NewSelfValProxyAssigmentProvider

func NewSelfValProxyAssigmentProvider(selfNodeFn func() *enode.Node) ValProxyAssigmnentProvider

type ValidatorChecker

type ValidatorChecker interface {
	// IsElectedOrNearValidator returns true iff this node is currently a NearlyElectedValidator.
	IsElectedOrNearValidator() (bool, error)
	// IsValidating returns true iff the node is started and running as a Validator.
	IsValidating() bool
}

func NewValidatorChecker

func NewValidatorChecker(
	wallets *atomic.Value,
	retrieveValidatorConnSetFn func() (map[common.Address]bool, error),
	isValidatingFn func() bool) ValidatorChecker

type ValidatorEnodeDB

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

ValidatorEnodeDB represents a Map that can be accessed either by address or enode

func OpenValidatorEnodeDB

func OpenValidatorEnodeDB(path string, handler ValidatorEnodeHandler) (*ValidatorEnodeDB, error)

OpenValidatorEnodeDB opens a validator enode database for storing and retrieving infos about validator enodes. If no path is given an in-memory, temporary database is constructed.

func (*ValidatorEnodeDB) Close

func (vet *ValidatorEnodeDB) Close() error

Close flushes and closes the database files.

func (*ValidatorEnodeDB) GetAddressFromNodeID

func (vet *ValidatorEnodeDB) GetAddressFromNodeID(nodeID enode.ID) (common.Address, error)

GetAddressFromNodeID will return the address for an nodeID if it's known

func (*ValidatorEnodeDB) GetHighestKnownVersionFromAddress

func (vet *ValidatorEnodeDB) GetHighestKnownVersionFromAddress(address common.Address) (uint, error)

GetHighestKnownVersionFromAddress will return the highest known version for an address if it's known

func (*ValidatorEnodeDB) GetNodeFromAddress

func (vet *ValidatorEnodeDB) GetNodeFromAddress(address common.Address) (*enode.Node, error)

GetNodeFromAddress will return the enodeURL for an address if it's known

func (*ValidatorEnodeDB) GetValEnodes

func (vet *ValidatorEnodeDB) GetValEnodes(valAddresses []common.Address) (map[common.Address]*istanbul.AddressEntry, error)

GetValEnodes will return entries in the valEnodeDB filtered on the valAddresses parameter. If it's set to nil, then no filter will be applied.

func (*ValidatorEnodeDB) GetVersionFromAddress

func (vet *ValidatorEnodeDB) GetVersionFromAddress(address common.Address) (uint, error)

GetVersionFromAddress will return the version for an address if it's known

func (*ValidatorEnodeDB) PruneEntries

func (vet *ValidatorEnodeDB) PruneEntries(addressesToKeep map[common.Address]bool) error

PruneEntries will remove entries for all address not present in addressesToKeep

func (*ValidatorEnodeDB) RefreshValPeers

func (vet *ValidatorEnodeDB) RefreshValPeers(valConnSet map[common.Address]bool, ourAddress common.Address)

func (*ValidatorEnodeDB) RemoveEntry

func (vet *ValidatorEnodeDB) RemoveEntry(address common.Address) error

RemoveEntry will remove an entry from the table

func (*ValidatorEnodeDB) String

func (vet *ValidatorEnodeDB) String() string

func (*ValidatorEnodeDB) UpdateQueryEnodeStats

func (vet *ValidatorEnodeDB) UpdateQueryEnodeStats(valEnodeEntries []*istanbul.AddressEntry) error

UpdateQueryEnodeStats function will do the following 1. Increment each entry's NumQueryAttemptsForHKVersion by 1 is existing HighestKnownVersion is the same 2. Set each entry's LastQueryTimestamp to the current time

func (*ValidatorEnodeDB) UpsertHighestKnownVersion

func (vet *ValidatorEnodeDB) UpsertHighestKnownVersion(valEnodeEntries []*istanbul.AddressEntry) error

UpsertHighestKnownVersion function will do the following 1. Check if the updated HighestKnownVersion is higher than the existing HighestKnownVersion 2. Update the fields HighestKnownVersion, NumQueryAttempsForHKVersion, and PublicKey

func (*ValidatorEnodeDB) UpsertVersionAndEnode

func (vet *ValidatorEnodeDB) UpsertVersionAndEnode(valEnodeEntries []*istanbul.AddressEntry) error

UpsertVersionAndEnode will do the following 1. Check if the updated Version higher than the existing Version 2. Update Node, Version, HighestKnownVersion (if it's less than the new Version) 3. If the Node has been updated, establish new validator peer

func (*ValidatorEnodeDB) ValEnodeTableInfo

func (vet *ValidatorEnodeDB) ValEnodeTableInfo() (map[string]*ValEnodeEntryInfo, error)

ValEnodeTableInfo gives basic information for each entry of the table

type ValidatorEnodeHandler

type ValidatorEnodeHandler interface {
	// AddValidatorPeer adds a validator peer
	AddValidatorPeer(node *enode.Node, address common.Address)

	// RemoveValidatorPeer removes a validator peer
	RemoveValidatorPeer(node *enode.Node)

	// ReplaceValidatorPeers replace all validator peers for new list of enodeURLs
	ReplaceValidatorPeers(newNodes []*enode.Node)

	// Clear all validator peers
	ClearValidatorPeers()
}

ValidatorEnodeHandler is handler to Add/Remove events. Events execute within write lock

type Version

type Version interface {
	Get() uint
	Set(version uint)
}

func NewAtomicVersion

func NewAtomicVersion() Version

type VersionCertificateDB

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

VersionCertificateDB stores

func OpenVersionCertificateDB

func OpenVersionCertificateDB(path string) (*VersionCertificateDB, error)

OpenVersionCertificateDB opens a signed announce version database for storing VersionCertificates. If no path is given an in-memory, temporary database is constructed.

func (*VersionCertificateDB) Close

func (svdb *VersionCertificateDB) Close() error

Close flushes and closes the database files.

func (*VersionCertificateDB) Get

Get gets the istanbul.VersionCertificateEntry entry with address `address`. Returns an error if no entry exists.

func (*VersionCertificateDB) GetAll

GetAll gets each istanbul.VersionCertificateEntry in the db

func (*VersionCertificateDB) GetVersion

func (svdb *VersionCertificateDB) GetVersion(address common.Address) (uint, error)

GetVersion gets the version for the entry with address `address` Returns an error if no entry exists

func (*VersionCertificateDB) Info

Info gives a map VersionCertificateEntryInfo where each key is the address. Intended for RPC use

func (*VersionCertificateDB) Prune

func (svdb *VersionCertificateDB) Prune(addressesToKeep map[common.Address]bool) error

Prune will remove entries for all addresses not present in addressesToKeep

func (*VersionCertificateDB) Remove

func (svdb *VersionCertificateDB) Remove(address common.Address) error

Remove will remove an entry from the table

func (*VersionCertificateDB) String

func (svdb *VersionCertificateDB) String() string

String gives a string representation of the entire db

func (*VersionCertificateDB) Upsert

Upsert inserts any new entries or entries with a Version higher than the existing version. Returns any new or updated entries

type VersionCertificateEntryInfo

type VersionCertificateEntryInfo struct {
	Address string `json:"address"`
	Version uint   `json:"version"`
}

VersionCertificateEntryInfo gives basic information for an entry in the DB

type VersionCertificateGossiper

type VersionCertificateGossiper interface {
	// GossipAllFrom gossips all version certificates to every peer. Only the entries
	// that are new to a node will end up being regossiped throughout the
	// network.
	GossipAllFrom(*VersionCertificateDB) error
	// SendAllFrom sends all VersionCertificates this node
	// has to a specific peer.
	SendAllFrom(*VersionCertificateDB, consensus.Peer) error
	// Gossip will send the given version certificates to all peers.
	Gossip(versionCertificates []*istanbul.VersionCertificate) error
}

func NewVcGossiper

func NewVcGossiper(gossipFunction func(payload []byte) error) VersionCertificateGossiper

type VersionReader

type VersionReader interface {
	Get() uint
}

type VersionSharer

type VersionSharer interface {
	// ShareVersion generates announce data structures and
	// and shares them with relevant nodes.
	// It will:
	//  1) Generate a new enode certificate
	//  2) Multicast the new enode certificate to all peers in the validator conn set
	//	   * Note: If this is a proxied validator, it's multicast message will be wrapped within a forward
	//       message to the proxy, which will in turn send the enode certificate to remote validators.
	//  3) Generate a new version certificate
	//  4) Gossip the new version certificate to all peers
	ShareVersion(version uint) error
}

func NewVersionSharer

func NewVersionSharer(
	aWallets *atomic.Value,
	network Network,
	state *AnnounceState,
	ovcp OutboundVersionCertificateProcessor,
	ecertGenerator EnodeCertificateMsgGenerator,
	ecertHolder EnodeCertificateMsgHolder,
	onNewEnodeMsgsFn OnNewEnodeCertsMsgSentFn,
) VersionSharer

type Worker

type Worker interface {
	Run()
	UpdateVersion()
	GetVersion() uint
	Stop()

	// UpdateVersionTo is only public for testing purposes
	UpdateVersionTo(version uint) error
	// GenerateAndGossipQueryEnode is only public for testing purposes
	GenerateAndGossipQueryEnode(enforceRetryBackoff bool) (*istanbul.Message, error)
}

Worker is responsible for, while running, spawn all messages that this node should send: VersionCertificates sharing, and QueryEnode messages if the node is a NearlyElectedValidator.

It automatically polls to check if it entered (or exited) NearlyElectedValidator status.

It also periodically runs Prune in an AnnounceStatePruner.

func NewWorker

func NewWorker(initialWaitPeriod time.Duration,
	aWallets *atomic.Value,
	version Version,
	state *AnnounceState,
	checker ValidatorChecker,
	pruner AnnounceStatePruner,
	vcGossiper VersionCertificateGossiper,
	enodeGossiper EnodeQueryGossiper,
	config *istanbul.Config,
	countPeersFn PeerCounterFn,
	vpap ValProxyAssigmnentProvider,
	avs VersionSharer) Worker

Jump to

Keyboard shortcuts

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