brdcst

package
v2.0.0-...-03adce6 Latest Latest
Warning

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

Go to latest
Published: Sep 28, 2023 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package brdcst contains state machines that implement algorithms for broadcasting records into the DHT network.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Broadcast

Broadcast is a type alias for a specific kind of state machine that any kind of broadcast strategy state machine must implement. Currently, there are the FollowUp and Static state machines.

type BroadcastEvent

type BroadcastEvent interface {
	// contains filtered or unexported methods
}

BroadcastEvent is an event intended to advance the state of a Broadcast state machine. Broadcast state machines only operate on events that implement this interface. An "Event" is the opposite of a "State." An "Event" flows into the state machine and a "State" flows out of it.

Currently, there are the FollowUp and Static state machines.

type BroadcastState

type BroadcastState interface {
	// contains filtered or unexported methods
}

BroadcastState must be implemented by all states that a Broadcast state machine can reach. There are multiple different broadcast state machines that all have in common to "emit" a BroadcastState and accept a BroadcastEvent. Recall, states are basically the "events" that a state machine emits which other state machines or behaviours could react upon.

type Config

type Config interface {
	// contains filtered or unexported methods
}

Config is an interface that all broadcast configurations must implement. Because we have multiple ways of broadcasting records to the network, like FollowUp or Static, the EventPoolStartBroadcast has a configuration field that depending on the concrete type of Config initializes the respective state machine. Then the broadcast operation will be performed based on the encoded rules in that state machine.

type ConfigFollowUp

type ConfigFollowUp struct{}

ConfigFollowUp specifies the configuration for the FollowUp state machine.

func DefaultConfigFollowUp

func DefaultConfigFollowUp() *ConfigFollowUp

DefaultConfigFollowUp returns the default configuration options for the FollowUp state machine.

func (*ConfigFollowUp) Validate

func (c *ConfigFollowUp) Validate() error

Validate checks the configuration options and returns an error if any have invalid values.

type ConfigOptimistic

type ConfigOptimistic struct{}

ConfigOptimistic specifies the configuration for the [Optimistic] state machine.

func DefaultConfigOptimistic

func DefaultConfigOptimistic() *ConfigOptimistic

DefaultConfigOptimistic returns the default configuration options for the [Optimistic] state machine.

func (*ConfigOptimistic) Validate

func (c *ConfigOptimistic) Validate() error

Validate checks the configuration options and returns an error if any have invalid values.

type ConfigPool

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

ConfigPool specifies the configuration for a broadcast Pool.

func DefaultConfigPool

func DefaultConfigPool() *ConfigPool

DefaultConfigPool returns the default configuration options for a Pool. Options may be overridden before passing to NewPool

func (*ConfigPool) Validate

func (cfg *ConfigPool) Validate() error

Validate checks the configuration options and returns an error if any have invalid values.

type ConfigStatic

type ConfigStatic struct{}

ConfigStatic specifies the configuration for the Static state machine.

func DefaultConfigStatic

func DefaultConfigStatic() *ConfigStatic

DefaultConfigStatic returns the default configuration options for the Static state machine.

func (*ConfigStatic) Validate

func (c *ConfigStatic) Validate() error

Validate checks the configuration options and returns an error if any have invalid values.

type EventBroadcastNodeFailure

type EventBroadcastNodeFailure[K kad.Key[K], N kad.NodeID[K]] struct {
	NodeID N     // the node the message was sent to and that has replied
	Error  error // the error that caused the failure, if any
}

EventBroadcastNodeFailure notifies a Broadcast state machine that a remote node (NodeID) has failed responding with closer nodes to the target key.

type EventBroadcastNodeResponse

type EventBroadcastNodeResponse[K kad.Key[K], N kad.NodeID[K]] struct {
	NodeID      N   // the node the message was sent to and that replied
	CloserNodes []N // the closer nodes sent by the node
}

EventBroadcastNodeResponse notifies a Broadcast state machine that a remote node (NodeID) has successfully responded with closer nodes (CloserNodes) to the Target key that's stored on the Broadcast state machine

type EventBroadcastPoll

type EventBroadcastPoll struct{}

EventBroadcastPoll is an event that signals a Broadcast state machine that it can perform housekeeping work such as time out queries.

type EventBroadcastStart

type EventBroadcastStart[K kad.Key[K], N kad.NodeID[K]] struct {
	Target K   // the key we want to store the record for
	Seed   []N // the closest nodes we know so far and from where we start the operation
}

EventBroadcastStart is an event that instructs a broadcast state machine to start the operation.

type EventBroadcastStop

type EventBroadcastStop struct{}

EventBroadcastStop notifies a Broadcast state machine to stop the operation. This comprises all in-flight queries.

