Skip to content

Commit

Permalink
feat: swarm peering command without save option
Browse files Browse the repository at this point in the history
  • Loading branch information
TakashiMatsuda committed Aug 17, 2021
1 parent 7c76118 commit d70ae1b
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 0 deletions.
4 changes: 4 additions & 0 deletions core/commands/commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,10 @@ func TestCommands(t *testing.T) {
"/swarm/filters/add",
"/swarm/filters/rm",
"/swarm/peers",
"/swarm/peering",
"/swarm/peering/add",
"/swarm/peering/ls",
"/swarm/peering/rm",
"/tar",
"/tar/add",
"/tar/cat",
Expand Down
124 changes: 124 additions & 0 deletions core/commands/swarm.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ ipfs peers in the internet.
"disconnect": swarmDisconnectCmd,
"filters": swarmFiltersCmd,
"peers": swarmPeersCmd,
"peering": swarmPeeringCmd,
},
}

Expand All @@ -61,6 +62,129 @@ const (
swarmDirectionOptionName = "direction"
)

var swarmPeeringCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "modify the peering service.",
ShortDescription: `
'ipfs swarm peering' is a tool to manupulate the peering service.
Peers in the peering service is maintained to be connected, reconnected
on disconnect with a back-off.
`,
},
Subcommands: map[string]*cmds.Command{
"add": swarmPeeringAddCmd,
"ls": swarmPeeringLsCmd,
"rm": swarmPeeringRmCmd,
},
}

var swarmPeeringAddCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "add peers into the peering service.",
ShortDescription: `
'ipfs swarm peering add' adds peers into the peering service.
`,
},
Arguments: []cmds.Argument{
cmds.StringArg("address", true, true, "address of peer to add into the PeeringService"),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
addrs := make([]ma.Multiaddr, len(req.Arguments))

for i, arg := range req.Arguments {
addr, err := ma.NewMultiaddr(arg)
if err != nil {
return err
}

addrs[i] = addr
}

addInfos, err := peer.AddrInfosFromP2pAddrs(addrs...)
if err != nil {
return err
}

node, err := cmdenv.GetNode(env)
if err != nil {
return err
}

output := make([]string, len(addInfos))
for i, id := range addInfos {
output[i] = "add " + id.ID.Pretty()
node.Peering.AddPeer(id)

output[i] += " success"
}

return cmds.EmitOnce(res, &stringList{output})
},
Encoders: cmds.EncoderMap{
cmds.Text: cmds.MakeTypedEncoder(stringListEncoder),
},
Type: stringList{},
}

var swarmPeeringLsCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "list peers registered in the peering service.",
ShortDescription: `
'ipfs swarm peering ls' lists peers registered in the peering service.`,
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
node, err := cmdenv.GetNode(env)
if err != nil {
return err
}
peers := node.Peering.ListPeer()
return cmds.EmitOnce(res, addrInfos{Peers: peers})
},
Type: addrInfos{},
}

type addrInfos struct {
Peers []peer.AddrInfo
}

var swarmPeeringRmCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "remove a peer from the peering service.",
ShortDescription: `
'ipfs swarm peering rm' removes peers from the peering service.
`,
},
Arguments: []cmds.Argument{
cmds.StringArg("ID", true, true, "ID of peer to remove from PeeringService"),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
node, err := cmdenv.GetNode(env)
if err != nil {
return err
}

output := make([]string, 0, len(req.Arguments))
for _, arg := range req.Arguments {
id, err := peer.Decode(arg)
if err != nil {
return err
}

msg := "remove " + id.Pretty()

node.Peering.RemovePeer(id)

msg += " success"
output = append(output, msg)
}
return cmds.EmitOnce(res, &stringList{output})
},
Type: stringList{},
Encoders: cmds.EncoderMap{
cmds.Text: cmds.MakeTypedEncoder(stringListEncoder),
},
}

var swarmPeersCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "List peers with open connections.",
Expand Down
19 changes: 19 additions & 0 deletions peering/peering.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package peering
import (
"context"
"errors"
"fmt"
"math/rand"
"sync"
"time"
Expand Down Expand Up @@ -212,6 +213,7 @@ func (ps *PeeringService) Stop() error {
// Add peer may also be called multiple times for the same peer. The new
// addresses will replace the old.
func (ps *PeeringService) AddPeer(info peer.AddrInfo) {
fmt.Printf("atempt to add peer %s of addrs %s\n", info.ID, info.Addrs)
ps.mu.Lock()
defer ps.mu.Unlock()

Expand All @@ -220,6 +222,7 @@ func (ps *PeeringService) AddPeer(info peer.AddrInfo) {
handler.setAddrs(info.Addrs)
} else {
logger.Infow("peer added", "peer", info.ID, "addrs", info.Addrs)
// in case ps.host is null this line results in a panic.
ps.host.ConnManager().Protect(info.ID, connmgrTag)

handler = &peerHandler{
Expand All @@ -242,6 +245,22 @@ func (ps *PeeringService) AddPeer(info peer.AddrInfo) {
}
}

// ListPeer lists peers in the peering service.
func (ps *PeeringService) ListPeer() []peer.AddrInfo {
out := make([]peer.AddrInfo, len(ps.peers))
c := 0
for k, v := range ps.peers {
out_addrs := make([]multiaddr.Multiaddr, len(v.addrs))
copy(out_addrs, v.addrs)
out[c] = peer.AddrInfo{
ID: k,
Addrs: out_addrs,
}
c++
}
return out
}

// RemovePeer removes a peer from the peering service. This function may be
// safely called at any time: before the service is started, while running, or
// after it stops.
Expand Down
6 changes: 6 additions & 0 deletions peering/peering_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func TestPeeringService(t *testing.T) {

// peer 1 -> 2
ps1.AddPeer(peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()})
require.Contains(t, ps1.ListPeer(), peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()})

// We haven't started so we shouldn't have any peers.
require.Never(t, func() bool {
Expand Down Expand Up @@ -109,6 +110,7 @@ func TestPeeringService(t *testing.T) {

// Unprotect 2 from 1.
ps1.RemovePeer(h2.ID())
require.NotContains(t, ps1.ListPeer(), peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()})

// Trim connections.
h1.ConnManager().TrimOpenConns(ctx)
Expand All @@ -127,7 +129,9 @@ func TestPeeringService(t *testing.T) {

// Until added back
ps1.AddPeer(peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()})
require.Contains(t, ps1.ListPeer(), peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()})
ps1.AddPeer(peer.AddrInfo{ID: h3.ID(), Addrs: h3.Addrs()})
require.Contains(t, ps1.ListPeer(), peer.AddrInfo{ID: h3.ID(), Addrs: h3.Addrs()})
t.Logf("wait for h1 to connect to h2 and h3 again")
require.Eventually(t, func() bool {
return h1.Network().Connectedness(h2.ID()) == network.Connected
Expand All @@ -142,7 +146,9 @@ func TestPeeringService(t *testing.T) {

// Adding and removing should work after stopping.
ps1.AddPeer(peer.AddrInfo{ID: h4.ID(), Addrs: h4.Addrs()})
require.Contains(t, ps1.ListPeer(), peer.AddrInfo{ID: h4.ID(), Addrs: h4.Addrs()})
ps1.RemovePeer(h2.ID())
require.NotContains(t, ps1.ListPeer(), peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()})
}

func TestNextBackoff(t *testing.T) {
Expand Down
30 changes: 30 additions & 0 deletions test/sharness/t0140-swarm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,36 @@ test_expect_success "Addresses.NoAnnounce with /ipcidr affects addresses" '

test_kill_ipfs_daemon

test_launch_ipfs_daemon

test_expect_success "'ipfs swarm peering ls' lists peerings" '
ipfs swarm peering ls
'

peeringID='QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N'
peeringAddr='/ip4/1.2.3.4/tcp/1234/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N'
test_expect_success "'ipfs swarm peering add' adds a peering" '
ipfs swarm peering ls > peeringls &&
! test_should_contain ${peeringID} peeringls
ipfs swarm peering add $peeringAddr
'

test_expect_success 'a peering is added' '
ipfs swarm peering ls > peeringadd &&
test_should_contain ${peeringID} peeringadd
'

test_expect_success "'swarm peering rm' removes a peering" '
ipfs swarm peering rm ${peeringID}
'

test_expect_success 'peering is removed' '
ipfs swarm peering ls > peeringrm &&
! test_should_contain ${peeringID} peeringrm
'

test_kill_ipfs_daemon

test_expect_success "set up tcp testbed" '
iptb testbed create -type localipfs -count 2 -force -init
'
Expand Down

0 comments on commit d70ae1b

Please sign in to comment.