forked from spacemeshos/go-spacemesh
/
swarm.go
118 lines (94 loc) · 3.73 KB
/
swarm.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Package p2p implement the core spacemesh p2p protocol and provide types for higher-level protcols such as handshake.
// See Ping for an example higher-level protocol
package p2p
import (
"strconv"
"github.com/spacemeshos/go-spacemesh/p2p/dht/table"
"github.com/spacemeshos/go-spacemesh/p2p/node"
)
// Swarm is p2p virtual network of spacemesh nodes as viewed by a local node.
type Swarm interface {
// SendMessage sends a message to a specific remote node based just on its id
// without knowing its ip address.
// In this case we will try to locate the node via dht node search,
// and send the message if we obtained node ip address and were able to connect to it.
//
// req.msg should be marshaled protocol message. e.g. something like pb.PingReqData;
//
// This is designed for standard messages that require a session.
// This method is designed to be used by protocols implementations to send message
// to any destination.
SendMessage(req SendMessageReq)
// TODO(devs): support sending a message to all connected peers without any dest id provided by caller
// RegisterNode registers a node with the swarm based on its id and tcp address but don't
// attempt to connect to it.
RegisterNode(data node.RemoteNodeData)
// ConnectTo attempts to establish a session with a remote node with a known
// id and tcp address.
// Used for bootstrapping known bootstrap nodes.
ConnectTo(req node.RemoteNodeData)
// ConnectToRandomNodes connects to count random nodes - used for bootstrapping
// the swarm.
ConnectToRandomNodes(count int)
// Forcefully disconnect form a node - close any connections and sessions with it.
DisconnectFrom(req node.RemoteNodeData)
// Send a handshake protocol message that is used to establish a session.
sendHandshakeMessage(req SendMessageReq)
// Register a callback channel for state changes related to remote nodes.
// Currently used for testing network bootstrapping.
RegisterNodeEventsCallback(callback NodeEventCallback)
// Todo(devs): allow client to register callback to get notified when swarm has shut down
Shutdown()
// Services getters.
GetDemuxer() Demuxer
GetLocalNode() LocalNode
// These used by protocols and for testing.
getHandshakeProtocol() HandshakeProtocol
getRoutingTable() table.RoutingTable
getFindNodeProtocol() FindNodeProtocol
}
// SendMessageReq specifies data required for sending a p2p message to a remote peer.
type SendMessageReq struct {
PeerID string // base58 message destination peer id
ReqID []byte // unique request id
Payload []byte // this should be a marshaled protocol msg e.g. PingReqData
Callback chan SendError // optional callback to receive send errors or timeout
}
// SendError specifies message sending error data.
type SendError struct {
ReqID []byte // unique request id
err error // error - nil if message was sent
}
// NodeResp defines node response data.
type NodeResp struct {
peerID string
err error
}
// NodeEvent specifies node state data.
type NodeEvent struct {
PeerID string
State NodeState
}
// NodeEventCallback is a channel of NodeEvents.
type NodeEventCallback chan NodeEvent
// NodeState specifies the node's connectivity state.
type NodeState int32
// NodeState
const (
Unknown NodeState = iota
Registered
Connecting
Connected
HandshakeStarted
SessionEstablished
Disconnected
)
// Created by stringer -type=NodeState
const nodeStateName = "UnknownRegisteredConnectingConnectedHandshakeStartedSessionEstablishedDisconnected"
var nodeStateIndex = [...]uint8{0, 7, 17, 27, 36, 52, 70, 82}
func (i NodeState) String() string {
if i < 0 || i >= NodeState(len(nodeStateIndex)-1) {
return "NodeState(" + strconv.FormatInt(int64(i), 10) + ")"
}
return nodeStateName[nodeStateIndex[i]:nodeStateIndex[i+1]]
}