type EventBroadcastStoreRecordFailure

type EventBroadcastStoreRecordFailure[K kad.Key[K], N kad.NodeID[K], M coordt.Message] struct {
	NodeID  N     // the node the message was sent to
	Request M     // the message that was sent to the remote node
	Error   error // the error that caused the failure, if any
}

EventBroadcastStoreRecordFailure notifies a broadcast Broadcast state machine that storing a record with a remote node (NodeID) has failed. The message that was sent is held in Request, and the error will be in Error.

type EventBroadcastStoreRecordSuccess

type EventBroadcastStoreRecordSuccess[K kad.Key[K], N kad.NodeID[K], M coordt.Message] struct {
	NodeID   N // the node the message was sent to
	Request  M // the message that was sent to the remote node
	Response M // the reply we got from the remote node (nil in many cases of the Amino DHT)
}

EventBroadcastStoreRecordSuccess notifies a broadcast Broadcast state machine that storing a record with a remote node (NodeID) was successful. The message that was sent is held in Request, and the returned value is contained in Response. However, in the case of the Amino DHT, nodes do not respond with a confirmation, so Response will always be nil. Check out [pb.Message.ExpectResponse] for information about which requests should receive a response.

type EventPoolGetCloserNodesFailure

type EventPoolGetCloserNodesFailure[K kad.Key[K], N kad.NodeID[K]] struct {
	QueryID coordt.QueryID // the id of the query that sent the message
	NodeID  N              // the node the message was sent to and that has replied
	Target  K              // the key we want are searching closer nodes for
	Error   error          // the error that caused the failure, if any
}

EventPoolGetCloserNodesFailure notifies a Pool that a remote node (NodeID) has failed responding with closer nodes to the Target key for the broadcast operation with the given id (QueryID).

type EventPoolGetCloserNodesSuccess

type EventPoolGetCloserNodesSuccess[K kad.Key[K], N kad.NodeID[K]] struct {
	QueryID     coordt.QueryID // the id of the broadcast operation that this response belongs to
	NodeID      N              // the node the message was sent to and that replied
	Target      K              // the key we want are searching closer nodes for
	CloserNodes []N            // the closer nodes sent by the node NodeID
}

EventPoolGetCloserNodesSuccess notifies a Pool that a remote node (NodeID) has successfully responded with closer nodes (CloserNodes) to the Target key for the broadcast operation with the given id (QueryID).

type EventPoolPoll

type EventPoolPoll struct{}

EventPoolPoll is an event that signals the broadcast Pool state machine that it can perform housekeeping work such as time out queries.

type EventPoolStartBroadcast

type EventPoolStartBroadcast[K kad.Key[K], N kad.NodeID[K], M coordt.Message] struct {
	QueryID coordt.QueryID // the unique ID for this operation
	Target  K              // the key we want to store the record for
	Message M              // the message that we want to send to the closest peers (this encapsulates the payload we want to store)
	Seed    []N            // the closest nodes we know so far and from where we start the operation
	Config  Config         // the configuration for this operation. Most importantly, this defines the broadcast strategy ([FollowUp] or [Static])
}

EventPoolStartBroadcast is an event that attempts to start a new broadcast operation. This is the entry point.

type EventPoolStopBroadcast

type EventPoolStopBroadcast struct {
	QueryID coordt.QueryID // the id of the broadcast operation that should be stopped
}

EventPoolStopBroadcast notifies broadcast Pool to stop a broadcast operation.

type EventPoolStoreRecordFailure

type EventPoolStoreRecordFailure[K kad.Key[K], N kad.NodeID[K], M coordt.Message] struct {
	QueryID coordt.QueryID // the id of the query that sent the message
	NodeID  N              // the node the message was sent to
	Request M              // the message that was sent to the remote node
	Error   error          // the error that caused the failure
}

EventPoolStoreRecordFailure noties the broadcast Pool that storing a record with a remote node (NodeID) has failed. The message that was sent is hold in Request, and the error will be in Error.

type EventPoolStoreRecordSuccess

type EventPoolStoreRecordSuccess[K kad.Key[K], N kad.NodeID[K], M coordt.Message] struct {
	QueryID  coordt.QueryID // the id of the query that sent the message
	NodeID   N              // the node the message was sent to
	Request  M              // the message that was sent to the remote node
	Response M              // the reply we got from the remote node (nil in many cases of the Amino DHT)
}

EventPoolStoreRecordSuccess noties the broadcast Pool that storing a record with a remote node (NodeID) was successful. The message that was sent is held in Request, and the returned value is contained in Response. However, in the case of the Amino DHT, nodes do not respond with a confirmation, so Response will always be nil. Check out [pb.Message.ExpectResponse] for information about which requests should receive a response.

