forked from NebulousLabs/Sia
/
gateway.go
111 lines (91 loc) · 3.15 KB
/
gateway.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
package modules
import (
"io"
"net"
"net/http"
"time"
"github.com/NebulousLabs/Sia/build"
)
const (
GatewayDir = "gateway"
)
// TODO: Move this and it's functionality into the gateway package.
var (
BootstrapPeers = []NetAddress{
"23.239.14.98:9981",
"87.98.216.46:9981",
}
)
// A PeerConn is the connection type used when communicating with peers during
// an RPC. For now it is identical to a net.Conn.
type PeerConn interface {
net.Conn
// AddStrike() ?
}
// RPCFunc is the type signature of functions that handle RPCs. It is used for
// both the caller and the callee. RPCFuncs may perform locking. RPCFuncs may
// close the connection early, and it is recommended that they do so to avoid
// keeping the connection open after all necessary I/O has been performed.
type RPCFunc func(PeerConn) error
// A NetAddress contains the information needed to contact a peer.
type NetAddress string
// Host returns the NetAddress' IP.
func (na NetAddress) Host() string {
host, _, _ := net.SplitHostPort(string(na))
return host
}
// Port returns the NetAddress' port number.
func (na NetAddress) Port() string {
_, port, _ := net.SplitHostPort(string(na))
return port
}
// A Gateway facilitates the interactions between the local node and remote
// nodes (peers). It relays incoming blocks and transactions to local modules,
// and broadcasts outgoing blocks and transactions to peers. In a broad sense,
// it is responsible for ensuring that the local consensus set is consistent
// with the "network" consensus set.
type Gateway interface {
// Connect establishes a persistent connection to a peer.
Connect(NetAddress) error
// Disconnect terminates a connection to a peer.
Disconnect(NetAddress) error
// Address returns the Gateway's address.
Address() NetAddress
// Peers returns the addresses that the Gateway is currently connected to.
Peers() []NetAddress
// RegisterRPC registers a function to handle incoming connections that
// supply the given RPC ID.
RegisterRPC(string, RPCFunc)
// RegisterConnectCall registers an RPC name and function to be called
// upon connecting to a peer.
RegisterConnectCall(string, RPCFunc)
// RPC calls an RPC on the given address. RPC cannot be called on an
// address that the Gateway is not connected to.
RPC(NetAddress, string, RPCFunc) error
// Broadcast transmits obj, prefaced by the RPC name, to all of the
// Gateway's connected peers in parallel.
Broadcast(name string, obj interface{})
// Close safely stops the Gateway's listener process.
Close() error
}
// ExternalIP is the external IP of the computer running this code. It is
// defined here to facilitate reuse, instead of requiring each module to make
// an HTTP call. During testing, the loopback address is returned.
var ExternalIP = func() string {
if build.Release == "testing" {
return "::1"
}
// timeout after 3 seconds
client := http.Client{Timeout: time.Duration(3 * time.Second)}
resp, err := client.Get("http://myexternalip.com/raw")
if err != nil {
return "::1"
}
defer resp.Body.Close()
buf := make([]byte, 64)
n, err := resp.Body.Read(buf)
if err != nil && err != io.EOF {
return "::1"
}
return string(buf[:n-1]) // trim newline
}()