-
Notifications
You must be signed in to change notification settings - Fork 2
/
peer.go
153 lines (121 loc) · 4.37 KB
/
peer.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package peer
import (
"sync"
"time"
"github.com/bugnanetwork/bugnad/domain/consensus/model/externalapi"
"github.com/bugnanetwork/bugnad/infrastructure/network/netadapter"
"github.com/bugnanetwork/bugnad/app/appmessage"
"github.com/bugnanetwork/bugnad/infrastructure/network/netadapter/id"
mathUtil "github.com/bugnanetwork/bugnad/util/math"
"github.com/bugnanetwork/bugnad/util/mstime"
)
// Peer holds data about a peer.
type Peer struct {
connection *netadapter.NetConnection
userAgent string
services appmessage.ServiceFlag
advertisedProtocolVerion uint32 // protocol version advertised by remote
protocolVersion uint32 // negotiated protocol version
disableRelayTx bool
subnetworkID *externalapi.DomainSubnetworkID
timeOffset time.Duration
connectionStarted time.Time
pingLock sync.RWMutex
lastPingNonce uint64 // The nonce of the last ping we sent
lastPingTime time.Time // Time we sent last ping
lastPingDuration time.Duration // Time for last ping to return
ibdRequestChannel chan *externalapi.DomainBlock // A channel used to communicate IBD requests between flows
}
// New returns a new Peer
func New(connection *netadapter.NetConnection) *Peer {
return &Peer{
connection: connection,
connectionStarted: time.Now(),
ibdRequestChannel: make(chan *externalapi.DomainBlock),
}
}
// Connection returns the NetConnection associated with this peer
func (p *Peer) Connection() *netadapter.NetConnection {
return p.connection
}
// SubnetworkID returns the subnetwork the peer is associated with.
// It is nil in full nodes.
func (p *Peer) SubnetworkID() *externalapi.DomainSubnetworkID {
return p.subnetworkID
}
// ID returns the peer ID.
func (p *Peer) ID() *id.ID {
return p.connection.ID()
}
// TimeOffset returns the peer's time offset.
func (p *Peer) TimeOffset() time.Duration {
return p.timeOffset
}
// UserAgent returns the peer's user agent.
func (p *Peer) UserAgent() string {
return p.userAgent
}
// AdvertisedProtocolVersion returns the peer's advertised protocol version.
func (p *Peer) AdvertisedProtocolVersion() uint32 {
return p.advertisedProtocolVerion
}
// ProtocolVersion returns the protocol version which is used when communicating with the peer.
func (p *Peer) ProtocolVersion() uint32 {
return p.protocolVersion
}
// TimeConnected returns the time since the connection to this been has been started.
func (p *Peer) TimeConnected() time.Duration {
return time.Since(p.connectionStarted)
}
// IsOutbound returns whether the peer is an outbound connection.
func (p *Peer) IsOutbound() bool {
return p.connection.IsOutbound()
}
// UpdateFieldsFromMsgVersion updates the peer with the data from the version message.
func (p *Peer) UpdateFieldsFromMsgVersion(msg *appmessage.MsgVersion, maxProtocolVersion uint32) {
// Negotiate the protocol version.
p.advertisedProtocolVerion = msg.ProtocolVersion
p.protocolVersion = mathUtil.MinUint32(maxProtocolVersion, p.advertisedProtocolVerion)
log.Debugf("Negotiated protocol version %d for peer %s",
p.protocolVersion, p)
// Set the supported services for the peer to what the remote peer
// advertised.
p.services = msg.Services
// Set the remote peer's user agent.
p.userAgent = msg.UserAgent
p.disableRelayTx = msg.DisableRelayTx
p.subnetworkID = msg.SubnetworkID
p.timeOffset = mstime.Since(msg.Timestamp)
}
// SetPingPending sets the ping state of the peer to 'pending'
func (p *Peer) SetPingPending(nonce uint64) {
p.pingLock.Lock()
defer p.pingLock.Unlock()
p.lastPingNonce = nonce
p.lastPingTime = time.Now()
}
// SetPingIdle sets the ping state of the peer to 'idle'
func (p *Peer) SetPingIdle() {
p.pingLock.Lock()
defer p.pingLock.Unlock()
p.lastPingNonce = 0
p.lastPingDuration = time.Since(p.lastPingTime)
}
func (p *Peer) String() string {
return p.connection.String()
}
// Address returns the address associated with this connection
func (p *Peer) Address() string {
return p.connection.Address()
}
// LastPingDuration returns the duration of the last ping to
// this peer
func (p *Peer) LastPingDuration() time.Duration {
p.pingLock.Lock()
defer p.pingLock.Unlock()
return p.lastPingDuration
}
// IBDRequestChannel returns the channel used in order to communicate an IBD request between peer flows
func (p *Peer) IBDRequestChannel() chan *externalapi.DomainBlock {
return p.ibdRequestChannel
}