type FollowUp

type FollowUp[K kad.Key[K], N kad.NodeID[K], M coordt.Message] struct {
	// contains filtered or unexported fields
}

FollowUp is a Broadcast state machine and encapsulates the logic around doing a "classic" put operation. This mimics the algorithm employed in the original go-libp2p-kad-dht v1 code base. It first queries the closest nodes to a certain target key, and after they were discovered, it "follows up" with storing the record with these closest nodes.

func NewFollowUp

func NewFollowUp[K kad.Key[K], N kad.NodeID[K], M coordt.Message](qid coordt.QueryID, pool *query.Pool[K, N, M], msg M, cfg *ConfigFollowUp) *FollowUp[K, N, M]

NewFollowUp initializes a new FollowUp struct.

func (*FollowUp[K, N, M]) Advance

func (f *FollowUp[K, N, M]) Advance(ctx context.Context, ev BroadcastEvent) (out BroadcastState)

Advance advances the state of the FollowUp Broadcast state machine. It first handles the event by mapping it to a potential event for the query pool. If the BroadcastEvent maps to a query.PoolEvent, it gets forwarded to the query pool and handled in [FollowUp.advancePool]. If it doesn't map to a query pool event, we check if there are any nodes we should contact to hold the record for us and emit that instruction instead. Similarly, if we're waiting on responses or are completely finished, we return that as well.

type Pool

type Pool[K kad.Key[K], N kad.NodeID[K], M coordt.Message] struct {
	// contains filtered or unexported fields
}

Pool is a coordt.StateMachine that manages all running broadcast operations. In the future it could limit the number of concurrent operations, but right now it is just keeping track of all running broadcasts. The referenced query.Pool is passed down to the respective broadcast state machines. This is not nice because it breaks the hierarchy but makes things way easier.

Conceptually, a broadcast consists of finding the closest nodes to a certain key and then storing the record with them. There are a few different strategies that can be applied. For now, these are the FollowUp and the Static strategies. In the future, we also want to support Reprovide Sweep. However, this requires a different type of query as we are not looking for the closest nodes but rather enumerating the keyspace. In any case, this broadcast Pool would keep track of all running broadcasts.

func NewPool

func NewPool[K kad.Key[K], N kad.NodeID[K], M coordt.Message](self N, cfg *ConfigPool) (*Pool[K, N, M], error)

NewPool initializes a new broadcast pool. If cfg is nil, the DefaultConfigPool will be used. Each broadcast pool creates its own query pool (query.Pool). A query pool limits the number of concurrent queries and already exists "stand-alone" beneath the [coord.PooledQueryBehaviour]. We are initializing a new one in here because:

  1. it allows us to apply different limits to either broadcast or ordinary "get closer nodes" queries
  2. the query pool logic will stay simpler
  3. we don't need to cross communicated from the broadcast to the query pool 4.

func (*Pool[K, N, M]) Advance

func (p *Pool[K, N, M]) Advance(ctx context.Context, ev PoolEvent) (out PoolState)

Advance advances the state of the broadcast Pool. It first handles the event by extracting the broadcast state machine that should handle this event from the [Pool.bcs] map and constructing the correct event for that broadcast state machine. If either the state machine wasn't found (shouldn't happen) or there's no corresponding broadcast event (EventPoolPoll for example) don't do anything and instead try to advance the other broadcast state machines.

type PoolEvent

type PoolEvent interface {
	// contains filtered or unexported methods
}

PoolEvent is an event intended to advance the state of the broadcast Pool state machine. The Pool state machine only operates on events that implement this interface. An "Event" is the opposite of a "State." An "Event" flows into the state machine and a "State" flows out of it.

type PoolState

type PoolState interface {
	// contains filtered or unexported methods
}

PoolState must be implemented by all states that a Pool can reach. States are basically the events that the Pool emits that other state machines or behaviours could react upon.

type StateBroadcastFindCloser

type StateBroadcastFindCloser[K kad.Key[K], N kad.NodeID[K]] struct {
	QueryID coordt.QueryID // the id of the broadcast operation that wants to send the message
	NodeID  N              // the node to send the message to
	Target  K              // the key that the query wants to find closer nodes for
}

StateBroadcastFindCloser indicates to the broadcast Pool or any other upper layer that a Broadcast state machine wants to query the given node (NodeID) for closer nodes to the target key (Target).

type StateBroadcastFinished

type StateBroadcastFinished[K kad.Key[K], N kad.NodeID[K]] struct {
	QueryID   coordt.QueryID // the id of the broadcast operation that has finished
	Contacted []N            // all nodes we contacted to store the record (successful or not)
	Errors    map[string]struct {
		Node N     // a node from the Contacted slice
		Err  error // the error that happened when contacting that Node
	}
}

