Documentation ¶
Index ¶
Examples ¶
Constants ¶
View Source
const ( ConnectedPeersKey = "connectedPeers" TimeSinceLastMsgReceivedKey = "timeSinceLastMsgReceived" TimeSinceLastMsgSentKey = "timeSinceLastMsgSent" SendFailRateKey = "sendFailRate" )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct { HealthConfig `json:"healthConfig"` PeerListGossipConfig `json:"peerListGossipConfig"` TimeoutConfig `json:"timeoutConfigs"` DelayConfig `json:"delayConfig"` ThrottlerConfig ThrottlerConfig `json:"throttlerConfig"` ProxyEnabled bool `json:"proxyEnabled"` ProxyReadHeaderTimeout time.Duration `json:"proxyReadHeaderTimeout"` DialerConfig dialer.Config `json:"dialerConfig"` TLSConfig *tls.Config `json:"-"` TLSKeyLogFile string `json:"tlsKeyLogFile"` Namespace string `json:"namespace"` MyNodeID ids.NodeID `json:"myNodeID"` MyIPPort ips.DynamicIPPort `json:"myIP"` NetworkID uint32 `json:"networkID"` MaxClockDifference time.Duration `json:"maxClockDifference"` PingFrequency time.Duration `json:"pingFrequency"` AllowPrivateIPs bool `json:"allowPrivateIPs"` // The compression type to use when compressing outbound messages. // Assumes all peers support this compression type. CompressionType compression.Type `json:"compressionType"` // TLSKey is this node's TLS key that is used to sign IPs. TLSKey crypto.Signer `json:"-"` // TrackedSubnets of the node. TrackedSubnets set.Set[ids.ID] `json:"-"` Beacons validators.Set `json:"-"` // Validators are the current validators in the Odyssey network Validators validators.Manager `json:"-"` UptimeCalculator uptime.Calculator `json:"-"` // UptimeMetricFreq marks how frequently this node will recalculate the // observed average uptime metrics. UptimeMetricFreq time.Duration `json:"uptimeMetricFreq"` // UptimeRequirement is the fraction of time a validator must be online and // responsive for us to vote that they should receive a staking reward. UptimeRequirement float64 `json:"-"` // RequireValidatorToConnect require that all connections must have at least // one validator between the 2 peers. This can be useful to enable if the // node wants to connect to the minimum number of nodes without impacting // the network negatively. RequireValidatorToConnect bool `json:"requireValidatorToConnect"` // MaximumInboundMessageTimeout is the maximum deadline duration in a // message. Messages sent by clients setting values higher than this value // will be reset to this value. MaximumInboundMessageTimeout time.Duration `json:"maximumInboundMessageTimeout"` // Size, in bytes, of the buffer that we read peer messages into // (there is one buffer per peer) PeerReadBufferSize int `json:"peerReadBufferSize"` // Size, in bytes, of the buffer that we write peer messages into // (there is one buffer per peer) PeerWriteBufferSize int `json:"peerWriteBufferSize"` // Tracks the CPU/disk usage caused by processing messages of each peer. ResourceTracker tracker.ResourceTracker `json:"-"` // Specifies how much CPU usage each peer can cause before // we rate-limit them. CPUTargeter tracker.Targeter `json:"-"` // Specifies how much disk usage each peer can cause before // we rate-limit them. DiskTargeter tracker.Targeter `json:"-"` // Tracks which validators have been sent to which peers GossipTracker peer.GossipTracker `json:"-"` }
type DelayConfig ¶
type DelayConfig struct { // InitialReconnectDelay is the minimum amount of time the node will delay a // reconnection to a peer. This value is used to start the exponential // backoff. InitialReconnectDelay time.Duration `json:"initialReconnectDelay"` // MaxReconnectDelay is the maximum amount of time the node will delay a // reconnection to a peer. MaxReconnectDelay time.Duration `json:"maxReconnectDelay"` }
type HealthConfig ¶
type HealthConfig struct { // Marks if the health check should be enabled Enabled bool `json:"-"` // MinConnectedPeers is the minimum number of peers that the network should // be connected to to be considered healthy. MinConnectedPeers uint `json:"minConnectedPeers"` // MaxTimeSinceMsgReceived is the maximum amount of time since the network // last received a message to be considered healthy. MaxTimeSinceMsgReceived time.Duration `json:"maxTimeSinceMsgReceived"` // MaxTimeSinceMsgSent is the maximum amount of time since the network last // sent a message to be considered healthy. MaxTimeSinceMsgSent time.Duration `json:"maxTimeSinceMsgSent"` // MaxPortionSendQueueBytesFull is the maximum percentage of the pending // send byte queue that should be used for the network to be considered // healthy. Should be in (0,1]. MaxPortionSendQueueBytesFull float64 `json:"maxPortionSendQueueBytesFull"` // MaxSendFailRate is the maximum percentage of send attempts that should be // failing for the network to be considered healthy. This does not include // send attempts that were not made due to benching. Should be in [0,1]. MaxSendFailRate float64 `json:"maxSendFailRate"` // SendFailRateHalflife is the halflife of the averager used to calculate // the send fail rate percentage. Should be > 0. Larger values mean that the // fail rate is affected less by recently dropped messages. SendFailRateHalflife time.Duration `json:"sendFailRateHalflife"` }
HealthConfig describes parameters for network layer health checks.
type Network ¶
type Network interface { // All consensus messages can be sent through this interface. Thread safety // must be managed internally in the network. sender.ExternalSender // Has a health check health.Checker peer.Network // StartClose this network and all existing connections it has. Calling // StartClose multiple times is handled gracefully. StartClose() // Should only be called once, will run until either a fatal error occurs, // or the network is closed. Dispatch() error // WantsConnection returns true if this node is willing to attempt to // connect to the provided nodeID. If the node is attempting to connect to // the minimum number of peers, then it should only connect if the peer is a // validator or beacon. WantsConnection(ids.NodeID) bool // Attempt to connect to this IP. The network will never stop attempting to // connect to this ID. ManuallyTrack(nodeID ids.NodeID, ip ips.IPPort) // PeerInfo returns information about peers. If [nodeIDs] is empty, returns // info about all peers that have finished the handshake. Otherwise, returns // info about the peers in [nodeIDs] that have finished the handshake. PeerInfo(nodeIDs []ids.NodeID) []peer.Info // NodeUptime returns given node's [subnetID] UptimeResults in the view of // this node's peer validators. NodeUptime(subnetID ids.ID) (UptimeResult, error) }
Network defines the functionality of the networking library.
func NewNetwork ¶
func NewNetwork( config *Config, msgCreator message.Creator, metricsRegisterer prometheus.Registerer, log logging.Logger, listener net.Listener, dialer dialer.Dialer, router router.ExternalHandler, ) (Network, error)
NewNetwork returns a new Network implementation with the provided parameters.
func NewTestNetwork ¶
func NewTestNetwork( log logging.Logger, networkID uint32, currentValidators validators.Set, trackedSubnets set.Set[ids.ID], router router.ExternalHandler, ) (Network, error)
Example ¶
package main import ( "context" "os" "time" "go.uber.org/zap" "github.com/DioneProtocol/odysseygo/genesis" "github.com/DioneProtocol/odysseygo/ids" "github.com/DioneProtocol/odysseygo/message" "github.com/DioneProtocol/odysseygo/snow/networking/router" "github.com/DioneProtocol/odysseygo/snow/validators" "github.com/DioneProtocol/odysseygo/utils/constants" "github.com/DioneProtocol/odysseygo/utils/ips" "github.com/DioneProtocol/odysseygo/utils/logging" "github.com/DioneProtocol/odysseygo/utils/set" "github.com/DioneProtocol/odysseygo/version" ) var _ router.ExternalHandler = (*testExternalHandler)(nil) // Note: all of the external handler's methods are called on peer goroutines. It // is possible for multiple concurrent calls to happen with different NodeIDs. // However, a given NodeID will only be performing one call at a time. type testExternalHandler struct { log logging.Logger } // Note: HandleInbound will be called with raw P2P messages, the networking // implementation does not implicitly register timeouts, so this handler is only // called by messages explicitly sent by the peer. If timeouts are required, // that must be handled by the user of this utility. func (t *testExternalHandler) HandleInbound(_ context.Context, message message.InboundMessage) { t.log.Info( "receiving message", zap.Stringer("op", message.Op()), ) } func (t *testExternalHandler) Connected(nodeID ids.NodeID, version *version.Application, subnetID ids.ID) { t.log.Info( "connected", zap.Stringer("nodeID", nodeID), zap.Stringer("version", version), zap.Stringer("subnetID", subnetID), ) } func (t *testExternalHandler) Disconnected(nodeID ids.NodeID) { t.log.Info( "disconnected", zap.Stringer("nodeID", nodeID), ) } type testAggressiveValidatorSet struct { validators.Set } func (*testAggressiveValidatorSet) Contains(ids.NodeID) bool { return true } func main() { log := logging.NewLogger( "networking", logging.NewWrappedCore( logging.Info, os.Stdout, logging.Colors.ConsoleEncoder(), ), ) // Needs to be periodically updated by the caller to have the latest // validator set validators := &testAggressiveValidatorSet{ Set: validators.NewSet(), } // If we want to be able to communicate with non-primary network subnets, we // should register them here. trackedSubnets := set.Set[ids.ID]{} // Messages and connections are handled by the external handler. handler := &testExternalHandler{ log: log, } network, err := NewTestNetwork( log, constants.TestnetID, validators, trackedSubnets, handler, ) if err != nil { log.Fatal( "failed to create test network", zap.Error(err), ) return } // We need to initially connect to some nodes in the network before peer // gossip will enable connecting to all the remaining nodes in the network. bootstrappers := genesis.SampleBootstrappers(constants.TestnetID, 5) for _, bootstrapper := range bootstrappers { network.ManuallyTrack(bootstrapper.ID, ips.IPPort(bootstrapper.IP)) } // Typically network.StartClose() should be called based on receiving a // SIGINT or SIGTERM. For the example, we close the network after 15s. go log.RecoverAndPanic(func() { time.Sleep(15 * time.Second) network.StartClose() }) // network.Send(...) and network.Gossip(...) can be used here to send // messages to peers. // Calling network.Dispatch() will block until a fatal error occurs or // network.StartClose() is called. err = network.Dispatch() log.Info( "network exited", zap.Error(err), ) }
Output:
type PeerListGossipConfig ¶
type PeerListGossipConfig struct { // PeerListNumValidatorIPs is the number of validator IPs to gossip in every // gossip event. PeerListNumValidatorIPs uint32 `json:"peerListNumValidatorIPs"` // PeerListValidatorGossipSize is the number of validators to gossip the IPs // to in every IP gossip event. PeerListValidatorGossipSize uint32 `json:"peerListValidatorGossipSize"` // PeerListNonValidatorGossipSize is the number of non-validators to gossip // the IPs to in every IP gossip event. PeerListNonValidatorGossipSize uint32 `json:"peerListNonValidatorGossipSize"` // PeerListPeersGossipSize is the number of peers to gossip // the IPs to in every IP gossip event. PeerListPeersGossipSize uint32 `json:"peerListPeersGossipSize"` // PeerListGossipFreq is the frequency that this node will attempt to gossip // signed IPs to its peers. PeerListGossipFreq time.Duration `json:"peerListGossipFreq"` }
type ThrottlerConfig ¶
type ThrottlerConfig struct { InboundConnUpgradeThrottlerConfig throttling.InboundConnUpgradeThrottlerConfig `json:"inboundConnUpgradeThrottlerConfig"` InboundMsgThrottlerConfig throttling.InboundMsgThrottlerConfig `json:"inboundMsgThrottlerConfig"` OutboundMsgThrottlerConfig throttling.MsgByteThrottlerConfig `json:"outboundMsgThrottlerConfig"` MaxInboundConnsPerSec float64 `json:"maxInboundConnsPerSec"` }
type TimeoutConfig ¶
type TimeoutConfig struct { // PingPongTimeout is the maximum amount of time to wait for a Pong response // from a peer we sent a Ping to. PingPongTimeout time.Duration `json:"pingPongTimeout"` // ReadHandshakeTimeout is the maximum amount of time to wait for the peer's // connection upgrade to finish before starting the p2p handshake. ReadHandshakeTimeout time.Duration `json:"readHandshakeTimeout"` }
type UptimeResult ¶
type UptimeResult struct { // RewardingStakePercentage shows what percent of network stake thinks we're // above the uptime requirement. RewardingStakePercentage float64 // WeightedAveragePercentage is the average perceived uptime of this node, // weighted by stake. // Note that this is different from RewardingStakePercentage, which shows // the percent of the network stake that thinks this node is above the // uptime requirement. WeightedAveragePercentage is weighted by uptime. // i.e If uptime requirement is 85 and a peer reports 40 percent it will be // counted (40*weight) in WeightedAveragePercentage but not in // RewardingStakePercentage since 40 < 85 WeightedAveragePercentage float64 }
Click to show internal directories.
Click to hide internal directories.