/
nodeinfo.go
315 lines (265 loc) · 6.96 KB
/
nodeinfo.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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gossip
import (
"sync"
"sync/atomic"
"google.golang.org/grpc/credentials"
"github.com/33cn/chain33/p2p/utils"
"github.com/33cn/chain33/queue"
"github.com/33cn/chain33/types"
)
// NodeInfo is interface object of the node
type NodeInfo struct {
mtx sync.Mutex
externalAddr *NetAddress
listenAddr *NetAddress
monitorChan chan *Peer
natNoticeChain chan struct{}
natResultChain chan bool
p2pCfg *types.P2P
cfg *subConfig
client queue.Client
blacklist *BlackList
peerInfos *PeerInfos
addrBook *AddrBook // known peers
natDone int32
outSide int32
ServiceType int32
channelVersion int32
cliCreds credentials.TransportCredentials
servCreds credentials.TransportCredentials
}
// NewNodeInfo new a node object
func NewNodeInfo(p2pCfg *types.P2P, subCfg *subConfig) *NodeInfo {
nodeInfo := new(NodeInfo)
nodeInfo.monitorChan = make(chan *Peer, 1024)
nodeInfo.natNoticeChain = make(chan struct{}, 1)
nodeInfo.natResultChain = make(chan bool, 1)
nodeInfo.blacklist = &BlackList{badPeers: make(map[string]int64)}
nodeInfo.p2pCfg = p2pCfg
nodeInfo.cfg = subCfg
nodeInfo.peerInfos = new(PeerInfos)
nodeInfo.peerInfos.infos = make(map[string]*types.Peer)
nodeInfo.externalAddr = new(NetAddress)
nodeInfo.listenAddr = new(NetAddress)
nodeInfo.addrBook = NewAddrBook(p2pCfg, subCfg)
nodeInfo.channelVersion = utils.CalcChannelVersion(subCfg.Channel, VERSION)
return nodeInfo
}
// PeerInfos encapsulation peer information
type PeerInfos struct {
mtx sync.Mutex
//key:peerName
infos map[string]*types.Peer
}
// PeerSize return a size of peer information
func (p *PeerInfos) PeerSize() int {
p.mtx.Lock()
defer p.mtx.Unlock()
return len(p.infos)
}
// FlushPeerInfos flush peer information
func (p *PeerInfos) FlushPeerInfos(in []*types.Peer) {
p.mtx.Lock()
defer p.mtx.Unlock()
for k := range p.infos {
delete(p.infos, k)
}
for _, peer := range in {
p.infos[peer.GetName()] = peer
}
}
// GetPeerInfos return a map for peerinfos
func (p *PeerInfos) GetPeerInfos() map[string]*types.Peer {
p.mtx.Lock()
defer p.mtx.Unlock()
var pinfos = make(map[string]*types.Peer)
for k, v := range p.infos {
pinfos[k] = v
}
return pinfos
}
// SetPeerInfo modify peer infos
func (p *PeerInfos) SetPeerInfo(peer *types.Peer) {
p.mtx.Lock()
defer p.mtx.Unlock()
if peer.GetName() == "" {
return
}
p.infos[peer.GetName()] = peer
}
// GetPeerInfo return a infos by key
func (p *PeerInfos) GetPeerInfo(peerName string) *types.Peer {
p.mtx.Lock()
defer p.mtx.Unlock()
if peer, ok := p.infos[peerName]; ok {
return peer
}
return nil
}
// BlackList badpeers list
type BlackList struct {
mtx sync.Mutex
badPeers map[string]int64
peerstore sync.Map
}
// FetchPeerInfo get peerinfo by node
func (nf *NodeInfo) FetchPeerInfo(n *Node) {
var peerlist []*types.Peer
peerInfos := nf.latestPeerInfo(n)
for _, peerinfo := range peerInfos {
peerlist = append(peerlist, peerinfo)
}
nf.flushPeerInfos(peerlist)
}
func (nf *NodeInfo) flushPeerInfos(in []*types.Peer) {
nf.peerInfos.FlushPeerInfos(in)
}
func (nf *NodeInfo) latestPeerInfo(n *Node) map[string]*types.Peer {
var peerlist = make(map[string]*types.Peer)
peers := n.GetRegisterPeers()
log.Debug("latestPeerInfo", "register peer num", len(peers))
for _, peer := range peers {
if !peer.GetRunning() || peer.Addr() == n.nodeInfo.GetExternalAddr().String() {
n.remove(peer.Addr())
continue
}
peerinfo, err := peer.GetPeerInfo()
if err != nil || peerinfo.GetName() == "" {
P2pComm.CollectPeerStat(err, peer)
log.Error("latestPeerInfo", "Err", err, "peer", peer.Addr())
continue
}
var pr types.Peer
pr.Addr = peerinfo.GetAddr()
pr.Port = peerinfo.GetPort()
pr.Name = peerinfo.GetName()
pr.MempoolSize = peerinfo.GetMempoolSize()
pr.Header = peerinfo.GetHeader()
peerlist[pr.Name] = &pr
}
return peerlist
}
// Set modidy nodeinfo by nodeinfo
func (nf *NodeInfo) Set(n *NodeInfo) {
nf.mtx.Lock()
defer nf.mtx.Unlock()
nf = n
}
// Get return nodeinfo
func (nf *NodeInfo) Get() *NodeInfo {
nf.mtx.Lock()
defer nf.mtx.Unlock()
return nf
}
// SetExternalAddr modidy address of the nodeinfo
func (nf *NodeInfo) SetExternalAddr(addr *NetAddress) {
nf.mtx.Lock()
defer nf.mtx.Unlock()
nf.externalAddr = addr
}
// GetExternalAddr return external address
func (nf *NodeInfo) GetExternalAddr() *NetAddress {
nf.mtx.Lock()
defer nf.mtx.Unlock()
return nf.externalAddr
}
// SetListenAddr modify listen address
func (nf *NodeInfo) SetListenAddr(addr *NetAddress) {
nf.mtx.Lock()
defer nf.mtx.Unlock()
nf.listenAddr = addr
}
// GetListenAddr return listen address
func (nf *NodeInfo) GetListenAddr() *NetAddress {
nf.mtx.Lock()
defer nf.mtx.Unlock()
return nf.listenAddr
}
// SetNatDone modify natdone
func (nf *NodeInfo) SetNatDone() {
atomic.StoreInt32(&nf.natDone, 1)
}
// IsNatDone return ture and false
func (nf *NodeInfo) IsNatDone() bool {
return atomic.LoadInt32(&nf.natDone) == 1
}
// IsOutService return true and false for out service
func (nf *NodeInfo) IsOutService() bool {
if !nf.cfg.ServerStart {
return false
}
if nf.OutSide() || nf.ServiceTy() == Service {
return true
}
return false
}
// SetServiceTy set service type
func (nf *NodeInfo) SetServiceTy(ty int32) {
atomic.StoreInt32(&nf.ServiceType, ty)
}
// ServiceTy return serveice type
func (nf *NodeInfo) ServiceTy() int32 {
return atomic.LoadInt32(&nf.ServiceType)
}
// SetNetSide set net side
func (nf *NodeInfo) SetNetSide(ok bool) {
var isoutside int32
if ok {
isoutside = 1
}
atomic.StoreInt32(&nf.outSide, isoutside)
}
// OutSide return true and false for outside
func (nf *NodeInfo) OutSide() bool {
return atomic.LoadInt32(&nf.outSide) == 1
}
// Add add badpeer
func (bl *BlackList) Add(addr string, deadline int64) {
bl.mtx.Lock()
defer bl.mtx.Unlock()
if deadline == 0 { //默认1年
deadline = 365 * 24 * 3600
}
bl.badPeers[addr] = types.Now().Unix() + deadline
}
func (bl *BlackList) addPeerStore(peerName, remoteAddr string) {
bl.peerstore.Store(peerName, remoteAddr)
}
func (bl *BlackList) getpeerStore(key string) (string, bool) {
v, ok := bl.peerstore.Load(key)
if ok {
return v.(string), ok
}
return "", ok
}
// Delete delete badpeer
func (bl *BlackList) Delete(addr string) {
bl.mtx.Lock()
defer bl.mtx.Unlock()
delete(bl.badPeers, addr)
}
func (bl *BlackList) deletePeerStore(peerName string) {
bl.peerstore.Delete(peerName)
}
// Has the badpeer true and false
func (bl *BlackList) Has(addr string) bool {
bl.mtx.Lock()
defer bl.mtx.Unlock()
if _, ok := bl.badPeers[addr]; ok {
return true
}
return false
}
// GetBadPeers reurn black list peers
func (bl *BlackList) GetBadPeers() map[string]int64 {
bl.mtx.Lock()
defer bl.mtx.Unlock()
var copyData = make(map[string]int64)
for k, v := range bl.badPeers {
copyData[k] = v
}
return copyData
}