@cryptotaxi247 / kubo / commits / 3db9551f7

Extract the namesys and the keystore submodules

Namesys is a very useful submodule. Given a ValueStore and a Datastore it can resolve and publish /ipns/ paths. This functionality does not need to be sequestered inside go-ipfs as it can and should be used without IPFS, for example, for implementing lightweight IPNS publishing services or for resolving /ipns/ paths. "keystore" extraction was necessary, as there is a dependency to it in namesys. Keystore is also a useful module by itself within the stack. Fixes #6537

Hector Sanjuan committed Feb 19, 2021 at 00:33 UTC 3db9551f7948809e6f9104651412557fbde08af0
39 files changed +114 -3124
cmd/ipfs/init.go
+1 -1
@@ -14,8 +14,8 @@ import (
14 oldcmds "github.com/ipfs/go-ipfs/commands"
15 core "github.com/ipfs/go-ipfs/core"
16 "github.com/ipfs/go-ipfs/core/commands"
17 - namesys "github.com/ipfs/go-ipfs/namesys"
17 fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo"
18 + namesys "github.com/ipfs/go-namesys"
19
20 cmds "github.com/ipfs/go-ipfs-cmds"
21 config "github.com/ipfs/go-ipfs-config"
core/commands/dht_test.go
+1 -1
@@ -3,7 +3,7 @@ package commands
3 import (
4 "testing"
5
6 - "github.com/ipfs/go-ipfs/namesys"
6 + "github.com/ipfs/go-namesys"
7
8 ipns "github.com/ipfs/go-ipns"
9 "github.com/libp2p/go-libp2p-core/test"
core/commands/dns.go
+1 -1
@@ -6,7 +6,7 @@ import (
6
7 cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
8 ncmd "github.com/ipfs/go-ipfs/core/commands/name"
9 - namesys "github.com/ipfs/go-ipfs/namesys"
9 + namesys "github.com/ipfs/go-namesys"
10 nsopts "github.com/ipfs/interface-go-ipfs-core/options/namesys"
11
12 cmds "github.com/ipfs/go-ipfs-cmds"
core/commands/name/ipns.go
+1 -1
@@ -8,7 +8,7 @@ import (
8 "time"
9
10 cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
11 - namesys "github.com/ipfs/go-ipfs/namesys"
11 + namesys "github.com/ipfs/go-namesys"
12
13 cmds "github.com/ipfs/go-ipfs-cmds"
14 logging "github.com/ipfs/go-log"
core/commands/resolve.go
+1 -1
@@ -9,7 +9,7 @@ import (
9
10 cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
11 ncmd "github.com/ipfs/go-ipfs/core/commands/name"
12 - ns "github.com/ipfs/go-ipfs/namesys"
12 + ns "github.com/ipfs/go-namesys"
13
14 cidenc "github.com/ipfs/go-cidutil/cidenc"
15 cmds "github.com/ipfs/go-ipfs-cmds"
core/core.go
+2 -2
@@ -45,11 +45,11 @@ import (
45 "github.com/ipfs/go-ipfs/core/node"
46 "github.com/ipfs/go-ipfs/core/node/libp2p"
47 "github.com/ipfs/go-ipfs/fuse/mount"
48 - "github.com/ipfs/go-ipfs/namesys"
49 - ipnsrp "github.com/ipfs/go-ipfs/namesys/republisher"
48 "github.com/ipfs/go-ipfs/p2p"
49 "github.com/ipfs/go-ipfs/peering"
50 "github.com/ipfs/go-ipfs/repo"
51 + "github.com/ipfs/go-namesys"
52 + ipnsrp "github.com/ipfs/go-namesys/republisher"
53 )
54
55 var log = logging.Logger("core")
core/coreapi/coreapi.go
+1 -1
@@ -39,8 +39,8 @@ import (
39
40 "github.com/ipfs/go-ipfs/core"
41 "github.com/ipfs/go-ipfs/core/node"
42 - "github.com/ipfs/go-ipfs/namesys"
42 "github.com/ipfs/go-ipfs/repo"
43 + "github.com/ipfs/go-namesys"
44 )
45
46 type CoreAPI struct {
core/coreapi/name.go
+2 -2
@@ -6,8 +6,8 @@ import (
6 "strings"
7 "time"
8
9 - "github.com/ipfs/go-ipfs/keystore"
10 - "github.com/ipfs/go-ipfs/namesys"
9 + "github.com/ipfs/go-ipfs-keystore"
10 + "github.com/ipfs/go-namesys"
11
12 ipath "github.com/ipfs/go-path"
13 coreiface "github.com/ipfs/interface-go-ipfs-core"
core/coreapi/path.go
+1 -1
@@ -5,7 +5,7 @@ import (
5 "fmt"
6 gopath "path"
7
8 - "github.com/ipfs/go-ipfs/namesys/resolve"
8 + "github.com/ipfs/go-namesys/resolve"
9
10 "github.com/ipfs/go-cid"
11 ipld "github.com/ipfs/go-ipld-format"
core/coreapi/test/api_test.go
+1 -1
@@ -9,12 +9,12 @@ import (
9 "testing"
10
11 "github.com/ipfs/go-filestore"
12 + "github.com/ipfs/go-ipfs-keystore"
13 "github.com/ipfs/go-ipfs/core"
14 "github.com/ipfs/go-ipfs/core/bootstrap"
15 "github.com/ipfs/go-ipfs/core/coreapi"
16 mock "github.com/ipfs/go-ipfs/core/mock"
17 "github.com/ipfs/go-ipfs/core/node/libp2p"
17 - "github.com/ipfs/go-ipfs/keystore"
18 "github.com/ipfs/go-ipfs/repo"
19
20 "github.com/ipfs/go-datastore"
core/corehttp/gateway_test.go
+1 -1
@@ -14,8 +14,8 @@ import (
14 version "github.com/ipfs/go-ipfs"
15 core "github.com/ipfs/go-ipfs/core"
16 "github.com/ipfs/go-ipfs/core/coreapi"
17 - namesys "github.com/ipfs/go-ipfs/namesys"
17 repo "github.com/ipfs/go-ipfs/repo"
18 + namesys "github.com/ipfs/go-namesys"
19
20 datastore "github.com/ipfs/go-datastore"
21 syncds "github.com/ipfs/go-datastore/sync"
core/corehttp/hostname.go
+1 -1
@@ -12,7 +12,7 @@ import (
12 cid "github.com/ipfs/go-cid"
13 core "github.com/ipfs/go-ipfs/core"
14 coreapi "github.com/ipfs/go-ipfs/core/coreapi"
15 - namesys "github.com/ipfs/go-ipfs/namesys"
15 + namesys "github.com/ipfs/go-namesys"
16 isd "github.com/jbenet/go-is-domain"
17 "github.com/libp2p/go-libp2p-core/peer"
18 mbase "github.com/multiformats/go-multibase"
core/node/ipns.go
+2 -2
@@ -11,9 +11,9 @@ import (
11 "github.com/libp2p/go-libp2p-core/routing"
12 "github.com/libp2p/go-libp2p-record"
13
14 - "github.com/ipfs/go-ipfs/namesys"
15 - "github.com/ipfs/go-ipfs/namesys/republisher"
14 "github.com/ipfs/go-ipfs/repo"
15 + "github.com/ipfs/go-namesys"
16 + "github.com/ipfs/go-namesys/republisher"
17 )
18
19 const DefaultIpnsCacheSize = 128
fuse/ipns/common.go
+1 -1
@@ -4,7 +4,7 @@ import (
4 "context"
5
6 "github.com/ipfs/go-ipfs/core"
7 - nsys "github.com/ipfs/go-ipfs/namesys"
7 + nsys "github.com/ipfs/go-namesys"
8 path "github.com/ipfs/go-path"
9 ft "github.com/ipfs/go-unixfs"
10 ci "github.com/libp2p/go-libp2p-core/crypto"
go.mod
+2 -6
@@ -4,7 +4,6 @@ require (
4 bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc
5 contrib.go.opencensus.io/exporter/prometheus v0.2.0
6 github.com/blang/semver/v4 v4.0.0
7 - github.com/bren2010/proquint v0.0.0-20201027163346-95122a84635f
7 github.com/cheggaaa/pb v1.0.29
8 github.com/coreos/go-systemd/v22 v22.1.0
9 github.com/dustin/go-humanize v1.0.0
@@ -12,9 +11,7 @@ require (
11 github.com/fsnotify/fsnotify v1.4.9
12 github.com/gabriel-vasile/mimetype v1.1.2
13 github.com/go-bindata/go-bindata/v3 v3.1.3
15 - github.com/gogo/protobuf v1.3.2
14 github.com/hashicorp/go-multierror v1.1.0
17 - github.com/hashicorp/golang-lru v0.5.4
15 github.com/ipfs/go-bitswap v0.3.3
16 github.com/ipfs/go-block-format v0.0.3
17 github.com/ipfs/go-blockservice v0.1.4
@@ -33,10 +30,10 @@ require (
30 github.com/ipfs/go-ipfs-chunker v0.0.5
31 github.com/ipfs/go-ipfs-cmds v0.6.0
32 github.com/ipfs/go-ipfs-config v0.12.0
36 - github.com/ipfs/go-ipfs-ds-help v0.1.1
33 github.com/ipfs/go-ipfs-exchange-interface v0.0.1
34 github.com/ipfs/go-ipfs-exchange-offline v0.0.1
35 github.com/ipfs/go-ipfs-files v0.0.8
36 + github.com/ipfs/go-ipfs-keystore v0.0.2
37 github.com/ipfs/go-ipfs-pinner v0.1.1
38 github.com/ipfs/go-ipfs-posinfo v0.0.1
39 github.com/ipfs/go-ipfs-provider v0.4.3
@@ -51,6 +48,7 @@ require (
48 github.com/ipfs/go-metrics-interface v0.0.1
49 github.com/ipfs/go-metrics-prometheus v0.0.2
50 github.com/ipfs/go-mfs v0.1.2
51 + github.com/ipfs/go-namesys v0.0.1
52 github.com/ipfs/go-path v0.0.9
53 github.com/ipfs/go-pinning-service-http-client v0.1.0
54 github.com/ipfs/go-unixfs v0.2.4
@@ -86,7 +84,6 @@ require (
84 github.com/libp2p/go-tcp-transport v0.2.1
85 github.com/libp2p/go-ws-transport v0.4.0
86 github.com/lucas-clemente/quic-go v0.19.3
89 - github.com/mattn/go-runewidth v0.0.9 // indirect
87 github.com/mitchellh/go-homedir v1.1.0
88 github.com/multiformats/go-multiaddr v0.3.1
89 github.com/multiformats/go-multiaddr-dns v0.2.0
@@ -97,7 +94,6 @@ require (
94 github.com/prometheus/client_golang v1.9.0
95 github.com/stretchr/testify v1.7.0
96 github.com/syndtr/goleveldb v1.0.0
100 - github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc
97 github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1
98 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7
99 github.com/whyrusleeping/tar-utils v0.0.0-20201201191210-20a61371de5b
go.sum
+92 -4
@@ -40,6 +40,7 @@ github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE
40 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
41 github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
42 github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
43 +github.com/Stebalien/go-bitfield v0.0.0-20180330043415-076a62f9ce6e/go.mod h1:3oM7gXIttpYDAJXpVNnSCiUMYBLIZ6cb1t+Ip982MRo=
44 github.com/Stebalien/go-bitfield v0.0.1 h1:X3kbSSPUaJK60wV2hjOPZwmpljr6VGCqdq4cBLhbQBo=
45 github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s=
46 github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
@@ -73,11 +74,13 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce
74 github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
75 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
76 github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
77 +github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
78 +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
79 github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
80 github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
81 github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
79 -github.com/bren2010/proquint v0.0.0-20201027163346-95122a84635f h1:aYq2dAS53HXEmxlI9AAggLbqJS4DML1/H0+r59TH/vw=
80 -github.com/bren2010/proquint v0.0.0-20201027163346-95122a84635f/go.mod h1:Jbj8eKecMNwf0KFI75skSUZqMB4UCRcndUScVBTWyUI=
82 +github.com/bren2010/proquint v0.0.0-20160323162903-38337c27106d h1:QgeLLoPD3kRVmeu/1al9iIpIANMi9O1zXFm8BnYGCJg=
83 +github.com/bren2010/proquint v0.0.0-20160323162903-38337c27106d/go.mod h1:Jbj8eKecMNwf0KFI75skSUZqMB4UCRcndUScVBTWyUI=
84 github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8=
85 github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
86 github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
@@ -171,6 +174,7 @@ github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:Jp
174 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
175 github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
176 github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
177 +github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E=
178 github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
179 github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 h1:u/UEqS66A5ckRmS4yNpjmVH56sVtS/RfclBAYocb4as=
180 github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ=
@@ -181,6 +185,7 @@ github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2
185 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
186 github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
187 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
188 +github.com/gabriel-vasile/mimetype v1.1.1/go.mod h1:6CDPel/o/3/s4+bp6kIbsWATq8pmgOisOPG40CJa6To=
189 github.com/gabriel-vasile/mimetype v1.1.2 h1:gaPnPcNor5aZSVCJVSGipcpbgMWiAAj9z182ocSGbHU=
190 github.com/gabriel-vasile/mimetype v1.1.2/go.mod h1:6CDPel/o/3/s4+bp6kIbsWATq8pmgOisOPG40CJa6To=
191 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
@@ -285,6 +290,7 @@ github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpg
290 github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
291 github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU=
292 github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48=
293 +github.com/gxed/pubsub v0.0.0-20180201040156-26ebdf44f824/go.mod h1:OiEWyHgK+CWrmOlVquHaIK1vhpUJydC9m0Je6mhaiNE=
294 github.com/hannahhoward/cbor-gen-for v0.0.0-20200817222906-ea96cece81f1/go.mod h1:jvfsLIxk0fY/2BKSQ1xf2406AKA5dwMmKKv0ADcOfN8=
295 github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e h1:3YKHER4nmd7b5qy5t0GWDTwSn4OyRgfAXSmo6VnryBY=
296 github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e/go.mod h1:I8h3MITA53gN9OnWGCgaMa0JWVRdXthWw4M3CPM54OY=
@@ -316,6 +322,7 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p
322 github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
323 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
324 github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
325 +github.com/huin/goupnp v0.0.0-20180415215157-1395d1447324/go.mod h1:MZ2ZmwcBpvOoJ22IJsc7va19ZwoheaBk43rKg12SKag=
326 github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo=
327 github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc=
328 github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
@@ -325,17 +332,20 @@ github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod
332 github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI=
333 github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
334 github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
335 +github.com/ipfs/go-bitswap v0.0.3/go.mod h1:jadAZYsP/tcRMl47ZhFxhaNuDQoXawT8iHMg+iFoQbg=
336 github.com/ipfs/go-bitswap v0.0.9/go.mod h1:kAPf5qgn2W2DrgAcscZ3HrM9qh4pH+X8Fkk3UPrwvis=
337 github.com/ipfs/go-bitswap v0.1.0/go.mod h1:FFJEf18E9izuCqUtHxbWEvq+reg7o4CW5wSAE1wsxj0=
338 github.com/ipfs/go-bitswap v0.1.2/go.mod h1:qxSWS4NXGs7jQ6zQvoPY3+NmOfHHG47mhkiLzBpJQIs=
339 github.com/ipfs/go-bitswap v0.1.3/go.mod h1:YEQlFy0kkxops5Vy+OxWdRSEZIoS7I7KDIwoa5Chkps=
340 github.com/ipfs/go-bitswap v0.1.8/go.mod h1:TOWoxllhccevbWFUR2N7B1MTSVVge1s6XSMiCSA4MzM=
341 +github.com/ipfs/go-bitswap v0.2.20/go.mod h1:C7TwBgHnu89Q8sHsTJP7IhUqF9XYLe71P4tT5adgmYo=
342 github.com/ipfs/go-bitswap v0.3.3 h1:CrTO3OiOYFBcdliw074/C7T2QYHEOsPClgvR6RIYcO4=
343 github.com/ipfs/go-bitswap v0.3.3/go.mod h1:AyWWfN3moBzQX0banEtfKOfbXb3ZeoOeXnZGNPV9S6w=
344 github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc=
345 github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY=
346 github.com/ipfs/go-block-format v0.0.3 h1:r8t66QstRp/pd/or4dpnbVfXT5Gt7lOqRvC+/dDTpMc=
347 github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk=
348 +github.com/ipfs/go-blockservice v0.0.3/go.mod h1:/NNihwTi6V2Yr6g8wBI+BSwPuURpBRMtYNGrlxZ8KuI=
349 github.com/ipfs/go-blockservice v0.0.7/go.mod h1:EOfb9k/Y878ZTRY/CH0x5+ATtaipfbRhbvNSdgc/7So=
350 github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M=
351 github.com/ipfs/go-blockservice v0.1.1/go.mod h1:t+411r7psEUhLueM8C7aPA7cxCclv4O3VsUVxt9kz2I=
@@ -371,6 +381,7 @@ github.com/ipfs/go-ds-badger v0.0.5/go.mod h1:g5AuuCGmr7efyzQhLL8MzwqcauPojGPUaH
381 github.com/ipfs/go-ds-badger v0.0.7/go.mod h1:qt0/fWzZDoPW6jpQeqUjR5kBfhDNB65jd9YlmAvpQBk=
382 github.com/ipfs/go-ds-badger v0.2.1/go.mod h1:Tx7l3aTph3FMFrRS838dcSJh+jjA7cX9DrGVwx/NOwE=
383 github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk=
384 +github.com/ipfs/go-ds-badger v0.2.4/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk=
385 github.com/ipfs/go-ds-badger v0.2.6 h1:Hy8jw4rifxtRDrqpvC1yh36oIyE37KDzsUzlHUPOFiU=
386 github.com/ipfs/go-ds-badger v0.2.6/go.mod h1:02rnztVKA4aZwDuaRPTf8mpqcKmXP7mLl6JPxd14JHA=
387 github.com/ipfs/go-ds-flatfs v0.4.5 h1:4QceuKEbH+HVZ2ZommstJMi3o3II+dWS3IhLaD7IGHs=
@@ -386,8 +397,10 @@ github.com/ipfs/go-filestore v0.0.3 h1:MhZ1jT5K3NewZwim6rS/akcJLm1xM+r6nz6foeB9E
397 github.com/ipfs/go-filestore v0.0.3/go.mod h1:dvXRykFzyyXN2CdNlRGzDAkXMDPyI+D7JE066SiKLSE=
398 github.com/ipfs/go-fs-lock v0.0.6 h1:sn3TWwNVQqSeNjlWy6zQ1uUGAZrV3hPOyEA6y1/N2a0=
399 github.com/ipfs/go-fs-lock v0.0.6/go.mod h1:OTR+Rj9sHiRubJh3dRhD15Juhd/+w6VPOY28L7zESmM=
400 +github.com/ipfs/go-graphsync v0.1.1/go.mod h1:jMXfqIEDFukLPZHqDPp8tJMbHO9Rmeb9CEGevngQbmE=
401 github.com/ipfs/go-graphsync v0.7.0 h1:ZdyU2otZYPjcvduAPwVjCdijmkPtHI1mm1VyZbRQ5KI=
402 github.com/ipfs/go-graphsync v0.7.0/go.mod h1:YRQg0TyvD2HzFansAZdMcUFBJ8zIJ4K+32kNdnHfHZc=
403 +github.com/ipfs/go-ipfs v0.7.0/go.mod h1:4UNBZMgbAZ6/+xUZDlMkGxMFPiu1RB67+TaNVvKV7ZQ=
404 github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08=
405 github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw=
406 github.com/ipfs/go-ipfs-blockstore v0.1.4 h1:2SGI6U1B44aODevza8Rde3+dY30Pb+lbcObe1LETxOQ=
@@ -397,8 +410,10 @@ github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtL
410 github.com/ipfs/go-ipfs-chunker v0.0.1/go.mod h1:tWewYK0we3+rMbOh7pPFGDyypCtvGcBFymgY4rSDLAw=
411 github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8=
412 github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8=
413 +github.com/ipfs/go-ipfs-cmds v0.4.0/go.mod h1:ZgYiWVnCk43ChwoH8hAmI1IRbuVtq3GSTHwtRB/Kqhk=
414 github.com/ipfs/go-ipfs-cmds v0.6.0 h1:yAxdowQZzoFKjcLI08sXVNnqVj3jnABbf9smrPQmBsw=
415 github.com/ipfs/go-ipfs-cmds v0.6.0/go.mod h1:ZgYiWVnCk43ChwoH8hAmI1IRbuVtq3GSTHwtRB/Kqhk=
416 +github.com/ipfs/go-ipfs-config v0.9.0/go.mod h1:GQUxqb0NfkZmEU92PxqqqLVVFTLpoGGUlBaTyDaAqrE=
417 github.com/ipfs/go-ipfs-config v0.12.0 h1:wxqN3ohBlis1EkhkzIKuF+XLx4YNn9rNpiSOYw3DFZc=
418 github.com/ipfs/go-ipfs-config v0.12.0/go.mod h1:Ei/FLgHGTdPyqCPK0oPCwGTe8VSnsjJjx7HZqUb6Ry0=
419 github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw=
@@ -411,9 +426,14 @@ github.com/ipfs/go-ipfs-exchange-interface v0.0.1 h1:LJXIo9W7CAmugqI+uofioIpRb6r
426 github.com/ipfs/go-ipfs-exchange-interface v0.0.1/go.mod h1:c8MwfHjtQjPoDyiy9cFquVtVHkO9b9Ob3FG91qJnWCM=
427 github.com/ipfs/go-ipfs-exchange-offline v0.0.1 h1:P56jYKZF7lDDOLx5SotVh5KFxoY6C81I1NSHW1FxGew=
428 github.com/ipfs/go-ipfs-exchange-offline v0.0.1/go.mod h1:WhHSFCVYX36H/anEKQboAzpUws3x7UeEGkzQc3iNkM0=
429 +github.com/ipfs/go-ipfs-files v0.0.2/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4=
430 github.com/ipfs/go-ipfs-files v0.0.3/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4=
431 github.com/ipfs/go-ipfs-files v0.0.8 h1:8o0oFJkJ8UkO/ABl8T6ac6tKF3+NIpj67aAB6ZpusRg=
432 github.com/ipfs/go-ipfs-files v0.0.8/go.mod h1:wiN/jSG8FKyk7N0WyctKSvq3ljIa2NNTiZB55kpTdOs=
433 +github.com/ipfs/go-ipfs-flags v0.0.1/go.mod h1:RnXBb9WV53GSfTrSDVK61NLTFKvWc60n+K9EgCDh+rA=
434 +github.com/ipfs/go-ipfs-keystore v0.0.2 h1:Fa9xg9IFD1VbiZtrNLzsD0GuELVHUFXCWF64kCPfEXU=
435 +github.com/ipfs/go-ipfs-keystore v0.0.2/go.mod h1:H49tRmibOEs7gLMgbOsjC4dqh1u5e0R/SWuc2ScfgSo=
436 +github.com/ipfs/go-ipfs-pinner v0.0.4/go.mod h1:s4kFZWLWGDudN8Jyd/GTpt222A12C2snA2+OTdy/7p8=
437 github.com/ipfs/go-ipfs-pinner v0.1.1 h1:iJd1gwILGQJSZhhI0jn6yFOLg34Ua7fdKcB6mXp6k/M=
438 github.com/ipfs/go-ipfs-pinner v0.1.1/go.mod h1:EzyyaWCWeZJ/he9cDBH6QrEkSuRqTRWMmCoyNkylTTg=
439 github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs=
@@ -429,6 +449,7 @@ github.com/ipfs/go-ipfs-routing v0.1.0/go.mod h1:hYoUkJLyAUKhF58tysKpids8RNDPO42
449 github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc=
450 github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8=
451 github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ=
452 +github.com/ipfs/go-ipld-cbor v0.0.1/go.mod h1:RXHr8s4k0NE0TKhnrxqZC9M888QfsBN9rhS5NjfKzY8=
453 github.com/ipfs/go-ipld-cbor v0.0.2/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc=
454 github.com/ipfs/go-ipld-cbor v0.0.3/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc=
455 github.com/ipfs/go-ipld-cbor v0.0.4/go.mod h1:BkCduEx3XBCO6t2Sfo5BaHzuok7hbhdMm9Oh8B2Ftq4=
@@ -454,6 +475,7 @@ github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBW
475 github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw=
476 github.com/ipfs/go-log/v2 v2.1.1 h1:G4TtqN+V9y9HY9TA6BwbCVyyBZ2B9MbCjR2MtGx8FR0=
477 github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM=
478 +github.com/ipfs/go-merkledag v0.0.3/go.mod h1:Oc5kIXLHokkE1hWGMBHw+oxehkAaTOqtEb7Zbh6BhLA=
479 github.com/ipfs/go-merkledag v0.0.6/go.mod h1:QYPdnlvkOg7GnQRofu9XZimC5ZW5Wi3bKys/4GQQfto=
480 github.com/ipfs/go-merkledag v0.1.0/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk=
481 github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk=
@@ -467,7 +489,11 @@ github.com/ipfs/go-metrics-prometheus v0.0.2 h1:9i2iljLg12S78OhC6UAiXi176xvQGiZa
489 github.com/ipfs/go-metrics-prometheus v0.0.2/go.mod h1:ELLU99AQQNi+zX6GCGm2lAgnzdSH3u5UVlCdqSXnEks=
490 github.com/ipfs/go-mfs v0.1.2 h1:DlelNSmH+yz/Riy0RjPKlooPg0KML4lXGdLw7uZkfAg=
491 github.com/ipfs/go-mfs v0.1.2/go.mod h1:T1QBiZPEpkPLzDqEJLNnbK55BVKVlNi2a+gVm4diFo0=
492 +github.com/ipfs/go-namesys v0.0.1 h1:HmhgHDA2hyfVtFtbvPR92IdmKbUFRmlbU0Lv1IwmDas=
493 +github.com/ipfs/go-namesys v0.0.1/go.mod h1:I33kVZixNRWXe5FN1mpWBXsAeJj0t+kxcVDgbIkgE2E=
494 +github.com/ipfs/go-path v0.0.3/go.mod h1:zIRQUez3LuQIU25zFjC2hpBTHimWx7VK5bjZgRLbbdo=
495 github.com/ipfs/go-path v0.0.7/go.mod h1:6KTKmeRnBXgqrTvzFrPV3CamxcgvXX/4z79tfAd2Sno=
496 +github.com/ipfs/go-path v0.0.8/go.mod h1:VpDkSBKQ9EFQOUgi54Tq/O/tGi8n1RfYNks13M3DEs8=
497 github.com/ipfs/go-path v0.0.9 h1:BIi831cNED8YnIlIKo9y1SI3u+E+FwQQD+rIIw8PwFA=
498 github.com/ipfs/go-path v0.0.9/go.mod h1:VpDkSBKQ9EFQOUgi54Tq/O/tGi8n1RfYNks13M3DEs8=
499 github.com/ipfs/go-peertaskqueue v0.0.4/go.mod h1:03H8fhyeMfKNFWqzYEVyMbcPUeYrqP1MX6Kd+aN+rMQ=
@@ -477,19 +503,25 @@ github.com/ipfs/go-peertaskqueue v0.2.0 h1:2cSr7exUGKYyDeUyQ7P/nHPs9P7Ht/B+ROrpN
503 github.com/ipfs/go-peertaskqueue v0.2.0/go.mod h1:5/eNrBEbtSKWCG+kQK8K8fGNixoYUnr+P7jivavs9lY=
504 github.com/ipfs/go-pinning-service-http-client v0.1.0 h1:Au0P4NglL5JfzhNSZHlZ1qra+IcJyO3RWMd9EYCwqSY=
505 github.com/ipfs/go-pinning-service-http-client v0.1.0/go.mod h1:tcCKmlkWWH9JUUkKs8CrOZBanacNc1dmKLfjlyXAMu4=
506 +github.com/ipfs/go-unixfs v0.0.4/go.mod h1:eIo/p9ADu/MFOuyxzwU+Th8D6xoxU//r590vUpWyfz8=
507 github.com/ipfs/go-unixfs v0.1.0/go.mod h1:lysk5ELhOso8+Fed9U1QTGey2ocsfaZ18h0NCO2Fj9s=
508 github.com/ipfs/go-unixfs v0.2.4 h1:6NwppOXefWIyysZ4LR/qUBPvXd5//8J3jiMdvpbw6Lo=
509 github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw=
510 github.com/ipfs/go-verifcid v0.0.1 h1:m2HI7zIuR5TFyQ1b79Da5N9dnnCP1vcu2QqawmWlK2E=
511 github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0=
512 +github.com/ipfs/interface-go-ipfs-core v0.3.0/go.mod h1:Tihp8zxGpUeE3Tokr94L6zWZZdkRQvG5TL6i9MuNE+s=
513 github.com/ipfs/interface-go-ipfs-core v0.4.0 h1:+mUiamyHIwedqP8ZgbCIwpy40oX7QcXUbo4CZOeJVJg=
514 github.com/ipfs/interface-go-ipfs-core v0.4.0/go.mod h1:UJBcU6iNennuI05amq3FQ7g0JHUkibHFAfhfUIy927o=
515 +github.com/ipld/go-car v0.1.1-0.20200429200904-c222d793c339/go.mod h1:eajxljm6I8o3LitnFeVEmucwZmz7+yLSiKce9yYMefg=
516 github.com/ipld/go-car v0.2.0 h1:WwP83IdXdEuaW4fkCj+DWmdWygcFXpixramvItqFo1A=
517 github.com/ipld/go-car v0.2.0/go.mod h1:pPb7hzVBHBoRqU3GkPy1d6FZKQoGQ56yd3MyPGzZ0Xs=
518 +github.com/ipld/go-ipld-prime v0.0.2-0.20200428162820-8b59dc292b8e/go.mod h1:uVIwe/u0H4VdKv3kaN1ck7uCb6yD9cFLS9/ELyXbsw8=
519 github.com/ipld/go-ipld-prime v0.7.0 h1:eigF1ZpaL1prbsKYVMqPLoPJqD/pzkQOe2j1uzvVg7w=
520 github.com/ipld/go-ipld-prime v0.7.0/go.mod h1:0xEgdD6MKbZ1vF0GC+YcR/C4SQCAlRuOjIJ2i0HxqzM=
521 +github.com/ipld/go-ipld-prime-proto v0.0.0-20200428191222-c1ffdadc01e1/go.mod h1:OAV6xBmuTLsPZ+epzKkPB1e25FHk/vCtyatkdHcArLs=
522 github.com/ipld/go-ipld-prime-proto v0.1.1 h1:EX4yWYaIqSLwtVE30nxEcZDcvsWDtx1vImSG+XCJebY=
523 github.com/ipld/go-ipld-prime-proto v0.1.1/go.mod h1:cI9NwYAUKCLUwqufoUjChISxuTEkaY2yvNYCRCuhRck=
524 +github.com/jackpal/gateway v1.0.4/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA=
525 github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA=
526 github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
527 github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
@@ -556,6 +588,7 @@ github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoR
588 github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c=
589 github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic=
590 github.com/libp2p/go-conn-security v0.0.1/go.mod h1:bGmu51N0KU9IEjX7kl2PQjgZa40JQWnayTvNMgD/vyk=
591 +github.com/libp2p/go-conn-security-multistream v0.0.1/go.mod h1:nc9vud7inQ+d6SO0I/6dSWrdMnHnzZNHeyUQqrAJulE=
592 github.com/libp2p/go-conn-security-multistream v0.0.2/go.mod h1:nc9vud7inQ+d6SO0I/6dSWrdMnHnzZNHeyUQqrAJulE=
593 github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc=
594 github.com/libp2p/go-conn-security-multistream v0.2.0 h1:uNiDjS58vrvJTg9jO6bySd1rMKejieG7v45ekqHbZ1M=
@@ -567,35 +600,45 @@ github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZ
600 github.com/libp2p/go-flow-metrics v0.0.2/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs=
601 github.com/libp2p/go-flow-metrics v0.0.3 h1:8tAs/hSdNvUiLgtlSy3mxwxWP4I9y/jlkPFT7epKdeM=
602 github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs=
603 +github.com/libp2p/go-libp2p v0.0.2/go.mod h1:Qu8bWqFXiocPloabFGUcVG4kk94fLvfC8mWTDdFC9wE=
604 github.com/libp2p/go-libp2p v0.0.30/go.mod h1:XWT8FGHlhptAv1+3V/+J5mEpzyui/5bvFsNuWYs611A=
605 github.com/libp2p/go-libp2p v0.1.0/go.mod h1:6D/2OBauqLUoqcADOJpn9WbKqvaM07tDw68qHM0BxUM=
606 github.com/libp2p/go-libp2p v0.1.1/go.mod h1:I00BRo1UuUSdpuc8Q2mN7yDF/oTUTRAX6JWpTiK9Rp8=
607 +github.com/libp2p/go-libp2p v0.6.0/go.mod h1:mfKWI7Soz3ABX+XEBR61lGbg+ewyMtJHVt043oWeqwg=
608 github.com/libp2p/go-libp2p v0.6.1/go.mod h1:CTFnWXogryAHjXAKEbOf1OWY+VeAP3lDMZkfEI5sT54=
609 github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xSU1ivxn0k=
610 github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw=
611 github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o=
612 +github.com/libp2p/go-libp2p v0.8.3/go.mod h1:EsH1A+8yoWK+L4iKcbPYu6MPluZ+CHWI9El8cTaefiM=
613 +github.com/libp2p/go-libp2p v0.11.0/go.mod h1:3/ogJDXsbbepEfqtZKBR/DedzxJXCeK17t2Z9RE9bEE=
614 github.com/libp2p/go-libp2p v0.12.0/go.mod h1:FpHZrfC1q7nA8jitvdjKBDF31hguaC676g/nT9PgQM0=
615 github.com/libp2p/go-libp2p v0.13.0 h1:tDdrXARSghmusdm0nf1U/4M8aj8Rr0V2IzQOXmbzQ3s=
616 github.com/libp2p/go-libp2p v0.13.0/go.mod h1:pM0beYdACRfHO1WcJlp65WXyG2A6NqYM+t2DTVAJxMo=
617 github.com/libp2p/go-libp2p-asn-util v0.0.0-20200825225859-85005c6cf052 h1:BM7aaOF7RpmNn9+9g6uTjGJ0cTzWr5j9i9IKeun2M8U=
618 github.com/libp2p/go-libp2p-asn-util v0.0.0-20200825225859-85005c6cf052/go.mod h1:nRMRTab+kZuk0LnKZpxhOVH/ndsdr2Nr//Zltc/vwgo=
619 +github.com/libp2p/go-libp2p-autonat v0.0.2/go.mod h1:fs71q5Xk+pdnKU014o2iq1RhMs9/PMaG5zXRFNnIIT4=
620 github.com/libp2p/go-libp2p-autonat v0.0.6/go.mod h1:uZneLdOkZHro35xIhpbtTzLlgYturpu4J5+0cZK3MqE=
621 github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8=
622 github.com/libp2p/go-libp2p-autonat v0.1.1/go.mod h1:OXqkeGOY2xJVWKAGV2inNF5aKN/djNA3fdpCWloIudE=
623 github.com/libp2p/go-libp2p-autonat v0.2.0/go.mod h1:DX+9teU4pEEoZUqR1PiMlqliONQdNbfzE1C718tcViI=
624 github.com/libp2p/go-libp2p-autonat v0.2.1/go.mod h1:MWtAhV5Ko1l6QBsHQNSuM6b1sRkXrpk0/LqCr+vCVxI=
625 github.com/libp2p/go-libp2p-autonat v0.2.2/go.mod h1:HsM62HkqZmHR2k1xgX34WuWDzk/nBwNHoeyyT4IWV6A=
626 +github.com/libp2p/go-libp2p-autonat v0.3.2/go.mod h1:0OzOi1/cVc7UcxfOddemYD5vzEqi4fwRbnZcJGLi68U=
627 github.com/libp2p/go-libp2p-autonat v0.4.0 h1:3y8XQbpr+ssX8QfZUHekjHCYK64sj6/4hnf/awD4+Ug=
628 github.com/libp2p/go-libp2p-autonat v0.4.0/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk=
629 github.com/libp2p/go-libp2p-blankhost v0.0.1/go.mod h1:Ibpbw/7cPPYwFb7PACIWdvxxv0t0XCCI10t7czjAjTc=
630 github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro=
631 github.com/libp2p/go-libp2p-blankhost v0.1.4/go.mod h1:oJF0saYsAXQCSfDq254GMNmLNz6ZTHTOvtF4ZydUvwU=
632 +github.com/libp2p/go-libp2p-blankhost v0.1.6/go.mod h1:jONCAJqEP+Z8T6EQviGL4JsQcLx1LgTGtVqFNY8EMfQ=
633 github.com/libp2p/go-libp2p-blankhost v0.2.0 h1:3EsGAi0CBGcZ33GwRuXEYJLLPoVWyXJ1bcJzAJjINkk=
634 github.com/libp2p/go-libp2p-blankhost v0.2.0/go.mod h1:eduNKXGTioTuQAUcZ5epXi9vMl+t4d8ugUBRQ4SqaNQ=
635 +github.com/libp2p/go-libp2p-circuit v0.0.1/go.mod h1:Dqm0s/BiV63j8EEAs8hr1H5HudqvCAeXxDyic59lCwE=
636 github.com/libp2p/go-libp2p-circuit v0.0.9/go.mod h1:uU+IBvEQzCu953/ps7bYzC/D/R0Ho2A9LfKVVCatlqU=
637 github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8=
638 github.com/libp2p/go-libp2p-circuit v0.1.4/go.mod h1:CY67BrEjKNDhdTk8UgBX1Y/H5c3xkAcs3gnksxY7osU=
639 github.com/libp2p/go-libp2p-circuit v0.2.1/go.mod h1:BXPwYDN5A8z4OEY9sOfr2DUQMLQvKt/6oku45YUmjIo=
640 +github.com/libp2p/go-libp2p-circuit v0.2.2/go.mod h1:nkG3iE01tR3FoQ2nMm06IUrCpCyJp1Eo4A1xYdpjfs4=
641 +github.com/libp2p/go-libp2p-circuit v0.3.1/go.mod h1:8RMIlivu1+RxhebipJwFDA45DasLx+kkrp4IlJj53F4=
642 github.com/libp2p/go-libp2p-circuit v0.4.0 h1:eqQ3sEYkGTtybWgr6JLqJY6QLtPWRErvFjFDfAOO1wc=
643 github.com/libp2p/go-libp2p-circuit v0.4.0/go.mod h1:t/ktoFIUzM6uLQ+o1G6NuBl2ANhBKN9Bc8jRIk31MoA=
644 github.com/libp2p/go-libp2p-connmgr v0.2.4 h1:TMS0vc0TCBomtQJyWr7fYxcVYYhx+q/2gF++G5Jkl/w=
@@ -613,6 +656,7 @@ github.com/libp2p/go-libp2p-core v0.3.1/go.mod h1:thvWy0hvaSBhnVBaW37BvzgVV68OUh
656 github.com/libp2p/go-libp2p-core v0.4.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0=
657 github.com/libp2p/go-libp2p-core v0.5.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0=
658 github.com/libp2p/go-libp2p-core v0.5.1/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y=
659 +github.com/libp2p/go-libp2p-core v0.5.2/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y=
660 github.com/libp2p/go-libp2p-core v0.5.3/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y=
661 github.com/libp2p/go-libp2p-core v0.5.4/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y=
662 github.com/libp2p/go-libp2p-core v0.5.5/go.mod h1:vj3awlOr9+GMZJFH9s4mpt9RHHgGqeHCopzbYKZdRjM=
@@ -628,22 +672,27 @@ github.com/libp2p/go-libp2p-core v0.8.5/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJB
672 github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE=
673 github.com/libp2p/go-libp2p-crypto v0.0.2/go.mod h1:eETI5OUfBnvARGOHrJz2eWNyTUxEGZnBxMcbUjfIj4I=
674 github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI=
675 +github.com/libp2p/go-libp2p-discovery v0.0.1/go.mod h1:ZkkF9xIFRLA1xCc7bstYFkd80gBGK8Fc1JqGoU2i+zI=
676 github.com/libp2p/go-libp2p-discovery v0.0.5/go.mod h1:YtF20GUxjgoKZ4zmXj8j3Nb2TUSBHFlOCetzYdbZL5I=
677 github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g=
678 github.com/libp2p/go-libp2p-discovery v0.2.0/go.mod h1:s4VGaxYMbw4+4+tsoQTqh7wfxg97AEdo4GYBt6BadWg=
679 github.com/libp2p/go-libp2p-discovery v0.3.0/go.mod h1:o03drFnz9BVAZdzC/QUQ+NeQOu38Fu7LJGEOK2gQltw=
680 +github.com/libp2p/go-libp2p-discovery v0.4.0/go.mod h1:bZ0aJSrFc/eX2llP0ryhb1kpgkPyTo23SJ5b7UQCMh4=
681 github.com/libp2p/go-libp2p-discovery v0.5.0 h1:Qfl+e5+lfDgwdrXdu4YNCWyEo3fWuP+WgN9mN0iWviQ=
682 github.com/libp2p/go-libp2p-discovery v0.5.0/go.mod h1:+srtPIU9gDaBNu//UHvcdliKBIcr4SfDcm0/PfPJLug=
683 +github.com/libp2p/go-libp2p-gostream v0.2.1/go.mod h1:1Mjp3LDmkqICe5tH9yLVNCqFaRTy6OwBvuJV6j1b9Nk=
684 github.com/libp2p/go-libp2p-gostream v0.3.0 h1:rnas//vRdHYCr7bjraZJISPwZV8OGMjeX5k5fN5Ax44=
685 github.com/libp2p/go-libp2p-gostream v0.3.0/go.mod h1:pLBQu8db7vBMNINGsAwLL/ZCE8wng5V1FThoaE5rNjc=
686 github.com/libp2p/go-libp2p-host v0.0.1/go.mod h1:qWd+H1yuU0m5CwzAkvbSjqKairayEHdR5MMl7Cwa7Go=
687 github.com/libp2p/go-libp2p-host v0.0.3/go.mod h1:Y/qPyA6C8j2coYyos1dfRm0I8+nvd4TGrDGt4tA7JR8=
688 +github.com/libp2p/go-libp2p-http v0.1.5/go.mod h1:2YfPjsQxUlBGFQl2u461unkQ7ukwiSs7NX2eSslOJiU=
689 github.com/libp2p/go-libp2p-http v0.2.0 h1:GYeVd+RZzkRa8XFLITqOpcrIQG6KbFLPJqII6HHBHzY=
690 github.com/libp2p/go-libp2p-http v0.2.0/go.mod h1:GlNKFqDZHe25LVy2CvnZKx75/jLtMaD3VxZV6N39X7E=
691 github.com/libp2p/go-libp2p-interface-connmgr v0.0.1/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k=
692 github.com/libp2p/go-libp2p-interface-connmgr v0.0.4/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k=
693 github.com/libp2p/go-libp2p-interface-connmgr v0.0.5/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k=
694 github.com/libp2p/go-libp2p-interface-pnet v0.0.1/go.mod h1:el9jHpQAXK5dnTpKA4yfCNBZXvrzdOU75zz+C6ryp3k=
695 +github.com/libp2p/go-libp2p-kad-dht v0.9.0/go.mod h1:LEKcCFHxnvypOPaqZ0m6h0fLQ9Y8t1iZMOg7a0aQDD4=
696 github.com/libp2p/go-libp2p-kad-dht v0.11.1 h1:FsriVQhOUZpCotWIjyFSjEDNJmUzuMma/RyyTDZanwc=
697 github.com/libp2p/go-libp2p-kad-dht v0.11.1/go.mod h1:5ojtR2acDPqh/jXf5orWy8YGb8bHQDS+qeDcoscL/PI=
698 github.com/libp2p/go-libp2p-kbucket v0.4.7 h1:spZAcgxifvFZHBD8tErvppbnNiKA5uokDu3CV7axu70=
@@ -657,10 +706,12 @@ github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3
706 github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE=
707 github.com/libp2p/go-libp2p-mplex v0.2.2/go.mod h1:74S9eum0tVQdAfFiKxAyKzNdSuLqw5oadDq7+L/FELo=
708 github.com/libp2p/go-libp2p-mplex v0.2.3/go.mod h1:CK3p2+9qH9x+7ER/gWWDYJ3QW5ZxWDkm+dVvjfuG3ek=
709 +github.com/libp2p/go-libp2p-mplex v0.2.4/go.mod h1:mI7iOezdWFOisvUwaYd3IDrJ4oVmgoXK8H331ui39CE=
710 github.com/libp2p/go-libp2p-mplex v0.3.0/go.mod h1:l9QWxRbbb5/hQMECEb908GbS9Sm2UAR2KFZKUJEynEs=
711 github.com/libp2p/go-libp2p-mplex v0.4.0/go.mod h1:yCyWJE2sc6TBTnFpjvLuEJgTSw/u+MamvzILKdX7asw=
712 github.com/libp2p/go-libp2p-mplex v0.4.1 h1:/pyhkP1nLwjG3OM+VuaNJkQT/Pqq73WzB3aDN3Fx1sc=
713 github.com/libp2p/go-libp2p-mplex v0.4.1/go.mod h1:cmy+3GfqfM1PceHTLL7zQzAAYaryDu6iPSC+CIb094g=
714 +github.com/libp2p/go-libp2p-nat v0.0.2/go.mod h1:QrjXQSD5Dj4IJOdEcjHRkWTSomyxRo6HnUkf/TfQpLQ=
715 github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY=
716 github.com/libp2p/go-libp2p-nat v0.0.5/go.mod h1:1qubaE5bTZMJE+E/uu2URroMbzdubFz1ChgiN79yKPE=
717 github.com/libp2p/go-libp2p-nat v0.0.6 h1:wMWis3kYynCbHoyKLPBEMu4YRLltbm8Mk08HGSfvTkU=
@@ -684,17 +735,23 @@ github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVd
735 github.com/libp2p/go-libp2p-peerstore v0.2.0/go.mod h1:N2l3eVIeAitSg3Pi2ipSrJYnqhVnMNQZo9nkSCuAbnQ=
736 github.com/libp2p/go-libp2p-peerstore v0.2.1/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA=
737 github.com/libp2p/go-libp2p-peerstore v0.2.2/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA=
738 +github.com/libp2p/go-libp2p-peerstore v0.2.3/go.mod h1:K8ljLdFn590GMttg/luh4caB/3g0vKuY01psze0upRw=
739 +github.com/libp2p/go-libp2p-peerstore v0.2.4/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s=
740 github.com/libp2p/go-libp2p-peerstore v0.2.6 h1:2ACefBX23iMdJU9Ke+dcXt3w86MIryes9v7In4+Qq3U=
741 github.com/libp2p/go-libp2p-peerstore v0.2.6/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s=
742 github.com/libp2p/go-libp2p-pnet v0.2.0 h1:J6htxttBipJujEjz1y0a5+eYoiPcFHhSYHH6na5f0/k=
743 github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA=
744 github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s=
745 github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk=
746 +github.com/libp2p/go-libp2p-pubsub v0.3.2/go.mod h1:Uss7/Cfz872KggNb+doCVPHeCDmXB7z500m/R8DaAUk=
747 +github.com/libp2p/go-libp2p-pubsub v0.3.5/go.mod h1:DTMSVmZZfXodB/pvdTGrY2eHPZ9W2ev7hzTH83OKHrI=
748 github.com/libp2p/go-libp2p-pubsub v0.4.0/go.mod h1:izkeMLvz6Ht8yAISXjx60XUQZMq9ZMe5h2ih4dLIBIQ=
749 github.com/libp2p/go-libp2p-pubsub v0.4.1 h1:j4umIg5nyus+sqNfU+FWvb9aeYFQH/A+nDFhWj+8yy8=
750 github.com/libp2p/go-libp2p-pubsub v0.4.1/go.mod h1:izkeMLvz6Ht8yAISXjx60XUQZMq9ZMe5h2ih4dLIBIQ=
751 +github.com/libp2p/go-libp2p-pubsub-router v0.3.2/go.mod h1:G4MAvYzPxhoR0LEBluS9Ow+Nnr/8iDalUN+RNwVgNkY=
752 github.com/libp2p/go-libp2p-pubsub-router v0.4.0 h1:KjzTLIOBCt0+/4wH6epTxD/Qu4Up/IyeKHlj9MhWRJI=
753 github.com/libp2p/go-libp2p-pubsub-router v0.4.0/go.mod h1:hs0j0ugcBjMOMgJ6diOlZM2rZEId/w5Gg86E+ac4SmQ=
754 +github.com/libp2p/go-libp2p-quic-transport v0.8.0/go.mod h1:F2FG/6Bzz0U6essUVxDzE0s9CrY4XGLbl7QEmDNvU7A=
755 github.com/libp2p/go-libp2p-quic-transport v0.10.0 h1:koDCbWD9CCHwcHZL3/WEvP2A+e/o5/W5L3QS/2SPMA0=
756 github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA=
757 github.com/libp2p/go-libp2p-record v0.0.1/go.mod h1:grzqg263Rug/sRex85QrDOLntdFAymLDLm7lxMgU79Q=
@@ -706,15 +763,18 @@ github.com/libp2p/go-libp2p-record v0.1.3/go.mod h1:yNUff/adKIfPnYQXgp6FQmNu3gLJ
763 github.com/libp2p/go-libp2p-routing v0.0.1/go.mod h1:N51q3yTr4Zdr7V8Jt2JIktVU+3xBBylx1MZeVA6t1Ys=
764 github.com/libp2p/go-libp2p-routing-helpers v0.2.3 h1:xY61alxJ6PurSi+MXbywZpelvuU4U4p/gPTxjqCqTzY=
765 github.com/libp2p/go-libp2p-routing-helpers v0.2.3/go.mod h1:795bh+9YeoFl99rMASoiVgHdi5bjack0N1+AFAdbvBw=
766 +github.com/libp2p/go-libp2p-secio v0.0.1/go.mod h1:IdG6iQybdcYmbTzxp4J5dwtUEDTOvZrT0opIDVNPrJs=
767 github.com/libp2p/go-libp2p-secio v0.0.3/go.mod h1:hS7HQ00MgLhRO/Wyu1bTX6ctJKhVpm+j2/S2A5UqYb0=
768 github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8=
769 github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g=
770 github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8=
771 github.com/libp2p/go-libp2p-secio v0.2.2/go.mod h1:wP3bS+m5AUnFA+OFO7Er03uO1mncHG0uVwGrwvjYlNY=
772 +github.com/libp2p/go-libp2p-swarm v0.0.1/go.mod h1:mh+KZxkbd3lQnveQ3j2q60BM1Cw2mX36XXQqwfPOShs=
773 github.com/libp2p/go-libp2p-swarm v0.0.6/go.mod h1:s5GZvzg9xXe8sbeESuFpjt8CJPTCa8mhEusweJqyFy8=
774 github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4=
775 github.com/libp2p/go-libp2p-swarm v0.2.2/go.mod h1:fvmtQ0T1nErXym1/aa1uJEyN7JzaTNyBcHImCxRpPKU=
776 github.com/libp2p/go-libp2p-swarm v0.2.3/go.mod h1:P2VO/EpxRyDxtChXz/VPVXyTnszHvokHKRhfkEgFKNM=
777 +github.com/libp2p/go-libp2p-swarm v0.2.4/go.mod h1:/xIpHFPPh3wmSthtxdGbkHZ0OET1h/GGZes8Wku/M5Y=
778 github.com/libp2p/go-libp2p-swarm v0.2.8/go.mod h1:JQKMGSth4SMqonruY0a8yjlPVIkb0mdNSwckW7OYziM=
779 github.com/libp2p/go-libp2p-swarm v0.3.0/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJegb7H57B5hWQR5Kk=
780 github.com/libp2p/go-libp2p-swarm v0.3.1/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJegb7H57B5hWQR5Kk=
@@ -728,13 +788,16 @@ github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MB
788 github.com/libp2p/go-libp2p-testing v0.1.0/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0=
789 github.com/libp2p/go-libp2p-testing v0.1.1/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0=
790 github.com/libp2p/go-libp2p-testing v0.1.2-0.20200422005655-8775583591d8/go.mod h1:Qy8sAncLKpwXtS2dSnDOP8ktexIAHKu+J+pnZOFZLTc=
791 +github.com/libp2p/go-libp2p-testing v0.2.0/go.mod h1:Qy8sAncLKpwXtS2dSnDOP8ktexIAHKu+J+pnZOFZLTc=
792 github.com/libp2p/go-libp2p-testing v0.3.0/go.mod h1:efZkql4UZ7OVsEfaxNHZPzIehtsBXMrXnCfJIgDti5g=
793 github.com/libp2p/go-libp2p-testing v0.4.0 h1:PrwHRi0IGqOwVQWR3xzgigSlhlLfxgfXgkHxr77EghQ=
794 github.com/libp2p/go-libp2p-testing v0.4.0/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0=
795 github.com/libp2p/go-libp2p-tls v0.1.3 h1:twKMhMu44jQO+HgQK9X8NHO5HkeJu2QbhLzLJpa8oNM=
796 github.com/libp2p/go-libp2p-tls v0.1.3/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M=
797 github.com/libp2p/go-libp2p-transport v0.0.1/go.mod h1:UzbUs9X+PHOSw7S3ZmeOxfnwaQY5vGDzZmKPod3N3tk=
798 +github.com/libp2p/go-libp2p-transport v0.0.4/go.mod h1:StoY3sx6IqsP6XKoabsPnHCwqKXWUMWU7Rfcsubee/A=
799 github.com/libp2p/go-libp2p-transport v0.0.5/go.mod h1:StoY3sx6IqsP6XKoabsPnHCwqKXWUMWU7Rfcsubee/A=
800 +github.com/libp2p/go-libp2p-transport-upgrader v0.0.1/go.mod h1:NJpUAgQab/8K6K0m+JmZCe5RUXG10UMEx4kWe9Ipj5c=
801 github.com/libp2p/go-libp2p-transport-upgrader v0.0.4/go.mod h1:RGq+tupk+oj7PzL2kn/m1w6YXxcIAYJYeI90h6BGgUc=
802 github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA=
803 github.com/libp2p/go-libp2p-transport-upgrader v0.2.0/go.mod h1:mQcrHj4asu6ArfSoMuyojOdjx73Q47cYD7s5+gZOlns=
@@ -757,6 +820,7 @@ github.com/libp2p/go-maddr-filter v0.0.1/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9
820 github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q=
821 github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M=
822 github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU=
823 +github.com/libp2p/go-mplex v0.0.1/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0=
824 github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0=
825 github.com/libp2p/go-mplex v0.0.4/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0=
826 github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU=
@@ -765,6 +829,7 @@ github.com/libp2p/go-mplex v0.1.2/go.mod h1:Xgz2RDCi3co0LeZfgjm4OgUF15+sVR8SRcu3
829 github.com/libp2p/go-mplex v0.2.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ=
830 github.com/libp2p/go-mplex v0.3.0 h1:U1T+vmCYJaEoDJPV1aq31N56hS+lJgb397GsylNSgrU=
831 github.com/libp2p/go-mplex v0.3.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ=
832 +github.com/libp2p/go-msgio v0.0.1/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ=
833 github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ=
834 github.com/libp2p/go-msgio v0.0.3/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ=
835 github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ=
@@ -786,6 +851,7 @@ github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO
851 github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA=
852 github.com/libp2p/go-reuseport v0.0.2 h1:XSG94b1FJfGA01BUrT82imejHQyTxO4jEWqheyCXYvU=
853 github.com/libp2p/go-reuseport v0.0.2/go.mod h1:SPD+5RwGC7rcnzngoYC86GjPzjSywuQyMVAheVBD9nQ=
854 +github.com/libp2p/go-reuseport-transport v0.0.1/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs=
855 github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs=
856 github.com/libp2p/go-reuseport-transport v0.0.3/go.mod h1:Spv+MPft1exxARzP2Sruj2Wb5JSyHNncjf1Oi2dEbzM=
857 github.com/libp2p/go-reuseport-transport v0.0.4 h1:OZGz0RB620QDGpv300n1zaOcKGGAoGVf8h9txtt/1uM=
@@ -800,6 +866,7 @@ github.com/libp2p/go-stream-muxer-multistream v0.1.1/go.mod h1:zmGdfkQ1AzOECIAcc
866 github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc=
867 github.com/libp2p/go-stream-muxer-multistream v0.3.0 h1:TqnSHPJEIqDEO7h1wZZ0p3DXdvDSiLHQidKKUGZtiOY=
868 github.com/libp2p/go-stream-muxer-multistream v0.3.0/go.mod h1:yDh8abSIzmZtqtOt64gFJUXEryejzNb0lisTt+fAMJA=
869 +github.com/libp2p/go-tcp-transport v0.0.1/go.mod h1:mnjg0o0O5TmXUaUIanYPUqkW4+u6mK0en8rlpA6BBTs=
870 github.com/libp2p/go-tcp-transport v0.0.4/go.mod h1:+E8HvC8ezEVOxIo3V5vCK9l1y/19K427vCzQ+xHKH/o=
871 github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc=
872 github.com/libp2p/go-tcp-transport v0.1.1/go.mod h1:3HzGvLbx6etZjnFlERyakbaYPdfjg2pWP97dFZworkY=
@@ -808,6 +875,7 @@ github.com/libp2p/go-tcp-transport v0.2.1 h1:ExZiVQV+h+qL16fzCWtd1HSzPsqWottJ8KX
875 github.com/libp2p/go-tcp-transport v0.2.1/go.mod h1:zskiJ70MEfWz2MKxvFB/Pv+tPIB1PpPUrHIWQ8aFw7M=
876 github.com/libp2p/go-testutil v0.0.1/go.mod h1:iAcJc/DKJQanJ5ws2V+u5ywdL2n12X1WbbEG+Jjy69I=
877 github.com/libp2p/go-testutil v0.1.0/go.mod h1:81b2n5HypcVyrCg/MJx4Wgfp/VHojytjVe/gLzZ2Ehc=
878 +github.com/libp2p/go-ws-transport v0.0.1/go.mod h1:p3bKjDWHEgtuKKj+2OdPYs5dAPIjtpQGHF2tJfGz7Ww=
879 github.com/libp2p/go-ws-transport v0.0.5/go.mod h1:Qbl4BxPfXXhhd/o0wcrgoaItHqA9tnZjoFZnxykuaXU=
880 github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo=
881 github.com/libp2p/go-ws-transport v0.2.0/go.mod h1:9BHJz/4Q5A9ludYWKoGCFC5gUElzlHoKzu0yY9p/klM=
@@ -829,6 +897,7 @@ github.com/libp2p/go-yamux/v2 v2.0.0 h1:vSGhAy5u6iHBq11ZDcyHH4Blcf9xlBhT4WQDoOE9
897 github.com/libp2p/go-yamux/v2 v2.0.0/go.mod h1:NVWira5+sVUIU6tu1JWvaRn1dRnG+cawOJiflsAM+7U=
898 github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
899 github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
900 +github.com/lucas-clemente/quic-go v0.18.0/go.mod h1:yXttHsSNxQi8AWijC/vLP+OJczXqzHSOcJrM5ITUlCg=
901 github.com/lucas-clemente/quic-go v0.19.3 h1:eCDQqvGBB+kCTkA0XrAFtNe81FMa0/fn4QSoeAbmiF4=
902 github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8=
903 github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
@@ -836,9 +905,11 @@ github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0Q
905 github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
906 github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
907 github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
908 +github.com/marten-seemann/qpack v0.2.0/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc=
909 github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc=
910 github.com/marten-seemann/qtls v0.10.0 h1:ECsuYUKalRL240rRD4Ri33ISb7kAQ3qGDlrrl55b2pc=
911 github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0aGm99sJhbT8hs=
912 +github.com/marten-seemann/qtls-go1-15 v0.1.0/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I=
913 github.com/marten-seemann/qtls-go1-15 v0.1.1 h1:LIH6K34bPVttyXnUWixk0bzH6/N07VxbSabxn5A5gZQ=
914 github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I=
915 github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
@@ -862,6 +933,7 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1f
933 github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
934 github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
935 github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
936 +github.com/miekg/dns v1.1.4/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
937 github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
938 github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
939 github.com/miekg/dns v1.1.31 h1:sJFOl9BgwbYAWOGEwr61FU28pqsBNdpRBnhGXtO06Oo=
@@ -925,10 +997,12 @@ github.com/multiformats/go-multiaddr-net v0.1.5/go.mod h1:ilNnaM9HbmVFqsb/qcNysj
997 github.com/multiformats/go-multiaddr-net v0.2.0 h1:MSXRGN0mFymt6B1yo/6BPnIRpLPEnKgQNvVfCX5VDJk=
998 github.com/multiformats/go-multiaddr-net v0.2.0/go.mod h1:gGdH3UXny6U3cKKYCvpXI5rnK7YaOIEOPVDI9tsJbEA=
999 github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs=
1000 +github.com/multiformats/go-multibase v0.0.2/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs=
1001 github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk=
1002 github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc=
1003 github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U=
1004 github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po=
1005 +github.com/multiformats/go-multihash v0.0.7/go.mod h1:XuKXPp8VHcTygube3OWZC+aZrA+H1IhmjoCDtJc7PXM=
1006 github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
1007 github.com/multiformats/go-multihash v0.0.9/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
1008 github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
@@ -939,6 +1013,7 @@ github.com/multiformats/go-multistream v0.0.1/go.mod h1:fJTiDfXJVmItycydCnNx4+wS
1013 github.com/multiformats/go-multistream v0.0.4/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg=
1014 github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg=
1015 github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38=
1016 +github.com/multiformats/go-multistream v0.1.2/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k=
1017 github.com/multiformats/go-multistream v0.2.0 h1:6AuNmQVKUkRnddw2YiDjt5Elit40SFxMJkVnhmETXtU=
1018 github.com/multiformats/go-multistream v0.2.0/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k=
1019 github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
@@ -1004,6 +1079,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
1079 github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o=
1080 github.com/polydawn/refmt v0.0.0-20190408063855-01bf1e26dd14/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o=
1081 github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o=
1082 +github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o=
1083 github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e h1:ZOcivgkkFRnjfoTcGsDq3UQYiBmekwLA+qg0OjyB/ls=
1084 github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o=
1085 github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
@@ -1090,6 +1166,7 @@ github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHei
1166 github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
1167 github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU=
1168 github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
1169 +github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
1170 github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
1171 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
1172 github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY=
@@ -1145,6 +1222,7 @@ github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvS
1222 github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4=
1223 github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM=
1224 github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
1225 +github.com/whyrusleeping/cbor-gen v0.0.0-20200402171437-3d27c146c105/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI=
1226 github.com/whyrusleeping/cbor-gen v0.0.0-20200710004633-5379fc63235d/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
1227 github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2 h1:bsUlNhdmbtlfdLVXAVfuvKQ01RnWAM09TVrJkI7NZs4=
1228 github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
@@ -1155,6 +1233,10 @@ github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h
1233 github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM=
1234 github.com/whyrusleeping/go-logging v0.0.1/go.mod h1:lDPYj54zutzG1XYfHAhcc7oNXEburHQBn+Iqd4yS4vE=
1235 github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8=
1236 +github.com/whyrusleeping/go-smux-multiplex v3.0.16+incompatible/go.mod h1:34LEDbeKFZInPUrAG+bjuJmUXONGdEFW7XL0SpTY1y4=
1237 +github.com/whyrusleeping/go-smux-multistream v2.0.2+incompatible/go.mod h1:dRWHHvc4HDQSHh9gbKEBbUZ+f2Q8iZTPG3UOGYODxSQ=
1238 +github.com/whyrusleeping/go-smux-yamux v2.0.8+incompatible/go.mod h1:6qHUzBXUbB9MXmw3AUdB52L8sEb/hScCqOdW2kj/wuI=
1239 +github.com/whyrusleeping/go-smux-yamux v2.0.9+incompatible/go.mod h1:6qHUzBXUbB9MXmw3AUdB52L8sEb/hScCqOdW2kj/wuI=
1240 github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1 h1:ctS9Anw/KozviCCtK6VWMz5kPL9nbQzbQY4yfqlIV4M=
1241 github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1/go.mod h1:tKH72zYNt/exx6/5IQO6L9LoQ0rEjd5SbbWaDTs9Zso=
1242 github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA=
@@ -1163,10 +1245,12 @@ github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9 h1:Y1/FEOpaCpD2
1245 github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4=
1246 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds=
1247 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI=
1248 +github.com/whyrusleeping/tar-utils v0.0.0-20180509141711-8c6c8ba81d5c/go.mod h1:xxcJeBb7SIUl/Wzkz1eVKJE/CB34YNrqX2TQI6jY9zs=
1249 github.com/whyrusleeping/tar-utils v0.0.0-20201201191210-20a61371de5b h1:wA3QeTsaAXybLL2kb2cKhCAQTHgYTMwuI8lBlJSv5V8=
1250 github.com/whyrusleeping/tar-utils v0.0.0-20201201191210-20a61371de5b/go.mod h1:xT1Y5p2JR2PfSZihE0s4mjdJaRGp1waCTf5JzhQLBck=
1251 github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee h1:lYbXeSvJi5zk5GLKVuid9TVjS9a0OmLIDKTfoZBL6Ow=
1252 github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg=
1253 +github.com/whyrusleeping/yamux v1.1.5/go.mod h1:E8LnQQ8HKx5KD29HZFUwM1PxCOdPRzGwur1mcYhXcD8=
1254 github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE=
1255 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
1256 github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
@@ -1237,6 +1321,7 @@ golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPh
1321 golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
1322 golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
1323 golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
1324 +golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
1325 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
1326 golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
1327 golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g=
@@ -1261,6 +1346,7 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHl
1346 golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
1347 golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
1348 golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
1349 +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
1350 golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI=
1351 golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
1352 golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
@@ -1272,6 +1358,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
1358 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
1359 golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY=
1360 golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
1361 +golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
1362 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
1363 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
1364 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1327,7 +1414,6 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
1414 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
1415 golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
1416 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
1330 -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
1417 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
1418 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
1419 golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1378,11 +1464,11 @@ golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7w
1464 golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
1465 golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
1466 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
1467 +golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
1468 golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
1469 golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
1470 golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
1471 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
1385 -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
1472 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
1473 golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
1474 golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1438,6 +1524,7 @@ golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapK
1524 golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
1525 golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
1526 golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
1527 +golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
1528 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
1529 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
1530 golang.org/x/tools v0.1.1-0.20210225150353-54dc8c5edb56 h1:g3QwFWCjsUzBtcQIcI+CYmiL/0i0BxTJjQp54GGDLEM=
@@ -1523,6 +1610,7 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
1610 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
1611 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
1612 gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
1613 +gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
1614 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
1615 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
1616 gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
keystore/keystore.go deleted
-189
@@ -1,189 +0,0 @@
1 -package keystore
2 -
3 -import (
4 - "fmt"
5 - "io/ioutil"
6 - "os"
7 - "path/filepath"
8 - "strings"
9 -
10 - base32 "encoding/base32"
11 -
12 - logging "github.com/ipfs/go-log"
13 - ci "github.com/libp2p/go-libp2p-core/crypto"
14 -)
15 -
16 -var log = logging.Logger("keystore")
17 -
18 -var codec = base32.StdEncoding.WithPadding(base32.NoPadding)
19 -
20 -// Keystore provides a key management interface
21 -type Keystore interface {
22 - // Has returns whether or not a key exists in the Keystore
23 - Has(string) (bool, error)
24 - // Put stores a key in the Keystore, if a key with the same name already exists, returns ErrKeyExists
25 - Put(string, ci.PrivKey) error
26 - // Get retrieves a key from the Keystore if it exists, and returns ErrNoSuchKey
27 - // otherwise.
28 - Get(string) (ci.PrivKey, error)
29 - // Delete removes a key from the Keystore
30 - Delete(string) error
31 - // List returns a list of key identifier
32 - List() ([]string, error)
33 -}
34 -
35 -// ErrNoSuchKey is an error message returned when no key of a given name was found.
36 -var ErrNoSuchKey = fmt.Errorf("no key by the given name was found")
37 -
38 -// ErrKeyExists is an error message returned when a key already exists
39 -var ErrKeyExists = fmt.Errorf("key by that name already exists, refusing to overwrite")
40 -
41 -const keyFilenamePrefix = "key_"
42 -
43 -// FSKeystore is a keystore backed by files in a given directory stored on disk.
44 -type FSKeystore struct {
45 - dir string
46 -}
47 -
48 -// NewFSKeystore returns a new filesystem-backed keystore.
49 -func NewFSKeystore(dir string) (*FSKeystore, error) {
50 - err := os.Mkdir(dir, 0700)
51 - switch {
52 - case os.IsExist(err):
53 - case err == nil:
54 - default:
55 - return nil, err
56 - }
57 - return &FSKeystore{dir}, nil
58 -}
59 -
60 -// Has returns whether or not a key exists in the Keystore
61 -func (ks *FSKeystore) Has(name string) (bool, error) {
62 - name, err := encode(name)
63 - if err != nil {
64 - return false, err
65 - }
66 -
67 - kp := filepath.Join(ks.dir, name)
68 -
69 - _, err = os.Stat(kp)
70 -
71 - if os.IsNotExist(err) {
72 - return false, nil
73 - }
74 - return err == nil, err
75 -}
76 -
77 -// Put stores a key in the Keystore, if a key with the same name already exists, returns ErrKeyExists
78 -func (ks *FSKeystore) Put(name string, k ci.PrivKey) error {
79 - name, err := encode(name)
80 - if err != nil {
81 - return err
82 - }
83 -
84 - b, err := ci.MarshalPrivateKey(k)
85 - if err != nil {
86 - return err
87 - }
88 -
89 - kp := filepath.Join(ks.dir, name)
90 -
91 - fi, err := os.OpenFile(kp, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0400)
92 - if err != nil {
93 - if os.IsExist(err) {
94 - err = ErrKeyExists
95 - }
96 - return err
97 - }
98 - defer fi.Close()
99 -
100 - _, err = fi.Write(b)
101 -
102 - return err
103 -}
104 -
105 -// Get retrieves a key from the Keystore if it exists, and returns ErrNoSuchKey
106 -// otherwise.
107 -func (ks *FSKeystore) Get(name string) (ci.PrivKey, error) {
108 - name, err := encode(name)
109 - if err != nil {
110 - return nil, err
111 - }
112 -
113 - kp := filepath.Join(ks.dir, name)
114 -
115 - data, err := ioutil.ReadFile(kp)
116 - if err != nil {
117 - if os.IsNotExist(err) {
118 - return nil, ErrNoSuchKey
119 - }
120 - return nil, err
121 - }
122 -
123 - return ci.UnmarshalPrivateKey(data)
124 -}
125 -
126 -// Delete removes a key from the Keystore
127 -func (ks *FSKeystore) Delete(name string) error {
128 - name, err := encode(name)
129 - if err != nil {
130 - return err
131 - }
132 -
133 - kp := filepath.Join(ks.dir, name)
134 -
135 - return os.Remove(kp)
136 -}
137 -
138 -// List return a list of key identifier
139 -func (ks *FSKeystore) List() ([]string, error) {
140 - dir, err := os.Open(ks.dir)
141 - if err != nil {
142 - return nil, err
143 - }
144 -
145 - dirs, err := dir.Readdirnames(0)
146 - if err != nil {
147 - return nil, err
148 - }
149 -
150 - list := make([]string, 0, len(dirs))
151 -
152 - for _, name := range dirs {
153 - decodedName, err := decode(name)
154 - if err == nil {
155 - list = append(list, decodedName)
156 - } else {
157 - log.Errorf("Ignoring keyfile with invalid encoded filename: %s", name)
158 - }
159 - }
160 -
161 - return list, nil
162 -}
163 -
164 -func encode(name string) (string, error) {
165 - if name == "" {
166 - return "", fmt.Errorf("key name must be at least one character")
167 - }
168 -
169 - encodedName := codec.EncodeToString([]byte(name))
170 - log.Debugf("Encoded key name: %s to: %s", name, encodedName)
171 -
172 - return keyFilenamePrefix + strings.ToLower(encodedName), nil
173 -}
174 -
175 -func decode(name string) (string, error) {
176 - if !strings.HasPrefix(name, keyFilenamePrefix) {
177 - return "", fmt.Errorf("key's filename has unexpected format")
178 - }
179 -
180 - nameWithoutPrefix := strings.ToUpper(name[len(keyFilenamePrefix):])
181 - decodedName, err := codec.DecodeString(nameWithoutPrefix)
182 - if err != nil {
183 - return "", err
184 - }
185 -
186 - log.Debugf("Decoded key name: %s to: %s", name, decodedName)
187 -
188 - return string(decodedName), nil
189 -}
keystore/keystore_test.go deleted
-278
@@ -1,278 +0,0 @@
1 -package keystore
2 -
3 -import (
4 - "fmt"
5 - "io/ioutil"
6 - "math/rand"
7 - "os"
8 - "path/filepath"
9 - "sort"
10 - "testing"
11 -
12 - ci "github.com/libp2p/go-libp2p-core/crypto"
13 -)
14 -
15 -type rr struct{}
16 -
17 -func (rr rr) Read(b []byte) (int, error) {
18 - return rand.Read(b)
19 -}
20 -
21 -func privKeyOrFatal(t *testing.T) ci.PrivKey {
22 - priv, _, err := ci.GenerateEd25519Key(rr{})
23 - if err != nil {
24 - t.Fatal(err)
25 - }
26 - return priv
27 -}
28 -
29 -func TestKeystoreBasics(t *testing.T) {
30 - tdir, err := ioutil.TempDir("", "keystore-test")
31 - if err != nil {
32 - t.Fatal(err)
33 - }
34 -
35 - ks, err := NewFSKeystore(tdir)
36 - if err != nil {
37 - t.Fatal(err)
38 - }
39 -
40 - l, err := ks.List()
41 - if err != nil {
42 - t.Fatal(err)
43 - }
44 -
45 - if len(l) != 0 {
46 - t.Fatal("expected no keys")
47 - }
48 -
49 - k1 := privKeyOrFatal(t)
50 - k2 := privKeyOrFatal(t)
51 - k3 := privKeyOrFatal(t)
52 - k4 := privKeyOrFatal(t)
53 -
54 - err = ks.Put("foo", k1)
55 - if err != nil {
56 - t.Fatal(err)
57 - }
58 -
59 - err = ks.Put("bar", k2)
60 - if err != nil {
61 - t.Fatal(err)
62 - }
63 -
64 - l, err = ks.List()
65 - if err != nil {
66 - t.Fatal(err)
67 - }
68 -
69 - sort.Strings(l)
70 - if l[0] != "bar" || l[1] != "foo" {
71 - t.Fatal("wrong entries listed")
72 - }
73 -
74 - if err := assertDirContents(tdir, []string{"foo", "bar"}); err != nil {
75 - t.Fatal(err)
76 - }
77 -
78 - err = ks.Put("foo", k3)
79 - if err == nil {
80 - t.Fatal("should not be able to overwrite key")
81 - }
82 -
83 - if err := assertDirContents(tdir, []string{"foo", "bar"}); err != nil {
84 - t.Fatal(err)
85 - }
86 -
87 - exist, err := ks.Has("foo")
88 - if !exist {
89 - t.Fatal("should know it has a key named foo")
90 - }
91 - if err != nil {
92 - t.Fatal(err)
93 - }
94 -
95 - exist, err = ks.Has("nonexistingkey")
96 - if exist {
97 - t.Fatal("should know it doesn't have a key named nonexistingkey")
98 - }
99 - if err != nil {
100 - t.Fatal(err)
101 - }
102 -
103 - if err := ks.Delete("bar"); err != nil {
104 - t.Fatal(err)
105 - }
106 -
107 - if err := assertDirContents(tdir, []string{"foo"}); err != nil {
108 - t.Fatal(err)
109 - }
110 -
111 - if err := ks.Put("beep", k3); err != nil {
112 - t.Fatal(err)
113 - }
114 -
115 - if err := ks.Put("boop", k4); err != nil {
116 - t.Fatal(err)
117 - }
118 -
119 - if err := assertDirContents(tdir, []string{"foo", "beep", "boop"}); err != nil {
120 - t.Fatal(err)
121 - }
122 -
123 - if err := assertGetKey(ks, "foo", k1); err != nil {
124 - t.Fatal(err)
125 - }
126 -
127 - if err := assertGetKey(ks, "beep", k3); err != nil {
128 - t.Fatal(err)
129 - }
130 -
131 - if err := assertGetKey(ks, "boop", k4); err != nil {
132 - t.Fatal(err)
133 - }
134 -
135 - if err := ks.Put("..///foo/", k1); err != nil {
136 - t.Fatal(err)
137 - }
138 -
139 - if err := ks.Put("", k1); err == nil {
140 - t.Fatal("shouldn't be able to put a key with no name")
141 - }
142 -
143 - if err := ks.Put(".foo", k1); err != nil {
144 - t.Fatal(err)
145 - }
146 -}
147 -
148 -func TestInvalidKeyFiles(t *testing.T) {
149 - tdir, err := ioutil.TempDir("", "keystore-test")
150 -
151 - if err != nil {
152 - t.Fatal(err)
153 - }
154 -
155 - defer os.RemoveAll(tdir)
156 -
157 - ks, err := NewFSKeystore(tdir)
158 - if err != nil {
159 - t.Fatal(err)
160 - }
161 -
162 - key := privKeyOrFatal(t)
163 -
164 - bytes, err := key.Bytes()
165 - if err != nil {
166 - t.Fatal(err)
167 - }
168 -
169 - encodedName, err := encode("valid")
170 - if err != nil {
171 - t.Fatal(err)
172 - }
173 -
174 - err = ioutil.WriteFile(filepath.Join(ks.dir, encodedName), bytes, 0644)
175 - if err != nil {
176 - t.Fatal(err)
177 - }
178 -
179 - err = ioutil.WriteFile(filepath.Join(ks.dir, "z.invalid"), bytes, 0644)
180 - if err != nil {
181 - t.Fatal(err)
182 - }
183 -
184 - l, err := ks.List()
185 - if err != nil {
186 - t.Fatal(err)
187 - }
188 -
189 - sort.Strings(l)
190 - if len(l) != 1 {
191 - t.Fatal("wrong entry count")
192 - }
193 -
194 - if l[0] != "valid" {
195 - t.Fatal("wrong entries listed")
196 - }
197 -
198 - exist, err := ks.Has("valid")
199 - if !exist {
200 - t.Fatal("should know it has a key named valid")
201 - }
202 - if err != nil {
203 - t.Fatal(err)
204 - }
205 -}
206 -
207 -func TestNonExistingKey(t *testing.T) {
208 - tdir, err := ioutil.TempDir("", "keystore-test")
209 - if err != nil {
210 - t.Fatal(err)
211 - }
212 -
213 - ks, err := NewFSKeystore(tdir)
214 - if err != nil {
215 - t.Fatal(err)
216 - }
217 -
218 - k, err := ks.Get("does-it-exist")
219 - if err != ErrNoSuchKey {
220 - t.Fatalf("expected: %s, got %s", ErrNoSuchKey, err)
221 - }
222 - if k != nil {
223 - t.Fatalf("Get on nonexistant key should give nil")
224 - }
225 -}
226 -
227 -func TestMakeKeystoreNoDir(t *testing.T) {
228 - _, err := NewFSKeystore("/this/is/not/a/real/dir")
229 - if err == nil {
230 - t.Fatal("shouldnt be able to make a keystore in a nonexistant directory")
231 - }
232 -}
233 -
234 -func assertGetKey(ks Keystore, name string, exp ci.PrivKey) error {
235 - outK, err := ks.Get(name)
236 - if err != nil {
237 - return err
238 - }
239 -
240 - if !outK.Equals(exp) {
241 - return fmt.Errorf("key we got out didn't match expectation")
242 - }
243 -
244 - return nil
245 -}
246 -
247 -func assertDirContents(dir string, exp []string) error {
248 - finfos, err := ioutil.ReadDir(dir)
249 - if err != nil {
250 - return err
251 - }
252 -
253 - if len(finfos) != len(exp) {
254 - return fmt.Errorf("expected %d directory entries", len(exp))
255 - }
256 -
257 - var names []string
258 - for _, fi := range finfos {
259 - decodedName, err := decode(fi.Name())
260 - if err != nil {
261 - return err
262 - }
263 - names = append(names, decodedName)
264 - }
265 -
266 - sort.Strings(names)
267 - sort.Strings(exp)
268 - if len(names) != len(exp) {
269 - return fmt.Errorf("directory had wrong number of entries in it")
270 - }
271 -
272 - for i, v := range names {
273 - if v != exp[i] {
274 - return fmt.Errorf("had wrong entry in directory")
275 - }
276 - }
277 - return nil
278 -}
keystore/memkeystore.go deleted
-64
@@ -1,64 +0,0 @@
1 -package keystore
2 -
3 -import (
4 - "errors"
5 -
6 - ci "github.com/libp2p/go-libp2p-core/crypto"
7 -)
8 -
9 -// MemKeystore is an in memory keystore implementation that is not persisted to
10 -// any backing storage.
11 -type MemKeystore struct {
12 - keys map[string]ci.PrivKey
13 -}
14 -
15 -// NewMemKeystore creates a MemKeystore.
16 -func NewMemKeystore() *MemKeystore {
17 - return &MemKeystore{make(map[string]ci.PrivKey)}
18 -}
19 -
20 -// Has return whether or not a key exists in the Keystore
21 -func (mk *MemKeystore) Has(name string) (bool, error) {
22 - _, ok := mk.keys[name]
23 - return ok, nil
24 -}
25 -
26 -// Put store a key in the Keystore
27 -func (mk *MemKeystore) Put(name string, k ci.PrivKey) error {
28 - if name == "" {
29 - return errors.New("key name must be at least one character")
30 - }
31 -
32 - _, ok := mk.keys[name]
33 - if ok {
34 - return ErrKeyExists
35 - }
36 -
37 - mk.keys[name] = k
38 - return nil
39 -}
40 -
41 -// Get retrieve a key from the Keystore
42 -func (mk *MemKeystore) Get(name string) (ci.PrivKey, error) {
43 - k, ok := mk.keys[name]
44 - if !ok {
45 - return nil, ErrNoSuchKey
46 - }
47 -
48 - return k, nil
49 -}
50 -
51 -// Delete remove a key from the Keystore
52 -func (mk *MemKeystore) Delete(name string) error {
53 - delete(mk.keys, name)
54 - return nil
55 -}
56 -
57 -// List return a list of key identifier
58 -func (mk *MemKeystore) List() ([]string, error) {
59 - out := make([]string, 0, len(mk.keys))
60 - for k := range mk.keys {
61 - out = append(out, k)
62 - }
63 - return out, nil
64 -}
keystore/memkeystore_test.go deleted
-99
@@ -1,99 +0,0 @@
1 -package keystore
2 -
3 -import (
4 - "sort"
5 - "testing"
6 -)
7 -
8 -func TestMemKeyStoreBasics(t *testing.T) {
9 - ks := NewMemKeystore()
10 -
11 - l, err := ks.List()
12 - if err != nil {
13 - t.Fatal(err)
14 - }
15 -
16 - if len(l) != 0 {
17 - t.Fatal("expected no keys")
18 - }
19 -
20 - k1 := privKeyOrFatal(t)
21 - k2 := privKeyOrFatal(t)
22 - k3 := privKeyOrFatal(t)
23 - k4 := privKeyOrFatal(t)
24 -
25 - err = ks.Put("foo", k1)
26 - if err != nil {
27 - t.Fatal(err)
28 - }
29 -
30 - err = ks.Put("bar", k2)
31 - if err != nil {
32 - t.Fatal(err)
33 - }
34 -
35 - l, err = ks.List()
36 - if err != nil {
37 - t.Fatal(err)
38 - }
39 -
40 - sort.Strings(l)
41 - if l[0] != "bar" || l[1] != "foo" {
42 - t.Fatal("wrong entries listed")
43 - }
44 -
45 - err = ks.Put("foo", k3)
46 - if err == nil {
47 - t.Fatal("should not be able to overwrite key")
48 - }
49 -
50 - exist, err := ks.Has("foo")
51 - if !exist {
52 - t.Fatal("should know it has a key named foo")
53 - }
54 - if err != nil {
55 - t.Fatal(err)
56 - }
57 -
58 - exist, err = ks.Has("nonexistingkey")
59 - if exist {
60 - t.Fatal("should know it doesn't have a key named nonexistingkey")
61 - }
62 - if err != nil {
63 - t.Fatal(err)
64 - }
65 -
66 - if err := ks.Delete("bar"); err != nil {
67 - t.Fatal(err)
68 - }
69 - if err := ks.Put("beep", k3); err != nil {
70 - t.Fatal(err)
71 - }
72 -
73 - if err := ks.Put("boop", k4); err != nil {
74 - t.Fatal(err)
75 - }
76 - if err := assertGetKey(ks, "foo", k1); err != nil {
77 - t.Fatal(err)
78 - }
79 -
80 - if err := assertGetKey(ks, "beep", k3); err != nil {
81 - t.Fatal(err)
82 - }
83 -
84 - if err := assertGetKey(ks, "boop", k4); err != nil {
85 - t.Fatal(err)
86 - }
87 -
88 - if err := ks.Put("..///foo/", k1); err != nil {
89 - t.Fatal(err)
90 - }
91 -
92 - if err := ks.Put("", k1); err == nil {
93 - t.Fatal("shouldn't be able to put a key with no name")
94 - }
95 -
96 - if err := ks.Put(".foo", k1); err != nil {
97 - t.Fatal(err)
98 - }
99 -}
namesys/base.go deleted
-120
@@ -1,120 +0,0 @@
1 -package namesys
2 -
3 -import (
4 - "context"
5 - "strings"
6 - "time"
7 -
8 - path "github.com/ipfs/go-path"
9 - opts "github.com/ipfs/interface-go-ipfs-core/options/namesys"
10 -)
11 -
12 -type onceResult struct {
13 - value path.Path
14 - ttl time.Duration
15 - err error
16 -}
17 -
18 -type resolver interface {
19 - resolveOnceAsync(ctx context.Context, name string, options opts.ResolveOpts) <-chan onceResult
20 -}
21 -
22 -// resolve is a helper for implementing Resolver.ResolveN using resolveOnce.
23 -func resolve(ctx context.Context, r resolver, name string, options opts.ResolveOpts) (path.Path, error) {
24 - ctx, cancel := context.WithCancel(ctx)
25 - defer cancel()
26 -
27 - err := ErrResolveFailed
28 - var p path.Path
29 -
30 - resCh := resolveAsync(ctx, r, name, options)
31 -
32 - for res := range resCh {
33 - p, err = res.Path, res.Err
34 - if err != nil {
35 - break
36 - }
37 - }
38 -
39 - return p, err
40 -}
41 -
42 -func resolveAsync(ctx context.Context, r resolver, name string, options opts.ResolveOpts) <-chan Result {
43 - resCh := r.resolveOnceAsync(ctx, name, options)
44 - depth := options.Depth
45 - outCh := make(chan Result, 1)
46 -
47 - go func() {
48 - defer close(outCh)
49 - var subCh <-chan Result
50 - var cancelSub context.CancelFunc
51 - defer func() {
52 - if cancelSub != nil {
53 - cancelSub()
54 - }
55 - }()
56 -
57 - for {
58 - select {
59 - case res, ok := <-resCh:
60 - if !ok {
61 - resCh = nil
62 - break
63 - }
64 -
65 - if res.err != nil {
66 - emitResult(ctx, outCh, Result{Err: res.err})
67 - return
68 - }
69 - log.Debugf("resolved %s to %s", name, res.value.String())
70 - if !strings.HasPrefix(res.value.String(), ipnsPrefix) {
71 - emitResult(ctx, outCh, Result{Path: res.value})
72 - break
73 - }
74 -
75 - if depth == 1 {
76 - emitResult(ctx, outCh, Result{Path: res.value, Err: ErrResolveRecursion})
77 - break
78 - }
79 -
80 - subopts := options
81 - if subopts.Depth > 1 {
82 - subopts.Depth--
83 - }
84 -
85 - var subCtx context.Context
86 - if cancelSub != nil {
87 - // Cancel previous recursive resolve since it won't be used anyways
88 - cancelSub()
89 - }
90 - subCtx, cancelSub = context.WithCancel(ctx)
91 - _ = cancelSub
92 -
93 - p := strings.TrimPrefix(res.value.String(), ipnsPrefix)
94 - subCh = resolveAsync(subCtx, r, p, subopts)
95 - case res, ok := <-subCh:
96 - if !ok {
97 - subCh = nil
98 - break
99 - }
100 -
101 - // We don't bother returning here in case of context timeout as there is
102 - // no good reason to do that, and we may still be able to emit a result
103 - emitResult(ctx, outCh, res)
104 - case <-ctx.Done():
105 - return
106 - }
107 - if resCh == nil && subCh == nil {
108 - return
109 - }
110 - }
111 - }()
112 - return outCh
113 -}
114 -
115 -func emitResult(ctx context.Context, outCh chan<- Result, r Result) {
116 - select {
117 - case outCh <- r:
118 - case <-ctx.Done():
119 - }
120 -}
namesys/cache.go deleted
-62
@@ -1,62 +0,0 @@
1 -package namesys
2 -
3 -import (
4 - "time"
5 -
6 - path "github.com/ipfs/go-path"
7 -)
8 -
9 -func (ns *mpns) cacheGet(name string) (path.Path, bool) {
10 - // existence of optional mapping defined via IPFS_NS_MAP is checked first
11 - if ns.staticMap != nil {
12 - val, ok := ns.staticMap[name]
13 - if ok {
14 - return val, true
15 - }
16 - }
17 -
18 - if ns.cache == nil {
19 - return "", false
20 - }
21 -
22 - ientry, ok := ns.cache.Get(name)
23 - if !ok {
24 - return "", false
25 - }
26 -
27 - entry, ok := ientry.(cacheEntry)
28 - if !ok {
29 - // should never happen, purely for sanity
30 - log.Panicf("unexpected type %T in cache for %q.", ientry, name)
31 - }
32 -
33 - if time.Now().Before(entry.eol) {
34 - return entry.val, true
35 - }
36 -
37 - ns.cache.Remove(name)
38 -
39 - return "", false
40 -}
41 -
42 -func (ns *mpns) cacheSet(name string, val path.Path, ttl time.Duration) {
43 - if ns.cache == nil || ttl <= 0 {
44 - return
45 - }
46 - ns.cache.Add(name, cacheEntry{
47 - val: val,
48 - eol: time.Now().Add(ttl),
49 - })
50 -}
51 -
52 -func (ns *mpns) cacheInvalidate(name string) {
53 - if ns.cache == nil {
54 - return
55 - }
56 - ns.cache.Remove(name)
57 -}
58 -
59 -type cacheEntry struct {
60 - val path.Path
61 - eol time.Time
62 -}
namesys/dns.go deleted
-159
@@ -1,159 +0,0 @@
1 -package namesys
2 -
3 -import (
4 - "context"
5 - "errors"
6 - "fmt"
7 - "net"
8 - "strings"
9 -
10 - path "github.com/ipfs/go-path"
11 - opts "github.com/ipfs/interface-go-ipfs-core/options/namesys"
12 - isd "github.com/jbenet/go-is-domain"
13 -)
14 -
15 -const ethTLD = "eth"
16 -const linkTLD = "link"
17 -
18 -type LookupTXTFunc func(name string) (txt []string, err error)
19 -
20 -// DNSResolver implements a Resolver on DNS domains
21 -type DNSResolver struct {
22 - lookupTXT LookupTXTFunc
23 - // TODO: maybe some sort of caching?
24 - // cache would need a timeout
25 -}
26 -
27 -// NewDNSResolver constructs a name resolver using DNS TXT records.
28 -func NewDNSResolver() *DNSResolver {
29 - return &DNSResolver{lookupTXT: net.LookupTXT}
30 -}
31 -
32 -// Resolve implements Resolver.
33 -func (r *DNSResolver) Resolve(ctx context.Context, name string, options ...opts.ResolveOpt) (path.Path, error) {
34 - return resolve(ctx, r, name, opts.ProcessOpts(options))
35 -}
36 -
37 -// ResolveAsync implements Resolver.
38 -func (r *DNSResolver) ResolveAsync(ctx context.Context, name string, options ...opts.ResolveOpt) <-chan Result {
39 - return resolveAsync(ctx, r, name, opts.ProcessOpts(options))
40 -}
41 -
42 -type lookupRes struct {
43 - path path.Path
44 - error error
45 -}
46 -
47 -// resolveOnce implements resolver.
48 -// TXT records for a given domain name should contain a b58
49 -// encoded multihash.
50 -func (r *DNSResolver) resolveOnceAsync(ctx context.Context, name string, options opts.ResolveOpts) <-chan onceResult {
51 - var fqdn string
52 - out := make(chan onceResult, 1)
53 - segments := strings.SplitN(name, "/", 2)
54 - domain := segments[0]
55 -
56 - if !isd.IsDomain(domain) {
57 - out <- onceResult{err: fmt.Errorf("not a valid domain name: %s", domain)}
58 - close(out)
59 - return out
60 - }
61 - log.Debugf("DNSResolver resolving %s", domain)
62 -
63 - if strings.HasSuffix(domain, ".") {
64 - fqdn = domain
65 - } else {
66 - fqdn = domain + "."
67 - }
68 -
69 - if strings.HasSuffix(fqdn, "."+ethTLD+".") {
70 - // This is an ENS name. As we're resolving via an arbitrary DNS server
71 - // that may not know about .eth we need to add our link domain suffix.
72 - fqdn += linkTLD + "."
73 - }
74 -
75 - rootChan := make(chan lookupRes, 1)
76 - go workDomain(r, fqdn, rootChan)
77 -
78 - subChan := make(chan lookupRes, 1)
79 - go workDomain(r, "_dnslink."+fqdn, subChan)
80 -
81 - appendPath := func(p path.Path) (path.Path, error) {
82 - if len(segments) > 1 {
83 - return path.FromSegments("", strings.TrimRight(p.String(), "/"), segments[1])
84 - }
85 - return p, nil
86 - }
87 -
88 - go func() {
89 - defer close(out)
90 - for {
91 - select {
92 - case subRes, ok := <-subChan:
93 - if !ok {
94 - subChan = nil
95 - break
96 - }
97 - if subRes.error == nil {
98 - p, err := appendPath(subRes.path)
99 - emitOnceResult(ctx, out, onceResult{value: p, err: err})
100 - return
101 - }
102 - case rootRes, ok := <-rootChan:
103 - if !ok {
104 - rootChan = nil
105 - break
106 - }
107 - if rootRes.error == nil {
108 - p, err := appendPath(rootRes.path)
109 - emitOnceResult(ctx, out, onceResult{value: p, err: err})
110 - }
111 - case <-ctx.Done():
112 - return
113 - }
114 - if subChan == nil && rootChan == nil {
115 - return
116 - }
117 - }
118 - }()
119 -
120 - return out
121 -}
122 -
123 -func workDomain(r *DNSResolver, name string, res chan lookupRes) {
124 - defer close(res)
125 -
126 - txt, err := r.lookupTXT(name)
127 - if err != nil {
128 - // Error is != nil
129 - res <- lookupRes{"", err}
130 - return
131 - }
132 -
133 - for _, t := range txt {
134 - p, err := parseEntry(t)
135 - if err == nil {
136 - res <- lookupRes{p, nil}
137 - return
138 - }
139 - }
140 - res <- lookupRes{"", ErrResolveFailed}
141 -}
142 -
143 -func parseEntry(txt string) (path.Path, error) {
144 - p, err := path.ParseCidToPath(txt) // bare IPFS multihashes
145 - if err == nil {
146 - return p, nil
147 - }
148 -
149 - return tryParseDnsLink(txt)
150 -}
151 -
152 -func tryParseDnsLink(txt string) (path.Path, error) {
153 - parts := strings.SplitN(txt, "=", 2)
154 - if len(parts) == 2 && parts[0] == "dnslink" {
155 - return path.ParsePath(parts[1])
156 - }
157 -
158 - return "", errors.New("not a valid dnslink entry")
159 -}
namesys/dns_test.go deleted
-172
@@ -1,172 +0,0 @@
1 -package namesys
2 -
3 -import (
4 - "fmt"
5 - "testing"
6 -
7 - opts "github.com/ipfs/interface-go-ipfs-core/options/namesys"
8 -)
9 -
10 -type mockDNS struct {
11 - entries map[string][]string
12 -}
13 -
14 -func (m *mockDNS) lookupTXT(name string) (txt []string, err error) {
15 - txt, ok := m.entries[name]
16 - if !ok {
17 - return nil, fmt.Errorf("no TXT entry for %s", name)
18 - }
19 - return txt, nil
20 -}
21 -
22 -func TestDnsEntryParsing(t *testing.T) {
23 -
24 - goodEntries := []string{
25 - "QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD",
26 - "dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD",
27 - "dnslink=/ipns/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD",
28 - "dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/foo",
29 - "dnslink=/ipns/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/bar",
30 - "dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/foo/bar/baz",
31 - "dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/foo/bar/baz/",
32 - "dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD",
33 - }
34 -
35 - badEntries := []string{
36 - "QmYhE8xgFCjGcz6PHgnvJz5NOTCORRECT",
37 - "quux=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD",
38 - "dnslink=",
39 - "dnslink=/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/foo",
40 - "dnslink=ipns/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/bar",
41 - }
42 -
43 - for _, e := range goodEntries {
44 - _, err := parseEntry(e)
45 - if err != nil {
46 - t.Log("expected entry to parse correctly!")
47 - t.Log(e)
48 - t.Fatal(err)
49 - }
50 - }
51 -
52 - for _, e := range badEntries {
53 - _, err := parseEntry(e)
54 - if err == nil {
55 - t.Log("expected entry parse to fail!")
56 - t.Fatal(err)
57 - }
58 - }
59 -}
60 -
61 -func newMockDNS() *mockDNS {
62 - return &mockDNS{
63 - entries: map[string][]string{
64 - "multihash.example.com.": {
65 - "dnslink=QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD",
66 - },
67 - "ipfs.example.com.": {
68 - "dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD",
69 - },
70 - "_dnslink.dipfs.example.com.": {
71 - "dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD",
72 - },
73 - "dns1.example.com.": {
74 - "dnslink=/ipns/ipfs.example.com",
75 - },
76 - "dns2.example.com.": {
77 - "dnslink=/ipns/dns1.example.com",
78 - },
79 - "multi.example.com.": {
80 - "some stuff",
81 - "dnslink=/ipns/dns1.example.com",
82 - "masked dnslink=/ipns/example.invalid",
83 - },
84 - "equals.example.com.": {
85 - "dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/=equals",
86 - },
87 - "loop1.example.com.": {
88 - "dnslink=/ipns/loop2.example.com",
89 - },
90 - "loop2.example.com.": {
91 - "dnslink=/ipns/loop1.example.com",
92 - },
93 - "_dnslink.dloop1.example.com.": {
94 - "dnslink=/ipns/loop2.example.com",
95 - },
96 - "_dnslink.dloop2.example.com.": {
97 - "dnslink=/ipns/loop1.example.com",
98 - },
99 - "bad.example.com.": {
100 - "dnslink=",
101 - },
102 - "withsegment.example.com.": {
103 - "dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment",
104 - },
105 - "withrecsegment.example.com.": {
106 - "dnslink=/ipns/withsegment.example.com/subsub",
107 - },
108 - "withtrailing.example.com.": {
109 - "dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/",
110 - },
111 - "withtrailingrec.example.com.": {
112 - "dnslink=/ipns/withtrailing.example.com/segment/",
113 - },
114 - "double.example.com.": {
115 - "dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD",
116 - },
117 - "_dnslink.double.example.com.": {
118 - "dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD",
119 - },
120 - "double.conflict.com.": {
121 - "dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD",
122 - },
123 - "_dnslink.conflict.example.com.": {
124 - "dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjE",
125 - },
126 - "fqdn.example.com.": {
127 - "dnslink=/ipfs/QmYvMB9yrsSf7RKBghkfwmHJkzJhW2ZgVwq3LxBXXPasFr",
128 - },
129 - "www.wealdtech.eth.link.": {
130 - "dnslink=/ipns/ipfs.example.com",
131 - },
132 - },
133 - }
134 -}
135 -
136 -func TestDNSResolution(t *testing.T) {
137 - mock := newMockDNS()
138 - r := &DNSResolver{lookupTXT: mock.lookupTXT}
139 - testResolution(t, r, "multihash.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
140 - testResolution(t, r, "ipfs.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
141 - testResolution(t, r, "dipfs.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
142 - testResolution(t, r, "dns1.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
143 - testResolution(t, r, "dns1.example.com", 1, "/ipns/ipfs.example.com", ErrResolveRecursion)
144 - testResolution(t, r, "dns2.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
145 - testResolution(t, r, "dns2.example.com", 1, "/ipns/dns1.example.com", ErrResolveRecursion)
146 - testResolution(t, r, "dns2.example.com", 2, "/ipns/ipfs.example.com", ErrResolveRecursion)
147 - testResolution(t, r, "multi.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
148 - testResolution(t, r, "multi.example.com", 1, "/ipns/dns1.example.com", ErrResolveRecursion)
149 - testResolution(t, r, "multi.example.com", 2, "/ipns/ipfs.example.com", ErrResolveRecursion)
150 - testResolution(t, r, "equals.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/=equals", nil)
151 - testResolution(t, r, "loop1.example.com", 1, "/ipns/loop2.example.com", ErrResolveRecursion)
152 - testResolution(t, r, "loop1.example.com", 2, "/ipns/loop1.example.com", ErrResolveRecursion)
153 - testResolution(t, r, "loop1.example.com", 3, "/ipns/loop2.example.com", ErrResolveRecursion)
154 - testResolution(t, r, "loop1.example.com", opts.DefaultDepthLimit, "/ipns/loop1.example.com", ErrResolveRecursion)
155 - testResolution(t, r, "dloop1.example.com", 1, "/ipns/loop2.example.com", ErrResolveRecursion)
156 - testResolution(t, r, "dloop1.example.com", 2, "/ipns/loop1.example.com", ErrResolveRecursion)
157 - testResolution(t, r, "dloop1.example.com", 3, "/ipns/loop2.example.com", ErrResolveRecursion)
158 - testResolution(t, r, "dloop1.example.com", opts.DefaultDepthLimit, "/ipns/loop1.example.com", ErrResolveRecursion)
159 - testResolution(t, r, "bad.example.com", opts.DefaultDepthLimit, "", ErrResolveFailed)
160 - testResolution(t, r, "withsegment.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment", nil)
161 - testResolution(t, r, "withrecsegment.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub", nil)
162 - testResolution(t, r, "withsegment.example.com/test1", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/test1", nil)
163 - testResolution(t, r, "withrecsegment.example.com/test2", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub/test2", nil)
164 - testResolution(t, r, "withrecsegment.example.com/test3/", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub/test3/", nil)
165 - testResolution(t, r, "withtrailingrec.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/", nil)
166 - testResolution(t, r, "double.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
167 - testResolution(t, r, "conflict.example.com", opts.DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjE", nil)
168 - testResolution(t, r, "fqdn.example.com.", opts.DefaultDepthLimit, "/ipfs/QmYvMB9yrsSf7RKBghkfwmHJkzJhW2ZgVwq3LxBXXPasFr", nil)
169 - testResolution(t, r, "www.wealdtech.eth", 1, "/ipns/ipfs.example.com", ErrResolveRecursion)
170 - testResolution(t, r, "www.wealdtech.eth", 2, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
171 - testResolution(t, r, "www.wealdtech.eth.link", 2, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", nil)
172 -}
namesys/interface.go deleted
-106
@@ -1,106 +0,0 @@
1 -/*
2 -Package namesys implements resolvers and publishers for the IPFS
3 -naming system (IPNS).
4 -
5 -The core of IPFS is an immutable, content-addressable Merkle graph.
6 -That works well for many use cases, but doesn't allow you to answer
7 -questions like "what is Alice's current homepage?". The mutable name
8 -system allows Alice to publish information like:
9 -
10 - The current homepage for alice.example.com is
11 - /ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj
12 -
13 -or:
14 -
15 - The current homepage for node
16 - QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
17 - is
18 - /ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj
19 -
20 -The mutable name system also allows users to resolve those references
21 -to find the immutable IPFS object currently referenced by a given
22 -mutable name.
23 -
24 -For command-line bindings to this functionality, see:
25 -
26 - ipfs name
27 - ipfs dns
28 - ipfs resolve
29 -*/
30 -package namesys
31 -
32 -import (
33 - "errors"
34 - "time"
35 -
36 - context "context"
37 -
38 - path "github.com/ipfs/go-path"
39 - opts "github.com/ipfs/interface-go-ipfs-core/options/namesys"
40 - ci "github.com/libp2p/go-libp2p-core/crypto"
41 -)
42 -
43 -// ErrResolveFailed signals an error when attempting to resolve.
44 -var ErrResolveFailed = errors.New("could not resolve name")
45 -
46 -// ErrResolveRecursion signals a recursion-depth limit.
47 -var ErrResolveRecursion = errors.New(
48 - "could not resolve name (recursion limit exceeded)")
49 -
50 -// ErrPublishFailed signals an error when attempting to publish.
51 -var ErrPublishFailed = errors.New("could not publish name")
52 -
53 -// Namesys represents a cohesive name publishing and resolving system.
54 -//
55 -// Publishing a name is the process of establishing a mapping, a key-value
56 -// pair, according to naming rules and databases.
57 -//
58 -// Resolving a name is the process of looking up the value associated with the
59 -// key (name).
60 -type NameSystem interface {
61 - Resolver
62 - Publisher
63 -}
64 -
65 -// Result is the return type for Resolver.ResolveAsync.
66 -type Result struct {
67 - Path path.Path
68 - Err error
69 -}
70 -
71 -// Resolver is an object capable of resolving names.
72 -type Resolver interface {
73 -
74 - // Resolve performs a recursive lookup, returning the dereferenced
75 - // path. For example, if ipfs.io has a DNS TXT record pointing to
76 - // /ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
77 - // and there is a DHT IPNS entry for
78 - // QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
79 - // -> /ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj
80 - // then
81 - // Resolve(ctx, "/ipns/ipfs.io")
82 - // will resolve both names, returning
83 - // /ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj
84 - //
85 - // There is a default depth-limit to avoid infinite recursion. Most
86 - // users will be fine with this default limit, but if you need to
87 - // adjust the limit you can specify it as an option.
88 - Resolve(ctx context.Context, name string, options ...opts.ResolveOpt) (value path.Path, err error)
89 -
90 - // ResolveAsync performs recursive name lookup, like Resolve, but it returns
91 - // entries as they are discovered in the DHT. Each returned result is guaranteed
92 - // to be "better" (which usually means newer) than the previous one.
93 - ResolveAsync(ctx context.Context, name string, options ...opts.ResolveOpt) <-chan Result
94 -}
95 -
96 -// Publisher is an object capable of publishing particular names.
97 -type Publisher interface {
98 -
99 - // Publish establishes a name-value mapping.
100 - // TODO make this not PrivKey specific.
101 - Publish(ctx context.Context, name ci.PrivKey, value path.Path) error
102 -
103 - // TODO: to be replaced by a more generic 'PublishWithValidity' type
104 - // call once the records spec is implemented
105 - PublishWithEOL(ctx context.Context, name ci.PrivKey, value path.Path, eol time.Time) error
106 -}
namesys/ipns_resolver_validation_test.go deleted
-206
@@ -1,206 +0,0 @@
1 -package namesys
2 -
3 -import (
4 - "context"
5 - "testing"
6 - "time"
7 -
8 - ds "github.com/ipfs/go-datastore"
9 - dssync "github.com/ipfs/go-datastore/sync"
10 - mockrouting "github.com/ipfs/go-ipfs-routing/mock"
11 - offline "github.com/ipfs/go-ipfs-routing/offline"
12 - ipns "github.com/ipfs/go-ipns"
13 - ipns_pb "github.com/ipfs/go-ipns/pb"
14 - path "github.com/ipfs/go-path"
15 - opts "github.com/ipfs/interface-go-ipfs-core/options/namesys"
16 - ci "github.com/libp2p/go-libp2p-core/crypto"
17 - peer "github.com/libp2p/go-libp2p-core/peer"
18 - pstore "github.com/libp2p/go-libp2p-core/peerstore"
19 - routing "github.com/libp2p/go-libp2p-core/routing"
20 - "github.com/libp2p/go-libp2p-core/test"
21 - pstoremem "github.com/libp2p/go-libp2p-peerstore/pstoremem"
22 - record "github.com/libp2p/go-libp2p-record"
23 - testutil "github.com/libp2p/go-libp2p-testing/net"
24 -)
25 -
26 -func TestResolverValidation(t *testing.T) {
27 - t.Run("RSA",
28 - func(t *testing.T) {
29 - testResolverValidation(t, ci.RSA)
30 - })
31 - t.Run("Ed25519",
32 - func(t *testing.T) {
33 - testResolverValidation(t, ci.Ed25519)
34 - })
35 - t.Run("ECDSA",
36 - func(t *testing.T) {
37 - testResolverValidation(t, ci.ECDSA)
38 - })
39 - t.Run("Secp256k1",
40 - func(t *testing.T) {
41 - testResolverValidation(t, ci.Secp256k1)
42 - })
43 -}
44 -
45 -func testResolverValidation(t *testing.T, keyType int) {
46 - ctx := context.Background()
47 - rid := testutil.RandIdentityOrFatal(t)
48 - dstore := dssync.MutexWrap(ds.NewMapDatastore())
49 - peerstore := pstoremem.NewPeerstore()
50 -
51 - vstore := newMockValueStore(rid, dstore, peerstore)
52 - resolver := NewIpnsResolver(vstore)
53 -
54 - nvVstore := offline.NewOfflineRouter(dstore, mockrouting.MockValidator{})
55 -
56 - // Create entry with expiry in one hour
57 - priv, id, _, ipnsDHTPath := genKeys(t, keyType)
58 - ts := time.Now()
59 - p := []byte("/ipfs/QmfM2r8seH2GiRaC4esTjeraXEachRt8ZsSeGaWTPLyMoG")
60 - entry, err := createIPNSRecordWithEmbeddedPublicKey(priv, p, 1, ts.Add(time.Hour))
61 - if err != nil {
62 - t.Fatal(err)
63 - }
64 -
65 - // Publish entry
66 - err = PublishEntry(ctx, vstore, ipnsDHTPath, entry)
67 - if err != nil {
68 - t.Fatal(err)
69 - }
70 -
71 - // Resolve entry
72 - resp, err := resolve(ctx, resolver, id.Pretty(), opts.DefaultResolveOpts())
73 - if err != nil {
74 - t.Fatal(err)
75 - }
76 - if resp != path.Path(p) {
77 - t.Fatalf("Mismatch between published path %s and resolved path %s", p, resp)
78 - }
79 - // Create expired entry
80 - expiredEntry, err := createIPNSRecordWithEmbeddedPublicKey(priv, p, 1, ts.Add(-1*time.Hour))
81 - if err != nil {
82 - t.Fatal(err)
83 - }
84 -
85 - // Publish entry
86 - err = PublishEntry(ctx, nvVstore, ipnsDHTPath, expiredEntry)
87 - if err != nil {
88 - t.Fatal(err)
89 - }
90 -
91 - // Record should fail validation because entry is expired
92 - _, err = resolve(ctx, resolver, id.Pretty(), opts.DefaultResolveOpts())
93 - if err == nil {
94 - t.Fatal("ValidateIpnsRecord should have returned error")
95 - }
96 -
97 - // Create IPNS record path with a different private key
98 - priv2, id2, _, ipnsDHTPath2 := genKeys(t, keyType)
99 -
100 - // Publish entry
101 - err = PublishEntry(ctx, nvVstore, ipnsDHTPath2, entry)
102 - if err != nil {
103 - t.Fatal(err)
104 - }
105 -
106 - // Record should fail validation because public key defined by
107 - // ipns path doesn't match record signature
108 - _, err = resolve(ctx, resolver, id2.Pretty(), opts.DefaultResolveOpts())
109 - if err == nil {
110 - t.Fatal("ValidateIpnsRecord should have failed signature verification")
111 - }
112 -
113 - // Try embedding the incorrect private key inside the entry
114 - if err := ipns.EmbedPublicKey(priv2.GetPublic(), entry); err != nil {
115 - t.Fatal(err)
116 - }
117 -
118 - // Publish entry
119 - err = PublishEntry(ctx, nvVstore, ipnsDHTPath2, entry)
120 - if err != nil {
121 - t.Fatal(err)
122 - }
123 -
124 - // Record should fail validation because public key defined by
125 - // ipns path doesn't match record signature
126 - _, err = resolve(ctx, resolver, id2.Pretty(), opts.DefaultResolveOpts())
127 - if err == nil {
128 - t.Fatal("ValidateIpnsRecord should have failed signature verification")
129 - }
130 -}
131 -
132 -func genKeys(t *testing.T, keyType int) (ci.PrivKey, peer.ID, string, string) {
133 - bits := 0
134 - if keyType == ci.RSA {
135 - bits = 2048
136 - }
137 -
138 - sk, pk, err := test.RandTestKeyPair(keyType, bits)
139 - if err != nil {
140 - t.Fatal(err)
141 - }
142 - id, err := peer.IDFromPublicKey(pk)
143 - if err != nil {
144 - t.Fatal(err)
145 - }
146 - return sk, id, PkKeyForID(id), ipns.RecordKey(id)
147 -}
148 -
149 -func createIPNSRecordWithEmbeddedPublicKey(sk ci.PrivKey, val []byte, seq uint64, eol time.Time) (*ipns_pb.IpnsEntry, error) {
150 - entry, err := ipns.Create(sk, val, seq, eol)
151 - if err != nil {
152 - return nil, err
153 - }
154 - if err := ipns.EmbedPublicKey(sk.GetPublic(), entry); err != nil {
155 - return nil, err
156 - }
157 -
158 - return entry, nil
159 -}
160 -
161 -type mockValueStore struct {
162 - r routing.ValueStore
163 - kbook pstore.KeyBook
164 -}
165 -
166 -func newMockValueStore(id testutil.Identity, dstore ds.Datastore, kbook pstore.KeyBook) *mockValueStore {
167 - return &mockValueStore{
168 - r: offline.NewOfflineRouter(dstore, record.NamespacedValidator{
169 - "ipns": ipns.Validator{KeyBook: kbook},
170 - "pk": record.PublicKeyValidator{},
171 - }),
172 - kbook: kbook,
173 - }
174 -}
175 -
176 -func (m *mockValueStore) GetValue(ctx context.Context, k string, opts ...routing.Option) ([]byte, error) {
177 - return m.r.GetValue(ctx, k, opts...)
178 -}
179 -
180 -func (m *mockValueStore) SearchValue(ctx context.Context, k string, opts ...routing.Option) (<-chan []byte, error) {
181 - return m.r.SearchValue(ctx, k, opts...)
182 -}
183 -
184 -func (m *mockValueStore) GetPublicKey(ctx context.Context, p peer.ID) (ci.PubKey, error) {
185 - pk := m.kbook.PubKey(p)
186 - if pk != nil {
187 - return pk, nil
188 - }
189 -
190 - pkkey := routing.KeyForPublicKey(p)
191 - val, err := m.GetValue(ctx, pkkey)
192 - if err != nil {
193 - return nil, err
194 - }
195 -
196 - pk, err = ci.UnmarshalPublicKey(val)
197 - if err != nil {
198 - return nil, err
199 - }
200 -
201 - return pk, m.kbook.AddPubKey(p, pk)
202 -}
203 -
204 -func (m *mockValueStore) PutValue(ctx context.Context, k string, d []byte, opts ...routing.Option) error {
205 - return m.r.PutValue(ctx, k, d, opts...)
206 -}
namesys/namesys.go deleted
-238
@@ -1,238 +0,0 @@
1 -package namesys
2 -
3 -import (
4 - "context"
5 - "fmt"
6 - "os"
7 - "strings"
8 - "time"
9 -
10 - lru "github.com/hashicorp/golang-lru"
11 - cid "github.com/ipfs/go-cid"
12 - ds "github.com/ipfs/go-datastore"
13 - path "github.com/ipfs/go-path"
14 - opts "github.com/ipfs/interface-go-ipfs-core/options/namesys"
15 - isd "github.com/jbenet/go-is-domain"
16 - ci "github.com/libp2p/go-libp2p-core/crypto"
17 - peer "github.com/libp2p/go-libp2p-core/peer"
18 - routing "github.com/libp2p/go-libp2p-core/routing"
19 -)
20 -
21 -// mpns (a multi-protocol NameSystem) implements generic IPFS naming.
22 -//
23 -// Uses several Resolvers:
24 -// (a) IPFS routing naming: SFS-like PKI names.
25 -// (b) dns domains: resolves using links in DNS TXT records
26 -// (c) proquints: interprets string as the raw byte data.
27 -//
28 -// It can only publish to: (a) IPFS routing naming.
29 -//
30 -type mpns struct {
31 - dnsResolver, proquintResolver, ipnsResolver resolver
32 - ipnsPublisher Publisher
33 -
34 - staticMap map[string]path.Path
35 - cache *lru.Cache
36 -}
37 -
38 -// NewNameSystem will construct the IPFS naming system based on Routing
39 -func NewNameSystem(r routing.ValueStore, ds ds.Datastore, cachesize int) NameSystem {
40 - var (
41 - cache *lru.Cache
42 - staticMap map[string]path.Path
43 - )
44 - if cachesize > 0 {
45 - cache, _ = lru.New(cachesize)
46 - }
47 -
48 - // Prewarm namesys cache with static records for deterministic tests and debugging.
49 - // Useful for testing things like DNSLink without real DNS lookup.
50 - // Example:
51 - // IPFS_NS_MAP="dnslink-test.example.com:/ipfs/bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am"
52 - if list := os.Getenv("IPFS_NS_MAP"); list != "" {
53 - staticMap = make(map[string]path.Path)
54 - for _, pair := range strings.Split(list, ",") {
55 - mapping := strings.SplitN(pair, ":", 2)
56 - key := mapping[0]
57 - value := path.FromString(mapping[1])
58 - staticMap[key] = value
59 - }
60 - }
61 -
62 - return &mpns{
63 - dnsResolver: NewDNSResolver(),
64 - proquintResolver: new(ProquintResolver),
65 - ipnsResolver: NewIpnsResolver(r),
66 - ipnsPublisher: NewIpnsPublisher(r, ds),
67 - staticMap: staticMap,
68 - cache: cache,
69 - }
70 -}
71 -
72 -// DefaultResolverCacheTTL defines max ttl of a record placed in namesys cache.
73 -const DefaultResolverCacheTTL = time.Minute
74 -
75 -// Resolve implements Resolver.
76 -func (ns *mpns) Resolve(ctx context.Context, name string, options ...opts.ResolveOpt) (path.Path, error) {
77 - if strings.HasPrefix(name, "/ipfs/") {
78 - return path.ParsePath(name)
79 - }
80 -
81 - if !strings.HasPrefix(name, "/") {
82 - return path.ParsePath("/ipfs/" + name)
83 - }
84 -
85 - return resolve(ctx, ns, name, opts.ProcessOpts(options))
86 -}
87 -
88 -func (ns *mpns) ResolveAsync(ctx context.Context, name string, options ...opts.ResolveOpt) <-chan Result {
89 - if strings.HasPrefix(name, "/ipfs/") {
90 - p, err := path.ParsePath(name)
91 - res := make(chan Result, 1)
92 - res <- Result{p, err}
93 - close(res)
94 - return res
95 - }
96 -
97 - if !strings.HasPrefix(name, "/") {
98 - p, err := path.ParsePath("/ipfs/" + name)
99 - res := make(chan Result, 1)
100 - res <- Result{p, err}
101 - close(res)
102 - return res
103 - }
104 -
105 - return resolveAsync(ctx, ns, name, opts.ProcessOpts(options))
106 -}
107 -
108 -// resolveOnce implements resolver.
109 -func (ns *mpns) resolveOnceAsync(ctx context.Context, name string, options opts.ResolveOpts) <-chan onceResult {
110 - out := make(chan onceResult, 1)
111 -
112 - if !strings.HasPrefix(name, ipnsPrefix) {
113 - name = ipnsPrefix + name
114 - }
115 - segments := strings.SplitN(name, "/", 4)
116 - if len(segments) < 3 || segments[0] != "" {
117 - log.Debugf("invalid name syntax for %s", name)
118 - out <- onceResult{err: ErrResolveFailed}
119 - close(out)
120 - return out
121 - }
122 -
123 - key := segments[2]
124 -
125 - // Resolver selection:
126 - // 1. if it is a PeerID/CID/multihash resolve through "ipns".
127 - // 2. if it is a domain name, resolve through "dns"
128 - // 3. otherwise resolve through the "proquint" resolver
129 -
130 - var res resolver
131 - ipnsKey, err := peer.Decode(key)
132 -
133 - // CIDs in IPNS are expected to have libp2p-key multicodec
134 - // We ease the transition by returning a more meaningful error with a valid CID
135 - if err != nil && err.Error() == "can't convert CID of type protobuf to a peer ID" {
136 - ipnsCid, cidErr := cid.Decode(key)
137 - if cidErr == nil && ipnsCid.Version() == 1 && ipnsCid.Type() != cid.Libp2pKey {
138 - fixedCid := cid.NewCidV1(cid.Libp2pKey, ipnsCid.Hash()).String()
139 - codecErr := fmt.Errorf("peer ID represented as CIDv1 require libp2p-key multicodec: retry with /ipns/%s", fixedCid)
140 - log.Debugf("RoutingResolver: could not convert public key hash %s to peer ID: %s\n", key, codecErr)
141 - out <- onceResult{err: codecErr}
142 - close(out)
143 - return out
144 - }
145 - }
146 -
147 - cacheKey := key
148 - if err == nil {
149 - cacheKey = string(ipnsKey)
150 - }
151 -
152 - if p, ok := ns.cacheGet(cacheKey); ok {
153 - var err error
154 - if len(segments) > 3 {
155 - p, err = path.FromSegments("", strings.TrimRight(p.String(), "/"), segments[3])
156 - }
157 -
158 - out <- onceResult{value: p, err: err}
159 - close(out)
160 - return out
161 - }
162 -
163 - if err == nil {
164 - res = ns.ipnsResolver
165 - } else if isd.IsDomain(key) {
166 - res = ns.dnsResolver
167 - } else {
168 - res = ns.proquintResolver
169 - }
170 -
171 - resCh := res.resolveOnceAsync(ctx, key, options)
172 - var best onceResult
173 - go func() {
174 - defer close(out)
175 - for {
176 - select {
177 - case res, ok := <-resCh:
178 - if !ok {
179 - if best != (onceResult{}) {
180 - ns.cacheSet(cacheKey, best.value, best.ttl)
181 - }
182 - return
183 - }
184 - if res.err == nil {
185 - best = res
186 - }
187 - p := res.value
188 - err := res.err
189 - ttl := res.ttl
190 -
191 - // Attach rest of the path
192 - if len(segments) > 3 {
193 - p, err = path.FromSegments("", strings.TrimRight(p.String(), "/"), segments[3])
194 - }
195 -
196 - emitOnceResult(ctx, out, onceResult{value: p, ttl: ttl, err: err})
197 - case <-ctx.Done():
198 - return
199 - }
200 - }
201 - }()
202 -
203 - return out
204 -}
205 -
206 -func emitOnceResult(ctx context.Context, outCh chan<- onceResult, r onceResult) {
207 - select {
208 - case outCh <- r:
209 - case <-ctx.Done():
210 - }
211 -}
212 -
213 -// Publish implements Publisher
214 -func (ns *mpns) Publish(ctx context.Context, name ci.PrivKey, value path.Path) error {
215 - return ns.PublishWithEOL(ctx, name, value, time.Now().Add(DefaultRecordEOL))
216 -}
217 -
218 -func (ns *mpns) PublishWithEOL(ctx context.Context, name ci.PrivKey, value path.Path, eol time.Time) error {
219 - id, err := peer.IDFromPrivateKey(name)
220 - if err != nil {
221 - return err
222 - }
223 - if err := ns.ipnsPublisher.PublishWithEOL(ctx, name, value, eol); err != nil {
224 - // Invalidate the cache. Publishing may _partially_ succeed but
225 - // still return an error.
226 - ns.cacheInvalidate(string(id))
227 - return err
228 - }
229 - ttl := DefaultResolverCacheTTL
230 - if setTTL, ok := checkCtxTTL(ctx); ok {
231 - ttl = setTTL
232 - }
233 - if ttEol := time.Until(eol); ttEol < ttl {
234 - ttl = ttEol
235 - }
236 - ns.cacheSet(string(id), value, ttl)
237 - return nil
238 -}
namesys/namesys_test.go deleted
-169
@@ -1,169 +0,0 @@
1 -package namesys
2 -
3 -import (
4 - "context"
5 - "fmt"
6 - "testing"
7 - "time"
8 -
9 - ds "github.com/ipfs/go-datastore"
10 - dssync "github.com/ipfs/go-datastore/sync"
11 - offroute "github.com/ipfs/go-ipfs-routing/offline"
12 - ipns "github.com/ipfs/go-ipns"
13 - path "github.com/ipfs/go-path"
14 - unixfs "github.com/ipfs/go-unixfs"
15 - opts "github.com/ipfs/interface-go-ipfs-core/options/namesys"
16 - ci "github.com/libp2p/go-libp2p-core/crypto"
17 - peer "github.com/libp2p/go-libp2p-core/peer"
18 - pstoremem "github.com/libp2p/go-libp2p-peerstore/pstoremem"
19 - record "github.com/libp2p/go-libp2p-record"
20 -)
21 -
22 -type mockResolver struct {
23 - entries map[string]string
24 -}
25 -
26 -func testResolution(t *testing.T, resolver Resolver, name string, depth uint, expected string, expError error) {
27 - t.Helper()
28 - p, err := resolver.Resolve(context.Background(), name, opts.Depth(depth))
29 - if err != expError {
30 - t.Fatal(fmt.Errorf(
31 - "expected %s with a depth of %d to have a '%s' error, but got '%s'",
32 - name, depth, expError, err))
33 - }
34 - if p.String() != expected {
35 - t.Fatal(fmt.Errorf(
36 - "%s with depth %d resolved to %s != %s",
37 - name, depth, p.String(), expected))
38 - }
39 -}
40 -
41 -func (r *mockResolver) resolveOnceAsync(ctx context.Context, name string, options opts.ResolveOpts) <-chan onceResult {
42 - p, err := path.ParsePath(r.entries[name])
43 - out := make(chan onceResult, 1)
44 - out <- onceResult{value: p, err: err}
45 - close(out)
46 - return out
47 -}
48 -
49 -func mockResolverOne() *mockResolver {
50 - return &mockResolver{
51 - entries: map[string]string{
52 - "QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy": "/ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj",
53 - "QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n": "/ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy",
54 - "QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD": "/ipns/ipfs.io",
55 - "QmQ4QZh8nrsczdUEwTyfBope4THUhqxqc1fx6qYhhzZQei": "/ipfs/QmP3ouCnU8NNLsW6261pAx2pNLV2E4dQoisB1sgda12Act",
56 - "12D3KooWFB51PRY9BxcXSH6khFXw1BZeszeLDy7C8GciskqCTZn5": "/ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", // ed25519+identity multihash
57 - "bafzbeickencdqw37dpz3ha36ewrh4undfjt2do52chtcky4rxkj447qhdm": "/ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", // cidv1 in base32 with libp2p-key multicodec
58 - },
59 - }
60 -}
61 -
62 -func mockResolverTwo() *mockResolver {
63 - return &mockResolver{
64 - entries: map[string]string{
65 - "ipfs.io": "/ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n",
66 - },
67 - }
68 -}
69 -
70 -func TestNamesysResolution(t *testing.T) {
71 - r := &mpns{
72 - ipnsResolver: mockResolverOne(),
73 - dnsResolver: mockResolverTwo(),
74 - }
75 -
76 - testResolution(t, r, "Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj", opts.DefaultDepthLimit, "/ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj", nil)
77 - testResolution(t, r, "/ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy", opts.DefaultDepthLimit, "/ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj", nil)
78 - testResolution(t, r, "/ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", opts.DefaultDepthLimit, "/ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj", nil)
79 - testResolution(t, r, "/ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", 1, "/ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy", ErrResolveRecursion)
80 - testResolution(t, r, "/ipns/ipfs.io", opts.DefaultDepthLimit, "/ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj", nil)
81 - testResolution(t, r, "/ipns/ipfs.io", 1, "/ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", ErrResolveRecursion)
82 - testResolution(t, r, "/ipns/ipfs.io", 2, "/ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy", ErrResolveRecursion)
83 - testResolution(t, r, "/ipns/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", opts.DefaultDepthLimit, "/ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj", nil)
84 - testResolution(t, r, "/ipns/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", 1, "/ipns/ipfs.io", ErrResolveRecursion)
85 - testResolution(t, r, "/ipns/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", 2, "/ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", ErrResolveRecursion)
86 - testResolution(t, r, "/ipns/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", 3, "/ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy", ErrResolveRecursion)
87 - testResolution(t, r, "/ipns/12D3KooWFB51PRY9BxcXSH6khFXw1BZeszeLDy7C8GciskqCTZn5", 1, "/ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", ErrResolveRecursion)
88 - testResolution(t, r, "/ipns/bafzbeickencdqw37dpz3ha36ewrh4undfjt2do52chtcky4rxkj447qhdm", 1, "/ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", ErrResolveRecursion)
89 -}
90 -
91 -func TestPublishWithCache0(t *testing.T) {
92 - dst := dssync.MutexWrap(ds.NewMapDatastore())
93 - priv, _, err := ci.GenerateKeyPair(ci.RSA, 2048)
94 - if err != nil {
95 - t.Fatal(err)
96 - }
97 - ps := pstoremem.NewPeerstore()
98 - pid, err := peer.IDFromPrivateKey(priv)
99 - if err != nil {
100 - t.Fatal(err)
101 - }
102 - err = ps.AddPrivKey(pid, priv)
103 - if err != nil {
104 - t.Fatal(err)
105 - }
106 -
107 - routing := offroute.NewOfflineRouter(dst, record.NamespacedValidator{
108 - "ipns": ipns.Validator{KeyBook: ps},
109 - "pk": record.PublicKeyValidator{},
110 - })
111 -
112 - nsys := NewNameSystem(routing, dst, 0)
113 - p, err := path.ParsePath(unixfs.EmptyDirNode().Cid().String())
114 - if err != nil {
115 - t.Fatal(err)
116 - }
117 - err = nsys.Publish(context.Background(), priv, p)
118 - if err != nil {
119 - t.Fatal(err)
120 - }
121 -}
122 -
123 -func TestPublishWithTTL(t *testing.T) {
124 - dst := dssync.MutexWrap(ds.NewMapDatastore())
125 - priv, _, err := ci.GenerateKeyPair(ci.RSA, 2048)
126 - if err != nil {
127 - t.Fatal(err)
128 - }
129 - ps := pstoremem.NewPeerstore()
130 - pid, err := peer.IDFromPrivateKey(priv)
131 - if err != nil {
132 - t.Fatal(err)
133 - }
134 - err = ps.AddPrivKey(pid, priv)
135 - if err != nil {
136 - t.Fatal(err)
137 - }
138 -
139 - routing := offroute.NewOfflineRouter(dst, record.NamespacedValidator{
140 - "ipns": ipns.Validator{KeyBook: ps},
141 - "pk": record.PublicKeyValidator{},
142 - })
143 -
144 - nsys := NewNameSystem(routing, dst, 128)
145 - p, err := path.ParsePath(unixfs.EmptyDirNode().Cid().String())
146 - if err != nil {
147 - t.Fatal(err)
148 - }
149 -
150 - ttl := 1 * time.Second
151 - eol := time.Now().Add(2 * time.Second)
152 -
153 - ctx := context.WithValue(context.Background(), "ipns-publish-ttl", ttl)
154 - err = nsys.Publish(ctx, priv, p)
155 - if err != nil {
156 - t.Fatal(err)
157 - }
158 - ientry, ok := nsys.(*mpns).cache.Get(string(pid))
159 - if !ok {
160 - t.Fatal("cache get failed")
161 - }
162 - entry, ok := ientry.(cacheEntry)
163 - if !ok {
164 - t.Fatal("bad cache item returned")
165 - }
166 - if entry.eol.Sub(eol) > 10*time.Millisecond {
167 - t.Fatalf("bad cache ttl: expected %s, got %s", eol, entry.eol)
168 - }
169 -}
namesys/proquint.go deleted
-32
@@ -1,32 +0,0 @@
1 -package namesys
2 -
3 -import (
4 - "context"
5 - "errors"
6 -
7 - proquint "github.com/bren2010/proquint"
8 - path "github.com/ipfs/go-path"
9 - opts "github.com/ipfs/interface-go-ipfs-core/options/namesys"
10 -)
11 -
12 -type ProquintResolver struct{}
13 -
14 -// Resolve implements Resolver.
15 -func (r *ProquintResolver) Resolve(ctx context.Context, name string, options ...opts.ResolveOpt) (path.Path, error) {
16 - return resolve(ctx, r, name, opts.ProcessOpts(options))
17 -}
18 -
19 -// resolveOnce implements resolver. Decodes the proquint string.
20 -func (r *ProquintResolver) resolveOnceAsync(ctx context.Context, name string, options opts.ResolveOpts) <-chan onceResult {
21 - out := make(chan onceResult, 1)
22 - defer close(out)
23 -
24 - ok, err := proquint.IsProquint(name)
25 - if err != nil || !ok {
26 - out <- onceResult{err: errors.New("not a valid proquint string")}
27 - return out
28 - }
29 - // Return a 0 TTL as caching this result is pointless.
30 - out <- onceResult{value: path.FromString(string(proquint.Decode(name)))}
31 - return out
32 -}
namesys/publisher.go deleted
-309
@@ -1,309 +0,0 @@
1 -package namesys
2 -
3 -import (
4 - "context"
5 - "strings"
6 - "sync"
7 - "time"
8 -
9 - proto "github.com/gogo/protobuf/proto"
10 - ds "github.com/ipfs/go-datastore"
11 - dsquery "github.com/ipfs/go-datastore/query"
12 - pin "github.com/ipfs/go-ipfs-pinner"
13 - ipns "github.com/ipfs/go-ipns"
14 - pb "github.com/ipfs/go-ipns/pb"
15 - path "github.com/ipfs/go-path"
16 - ft "github.com/ipfs/go-unixfs"
17 - ci "github.com/libp2p/go-libp2p-core/crypto"
18 - peer "github.com/libp2p/go-libp2p-core/peer"
19 - routing "github.com/libp2p/go-libp2p-core/routing"
20 - base32 "github.com/whyrusleeping/base32"
21 -)
22 -
23 -const ipnsPrefix = "/ipns/"
24 -
25 -const DefaultRecordEOL = 24 * time.Hour
26 -
27 -// IpnsPublisher is capable of publishing and resolving names to the IPFS
28 -// routing system.
29 -type IpnsPublisher struct {
30 - routing routing.ValueStore
31 - ds ds.Datastore
32 -
33 - // Used to ensure we assign IPNS records *sequential* sequence numbers.
34 - mu sync.Mutex
35 -}
36 -
37 -// NewIpnsPublisher constructs a publisher for the IPFS Routing name system.
38 -func NewIpnsPublisher(route routing.ValueStore, ds ds.Datastore) *IpnsPublisher {
39 - if ds == nil {
40 - panic("nil datastore")
41 - }
42 - return &IpnsPublisher{routing: route, ds: ds}
43 -}
44 -
45 -// Publish implements Publisher. Accepts a keypair and a value,
46 -// and publishes it out to the routing system
47 -func (p *IpnsPublisher) Publish(ctx context.Context, k ci.PrivKey, value path.Path) error {
48 - log.Debugf("Publish %s", value)
49 - return p.PublishWithEOL(ctx, k, value, time.Now().Add(DefaultRecordEOL))
50 -}
51 -
52 -func IpnsDsKey(id peer.ID) ds.Key {
53 - return ds.NewKey("/ipns/" + base32.RawStdEncoding.EncodeToString([]byte(id)))
54 -}
55 -
56 -// PublishedNames returns the latest IPNS records published by this node and
57 -// their expiration times.
58 -//
59 -// This method will not search the routing system for records published by other
60 -// nodes.
61 -func (p *IpnsPublisher) ListPublished(ctx context.Context) (map[peer.ID]*pb.IpnsEntry, error) {
62 - query, err := p.ds.Query(dsquery.Query{
63 - Prefix: ipnsPrefix,
64 - })
65 - if err != nil {
66 - return nil, err
67 - }
68 - defer query.Close()
69 -
70 - records := make(map[peer.ID]*pb.IpnsEntry)
71 - for {
72 - select {
73 - case result, ok := <-query.Next():
74 - if !ok {
75 - return records, nil
76 - }
77 - if result.Error != nil {
78 - return nil, result.Error
79 - }
80 - e := new(pb.IpnsEntry)
81 - if err := proto.Unmarshal(result.Value, e); err != nil {
82 - // Might as well return what we can.
83 - log.Error("found an invalid IPNS entry:", err)
84 - continue
85 - }
86 - if !strings.HasPrefix(result.Key, ipnsPrefix) {
87 - log.Errorf("datastore query for keys with prefix %s returned a key: %s", ipnsPrefix, result.Key)
88 - continue
89 - }
90 - k := result.Key[len(ipnsPrefix):]
91 - pid, err := base32.RawStdEncoding.DecodeString(k)
92 - if err != nil {
93 - log.Errorf("ipns ds key invalid: %s", result.Key)
94 - continue
95 - }
96 - records[peer.ID(pid)] = e
97 - case <-ctx.Done():
98 - return nil, ctx.Err()
99 - }
100 - }
101 -}
102 -
103 -// GetPublished returns the record this node has published corresponding to the
104 -// given peer ID.
105 -//
106 -// If `checkRouting` is true and we have no existing record, this method will
107 -// check the routing system for any existing records.
108 -func (p *IpnsPublisher) GetPublished(ctx context.Context, id peer.ID, checkRouting bool) (*pb.IpnsEntry, error) {
109 - ctx, cancel := context.WithTimeout(ctx, time.Second*30)
110 - defer cancel()
111 -
112 - value, err := p.ds.Get(IpnsDsKey(id))
113 - switch err {
114 - case nil:
115 - case ds.ErrNotFound:
116 - if !checkRouting {
117 - return nil, nil
118 - }
119 - ipnskey := ipns.RecordKey(id)
120 - value, err = p.routing.GetValue(ctx, ipnskey)
121 - if err != nil {
122 - // Not found or other network issue. Can't really do
123 - // anything about this case.
124 - if err != routing.ErrNotFound {
125 - log.Debugf("error when determining the last published IPNS record for %s: %s", id, err)
126 - }
127 -
128 - return nil, nil
129 - }
130 - default:
131 - return nil, err
132 - }
133 - e := new(pb.IpnsEntry)
134 - if err := proto.Unmarshal(value, e); err != nil {
135 - return nil, err
136 - }
137 - return e, nil
138 -}
139 -
140 -func (p *IpnsPublisher) updateRecord(ctx context.Context, k ci.PrivKey, value path.Path, eol time.Time) (*pb.IpnsEntry, error) {
141 - id, err := peer.IDFromPrivateKey(k)
142 - if err != nil {
143 - return nil, err
144 - }
145 -
146 - p.mu.Lock()
147 - defer p.mu.Unlock()
148 -
149 - // get previous records sequence number
150 - rec, err := p.GetPublished(ctx, id, true)
151 - if err != nil {
152 - return nil, err
153 - }
154 -
155 - seqno := rec.GetSequence() // returns 0 if rec is nil
156 - if rec != nil && value != path.Path(rec.GetValue()) {
157 - // Don't bother incrementing the sequence number unless the
158 - // value changes.
159 - seqno++
160 - }
161 -
162 - // Create record
163 - entry, err := ipns.Create(k, []byte(value), seqno, eol)
164 - if err != nil {
165 - return nil, err
166 - }
167 -
168 - // Set the TTL
169 - // TODO: Make this less hacky.
170 - ttl, ok := checkCtxTTL(ctx)
171 - if ok {
172 - entry.Ttl = proto.Uint64(uint64(ttl.Nanoseconds()))
173 - }
174 -
175 - data, err := proto.Marshal(entry)
176 - if err != nil {
177 - return nil, err
178 - }
179 -
180 - // Put the new record.
181 - key := IpnsDsKey(id)
182 - if err := p.ds.Put(key, data); err != nil {
183 - return nil, err
184 - }
185 - if err := p.ds.Sync(key); err != nil {
186 - return nil, err
187 - }
188 - return entry, nil
189 -}
190 -
191 -// PublishWithEOL is a temporary stand in for the ipns records implementation
192 -// see here for more details: https://github.com/ipfs/specs/tree/master/records
193 -func (p *IpnsPublisher) PublishWithEOL(ctx context.Context, k ci.PrivKey, value path.Path, eol time.Time) error {
194 - record, err := p.updateRecord(ctx, k, value, eol)
195 - if err != nil {
196 - return err
197 - }
198 -
199 - return PutRecordToRouting(ctx, p.routing, k.GetPublic(), record)
200 -}
201 -
202 -// setting the TTL on published records is an experimental feature.
203 -// as such, i'm using the context to wire it through to avoid changing too
204 -// much code along the way.
205 -func checkCtxTTL(ctx context.Context) (time.Duration, bool) {
206 - v := ctx.Value("ipns-publish-ttl")
207 - if v == nil {
208 - return 0, false
209 - }
210 -
211 - d, ok := v.(time.Duration)
212 - return d, ok
213 -}
214 -
215 -func PutRecordToRouting(ctx context.Context, r routing.ValueStore, k ci.PubKey, entry *pb.IpnsEntry) error {
216 - ctx, cancel := context.WithCancel(ctx)
217 - defer cancel()
218 -
219 - errs := make(chan error, 2) // At most two errors (IPNS, and public key)
220 -
221 - if err := ipns.EmbedPublicKey(k, entry); err != nil {
222 - return err
223 - }
224 -
225 - id, err := peer.IDFromPublicKey(k)
226 - if err != nil {
227 - return err
228 - }
229 -
230 - go func() {
231 - errs <- PublishEntry(ctx, r, ipns.RecordKey(id), entry)
232 - }()
233 -
234 - // Publish the public key if a public key cannot be extracted from the ID
235 - // TODO: once v0.4.16 is widespread enough, we can stop doing this
236 - // and at that point we can even deprecate the /pk/ namespace in the dht
237 - //
238 - // NOTE: This check actually checks if the public key has been embedded
239 - // in the IPNS entry. This check is sufficient because we embed the
240 - // public key in the IPNS entry if it can't be extracted from the ID.
241 - if entry.PubKey != nil {
242 - go func() {
243 - errs <- PublishPublicKey(ctx, r, PkKeyForID(id), k)
244 - }()
245 -
246 - if err := waitOnErrChan(ctx, errs); err != nil {
247 - return err
248 - }
249 - }
250 -
251 - return waitOnErrChan(ctx, errs)
252 -}
253 -
254 -func waitOnErrChan(ctx context.Context, errs chan error) error {
255 - select {
256 - case err := <-errs:
257 - return err
258 - case <-ctx.Done():
259 - return ctx.Err()
260 - }
261 -}
262 -
263 -func PublishPublicKey(ctx context.Context, r routing.ValueStore, k string, pubk ci.PubKey) error {
264 - log.Debugf("Storing pubkey at: %s", k)
265 - pkbytes, err := pubk.Bytes()
266 - if err != nil {
267 - return err
268 - }
269 -
270 - // Store associated public key
271 - return r.PutValue(ctx, k, pkbytes)
272 -}
273 -
274 -func PublishEntry(ctx context.Context, r routing.ValueStore, ipnskey string, rec *pb.IpnsEntry) error {
275 - data, err := proto.Marshal(rec)
276 - if err != nil {
277 - return err
278 - }
279 -
280 - log.Debugf("Storing ipns entry at: %s", ipnskey)
281 - // Store ipns entry at "/ipns/"+h(pubkey)
282 - return r.PutValue(ctx, ipnskey, data)
283 -}
284 -
285 -// InitializeKeyspace sets the ipns record for the given key to
286 -// point to an empty directory.
287 -// TODO: this doesnt feel like it belongs here
288 -func InitializeKeyspace(ctx context.Context, pub Publisher, pins pin.Pinner, key ci.PrivKey) error {
289 - emptyDir := ft.EmptyDirNode()
290 -
291 - // pin recursively because this might already be pinned
292 - // and doing a direct pin would throw an error in that case
293 - err := pins.Pin(ctx, emptyDir, true)
294 - if err != nil {
295 - return err
296 - }
297 -
298 - err = pins.Flush(ctx)
299 - if err != nil {
300 - return err
301 - }
302 -
303 - return pub.Publish(ctx, key, path.FromCid(emptyDir.Cid()))
304 -}
305 -
306 -// PkKeyForID returns the public key routing key for the given peer ID.
307 -func PkKeyForID(id peer.ID) string {
308 - return "/pk/" + string(id)
309 -}
namesys/publisher_test.go deleted
-155
@@ -1,155 +0,0 @@
1 -package namesys
2 -
3 -import (
4 - "context"
5 - "crypto/rand"
6 - "github.com/ipfs/go-path"
7 - "testing"
8 - "time"
9 -
10 - ds "github.com/ipfs/go-datastore"
11 - dssync "github.com/ipfs/go-datastore/sync"
12 - dshelp "github.com/ipfs/go-ipfs-ds-help"
13 - mockrouting "github.com/ipfs/go-ipfs-routing/mock"
14 - ipns "github.com/ipfs/go-ipns"
15 - ci "github.com/libp2p/go-libp2p-core/crypto"
16 - peer "github.com/libp2p/go-libp2p-core/peer"
17 - testutil "github.com/libp2p/go-libp2p-testing/net"
18 - ma "github.com/multiformats/go-multiaddr"
19 -)
20 -
21 -type identity struct {
22 - testutil.PeerNetParams
23 -}
24 -
25 -func (p *identity) ID() peer.ID {
26 - return p.PeerNetParams.ID
27 -}
28 -
29 -func (p *identity) Address() ma.Multiaddr {
30 - return p.Addr
31 -}
32 -
33 -func (p *identity) PrivateKey() ci.PrivKey {
34 - return p.PrivKey
35 -}
36 -
37 -func (p *identity) PublicKey() ci.PubKey {
38 - return p.PubKey
39 -}
40 -
41 -func testNamekeyPublisher(t *testing.T, keyType int, expectedErr error, expectedExistence bool) {
42 - // Context
43 - ctx := context.Background()
44 -
45 - // Private key
46 - privKey, pubKey, err := ci.GenerateKeyPairWithReader(keyType, 2048, rand.Reader)
47 - if err != nil {
48 - t.Fatal(err)
49 - }
50 -
51 - // ID
52 - id, err := peer.IDFromPublicKey(pubKey)
53 - if err != nil {
54 - t.Fatal(err)
55 - }
56 -
57 - // Value
58 - value := []byte("ipfs/TESTING")
59 -
60 - // Seqnum
61 - seqnum := uint64(0)
62 -
63 - // Eol
64 - eol := time.Now().Add(24 * time.Hour)
65 -
66 - // Routing value store
67 - p := testutil.PeerNetParams{
68 - ID: id,
69 - PrivKey: privKey,
70 - PubKey: pubKey,
71 - Addr: testutil.ZeroLocalTCPAddress,
72 - }
73 -
74 - dstore := dssync.MutexWrap(ds.NewMapDatastore())
75 - serv := mockrouting.NewServer()
76 - r := serv.ClientWithDatastore(context.Background(), &identity{p}, dstore)
77 -
78 - entry, err := ipns.Create(privKey, value, seqnum, eol)
79 - if err != nil {
80 - t.Fatal(err)
81 - }
82 -
83 - err = PutRecordToRouting(ctx, r, pubKey, entry)
84 - if err != nil {
85 - t.Fatal(err)
86 - }
87 -
88 - // Check for namekey existence in value store
89 - namekey := PkKeyForID(id)
90 - _, err = r.GetValue(ctx, namekey)
91 - if err != expectedErr {
92 - t.Fatal(err)
93 - }
94 -
95 - // Also check datastore for completeness
96 - key := dshelp.NewKeyFromBinary([]byte(namekey))
97 - exists, err := dstore.Has(key)
98 - if err != nil {
99 - t.Fatal(err)
100 - }
101 -
102 - if exists != expectedExistence {
103 - t.Fatal("Unexpected key existence in datastore")
104 - }
105 -}
106 -
107 -func TestRSAPublisher(t *testing.T) {
108 - testNamekeyPublisher(t, ci.RSA, nil, true)
109 -}
110 -
111 -func TestEd22519Publisher(t *testing.T) {
112 - testNamekeyPublisher(t, ci.Ed25519, ds.ErrNotFound, false)
113 -}
114 -
115 -func TestAsyncDS(t *testing.T) {
116 - ctx, cancel := context.WithCancel(context.Background())
117 - defer cancel()
118 -
119 - rt := mockrouting.NewServer().Client(testutil.RandIdentityOrFatal(t))
120 - ds := &checkSyncDS{
121 - Datastore: ds.NewMapDatastore(),
122 - syncKeys: make(map[ds.Key]struct{}),
123 - }
124 - publisher := NewIpnsPublisher(rt, ds)
125 -
126 - ipnsFakeID := testutil.RandIdentityOrFatal(t)
127 - ipnsVal, err := path.ParsePath("/ipns/foo.bar")
128 - if err != nil {
129 - t.Fatal(err)
130 - }
131 -
132 - if err := publisher.Publish(ctx, ipnsFakeID.PrivateKey(), ipnsVal); err != nil {
133 - t.Fatal(err)
134 - }
135 -
136 - ipnsKey := IpnsDsKey(ipnsFakeID.ID())
137 -
138 - for k := range ds.syncKeys {
139 - if k.IsAncestorOf(ipnsKey) || k.Equal(ipnsKey) {
140 - return
141 - }
142 - }
143 -
144 - t.Fatal("ipns key not synced")
145 -}
146 -
147 -type checkSyncDS struct {
148 - ds.Datastore
149 - syncKeys map[ds.Key]struct{}
150 -}
151 -
152 -func (d *checkSyncDS) Sync(prefix ds.Key) error {
153 - d.syncKeys[prefix] = struct{}{}
154 - return d.Datastore.Sync(prefix)
155 -}
namesys/republisher/repub.go deleted
-168
@@ -1,168 +0,0 @@
1 -package republisher
2 -
3 -import (
4 - "context"
5 - "errors"
6 - "time"
7 -
8 - keystore "github.com/ipfs/go-ipfs/keystore"
9 - namesys "github.com/ipfs/go-ipfs/namesys"
10 - path "github.com/ipfs/go-path"
11 -
12 - proto "github.com/gogo/protobuf/proto"
13 - ds "github.com/ipfs/go-datastore"
14 - ipns "github.com/ipfs/go-ipns"
15 - pb "github.com/ipfs/go-ipns/pb"
16 - logging "github.com/ipfs/go-log"
17 - goprocess "github.com/jbenet/goprocess"
18 - gpctx "github.com/jbenet/goprocess/context"
19 - ic "github.com/libp2p/go-libp2p-core/crypto"
20 - peer "github.com/libp2p/go-libp2p-core/peer"
21 -)
22 -
23 -var errNoEntry = errors.New("no previous entry")
24 -
25 -var log = logging.Logger("ipns-repub")
26 -
27 -// DefaultRebroadcastInterval is the default interval at which we rebroadcast IPNS records
28 -var DefaultRebroadcastInterval = time.Hour * 4
29 -
30 -// InitialRebroadcastDelay is the delay before first broadcasting IPNS records on start
31 -var InitialRebroadcastDelay = time.Minute * 1
32 -
33 -// FailureRetryInterval is the interval at which we retry IPNS records broadcasts (when they fail)
34 -var FailureRetryInterval = time.Minute * 5
35 -
36 -// DefaultRecordLifetime is the default lifetime for IPNS records
37 -const DefaultRecordLifetime = time.Hour * 24
38 -
39 -type Republisher struct {
40 - ns namesys.Publisher
41 - ds ds.Datastore
42 - self ic.PrivKey
43 - ks keystore.Keystore
44 -
45 - Interval time.Duration
46 -
47 - // how long records that are republished should be valid for
48 - RecordLifetime time.Duration
49 -}
50 -
51 -// NewRepublisher creates a new Republisher
52 -func NewRepublisher(ns namesys.Publisher, ds ds.Datastore, self ic.PrivKey, ks keystore.Keystore) *Republisher {
53 - return &Republisher{
54 - ns: ns,
55 - ds: ds,
56 - self: self,
57 - ks: ks,
58 - Interval: DefaultRebroadcastInterval,
59 - RecordLifetime: DefaultRecordLifetime,
60 - }
61 -}
62 -
63 -func (rp *Republisher) Run(proc goprocess.Process) {
64 - timer := time.NewTimer(InitialRebroadcastDelay)
65 - defer timer.Stop()
66 - if rp.Interval < InitialRebroadcastDelay {
67 - timer.Reset(rp.Interval)
68 - }
69 -
70 - for {
71 - select {
72 - case <-timer.C:
73 - timer.Reset(rp.Interval)
74 - err := rp.republishEntries(proc)
75 - if err != nil {
76 - log.Info("republisher failed to republish: ", err)
77 - if FailureRetryInterval < rp.Interval {
78 - timer.Reset(FailureRetryInterval)
79 - }
80 - }
81 - case <-proc.Closing():
82 - return
83 - }
84 - }
85 -}
86 -
87 -func (rp *Republisher) republishEntries(p goprocess.Process) error {
88 - ctx, cancel := context.WithCancel(gpctx.OnClosingContext(p))
89 - defer cancel()
90 -
91 - // TODO: Use rp.ipns.ListPublished(). We can't currently *do* that
92 - // because:
93 - // 1. There's no way to get keys from the keystore by ID.
94 - // 2. We don't actually have access to the IPNS publisher.
95 - err := rp.republishEntry(ctx, rp.self)
96 - if err != nil {
97 - return err
98 - }
99 -
100 - if rp.ks != nil {
101 - keyNames, err := rp.ks.List()
102 - if err != nil {
103 - return err
104 - }
105 - for _, name := range keyNames {
106 - priv, err := rp.ks.Get(name)
107 - if err != nil {
108 - return err
109 - }
110 - err = rp.republishEntry(ctx, priv)
111 - if err != nil {
112 - return err
113 - }
114 -
115 - }
116 - }
117 -
118 - return nil
119 -}
120 -
121 -func (rp *Republisher) republishEntry(ctx context.Context, priv ic.PrivKey) error {
122 - id, err := peer.IDFromPrivateKey(priv)
123 - if err != nil {
124 - return err
125 - }
126 -
127 - log.Debugf("republishing ipns entry for %s", id)
128 -
129 - // Look for it locally only
130 - e, err := rp.getLastIPNSEntry(id)
131 - if err != nil {
132 - if err == errNoEntry {
133 - return nil
134 - }
135 - return err
136 - }
137 -
138 - p := path.Path(e.GetValue())
139 - prevEol, err := ipns.GetEOL(e)
140 - if err != nil {
141 - return err
142 - }
143 -
144 - // update record with same sequence number
145 - eol := time.Now().Add(rp.RecordLifetime)
146 - if prevEol.After(eol) {
147 - eol = prevEol
148 - }
149 - return rp.ns.PublishWithEOL(ctx, priv, p, eol)
150 -}
151 -
152 -func (rp *Republisher) getLastIPNSEntry(id peer.ID) (*pb.IpnsEntry, error) {
153 - // Look for it locally only
154 - val, err := rp.ds.Get(namesys.IpnsDsKey(id))
155 - switch err {
156 - case nil:
157 - case ds.ErrNotFound:
158 - return nil, errNoEntry
159 - default:
160 - return nil, err
161 - }
162 -
163 - e := new(pb.IpnsEntry)
164 - if err := proto.Unmarshal(val, e); err != nil {
165 - return nil, err
166 - }
167 - return e, nil
168 -}
namesys/republisher/repub_test.go deleted
-245
@@ -1,245 +0,0 @@
1 -package republisher_test
2 -
3 -import (
4 - "context"
5 - "errors"
6 - "testing"
7 - "time"
8 -
9 - "github.com/gogo/protobuf/proto"
10 -
11 - goprocess "github.com/jbenet/goprocess"
12 - peer "github.com/libp2p/go-libp2p-core/peer"
13 - mocknet "github.com/libp2p/go-libp2p/p2p/net/mock"
14 -
15 - ds "github.com/ipfs/go-datastore"
16 - "github.com/ipfs/go-ipns"
17 - "github.com/ipfs/go-ipns/pb"
18 - path "github.com/ipfs/go-path"
19 -
20 - "github.com/ipfs/go-ipfs/core"
21 - "github.com/ipfs/go-ipfs/core/bootstrap"
22 - mock "github.com/ipfs/go-ipfs/core/mock"
23 - namesys "github.com/ipfs/go-ipfs/namesys"
24 - . "github.com/ipfs/go-ipfs/namesys/republisher"
25 -)
26 -
27 -func TestRepublish(t *testing.T) {
28 - // set cache life to zero for testing low-period repubs
29 -
30 - ctx, cancel := context.WithCancel(context.Background())
31 - defer cancel()
32 -
33 - // create network
34 - mn := mocknet.New(ctx)
35 -
36 - var nodes []*core.IpfsNode
37 - for i := 0; i < 10; i++ {
38 - nd, err := mock.MockPublicNode(ctx, mn)
39 - if err != nil {
40 - t.Fatal(err)
41 - }
42 -
43 - nd.Namesys = namesys.NewNameSystem(nd.Routing, nd.Repo.Datastore(), 0)
44 -
45 - nodes = append(nodes, nd)
46 - }
47 -
48 - if err := mn.LinkAll(); err != nil {
49 - t.Fatal(err)
50 - }
51 -
52 - bsinf := bootstrap.BootstrapConfigWithPeers(
53 - []peer.AddrInfo{
54 - nodes[0].Peerstore.PeerInfo(nodes[0].Identity),
55 - },
56 - )
57 -
58 - for _, n := range nodes[1:] {
59 - if err := n.Bootstrap(bsinf); err != nil {
60 - t.Fatal(err)
61 - }
62 - }
63 -
64 - // have one node publish a record that is valid for 1 second
65 - publisher := nodes[3]
66 - p := path.FromString("/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn") // does not need to be valid
67 - rp := namesys.NewIpnsPublisher(publisher.Routing, publisher.Repo.Datastore())
68 - name := "/ipns/" + publisher.Identity.Pretty()
69 -
70 - // Retry in case the record expires before we can fetch it. This can
71 - // happen when running the test on a slow machine.
72 - var expiration time.Time
73 - timeout := time.Second
74 - for {
75 - expiration = time.Now().Add(time.Second)
76 - err := rp.PublishWithEOL(ctx, publisher.PrivateKey, p, expiration)
77 - if err != nil {
78 - t.Fatal(err)
79 - }
80 -
81 - err = verifyResolution(nodes, name, p)
82 - if err == nil {
83 - break
84 - }
85 -
86 - if time.Now().After(expiration) {
87 - timeout *= 2
88 - continue
89 - }
90 - t.Fatal(err)
91 - }
92 -
93 - // Now wait a second, the records will be invalid and we should fail to resolve
94 - time.Sleep(timeout)
95 - if err := verifyResolutionFails(nodes, name); err != nil {
96 - t.Fatal(err)
97 - }
98 -
99 - // The republishers that are contained within the nodes have their timeout set
100 - // to 12 hours. Instead of trying to tweak those, we're just going to pretend
101 - // they don't exist and make our own.
102 - repub := NewRepublisher(rp, publisher.Repo.Datastore(), publisher.PrivateKey, publisher.Repo.Keystore())
103 - repub.Interval = time.Second
104 - repub.RecordLifetime = time.Second * 5
105 -
106 - proc := goprocess.Go(repub.Run)
107 - defer proc.Close()
108 -
109 - // now wait a couple seconds for it to fire
110 - time.Sleep(time.Second * 2)
111 -
112 - // we should be able to resolve them now
113 - if err := verifyResolution(nodes, name, p); err != nil {
114 - t.Fatal(err)
115 - }
116 -}
117 -
118 -func TestLongEOLRepublish(t *testing.T) {
119 - // set cache life to zero for testing low-period repubs
120 -
121 - ctx, cancel := context.WithCancel(context.Background())
122 - defer cancel()
123 -
124 - // create network
125 - mn := mocknet.New(ctx)
126 -
127 - var nodes []*core.IpfsNode
128 - for i := 0; i < 10; i++ {
129 - nd, err := mock.MockPublicNode(ctx, mn)
130 - if err != nil {
131 - t.Fatal(err)
132 - }
133 -
134 - nd.Namesys = namesys.NewNameSystem(nd.Routing, nd.Repo.Datastore(), 0)
135 -
136 - nodes = append(nodes, nd)
137 - }
138 -
139 - if err := mn.LinkAll(); err != nil {
140 - t.Fatal(err)
141 - }
142 -
143 - bsinf := bootstrap.BootstrapConfigWithPeers(
144 - []peer.AddrInfo{
145 - nodes[0].Peerstore.PeerInfo(nodes[0].Identity),
146 - },
147 - )
148 -
149 - for _, n := range nodes[1:] {
150 - if err := n.Bootstrap(bsinf); err != nil {
151 - t.Fatal(err)
152 - }
153 - }
154 -
155 - // have one node publish a record that is valid for 1 second
156 - publisher := nodes[3]
157 - p := path.FromString("/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn") // does not need to be valid
158 - rp := namesys.NewIpnsPublisher(publisher.Routing, publisher.Repo.Datastore())
159 - name := "/ipns/" + publisher.Identity.Pretty()
160 -
161 - expiration := time.Now().Add(time.Hour)
162 - err := rp.PublishWithEOL(ctx, publisher.PrivateKey, p, expiration)
163 - if err != nil {
164 - t.Fatal(err)
165 - }
166 -
167 - err = verifyResolution(nodes, name, p)
168 - if err != nil {
169 - t.Fatal(err)
170 - }
171 -
172 - // The republishers that are contained within the nodes have their timeout set
173 - // to 12 hours. Instead of trying to tweak those, we're just going to pretend
174 - // they don't exist and make our own.
175 - repub := NewRepublisher(rp, publisher.Repo.Datastore(), publisher.PrivateKey, publisher.Repo.Keystore())
176 - repub.Interval = time.Millisecond * 500
177 - repub.RecordLifetime = time.Second
178 -
179 - proc := goprocess.Go(repub.Run)
180 - defer proc.Close()
181 -
182 - // now wait a couple seconds for it to fire a few times
183 - time.Sleep(time.Second * 2)
184 -
185 - err = verifyResolution(nodes, name, p)
186 - if err != nil {
187 - t.Fatal(err)
188 - }
189 -
190 - entry, err := getLastIPNSEntry(publisher.Repo.Datastore(), publisher.Identity)
191 - if err != nil {
192 - t.Fatal(err)
193 - }
194 -
195 - finalEol, err := ipns.GetEOL(entry)
196 - if err != nil {
197 - t.Fatal(err)
198 - }
199 -
200 - if !finalEol.Equal(expiration) {
201 - t.Fatal("expiration time modified")
202 - }
203 -}
204 -
205 -func getLastIPNSEntry(dstore ds.Datastore, id peer.ID) (*ipns_pb.IpnsEntry, error) {
206 - // Look for it locally only
207 - val, err := dstore.Get(namesys.IpnsDsKey(id))
208 - if err != nil {
209 - return nil, err
210 - }
211 -
212 - e := new(ipns_pb.IpnsEntry)
213 - if err := proto.Unmarshal(val, e); err != nil {
214 - return nil, err
215 - }
216 - return e, nil
217 -}
218 -
219 -func verifyResolution(nodes []*core.IpfsNode, key string, exp path.Path) error {
220 - ctx, cancel := context.WithCancel(context.Background())
221 - defer cancel()
222 - for _, n := range nodes {
223 - val, err := n.Namesys.Resolve(ctx, key)
224 - if err != nil {
225 - return err
226 - }
227 -
228 - if val != exp {
229 - return errors.New("resolved wrong record")
230 - }
231 - }
232 - return nil
233 -}
234 -
235 -func verifyResolutionFails(nodes []*core.IpfsNode, key string) error {
236 - ctx, cancel := context.WithCancel(context.Background())
237 - defer cancel()
238 - for _, n := range nodes {
239 - _, err := n.Namesys.Resolve(ctx, key)
240 - if err == nil {
241 - return errors.New("expected resolution to fail")
242 - }
243 - }
244 - return nil
245 -}
namesys/resolve/resolve.go deleted
-52
@@ -1,52 +0,0 @@
1 -package resolve
2 -
3 -import (
4 - "context"
5 - "errors"
6 - "fmt"
7 - "strings"
8 -
9 - "github.com/ipfs/go-path"
10 -
11 - "github.com/ipfs/go-ipfs/namesys"
12 -)
13 -
14 -// ErrNoNamesys is an explicit error for when an IPFS node doesn't
15 -// (yet) have a name system
16 -var ErrNoNamesys = errors.New(
17 - "core/resolve: no Namesys on IpfsNode - can't resolve ipns entry")
18 -
19 -// ResolveIPNS resolves /ipns paths
20 -func ResolveIPNS(ctx context.Context, nsys namesys.NameSystem, p path.Path) (path.Path, error) {
21 - if strings.HasPrefix(p.String(), "/ipns/") {
22 - // TODO(cryptix): we should be able to query the local cache for the path
23 - if nsys == nil {
24 - return "", ErrNoNamesys
25 - }
26 -
27 - seg := p.Segments()
28 -
29 - if len(seg) < 2 || seg[1] == "" { // just "/<protocol/>" without further segments
30 - err := fmt.Errorf("invalid path %q: ipns path missing IPNS ID", p)
31 - return "", err
32 - }
33 -
34 - extensions := seg[2:]
35 - resolvable, err := path.FromSegments("/", seg[0], seg[1])
36 - if err != nil {
37 - return "", err
38 - }
39 -
40 - respath, err := nsys.Resolve(ctx, resolvable.String())
41 - if err != nil {
42 - return "", err
43 - }
44 -
45 - segments := append(respath.Segments(), extensions...)
46 - p, err = path.FromSegments("/", segments...)
47 - if err != nil {
48 - return "", err
49 - }
50 - }
51 - return p, nil
52 -}
namesys/resolve_test.go deleted
-123
@@ -1,123 +0,0 @@
1 -package namesys
2 -
3 -import (
4 - "context"
5 - "errors"
6 - "testing"
7 - "time"
8 -
9 - ds "github.com/ipfs/go-datastore"
10 - dssync "github.com/ipfs/go-datastore/sync"
11 - mockrouting "github.com/ipfs/go-ipfs-routing/mock"
12 - ipns "github.com/ipfs/go-ipns"
13 - path "github.com/ipfs/go-path"
14 - testutil "github.com/libp2p/go-libp2p-testing/net"
15 - tnet "github.com/libp2p/go-libp2p-testing/net"
16 -)
17 -
18 -func TestRoutingResolve(t *testing.T) {
19 - dstore := dssync.MutexWrap(ds.NewMapDatastore())
20 - serv := mockrouting.NewServer()
21 - id := testutil.RandIdentityOrFatal(t)
22 - d := serv.ClientWithDatastore(context.Background(), id, dstore)
23 -
24 - resolver := NewIpnsResolver(d)
25 - publisher := NewIpnsPublisher(d, dstore)
26 -
27 - identity := tnet.RandIdentityOrFatal(t)
28 -
29 - h := path.FromString("/ipfs/QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN")
30 - err := publisher.Publish(context.Background(), identity.PrivateKey(), h)
31 - if err != nil {
32 - t.Fatal(err)
33 - }
34 -
35 - res, err := resolver.Resolve(context.Background(), identity.ID().Pretty())
36 - if err != nil {
37 - t.Fatal(err)
38 - }
39 -
40 - if res != h {
41 - t.Fatal("Got back incorrect value.")
42 - }
43 -}
44 -
45 -func TestPrexistingExpiredRecord(t *testing.T) {
46 - dstore := dssync.MutexWrap(ds.NewMapDatastore())
47 - d := mockrouting.NewServer().ClientWithDatastore(context.Background(), testutil.RandIdentityOrFatal(t), dstore)
48 -
49 - resolver := NewIpnsResolver(d)
50 - publisher := NewIpnsPublisher(d, dstore)
51 -
52 - identity := tnet.RandIdentityOrFatal(t)
53 -
54 - // Make an expired record and put it in the datastore
55 - h := path.FromString("/ipfs/QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN")
56 - eol := time.Now().Add(time.Hour * -1)
57 -
58 - entry, err := ipns.Create(identity.PrivateKey(), []byte(h), 0, eol)
59 - if err != nil {
60 - t.Fatal(err)
61 - }
62 - err = PutRecordToRouting(context.Background(), d, identity.PublicKey(), entry)
63 - if err != nil {
64 - t.Fatal(err)
65 - }
66 -
67 - // Now, with an old record in the system already, try and publish a new one
68 - err = publisher.Publish(context.Background(), identity.PrivateKey(), h)
69 - if err != nil {
70 - t.Fatal(err)
71 - }
72 -
73 - err = verifyCanResolve(resolver, identity.ID().Pretty(), h)
74 - if err != nil {
75 - t.Fatal(err)
76 - }
77 -}
78 -
79 -func TestPrexistingRecord(t *testing.T) {
80 - dstore := dssync.MutexWrap(ds.NewMapDatastore())
81 - d := mockrouting.NewServer().ClientWithDatastore(context.Background(), testutil.RandIdentityOrFatal(t), dstore)
82 -
83 - resolver := NewIpnsResolver(d)
84 - publisher := NewIpnsPublisher(d, dstore)
85 -
86 - identity := tnet.RandIdentityOrFatal(t)
87 -
88 - // Make a good record and put it in the datastore
89 - h := path.FromString("/ipfs/QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN")
90 - eol := time.Now().Add(time.Hour)
91 - entry, err := ipns.Create(identity.PrivateKey(), []byte(h), 0, eol)
92 - if err != nil {
93 - t.Fatal(err)
94 - }
95 - err = PutRecordToRouting(context.Background(), d, identity.PublicKey(), entry)
96 - if err != nil {
97 - t.Fatal(err)
98 - }
99 -
100 - // Now, with an old record in the system already, try and publish a new one
101 - err = publisher.Publish(context.Background(), identity.PrivateKey(), h)
102 - if err != nil {
103 - t.Fatal(err)
104 - }
105 -
106 - err = verifyCanResolve(resolver, identity.ID().Pretty(), h)
107 - if err != nil {
108 - t.Fatal(err)
109 - }
110 -}
111 -
112 -func verifyCanResolve(r Resolver, name string, exp path.Path) error {
113 - res, err := r.Resolve(context.Background(), name)
114 - if err != nil {
115 - return err
116 - }
117 -
118 - if res != exp {
119 - return errors.New("got back wrong record")
120 - }
121 -
122 - return nil
123 -}
namesys/routing.go deleted
-148
@@ -1,148 +0,0 @@
1 -package namesys
2 -
3 -import (
4 - "context"
5 - "strings"
6 - "time"
7 -
8 - proto "github.com/gogo/protobuf/proto"
9 - cid "github.com/ipfs/go-cid"
10 - ipns "github.com/ipfs/go-ipns"
11 - pb "github.com/ipfs/go-ipns/pb"
12 - logging "github.com/ipfs/go-log"
13 - path "github.com/ipfs/go-path"
14 - opts "github.com/ipfs/interface-go-ipfs-core/options/namesys"
15 - peer "github.com/libp2p/go-libp2p-core/peer"
16 - routing "github.com/libp2p/go-libp2p-core/routing"
17 - dht "github.com/libp2p/go-libp2p-kad-dht"
18 - mh "github.com/multiformats/go-multihash"
19 -)
20 -
21 -var log = logging.Logger("namesys")
22 -
23 -// IpnsResolver implements NSResolver for the main IPFS SFS-like naming
24 -type IpnsResolver struct {
25 - routing routing.ValueStore
26 -}
27 -
28 -// NewIpnsResolver constructs a name resolver using the IPFS Routing system
29 -// to implement SFS-like naming on top.
30 -func NewIpnsResolver(route routing.ValueStore) *IpnsResolver {
31 - if route == nil {
32 - panic("attempt to create resolver with nil routing system")
33 - }
34 - return &IpnsResolver{
35 - routing: route,
36 - }
37 -}
38 -
39 -// Resolve implements Resolver.
40 -func (r *IpnsResolver) Resolve(ctx context.Context, name string, options ...opts.ResolveOpt) (path.Path, error) {
41 - return resolve(ctx, r, name, opts.ProcessOpts(options))
42 -}
43 -
44 -// ResolveAsync implements Resolver.
45 -func (r *IpnsResolver) ResolveAsync(ctx context.Context, name string, options ...opts.ResolveOpt) <-chan Result {
46 - return resolveAsync(ctx, r, name, opts.ProcessOpts(options))
47 -}
48 -
49 -// resolveOnce implements resolver. Uses the IPFS routing system to
50 -// resolve SFS-like names.
51 -func (r *IpnsResolver) resolveOnceAsync(ctx context.Context, name string, options opts.ResolveOpts) <-chan onceResult {
52 - out := make(chan onceResult, 1)
53 - log.Debugf("RoutingResolver resolving %s", name)
54 - cancel := func() {}
55 -
56 - if options.DhtTimeout != 0 {
57 - // Resolution must complete within the timeout
58 - ctx, cancel = context.WithTimeout(ctx, options.DhtTimeout)
59 - }
60 -
61 - name = strings.TrimPrefix(name, "/ipns/")
62 -
63 - pid, err := peer.Decode(name)
64 - if err != nil {
65 - log.Debugf("RoutingResolver: could not convert public key hash %s to peer ID: %s\n", name, err)
66 - out <- onceResult{err: err}
67 - close(out)
68 - cancel()
69 - return out
70 - }
71 -
72 - // Use the routing system to get the name.
73 - // Note that the DHT will call the ipns validator when retrieving
74 - // the value, which in turn verifies the ipns record signature
75 - ipnsKey := ipns.RecordKey(pid)
76 -
77 - vals, err := r.routing.SearchValue(ctx, ipnsKey, dht.Quorum(int(options.DhtRecordCount)))
78 - if err != nil {
79 - log.Debugf("RoutingResolver: dht get for name %s failed: %s", name, err)
80 - out <- onceResult{err: err}
81 - close(out)
82 - cancel()
83 - return out
84 - }
85 -
86 - go func() {
87 - defer cancel()
88 - defer close(out)
89 - for {
90 - select {
91 - case val, ok := <-vals:
92 - if !ok {
93 - return
94 - }
95 -
96 - entry := new(pb.IpnsEntry)
97 - err = proto.Unmarshal(val, entry)
98 - if err != nil {
99 - log.Debugf("RoutingResolver: could not unmarshal value for name %s: %s", name, err)
100 - emitOnceResult(ctx, out, onceResult{err: err})
101 - return
102 - }
103 -
104 - var p path.Path
105 - // check for old style record:
106 - if valh, err := mh.Cast(entry.GetValue()); err == nil {
107 - // Its an old style multihash record
108 - log.Debugf("encountered CIDv0 ipns entry: %s", valh)
109 - p = path.FromCid(cid.NewCidV0(valh))
110 - } else {
111 - // Not a multihash, probably a new style record
112 - p, err = path.ParsePath(string(entry.GetValue()))
113 - if err != nil {
114 - emitOnceResult(ctx, out, onceResult{err: err})
115 - return
116 - }
117 - }
118 -
119 - ttl := DefaultResolverCacheTTL
120 - if entry.Ttl != nil {
121 - ttl = time.Duration(*entry.Ttl)
122 - }
123 - switch eol, err := ipns.GetEOL(entry); err {
124 - case ipns.ErrUnrecognizedValidity:
125 - // No EOL.
126 - case nil:
127 - ttEol := time.Until(eol)
128 - if ttEol < 0 {
129 - // It *was* valid when we first resolved it.
130 - ttl = 0
131 - } else if ttEol < ttl {
132 - ttl = ttEol
133 - }
134 - default:
135 - log.Errorf("encountered error when parsing EOL: %s", err)
136 - emitOnceResult(ctx, out, onceResult{err: err})
137 - return
138 - }
139 -
140 - emitOnceResult(ctx, out, onceResult{value: p, ttl: ttl})
141 - case <-ctx.Done():
142 - return
143 - }
144 - }
145 - }()
146 -
147 - return out
148 -}
repo/fsrepo/fsrepo.go
+1 -1
@@ -11,7 +11,7 @@ import (
11 "sync"
12
13 filestore "github.com/ipfs/go-filestore"
14 - keystore "github.com/ipfs/go-ipfs/keystore"
14 + keystore "github.com/ipfs/go-ipfs-keystore"
15 repo "github.com/ipfs/go-ipfs/repo"
16 "github.com/ipfs/go-ipfs/repo/common"
17 mfsr "github.com/ipfs/go-ipfs/repo/fsrepo/migrations"
repo/mock.go
+1 -1
@@ -4,7 +4,7 @@ import (
4 "errors"
5
6 filestore "github.com/ipfs/go-filestore"
7 - keystore "github.com/ipfs/go-ipfs/keystore"
7 + keystore "github.com/ipfs/go-ipfs-keystore"
8
9 config "github.com/ipfs/go-ipfs-config"
10 ma "github.com/multiformats/go-multiaddr"
repo/repo.go
+1 -1
@@ -5,7 +5,7 @@ import (
5 "io"
6
7 filestore "github.com/ipfs/go-filestore"
8 - keystore "github.com/ipfs/go-ipfs/keystore"
8 + keystore "github.com/ipfs/go-ipfs-keystore"
9
10 ds "github.com/ipfs/go-datastore"
11 config "github.com/ipfs/go-ipfs-config"