StateBroadcastFinished indicates that a Broadcast state machine has finished its operation. During that operation, all nodes in Contacted have been contacted to store the record. The Contacted slice does not contain the nodes we have queried to find the closest nodes to the target key - only the ones that we eventually contacted to store the record. The Errors map maps the string representation of any node N in the Contacted slice to a potential error struct that contains the original Node and error. In the best case, this Errors map is empty.

type StateBroadcastIdle

type StateBroadcastIdle struct{}

StateBroadcastIdle means that a Broadcast state machine has finished all of its operation. This state will be emitted if the state machine is polled to advance its state but has already finished its operation. The last meaningful state will be StateBroadcastFinished. Being idle is different from waiting for network I/O to finish (see StateBroadcastWaiting).

type StateBroadcastStoreRecord

type StateBroadcastStoreRecord[K kad.Key[K], N kad.NodeID[K], M coordt.Message] struct {
	QueryID coordt.QueryID // the id of the broadcast operation that wants to send the message
	NodeID  N              // the node to send the message to
	Message M              // the message the broadcast behaviour wants to send
}

StateBroadcastStoreRecord indicates to the broadcast Pool or any other upper layer that a Broadcast state machine wants to store a record using the given Message with the given NodeID.

type StateBroadcastWaiting

type StateBroadcastWaiting struct {
	QueryID coordt.QueryID // the id of the broadcast operation that is waiting
}

StateBroadcastWaiting indicates that a Broadcast state machine is waiting for network I/O to finish. It means the state machine isn't idle, but that there are operations in-flight that it is waiting on to finish.

type StatePoolBroadcastFinished

type StatePoolBroadcastFinished[K kad.Key[K], N kad.NodeID[K]] struct {
	QueryID   coordt.QueryID // the id of the broadcast operation that has finished
	Contacted []N            // all nodes we contacted to store the record (successful or not)
	Errors    map[string]struct {
		Node N     // a node from the Contacted slice
		Err  error // the error that happened when contacting that Node
	}
}

StatePoolBroadcastFinished indicates that the broadcast operation with the id QueryID has finished. During that operation, all nodes in Contacted have been contacted to store the record. The Contacted slice does not contain the nodes we have queried to find the closest nodes to the target key - only the ones that we eventually contacted to store the record. The Errors map maps the string representation of any node N in the Contacted slice to a potential error struct that contains the original Node and error. In the best case, this Errors map is empty.

type StatePoolFindCloser

type StatePoolFindCloser[K kad.Key[K], N kad.NodeID[K]] struct {
	QueryID coordt.QueryID // the id of the broadcast operation that wants to send the message
	Target  K              // the key that the query wants to find closer nodes for
	NodeID  N              // the node to send the message to
}

StatePoolFindCloser indicates to the broadcast behaviour that a broadcast state machine and indirectly the broadcast pool wants to query the given node (NodeID) for closer nodes to the target key (Target).

type StatePoolIdle

type StatePoolIdle struct{}

StatePoolIdle means that the broadcast Pool is not managing any broadcast operations at this time.

type StatePoolStoreRecord

type StatePoolStoreRecord[K kad.Key[K], N kad.NodeID[K], M coordt.Message] struct {
	QueryID coordt.QueryID // the id of the broadcast operation that wants to send the message
	NodeID  N              // the node to send the message to
	Message M              // the message that should be sent to the remote node
}

StatePoolStoreRecord indicates to the upper layer that the broadcast Pool wants to store a record using the given Message with the given NodeID. The network behaviour should take over and notify the [coord.PooledBroadcastBehaviour] about updates.

type StatePoolWaiting

type StatePoolWaiting struct{}

StatePoolWaiting indicates that the broadcast Pool is waiting for network I/O to finish. It means the Pool isn't idle, but there are operations in-flight that it is waiting on to finish.

type Static

type Static[K kad.Key[K], N kad.NodeID[K], M coordt.Message] struct {
	// contains filtered or unexported fields
}

Static is a Broadcast state machine and encapsulates the logic around doing a put operation to a static set of nodes. That static set of nodes is given by the list of seed nodes in the EventBroadcastStart event.

func NewStatic

func NewStatic[K kad.Key[K], N kad.NodeID[K], M coordt.Message](qid coordt.QueryID, msg M, cfg *ConfigStatic) *Static[K, N, M]

NewStatic initializes a new Static struct.

func (*Static[K, N, M]) Advance

func (f *Static[K, N, M]) Advance(ctx context.Context, ev BroadcastEvent) (out BroadcastState)

Advance advances the state of the Static Broadcast state machine.

Jump to

Keyboard shortcuts

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