forked from willscott/go-selfish-bitswap-client
/
main.go
115 lines (102 loc) · 2.96 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package main
import (
"bytes"
"context"
"fmt"
"io"
"log"
"os"
"time"
"github.com/ipfs/go-cid"
"github.com/ipld/go-car/v2"
"github.com/ipld/go-ipld-prime/datamodel"
"github.com/ipld/go-ipld-prime/linking"
cidlink "github.com/ipld/go-ipld-prime/linking/cid"
selectorparse "github.com/ipld/go-ipld-prime/traversal/selector/parse"
"github.com/libp2p/go-libp2p"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/p2p/muxer/mplex"
"github.com/libp2p/go-libp2p/p2p/muxer/yamux"
"github.com/libp2p/go-libp2p/p2p/security/noise"
tls "github.com/libp2p/go-libp2p/p2p/security/tls"
quic "github.com/libp2p/go-libp2p/p2p/transport/quic"
"github.com/libp2p/go-libp2p/p2p/transport/tcp"
"github.com/libp2p/go-libp2p/p2p/transport/websocket"
"github.com/multiformats/go-multiaddr"
"github.com/urfave/cli/v2"
bitswap "github.com/willscott/go-selfish-bitswap-client"
)
func main() {
app := &cli.App{
Name: "getswap",
Usage: "Bitswap demonstration retrieval client",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "peer",
Aliases: []string{"p"},
Required: true,
},
},
Action: Get,
}
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
}
const yamuxID = "/yamux/1.0.0"
const mplexID = "/mplex/6.7.0"
func Get(c *cli.Context) error {
// handle /parse cid
if c.Args().Len() == 0 {
return fmt.Errorf("no cid specified")
}
cidStr := c.Args().First()
cidParsed, err := cid.Parse(cidStr)
if err != nil {
return err
}
// handle / parse peer
mStr := c.String("peer")
ma, err := multiaddr.NewMultiaddr(mStr)
if err != nil {
return err
}
ai, err := peer.AddrInfoFromP2pAddr(ma)
if err != nil {
return err
}
// make host
opts := make([]libp2p.Option, 0)
opts = append([]libp2p.Option{libp2p.Identity(nil)}, opts...)
opts = append([]libp2p.Option{libp2p.Transport(tcp.NewTCPTransport, tcp.WithMetrics()), libp2p.Transport(quic.NewTransport), libp2p.Transport(websocket.New)}, opts...)
// add security
opts = append([]libp2p.Option{libp2p.Security(tls.ID, tls.New), libp2p.Security(noise.ID, noise.New)}, opts...)
// add muxers
opts = append([]libp2p.Option{libp2p.Muxer(yamuxID, yamuxTransport()), libp2p.Muxer(mplexID, mplex.DefaultTransport)}, opts...)
host, err := libp2p.New(opts...)
if err != nil {
return err
}
host.Peerstore().AddAddr(ai.ID, ai.Addrs[0], time.Hour)
s := bitswap.New(host, ai.ID, bitswap.Options{})
// traverse the dag into a car.
ls := cidlink.DefaultLinkSystem()
ls.StorageReadOpener = func(ctx linking.LinkContext, l datamodel.Link) (io.Reader, error) {
c := l.(cidlink.Link).Cid
blk, err := s.Get(ctx.Ctx, c)
if err != nil {
return nil, err
}
r := bytes.NewBuffer(blk)
return r, nil
}
_, err = car.TraverseV1(context.Background(), &ls, cidParsed, selectorparse.CommonSelector_ExploreAllRecursively, os.Stdout)
return err
}
func yamuxTransport() network.Multiplexer {
tpt := *yamux.DefaultTransport
tpt.AcceptBacklog = 512
return &tpt
}