|
1 | 1 | package main
|
2 | 2 |
|
3 | 3 | import (
|
4 |
| - "bytes" |
5 | 4 | "context"
|
| 5 | + "encoding/json" |
| 6 | + "errors" |
6 | 7 | "fmt"
|
| 8 | + "io" |
7 | 9 | "log"
|
8 |
| - "strings" |
| 10 | + "os" |
9 | 11 | "time"
|
10 | 12 |
|
11 |
| - pbuf "github.com/gogo/protobuf/proto" |
12 |
| - |
| 13 | + "github.com/ipfs/boxo/ipns" |
| 14 | + "github.com/ipfs/boxo/routing/http/client" |
| 15 | + "github.com/ipfs/boxo/routing/http/types" |
| 16 | + "github.com/ipfs/boxo/routing/http/types/iter" |
13 | 17 | "github.com/ipfs/go-cid"
|
14 |
| - "github.com/ipfs/go-delegated-routing/client" |
15 |
| - "github.com/ipfs/go-ipns" |
16 |
| - ipns_pb "github.com/ipfs/go-ipns/pb" |
17 |
| - "github.com/ipld/go-ipld-prime/codec/dagjson" |
18 |
| - "github.com/libp2p/go-libp2p-core/peer" |
19 |
| - "github.com/multiformats/go-multiaddr" |
20 |
| - |
21 |
| - drp "github.com/ipfs/go-delegated-routing/gen/proto" |
| 18 | + "github.com/libp2p/go-libp2p/core/peer" |
22 | 19 | )
|
23 | 20 |
|
24 |
| -func identify(ctx context.Context, endpoint string, prettyOutput bool) error { |
25 |
| - ic, err := drp.New_DelegatedRouting_Client(endpoint) |
| 21 | +func findProviders(ctx context.Context, key cid.Cid, endpoint string, prettyOutput bool) error { |
| 22 | + drc, err := client.New(endpoint) |
26 | 23 | if err != nil {
|
27 | 24 | return err
|
28 | 25 | }
|
29 | 26 |
|
30 |
| - respCh, err := ic.Identify_Async(ctx, &drp.DelegatedRouting_IdentifyArg{}) |
31 |
| - for r := range respCh { |
32 |
| - if r.Err != nil { |
33 |
| - log.Println(r.Err) |
34 |
| - continue |
35 |
| - } |
36 |
| - |
37 |
| - if !prettyOutput { |
38 |
| - var buf bytes.Buffer |
39 |
| - if err := dagjson.Encode(r.Resp, &buf); err != nil { |
40 |
| - return err |
41 |
| - } |
42 |
| - fmt.Println(buf.String()) |
43 |
| - } else { |
44 |
| - var methods []string |
45 |
| - for _, m := range r.Resp.Methods { |
46 |
| - methods = append(methods, string(m)) |
47 |
| - } |
48 |
| - fmt.Println(strings.Join(methods, ",")) |
49 |
| - } |
| 27 | + recordsIter, err := drc.FindProviders(ctx, key) |
| 28 | + if err != nil { |
| 29 | + return err |
50 | 30 | }
|
51 |
| - return nil |
| 31 | + defer recordsIter.Close() |
| 32 | + |
| 33 | + return printIter(os.Stdout, prettyOutput, recordsIter) |
52 | 34 | }
|
53 | 35 |
|
54 |
| -func findprovs(ctx context.Context, c cid.Cid, endpoint string, prettyOutput bool) error { |
55 |
| - ic, err := drp.New_DelegatedRouting_Client(endpoint) |
| 36 | +func findPeers(ctx context.Context, pid peer.ID, endpoint string, prettyOutput bool) error { |
| 37 | + drc, err := client.New(endpoint) |
56 | 38 | if err != nil {
|
57 | 39 | return err
|
58 | 40 | }
|
59 | 41 |
|
60 |
| - respCh, err := ic.FindProviders_Async(ctx, &drp.FindProvidersRequest{ |
61 |
| - Key: drp.LinkToAny(c), |
62 |
| - }) |
| 42 | + recordsIter, err := drc.FindPeers(ctx, pid) |
63 | 43 | if err != nil {
|
64 | 44 | return err
|
65 | 45 | }
|
66 |
| - for r := range respCh { |
67 |
| - if r.Err != nil { |
68 |
| - log.Println(r.Err) |
69 |
| - continue |
| 46 | + defer recordsIter.Close() |
| 47 | + |
| 48 | + return printIter(os.Stdout, prettyOutput, recordsIter) |
| 49 | +} |
| 50 | + |
| 51 | +func printIter(w io.Writer, prettyOutput bool, iter iter.ResultIter[types.Record]) error { |
| 52 | + for iter.Next() { |
| 53 | + res := iter.Val() |
| 54 | + |
| 55 | + // Check for error, but do not complain if we exceeded the timeout. We are |
| 56 | + // expecting that to happen: we explicitly defined a timeout. |
| 57 | + if res.Err != nil { |
| 58 | + if !errors.Is(res.Err, context.DeadlineExceeded) { |
| 59 | + return res.Err |
| 60 | + } |
| 61 | + |
| 62 | + return nil |
70 | 63 | }
|
71 | 64 |
|
72 |
| - if !prettyOutput { |
73 |
| - var buf bytes.Buffer |
74 |
| - if err := dagjson.Encode(r.Resp, &buf); err != nil { |
75 |
| - return err |
| 65 | + if prettyOutput { |
| 66 | + switch res.Val.GetSchema() { |
| 67 | + case types.SchemaPeer: |
| 68 | + record := res.Val.(*types.PeerRecord) |
| 69 | + fmt.Fprintln(w, record.ID) |
| 70 | + fmt.Fprintln(w, "\tProtocols:", record.Protocols) |
| 71 | + fmt.Fprintln(w, "\tAddresses:", record.Addrs) |
| 72 | + |
| 73 | + case types.SchemaBitswap: |
| 74 | + record := res.Val.(*types.BitswapRecord) |
| 75 | + fmt.Fprintln(w, record.ID) |
| 76 | + fmt.Fprintln(w, "\tProtocol:", record.Protocol) |
| 77 | + fmt.Fprintln(w, "\tAddresses:", record.Addrs) |
| 78 | + |
| 79 | + default: |
| 80 | + // You may not want to fail here, it's up to you. You can just handle |
| 81 | + // the schemas you want, or that you know, but not fail. |
| 82 | + log.Printf("unrecognized schema: %s", res.Val.GetSchema()) |
76 | 83 | }
|
77 |
| - fmt.Println(buf.String()) |
78 | 84 | } else {
|
79 |
| - for _, prov := range r.Resp.Providers { |
80 |
| - if prov.ProviderNode.Peer != nil { |
81 |
| - ai := &peer.AddrInfo{} |
82 |
| - ai.ID = peer.ID(prov.ProviderNode.Peer.ID) |
83 |
| - for _, bma := range prov.ProviderNode.Peer.Multiaddresses { |
84 |
| - ma, err := multiaddr.NewMultiaddrBytes(bma) |
85 |
| - if err != nil { |
86 |
| - return err |
87 |
| - } |
88 |
| - ai.Addrs = append(ai.Addrs, ma) |
89 |
| - } |
90 |
| - fmt.Println(ai) |
91 |
| - } |
92 |
| - for _, proto := range prov.ProviderProto { |
93 |
| - if proto.Bitswap != nil { |
94 |
| - fmt.Println("\t Bitswap") |
95 |
| - } else if proto.GraphSyncFILv1 != nil { |
96 |
| - fmt.Println("\t GraphSyncFILv1") |
97 |
| - var buf bytes.Buffer |
98 |
| - if err := dagjson.Encode(proto.GraphSyncFILv1, &buf); err != nil { |
99 |
| - return err |
100 |
| - } |
101 |
| - fmt.Println("\t\t" + buf.String()) |
102 |
| - } else { |
103 |
| - var buf bytes.Buffer |
104 |
| - if err := dagjson.Encode(proto, &buf); err != nil { |
105 |
| - return err |
106 |
| - } |
107 |
| - fmt.Println("\t" + buf.String()) |
108 |
| - } |
109 |
| - } |
| 85 | + err := json.NewEncoder(os.Stdout).Encode(res.Val) |
| 86 | + if err != nil { |
| 87 | + return err |
110 | 88 | }
|
111 | 89 | }
|
112 | 90 | }
|
| 91 | + |
113 | 92 | return nil
|
114 | 93 | }
|
115 | 94 |
|
116 |
| -func getIPNS(ctx context.Context, p peer.ID, endpoint string, prettyOutput bool) error { |
117 |
| - ic, err := drp.New_DelegatedRouting_Client(endpoint) |
| 95 | +func getIPNS(ctx context.Context, name ipns.Name, endpoint string, prettyOutput bool) error { |
| 96 | + drc, err := client.New(endpoint) |
| 97 | + if err != nil { |
| 98 | + return err |
| 99 | + } |
| 100 | + |
| 101 | + rec, err := drc.GetIPNS(ctx, name) |
118 | 102 | if err != nil {
|
119 | 103 | return err
|
120 | 104 | }
|
121 | 105 |
|
122 | 106 | if prettyOutput {
|
123 |
| - c := client.NewClient(ic) |
124 |
| - respCh, err := c.GetIPNSAsync(ctx, []byte(p)) |
| 107 | + v, err := rec.Value() |
125 | 108 | if err != nil {
|
126 | 109 | return err
|
127 | 110 | }
|
128 |
| - for r := range respCh { |
129 |
| - if r.Err != nil { |
130 |
| - log.Println(r.Err) |
131 |
| - continue |
132 |
| - } |
133 |
| - rec := new(ipns_pb.IpnsEntry) |
134 |
| - if err := pbuf.Unmarshal(r.Record, rec); err != nil { |
135 |
| - return err |
136 |
| - } |
137 |
| - seqno := rec.GetSequence() |
138 |
| - ttl := time.Duration(rec.GetTtl()) |
139 |
| - eol, err := ipns.GetEOL(rec) |
140 |
| - if err != nil { |
141 |
| - return err |
142 |
| - } |
143 |
| - value := string(rec.GetValue()) |
144 |
| - fmt.Printf("Sequence: %d, TTL: %v, EOL: %v, Value: %s\n", seqno, ttl, eol, value) |
| 111 | + |
| 112 | + seq, err := rec.Sequence() |
| 113 | + if err != nil { |
| 114 | + return err |
145 | 115 | }
|
| 116 | + |
| 117 | + eol, err := rec.Validity() |
| 118 | + if err != nil { |
| 119 | + return err |
| 120 | + } |
| 121 | + |
| 122 | + fmt.Printf("/ipns/%s\n", name) |
| 123 | + |
| 124 | + // Since [client.Client.GetIPNS] verifies if the retrieved record is valid, we |
| 125 | + // do not need to verify it again. However, if you were not using this specific |
| 126 | + // client, but using some other tool, you should always validate the IPNS Record |
| 127 | + // using the [ipns.Validate] or [ipns.ValidateWithName] functions. |
| 128 | + fmt.Println("\tSignature: VALID") |
| 129 | + fmt.Println("\tValue:", v.String()) |
| 130 | + fmt.Println("\tSequence:", seq) |
| 131 | + fmt.Println("\tValidity:", eol.Format(time.RFC3339)) |
| 132 | + ttl, err := rec.TTL() |
| 133 | + if err == nil { |
| 134 | + fmt.Println("\tTTL:", ttl.String()) |
| 135 | + } |
| 136 | + |
146 | 137 | return nil
|
147 | 138 | }
|
148 | 139 |
|
149 |
| - respCh, err := ic.GetIPNS_Async(ctx, &drp.GetIPNSRequest{ |
150 |
| - ID: []byte(p), |
151 |
| - }) |
| 140 | + raw, err := ipns.MarshalRecord(rec) |
152 | 141 | if err != nil {
|
153 | 142 | return err
|
154 | 143 | }
|
155 |
| - for r := range respCh { |
156 |
| - if r.Err != nil { |
157 |
| - log.Println(r.Err) |
158 |
| - continue |
159 |
| - } |
160 |
| - var buf bytes.Buffer |
161 |
| - if err := dagjson.Encode(r.Resp, &buf); err != nil { |
162 |
| - return err |
163 |
| - } |
164 |
| - fmt.Println(buf.String()) |
165 |
| - } |
166 |
| - return nil |
| 144 | + |
| 145 | + _, err = os.Stdout.Write(raw) |
| 146 | + return err |
167 | 147 | }
|
168 | 148 |
|
169 |
| -func putIPNS(ctx context.Context, key peer.ID, record []byte, endpoint string) error { |
170 |
| - ic, err := drp.New_DelegatedRouting_Client(endpoint) |
| 149 | +func putIPNS(ctx context.Context, name ipns.Name, record []byte, endpoint string) error { |
| 150 | + drc, err := client.New(endpoint) |
| 151 | + if err != nil { |
| 152 | + return err |
| 153 | + } |
| 154 | + |
| 155 | + rec, err := ipns.UnmarshalRecord(record) |
171 | 156 | if err != nil {
|
172 | 157 | return err
|
173 | 158 | }
|
174 | 159 |
|
175 |
| - c := client.NewClient(ic) |
176 |
| - return c.PutIPNS(ctx, []byte(key), record) |
| 160 | + return drc.PutIPNS(ctx, name, rec) |
177 | 161 | }
|
0 commit comments