Skip to content
This repository was archived by the owner on Feb 7, 2024. It is now read-only.

Commit fe9de88

Browse files
committed
Support for P2P listeners and streams
1 parent 0a07e21 commit fe9de88

File tree

2 files changed

+168
-0
lines changed

2 files changed

+168
-0
lines changed

p2p.go

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package shell
2+
3+
import (
4+
"context"
5+
"strconv"
6+
7+
ma "github.com/multiformats/go-multiaddr"
8+
)
9+
10+
// P2PListener describes a P2P listener.
11+
type P2PListener struct {
12+
Protocol string
13+
Address string
14+
}
15+
16+
// P2POpenListener forwards P2P connections to a network multiaddr.
17+
func (s *Shell) P2POpenListener(ctx context.Context, protocol, maddr string) (*P2PListener, error) {
18+
if _, err := ma.NewMultiaddr(maddr); err != nil {
19+
return nil, err
20+
}
21+
22+
var response *P2PListener
23+
err := s.Request("p2p/listener/open").
24+
Arguments(protocol, maddr).Exec(ctx, &response)
25+
if err != nil {
26+
return nil, err
27+
}
28+
29+
return response, nil
30+
}
31+
32+
// P2PCloseListener closes one or all active P2P listeners.
33+
func (s *Shell) P2PCloseListener(ctx context.Context, protocol string, closeAll bool) error {
34+
req := s.Request("p2p/listener/close").
35+
Option("all", strconv.FormatBool(closeAll))
36+
37+
if protocol != "" {
38+
req.Arguments(protocol)
39+
}
40+
41+
if err := req.Exec(ctx, nil); err != nil {
42+
return err
43+
}
44+
45+
return nil
46+
}
47+
48+
// P2PListenerList contains a slice of P2PListeners.
49+
type P2PListenerList struct {
50+
Listeners []*P2PListener
51+
}
52+
53+
// P2PListListeners lists all P2P listeners.
54+
func (s *Shell) P2PListListeners(ctx context.Context) (*P2PListenerList, error) {
55+
var response *P2PListenerList
56+
57+
if err := s.Request("p2p/listener/ls").Exec(ctx, &response); err != nil {
58+
return nil, err
59+
}
60+
61+
return response, nil
62+
}
63+
64+
// P2PStream describes a P2P stream.
65+
type P2PStream struct {
66+
Protocol string
67+
Address string
68+
}
69+
70+
// P2PStreamDial dials to a peer's P2P listener.
71+
func (s *Shell) P2PStreamDial(ctx context.Context, peerID, protocol, listenerMaddr string) (*P2PStream, error) {
72+
var response *P2PStream
73+
req := s.Request("p2p/stream/dial").
74+
Arguments(peerID, protocol)
75+
76+
if listenerMaddr != "" {
77+
if _, err := ma.NewMultiaddr(listenerMaddr); err != nil {
78+
return nil, err
79+
}
80+
req.Arguments(listenerMaddr)
81+
}
82+
83+
if err := req.Exec(ctx, &response); err != nil {
84+
return nil, err
85+
}
86+
87+
return response, nil
88+
}
89+
90+
// P2PCloseStream closes one or all active P2P streams.
91+
func (s *Shell) P2PCloseStream(ctx context.Context, handlerID string, closeAll bool) error {
92+
req := s.Request("p2p/stream/close").
93+
Option("all", strconv.FormatBool(closeAll))
94+
95+
if handlerID != "" {
96+
req.Arguments(handlerID)
97+
}
98+
99+
if err := req.Exec(ctx, nil); err != nil {
100+
return err
101+
}
102+
103+
return nil
104+
}
105+
106+
// P2PStreamsList contains a slice of streams.
107+
type P2PStreamsList struct {
108+
Streams []*struct {
109+
HandlerID string
110+
Protocol string
111+
LocalPeer string
112+
LocalAddress string
113+
RemotePeer string
114+
RemoteAddress string
115+
}
116+
}
117+
118+
// P2PListStreams lists all P2P streams.
119+
func (s *Shell) P2PListStreams(ctx context.Context) (*P2PStreamsList, error) {
120+
var response *P2PStreamsList
121+
req := s.Request("p2p/stream/ls").
122+
Option("headers", strconv.FormatBool(true))
123+
124+
if err := req.Exec(ctx, &response); err != nil {
125+
return nil, err
126+
}
127+
128+
return response, nil
129+
}

p2p_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package shell
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/cheekybits/is"
8+
)
9+
10+
func TestP2PListener(t *testing.T) {
11+
is := is.New(t)
12+
s := NewShell(shellUrl)
13+
14+
listener, err := s.P2POpenListener(context.Background(), "p2p-open-listener-test", "/ip4/127.0.0.1/udp/3000")
15+
is.Nil(err)
16+
is.Equal(listener.Address, "/ip4/127.0.0.1/udp/3000")
17+
is.Equal(listener.Protocol, "/p2p/p2p-open-listener-test")
18+
19+
listenerList, err := s.P2PListListeners(context.Background())
20+
is.Nil(err)
21+
is.Equal(len(listenerList.Listeners), 1)
22+
is.Equal(listenerList.Listeners[0].Address, "/ip4/127.0.0.1/udp/3000")
23+
is.Equal(listenerList.Listeners[0].Protocol, "/p2p/p2p-open-listener-test")
24+
25+
is.Nil(s.P2PCloseListener(context.Background(), "p2p-open-listener-test", false))
26+
27+
listenerList, err = s.P2PListListeners(context.Background())
28+
is.Nil(err)
29+
is.Equal(len(listenerList.Listeners), 0)
30+
}
31+
32+
func TestP2PStreams(t *testing.T) {
33+
is := is.New(t)
34+
s := NewShell(shellUrl)
35+
36+
streamsList, err := s.P2PListStreams(context.Background())
37+
is.Nil(err)
38+
is.Equal(len(streamsList.Streams), 0)
39+
}

0 commit comments

Comments
 (0)