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

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

8 9
	"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/dustin/go-humanize"

10
	key "github.com/ipfs/go-ipfs/blocks/key"
11 12 13
	cmds "github.com/ipfs/go-ipfs/commands"
	bitswap "github.com/ipfs/go-ipfs/exchange/bitswap"
	u "github.com/ipfs/go-ipfs/util"
Jeromy's avatar
Jeromy committed
14
	peer "gx/ipfs/QmUBogf4nUefBjmYjn6jfsfPJRkmDGSeMhNj4usRKq69f4/go-libp2p/p2p/peer"
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{
Richard Littauer's avatar
Richard Littauer committed
34
		cmds.StringArg("key", true, true, "Key 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
		},
	},
}