Skip to content

Commit c2415ac

Browse files
authored
feat: update peer-sharing protocol (#544)
Fixes #314
1 parent 7f7e628 commit c2415ac

File tree

6 files changed

+140
-26
lines changed

6 files changed

+140
-26
lines changed

connection.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ type Connection struct {
6666
delayMuxerStart bool
6767
delayProtocolStart bool
6868
fullDuplex bool
69+
peerSharingEnabled bool
6970
// Mini-protocols
7071
blockFetch *blockfetch.BlockFetch
7172
blockFetchConfig *blockfetch.Config
@@ -279,8 +280,8 @@ func (c *Connection) setupConnection() error {
279280
protoOptions.Mode,
280281
c.networkMagic,
281282
handshakeDiffusionMode,
282-
// TODO: make these configurable
283-
protocol.PeerSharingModeNoPeerSharing,
283+
c.peerSharingEnabled,
284+
// TODO: make this configurable
284285
protocol.QueryModeDisabled,
285286
)
286287
// Perform handshake

connection_options.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,14 @@ func WithFullDuplex(fullDuplex bool) ConnectionOptionFunc {
104104
}
105105
}
106106

107+
// WithPeerSharing specifies whether to enable peer sharing. This affects both the protocol handshake and
108+
// whether the PeerSharing protocol is enabled
109+
func WithPeerSharing(peerSharing bool) ConnectionOptionFunc {
110+
return func(c *Connection) {
111+
c.peerSharingEnabled = peerSharing
112+
}
113+
}
114+
107115
// WithBlockFetchConfig specifies BlockFetch protocol config
108116
func WithBlockFetchConfig(cfg blockfetch.Config) ConnectionOptionFunc {
109117
return func(c *Connection) {

protocol/peersharing/client.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424
type Client struct {
2525
*protocol.Protocol
2626
config *Config
27-
sharePeersChan chan []interface{}
27+
sharePeersChan chan []PeerAddress
2828
}
2929

3030
// NewClient returns a new PeerSharing client object
@@ -35,7 +35,7 @@ func NewClient(protoOptions protocol.ProtocolOptions, cfg *Config) *Client {
3535
}
3636
c := &Client{
3737
config: cfg,
38-
sharePeersChan: make(chan []interface{}),
38+
sharePeersChan: make(chan []PeerAddress),
3939
}
4040
// Update state map with timeout
4141
stateMap := StateMap.Copy()
@@ -60,7 +60,7 @@ func NewClient(protoOptions protocol.ProtocolOptions, cfg *Config) *Client {
6060
return c
6161
}
6262

63-
func (c *Client) GetPeers(amount uint8) ([]interface{}, error) {
63+
func (c *Client) GetPeers(amount uint8) ([]PeerAddress, error) {
6464
msg := NewMsgShareRequest(amount)
6565
if err := c.SendMessage(msg); err != nil {
6666
return nil, err

protocol/peersharing/messages.go

Lines changed: 86 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
package peersharing
1616

1717
import (
18+
"encoding/binary"
1819
"fmt"
20+
"net"
1921

2022
"github.com/blinklabs-io/gouroboros/cbor"
2123
"github.com/blinklabs-io/gouroboros/protocol"
@@ -66,21 +68,10 @@ func NewMsgShareRequest(amount uint8) *MsgShareRequest {
6668

6769
type MsgSharePeers struct {
6870
protocol.MessageBase
69-
// TODO: parse peer addresses
70-
/*
71-
peerAddress = [0, word32, portNumber]
72-
; ipv6 + portNumber
73-
/ [1, word32, word32, word32, word32, flowInfo, scopeId, portNumber]
74-
75-
portNumber = word16
76-
77-
flowInfo = word32
78-
scopeId = word32
79-
*/
80-
PeerAddresses []interface{}
71+
PeerAddresses []PeerAddress
8172
}
8273

83-
func NewMsgSharePeers(peerAddresses []interface{}) *MsgSharePeers {
74+
func NewMsgSharePeers(peerAddresses []PeerAddress) *MsgSharePeers {
8475
m := &MsgSharePeers{
8576
MessageBase: protocol.MessageBase{
8677
MessageType: MessageTypeSharePeers,
@@ -102,3 +93,85 @@ func NewMsgDone() *MsgDone {
10293
}
10394
return m
10495
}
96+
97+
type PeerAddress struct {
98+
IP net.IP
99+
Port uint16
100+
}
101+
102+
func (p *PeerAddress) UnmarshalCBOR(cborData []byte) error {
103+
peerType, err := cbor.DecodeIdFromList(cborData)
104+
if err != nil {
105+
return err
106+
}
107+
switch peerType {
108+
case 0:
109+
// IPv4
110+
tmpPeer := struct {
111+
cbor.StructAsArray
112+
PeerType int
113+
Address uint32
114+
Port uint16
115+
}{}
116+
if _, err := cbor.Decode(cborData, &tmpPeer); err != nil {
117+
return err
118+
}
119+
p.IP = make(net.IP, net.IPv4len)
120+
binary.LittleEndian.PutUint32(p.IP, tmpPeer.Address)
121+
p.Port = tmpPeer.Port
122+
case 1:
123+
// IPv6
124+
cborListLen, err := cbor.ListLength(cborData)
125+
if err != nil {
126+
return err
127+
}
128+
if cborListLen == 8 {
129+
// V11-12
130+
tmpPeer := struct {
131+
cbor.StructAsArray
132+
PeerType int
133+
Address1 uint32
134+
Address2 uint32
135+
Address3 uint32
136+
Address4 uint32
137+
FlowInfo uint32 // ignored
138+
ScopeId uint32 // ignored
139+
Port uint16
140+
}{}
141+
if _, err := cbor.Decode(cborData, &tmpPeer); err != nil {
142+
return err
143+
}
144+
p.IP = make(net.IP, net.IPv6len)
145+
binary.LittleEndian.PutUint32(p.IP[0:], tmpPeer.Address1)
146+
binary.LittleEndian.PutUint32(p.IP[4:], tmpPeer.Address2)
147+
binary.LittleEndian.PutUint32(p.IP[8:], tmpPeer.Address3)
148+
binary.LittleEndian.PutUint32(p.IP[12:], tmpPeer.Address4)
149+
p.Port = tmpPeer.Port
150+
} else if cborListLen == 6 {
151+
// V13+
152+
tmpPeer := struct {
153+
cbor.StructAsArray
154+
PeerType int
155+
Address1 uint32
156+
Address2 uint32
157+
Address3 uint32
158+
Address4 uint32
159+
Port uint16
160+
}{}
161+
if _, err := cbor.Decode(cborData, &tmpPeer); err != nil {
162+
return err
163+
}
164+
p.IP = make(net.IP, net.IPv6len)
165+
binary.LittleEndian.PutUint32(p.IP[0:], tmpPeer.Address1)
166+
binary.LittleEndian.PutUint32(p.IP[4:], tmpPeer.Address2)
167+
binary.LittleEndian.PutUint32(p.IP[8:], tmpPeer.Address3)
168+
binary.LittleEndian.PutUint32(p.IP[12:], tmpPeer.Address4)
169+
p.Port = tmpPeer.Port
170+
} else {
171+
return fmt.Errorf("invalid peer address length: %d", cborListLen)
172+
}
173+
default:
174+
return fmt.Errorf("unknown peer type: %d\n", peerType)
175+
}
176+
return nil
177+
}

protocol/versiondata.go

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@ const (
2222
DiffusionModeInitiatorAndResponder = false
2323
)
2424

25-
// TODO: update this for NtN v13+
2625
// Peer sharing modes
2726
const (
28-
PeerSharingModeNoPeerSharing = 0
29-
PeerSharingModePeerSharingPrivate = 1
30-
PeerSharingModePeerSharingPublic = 2
27+
PeerSharingModeNoPeerSharing = 0
28+
PeerSharingModePeerSharingPublic = 1
29+
PeerSharingModeV11NoPeerSharing = 0
30+
PeerSharingModeV11PeerSharingPrivate = 1
31+
PeerSharingModeV11PeerSharingPublic = 2
3132
)
3233

3334
// Query modes
@@ -41,7 +42,7 @@ type VersionData interface {
4142
//Query() bool
4243
// NtN only
4344
DiffusionMode() bool
44-
//PeerSharing() uint
45+
PeerSharing() bool
4546
}
4647

4748
type VersionDataNtC9to14 uint32
@@ -60,6 +61,10 @@ func (v VersionDataNtC9to14) DiffusionMode() bool {
6061
return DiffusionModeInitiatorOnly
6162
}
6263

64+
func (v VersionDataNtC9to14) PeerSharing() bool {
65+
return false
66+
}
67+
6368
type VersionDataNtC15andUp struct {
6469
cbor.StructAsArray
6570
CborNetworkMagic uint32
@@ -80,6 +85,10 @@ func (v VersionDataNtC15andUp) DiffusionMode() bool {
8085
return DiffusionModeInitiatorOnly
8186
}
8287

88+
func (v VersionDataNtC15andUp) PeerSharing() bool {
89+
return false
90+
}
91+
8392
type VersionDataNtN7to10 struct {
8493
cbor.StructAsArray
8594
CborNetworkMagic uint32
@@ -100,6 +109,10 @@ func (v VersionDataNtN7to10) DiffusionMode() bool {
100109
return v.CborInitiatorAndResponderDiffusionMode
101110
}
102111

112+
func (v VersionDataNtN7to10) PeerSharing() bool {
113+
return false
114+
}
115+
103116
type VersionDataNtN11to12 struct {
104117
cbor.StructAsArray
105118
CborNetworkMagic uint32
@@ -122,6 +135,10 @@ func (v VersionDataNtN11to12) DiffusionMode() bool {
122135
return v.CborInitiatorAndResponderDiffusionMode
123136
}
124137

138+
func (v VersionDataNtN11to12) PeerSharing() bool {
139+
return v.CborPeerSharing >= PeerSharingModeV11PeerSharingPublic
140+
}
141+
125142
// NOTE: the format stays the same, but the values for PeerSharing change
126143
type VersionDataNtN13andUp struct {
127144
VersionDataNtN11to12
@@ -132,3 +149,7 @@ func NewVersionDataNtN13andUpFromCbor(cborData []byte) (VersionData, error) {
132149
_, err := cbor.Decode(cborData, &v)
133150
return v, err
134151
}
152+
153+
func (v VersionDataNtN13andUp) PeerSharing() bool {
154+
return v.CborPeerSharing >= PeerSharingModePeerSharingPublic
155+
}

protocol/versions.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ type ProtocolVersion struct {
3838
EnableKeepAliveProtocol bool
3939
EnableFullDuplex bool
4040
EnablePeerSharingProtocol bool
41+
PeerSharingUseV11 bool
4142
}
4243

4344
var protocolVersions = map[uint16]ProtocolVersion{
@@ -173,6 +174,7 @@ var protocolVersions = map[uint16]ProtocolVersion{
173174
EnableBabbageEra: true,
174175
EnableFullDuplex: true,
175176
EnablePeerSharingProtocol: true,
177+
PeerSharingUseV11: true,
176178
},
177179
12: ProtocolVersion{
178180
NewVersionDataFromCborFunc: NewVersionDataNtN11to12FromCbor,
@@ -185,6 +187,7 @@ var protocolVersions = map[uint16]ProtocolVersion{
185187
EnableConwayEra: true,
186188
EnableFullDuplex: true,
187189
EnablePeerSharingProtocol: true,
190+
PeerSharingUseV11: true,
188191
},
189192
13: ProtocolVersion{
190193
NewVersionDataFromCborFunc: NewVersionDataNtN13andUpFromCbor,
@@ -205,7 +208,7 @@ func GetProtocolVersionMap(
205208
protocolMode ProtocolMode,
206209
networkMagic uint32,
207210
diffusionMode bool,
208-
peerSharing uint,
211+
peerSharing bool,
209212
queryMode bool,
210213
) ProtocolVersionMap {
211214
ret := ProtocolVersionMap{}
@@ -224,19 +227,27 @@ func GetProtocolVersionMap(
224227
} else {
225228
if version < ProtocolVersionNtCOffset {
226229
if version >= 13 {
230+
var tmpPeerSharing uint = PeerSharingModeNoPeerSharing
231+
if peerSharing {
232+
tmpPeerSharing = PeerSharingModePeerSharingPublic
233+
}
227234
ret[version] = VersionDataNtN13andUp{
228235
VersionDataNtN11to12{
229236
CborNetworkMagic: networkMagic,
230237
CborInitiatorAndResponderDiffusionMode: diffusionMode,
231-
CborPeerSharing: peerSharing,
238+
CborPeerSharing: tmpPeerSharing,
232239
CborQuery: queryMode,
233240
},
234241
}
235242
} else if version >= 11 {
243+
var tmpPeerSharing uint = PeerSharingModeV11NoPeerSharing
244+
if peerSharing {
245+
tmpPeerSharing = PeerSharingModeV11PeerSharingPublic
246+
}
236247
ret[version] = VersionDataNtN11to12{
237248
CborNetworkMagic: networkMagic,
238249
CborInitiatorAndResponderDiffusionMode: diffusionMode,
239-
CborPeerSharing: peerSharing,
250+
CborPeerSharing: tmpPeerSharing,
240251
CborQuery: queryMode,
241252
}
242253
} else {

0 commit comments

Comments
 (0)