Documentation ¶
Overview ¶
Package brdcst contains state machines that implement algorithms for broadcasting records into the DHT network.
Index ¶
- type Broadcast
- type BroadcastEvent
- type BroadcastState
- type Config
- type ConfigFollowUp
- type ConfigOptimistic
- type ConfigPool
- type ConfigStatic
- type EventBroadcastNodeFailure
- type EventBroadcastNodeResponse
- type EventBroadcastPoll
- type EventBroadcastStart
- type EventBroadcastStop
- type EventBroadcastStoreRecordFailure
- type EventBroadcastStoreRecordSuccess
- type EventPoolGetCloserNodesFailure
- type EventPoolGetCloserNodesSuccess
- type EventPoolPoll
- type EventPoolStartBroadcast
- type EventPoolStopBroadcast
- type EventPoolStoreRecordFailure
- type EventPoolStoreRecordSuccess
- type FollowUp
- type Pool
- type PoolEvent
- type PoolState
- type StateBroadcastFindCloser
- type StateBroadcastFinished
- type StateBroadcastIdle
- type StateBroadcastStoreRecord
- type StateBroadcastWaiting
- type StatePoolBroadcastFinished
- type StatePoolFindCloser
- type StatePoolIdle
- type StatePoolStoreRecord
- type StatePoolWaiting
- type Static
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Broadcast ¶
type Broadcast = coordt.StateMachine[BroadcastEvent, BroadcastState]
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:
- it allows us to apply different limits to either broadcast or ordinary "get closer nodes" queries
- the query pool logic will stay simpler
- we don't need to cross communicated from the broadcast to the query pool 4.
func (*Pool[K, N, M]) Advance ¶
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.