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