forked from aergoio/aergo
/
peermeta.go
151 lines (136 loc) · 4.04 KB
/
peermeta.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
/*
* @file
* @copyright defined in aergo/LICENSE.txt
*/
package p2pcommon
import (
"github.com/aergoio/aergo/types"
"github.com/multiformats/go-multiaddr"
"strconv"
)
// PeerMeta contains non changeable information of peer node during connected state
type PeerMeta struct {
ID types.PeerID
// AcceptedRole is the role that the remote peer claims: the local peer may not admit it, and only admits it when there is a proper proof, such as vote result in chain or AgentCertificate.
Role types.PeerRole
// ProducerIDs is a list of block producer IDs produced by this peer if the peer is BP, and if it is Agent, it is a list of block producer IDs that this peer acts as.
ProducerIDs []types.PeerID
// Address is advertised address to which other peer can connect.
Addresses []types.Multiaddr
// Version is build version of binary
Version string
Hidden bool // Hidden means that meta info of this peer will not be sent to other peers when getting peer list
}
func (m *PeerMeta) GetVersion() string {
if m.Version == "" {
return ""
} else {
return m.Version
}
}
// NewMetaWith1Addr make instance of PeerMeta with single address
func NewMetaWith1Addr(id types.PeerID, addr string, port uint32, version string) PeerMeta {
ma, err := types.ToMultiAddr(addr, port)
if err != nil {
return PeerMeta{}
} else {
return PeerMeta{ID: id, Addresses: []types.Multiaddr{ma}, Version: version}
}
}
// FromStatusToMeta create peerMeta from Status message
func NewMetaFromStatus(status *types.Status) PeerMeta {
meta := FromPeerAddressNew(status.Sender)
// hidden field of remote peer should be got from Status struct
meta.Hidden = status.NoExpose
//if len(meta.Version) == 0 {
// meta.Version = status.Sender.Version
//}
return meta
}
// FromPeerAddress convert PeerAddress to PeerMeta
func FromPeerAddress(addr *types.PeerAddress) PeerMeta {
return FromPeerAddressNew(addr)
}
// ToPeerAddress convert PeerMeta to PeerAddress
func (m PeerMeta) ToPeerAddress() types.PeerAddress {
addrs := make([]string, len(m.Addresses))
for i, a := range m.Addresses {
addrs[i] = a.String()
}
pds := make([][]byte, len(m.ProducerIDs))
for i, a := range m.ProducerIDs {
pds[i] = []byte(a)
}
addr := types.PeerAddress{PeerID: []byte(m.ID), Address: m.PrimaryAddress(), Port: m.PrimaryPort(), Addresses: addrs, ProducerIDs: pds, Version: m.GetVersion(), Role: m.Role}
return addr
}
// PrimaryAddress is first advertised port of peer
func (m PeerMeta) PrimaryPort() uint32 {
if len(m.Addresses) > 0 {
portVal, _ := m.Addresses[0].ValueForProtocol(multiaddr.P_TCP)
port, _ := strconv.Atoi(portVal)
return uint32(port)
} else {
return 0
}
}
// PrimaryAddress is first advertised address of peer
func (m PeerMeta) PrimaryAddress() string {
if len(m.Addresses) > 0 {
return types.AddressFromMultiAddr(m.Addresses[0])
} else {
return ""
}
}
func (m PeerMeta) Equals(o PeerMeta) bool {
if !types.IsSamePeerID(m.ID, o.ID) {
return false
}
if m.Role != o.Role {
return false
}
if len(m.ProducerIDs) != len(o.ProducerIDs) {
return false
}
for i, id := range m.ProducerIDs {
if !types.IsSamePeerID(id, o.ProducerIDs[i]) {
return false
}
}
if len(m.Addresses) != len(o.Addresses) {
return false
}
for i, ad := range m.Addresses {
if !ad.Equal(o.Addresses[i]) {
return false
}
}
if m.Version != o.Version {
return false
}
if m.Hidden != o.Hidden {
return false
}
return true
}
func FromPeerAddressNew(addr *types.PeerAddress) PeerMeta {
addrs := make([]types.Multiaddr, 0, len(addr.Addresses))
for _, a := range addr.Addresses {
ma, err := multiaddr.NewMultiaddr(a)
if err != nil {
continue
}
addrs = append(addrs, ma)
}
role := types.PeerRole_LegacyVersion
_, found := types.PeerRole_name[int32(addr.Role)]
if found {
role = types.PeerRole(int32(addr.Role))
}
producerIds := make([]types.PeerID, len(addr.ProducerIDs))
for i, id := range addr.ProducerIDs {
producerIds[i] = types.PeerID(id)
}
meta := PeerMeta{ID: types.PeerID(addr.PeerID), Addresses: addrs, Role: role, Version: addr.Version, ProducerIDs: producerIds}
return meta
}