bitswap.go 4.18 KB
Newer Older
1 2 3 4
package commands

import (
	"bytes"
Jeromy's avatar
Jeromy committed
5
	"fmt"
6 7
	"io"

Jakub Sztandera's avatar
Jakub Sztandera committed
8
	"gx/ipfs/QmPSBJL4momYnE7DcUyk2DVhD6rH488ZmHBGLbxNdhU44K/go-humanize"
9

10
	key "github.com/ipfs/go-ipfs/blocks/key"
11 12
	cmds "github.com/ipfs/go-ipfs/commands"
	bitswap "github.com/ipfs/go-ipfs/exchange/bitswap"
13
	peer "gx/ipfs/QmRBqJF7hb8ZSpRcMwUt8hNhydWcxGEhtk81HKq6oUwKvs/go-libp2p-peer"
14
	u "gx/ipfs/QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1/go-ipfs-util"
15 16 17 18
)

var BitswapCmd = &cmds.Command{
	Helptext: cmds.HelpText{
Richard Littauer's avatar
Richard Littauer committed
19
		Tagline:          "A set of commands to manipulate the bitswap agent.",
20 21 22 23 24
		ShortDescription: ``,
	},
	Subcommands: map[string]*cmds.Command{
		"wantlist": showWantlistCmd,
		"stat":     bitswapStatCmd,
25 26 27 28 29 30
		"unwant":   unwantCmd,
	},
}

var unwantCmd = &cmds.Command{
	Helptext: cmds.HelpText{
Richard Littauer's avatar
Richard Littauer committed
31
		Tagline: "Remove a given block from your wantlist.",
32 33
	},
	Arguments: []cmds.Argument{
34
		cmds.StringArg("key", true, true, "Key(s) to remove from your wantlist.").EnableStdin(),
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
	},
	Run: func(req cmds.Request, res cmds.Response) {
		nd, err := req.InvocContext().GetNode()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		if !nd.OnlineMode() {
			res.SetError(errNotOnline, cmds.ErrClient)
			return
		}

		bs, ok := nd.Exchange.(*bitswap.Bitswap)
		if !ok {
			res.SetError(u.ErrCast(), cmds.ErrNormal)
			return
		}

		var ks []key.Key
		for _, arg := range req.Arguments() {
			dec := key.B58KeyDecode(arg)
			if dec == "" {
Richard Littauer's avatar
Richard Littauer committed
58
				res.SetError(fmt.Errorf("Incorrectly formatted key: %s", arg), cmds.ErrNormal)
59 60 61 62 63 64 65
				return
			}

			ks = append(ks, dec)
		}

		bs.CancelWants(ks)
66 67 68 69 70
	},
}

var showWantlistCmd = &cmds.Command{
	Helptext: cmds.HelpText{
Richard Littauer's avatar
Richard Littauer committed
71
		Tagline: "Show blocks currently on the wantlist.",
72
		ShortDescription: `
Richard Littauer's avatar
Richard Littauer committed
73
Print out all blocks currently on the bitswap wantlist for the local peer.`,
74
	},
75
	Options: []cmds.Option{
Richard Littauer's avatar
Richard Littauer committed
76
		cmds.StringOption("peer", "p", "Specify which peer to show wantlist for. Default: self."),
77
	},
78 79
	Type: KeyList{},
	Run: func(req cmds.Request, res cmds.Response) {
Jeromy's avatar
Jeromy committed
80
		nd, err := req.InvocContext().GetNode()
81 82 83 84
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
85 86 87 88 89 90

		if !nd.OnlineMode() {
			res.SetError(errNotOnline, cmds.ErrClient)
			return
		}

91 92 93 94 95
		bs, ok := nd.Exchange.(*bitswap.Bitswap)
		if !ok {
			res.SetError(u.ErrCast(), cmds.ErrNormal)
			return
		}
96

97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
		pstr, found, err := req.Option("peer").String()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		if found {
			pid, err := peer.IDB58Decode(pstr)
			if err != nil {
				res.SetError(err, cmds.ErrNormal)
				return
			}
			res.SetOutput(&KeyList{bs.WantlistForPeer(pid)})
		} else {
			res.SetOutput(&KeyList{bs.GetWantlist()})
		}
112 113 114 115 116 117 118 119
	},
	Marshalers: cmds.MarshalerMap{
		cmds.Text: KeyListTextMarshaler,
	},
}

var bitswapStatCmd = &cmds.Command{
	Helptext: cmds.HelpText{
Richard Littauer's avatar
Richard Littauer committed
120
		Tagline:          "Show some diagnostic information on the bitswap agent.",
121 122 123 124
		ShortDescription: ``,
	},
	Type: bitswap.Stat{},
	Run: func(req cmds.Request, res cmds.Response) {
Jeromy's avatar
Jeromy committed
125
		nd, err := req.InvocContext().GetNode()
126 127 128 129 130
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

131 132 133 134 135
		if !nd.OnlineMode() {
			res.SetError(errNotOnline, cmds.ErrClient)
			return
		}

136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
		bs, ok := nd.Exchange.(*bitswap.Bitswap)
		if !ok {
			res.SetError(u.ErrCast(), cmds.ErrNormal)
			return
		}

		st, err := bs.Stat()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		res.SetOutput(st)
	},
	Marshalers: cmds.MarshalerMap{
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
			out, ok := res.Output().(*bitswap.Stat)
			if !ok {
				return nil, u.ErrCast()
			}
			buf := new(bytes.Buffer)
Jeromy's avatar
Jeromy committed
157 158
			fmt.Fprintln(buf, "bitswap status")
			fmt.Fprintf(buf, "\tprovides buffer: %d / %d\n", out.ProvideBufLen, bitswap.HasBlockBufferSize)
159 160
			fmt.Fprintf(buf, "\tblocks received: %d\n", out.BlocksReceived)
			fmt.Fprintf(buf, "\tdup blocks received: %d\n", out.DupBlksReceived)
161
			fmt.Fprintf(buf, "\tdup data received: %s\n", humanize.Bytes(out.DupDataReceived))
Jeromy's avatar
Jeromy committed
162 163 164 165 166 167 168
			fmt.Fprintf(buf, "\twantlist [%d keys]\n", len(out.Wantlist))
			for _, k := range out.Wantlist {
				fmt.Fprintf(buf, "\t\t%s\n", k.B58String())
			}
			fmt.Fprintf(buf, "\tpartners [%d]\n", len(out.Peers))
			for _, p := range out.Peers {
				fmt.Fprintf(buf, "\t\t%s\n", p)
169 170 171 172 173
			}
			return buf, nil
		},
	},
}