Documentation ¶
Index ¶
Constants ¶
const HyperSyncSnapshotPeriod = 1000
Global variable that allows setting node configuration hypersync snapshot period.
const MaxSyncBlockHeight = 1500
Global variable that determines the max tip blockheight of syncing nodes throughout test cases.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ConnectionBridge ¶
type ConnectionBridge struct {
// contains filtered or unexported fields
}
ConnectionBridge is a bidirectional communication channel between two nodes. A bridge creates a pair of inbound and outbound peers for each of the nodes to handle communication. In total, it creates four peers.
An inbound Peer represents incoming communication to a node, and an outbound Peer represents outgoing communication. To disambiguate, a "Peer" in this context is basically a wrapper around inter-node communication that allows receiving and sending messages between the two nodes.
As mentioned, our bridge creates an inbound and outbound Peers for both nodes A and B. Now, you might be perplexed as to why we would need both of these peers, as opposed to just one. The reason is that inbound and outbound peers differ in a crucial aspect, which is, who creates them. Inbound Peers are created whenever any node on the network initiates a communication with our node - meaning a node has no control over the communication partner. On the other hand, outbound peers are created by the node itself, so they can be considered more trusted than inbound peers. As a result, certain communication is only sent to outbound peers. For instance, we never ask an inbound Peer for headers or blocks, but we can ask an outbound Peer. At the same time, a node will respond with headers/blocks if asked by an inbound Peer.
Let's say we have two nodes, nodeA and nodeB, that we want to bridge together. The connection bridge will then simulate the creation of two outbound and two inbound node connections:
nodeA : connectionOutboundA -> connectionInboundB : nodeB nodeB : connectionOutboundB -> connectionInboundA : nodeA
For example, let's say nodeA wants to send a GET_HEADERS message to nodeB, the traffic will look like this:
GET_HEADERS: nodeA -> connectionOutboundA -> connectionInboundB -> nodeB HEADER_BUNDLE: nodeB -> connectionInboundB -> connectionOutboundA -> nodeA
This middleware design of the ConnectionBridge allows us to have much higher control over the communication between the two nodes. In particular, we have full control over the `connectionOutboundA -> connectionInboundB` steps, which allows us to make sure nodes act predictably and deterministically in our tests. Moreover, we can simulate real-world network links by doing things like faking delays, dropping messages, partitioning networks, etc.
func NewConnectionBridge ¶
func NewConnectionBridge(nodeA *cmd.Node, nodeB *cmd.Node) *ConnectionBridge
NewConnectionBridge creates an instance of ConnectionBridge that's ready to be connected. This function is usually followed by ConnectionBridge.Start()
func (*ConnectionBridge) Disconnect ¶
func (bridge *ConnectionBridge) Disconnect()
Disconnect stops the connection bridge.
func (*ConnectionBridge) Restart ¶
func (bridge *ConnectionBridge) Restart()
Stop and start the connection bridge.
func (*ConnectionBridge) Start ¶
func (bridge *ConnectionBridge) Start() error