forked from 0xPolygon/polygon-edge
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpeers.go
69 lines (52 loc) · 1.13 KB
/
peers.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
package syncer
import (
"math/big"
"sync"
"github.com/libp2p/go-libp2p/core/peer"
)
type NoForkPeer struct {
// identifier
ID peer.ID
// peer's latest block number
Number uint64
// peer's distance
Distance *big.Int
}
func (p *NoForkPeer) IsBetter(t *NoForkPeer) bool {
if p.Number != t.Number {
return p.Number > t.Number
}
return p.Distance.Cmp(t.Distance) < 0
}
type PeerMap struct {
sync.Map
}
func NewPeerMap(peers []*NoForkPeer) *PeerMap {
peerMap := new(PeerMap)
peerMap.Put(peers...)
return peerMap
}
func (m *PeerMap) Put(peers ...*NoForkPeer) {
for _, peer := range peers {
m.Store(peer.ID.String(), peer)
}
}
// Remove removes a peer from heap if it exists
func (m *PeerMap) Remove(peerID peer.ID) {
m.Delete(peerID.String())
}
// BestPeer returns the top of heap
func (m *PeerMap) BestPeer(skipMap map[peer.ID]bool) *NoForkPeer {
var bestPeer *NoForkPeer
m.Range(func(key, value interface{}) bool {
peer, _ := value.(*NoForkPeer)
if skipMap != nil && skipMap[peer.ID] {
return true
}
if bestPeer == nil || peer.IsBetter(bestPeer) {
bestPeer = peer
}
return true
})
return bestPeer
}