From d7394fa0c1cb8a6d8b4b848666bdae6b87c0a1c9 Mon Sep 17 00:00:00 2001 From: Sander Pick Date: Thu, 13 Jun 2019 17:38:35 -0700 Subject: [PATCH 01/12] cluster: initial cluster integration Signed-off-by: Sander Pick --- cmd/daemon.go | 7 +- core/cluster.go | 226 ++++++++++++++++++ core/ipfs.go | 50 ++++ core/main.go | 42 ---- go.mod | 44 ++-- go.sum | 484 +++++++++++++++++++++++++++++++-------- ipfs/cluster.go | 75 ++++++ ipfs/swarm.go | 2 +- repo/config/init_ipfs.go | 3 +- service/main.go | 2 +- service/sender.go | 7 +- 11 files changed, 781 insertions(+), 161 deletions(-) create mode 100644 core/cluster.go create mode 100644 core/ipfs.go create mode 100644 ipfs/cluster.go diff --git a/cmd/daemon.go b/cmd/daemon.go index c1dd0036..08094617 100644 --- a/cmd/daemon.go +++ b/cmd/daemon.go @@ -30,9 +30,7 @@ func Daemon(repoPath string, pinCode string, docs bool, debug bool) error { return fmt.Errorf(fmt.Sprintf("create node failed: %s", err)) } - gateway.Host = &gateway.Gateway{ - Node: node, - } + gateway.Host = &gateway.Gateway{Node: node} err = startNode(docs) if err != nil { @@ -44,14 +42,17 @@ func Daemon(repoPath string, pinCode string, docs bool, debug bool) error { quit := make(chan os.Signal) signal.Notify(quit, os.Interrupt) <-quit + fmt.Println("Interrupted") fmt.Printf("Shutting down...") + err = stopNode() if err != nil && err != core.ErrStopped { fmt.Println(err.Error()) } else { fmt.Print("done\n") } + os.Exit(1) return nil } diff --git a/core/cluster.go b/core/cluster.go new file mode 100644 index 00000000..8fd59440 --- /dev/null +++ b/core/cluster.go @@ -0,0 +1,226 @@ +package core + +import ( + "context" + "fmt" + "time" + + ds "github.com/ipfs/go-datastore" + ipfscluster "github.com/ipfs/ipfs-cluster" + "github.com/ipfs/ipfs-cluster/allocator/ascendalloc" + "github.com/ipfs/ipfs-cluster/allocator/descendalloc" + "github.com/ipfs/ipfs-cluster/config" + "github.com/ipfs/ipfs-cluster/consensus/crdt" + "github.com/ipfs/ipfs-cluster/consensus/raft" + "github.com/ipfs/ipfs-cluster/informer/disk" + "github.com/ipfs/ipfs-cluster/informer/numpin" + "github.com/ipfs/ipfs-cluster/monitor/pubsubmon" + "github.com/ipfs/ipfs-cluster/pintracker/maptracker" + "github.com/ipfs/ipfs-cluster/pintracker/stateless" + host "github.com/libp2p/go-libp2p-host" + dht "github.com/libp2p/go-libp2p-kad-dht" + peer "github.com/libp2p/go-libp2p-peer" + pubsub "github.com/libp2p/go-libp2p-pubsub" + ma "github.com/multiformats/go-multiaddr" + "github.com/textileio/go-textile/ipfs" +) + +type cfgs struct { + clusterCfg *ipfscluster.Config + crdtCfg *crdt.Config + maptrackerCfg *maptracker.Config + statelessTrackerCfg *stateless.Config + pubsubmonCfg *pubsubmon.Config + diskInfCfg *disk.Config + numpinInfCfg *numpin.Config +} + +func makeConfigs() (*config.Manager, *cfgs) { + cfg := config.NewManager() + clusterCfg := &ipfscluster.Config{} + crdtCfg := &crdt.Config{} + maptrackerCfg := &maptracker.Config{} + statelessCfg := &stateless.Config{} + pubsubmonCfg := &pubsubmon.Config{} + diskInfCfg := &disk.Config{} + numpinInfCfg := &numpin.Config{} + cfg.RegisterComponent(config.Cluster, clusterCfg) + cfg.RegisterComponent(config.Consensus, crdtCfg) + cfg.RegisterComponent(config.PinTracker, maptrackerCfg) + cfg.RegisterComponent(config.PinTracker, statelessCfg) + cfg.RegisterComponent(config.Monitor, pubsubmonCfg) + cfg.RegisterComponent(config.Informer, diskInfCfg) + cfg.RegisterComponent(config.Informer, numpinInfCfg) + return cfg, &cfgs{ + clusterCfg, + crdtCfg, + maptrackerCfg, + statelessCfg, + pubsubmonCfg, + diskInfCfg, + numpinInfCfg, + } +} + +func makeAndLoadConfigs(repoPath string) (*config.Manager, *cfgs, error) { + cfgMgr, cfgs := makeConfigs() + err := cfgMgr.LoadJSONFileAndEnv(repoPath) + if err != nil { + return nil, nil, err + } + return cfgMgr, cfgs, nil +} + +// createCluster creates all the necessary things to produce the cluster object +func (t *Textile) createCluster(ctx context.Context, bootstraps []ma.Multiaddr) (*ipfscluster.Cluster, error) { + cfgMgr, cfgs, err := makeAndLoadConfigs(t.repoPath) + if err != nil { + return nil, err + } + defer cfgMgr.Shutdown() + + cfgs.clusterCfg.LeaveOnShutdown = true + + tracker, err := setupPinTracker( + "map", + t.node.PeerHost, + cfgs.maptrackerCfg, + cfgs.statelessTrackerCfg, + cfgs.clusterCfg.Peername, + ) + if err != nil { + return nil, err + } + + informer, alloc, err := setupAllocation( + "disk-freespace", + cfgs.diskInfCfg, + cfgs.numpinInfCfg, + ) + if err != nil { + return nil, err + } + + ipfscluster.ReadyTimeout = raft.DefaultWaitForLeaderTimeout + 5*time.Second + + cons, err := setupConsensus( + t.node.PeerHost, + t.node.DHT, + t.node.PubSub, + cfgs.crdtCfg, + t.node.Repo.Datastore(), + ) + if err != nil { + return nil, err + } + + var peersF func(context.Context) ([]peer.ID, error) + mon, err := pubsubmon.New(ctx, cfgs.pubsubmonCfg, t.node.PubSub, peersF) + if err != nil { + return nil, err + } + + cluster, err := ipfscluster.NewCluster( + ctx, + t.node.PeerHost, + t.node.DHT, + cfgs.clusterCfg, + t.node.Repo.Datastore(), + cons, + nil, + ipfs.NewClusterConnector(t.node), + tracker, + mon, + alloc, + informer, + nil, + ) + if err != nil { + return nil, err + } + + // noop if no bootstraps + // if bootstrapping fails, consensus will never be ready + // and timeout. So this can happen in background and we + // avoid worrying about error handling here (since Cluster + // will realize). + go bootstrap(ctx, cluster, bootstraps) + + return cluster, nil +} + +// bootstrap will bootstrap this peer to one of the bootstrap addresses +// if there are any. +func bootstrap(ctx context.Context, cluster *ipfscluster.Cluster, bootstraps []ma.Multiaddr) { + for _, bstrap := range bootstraps { + log.Infof("Bootstrapping to %s", bstrap) + err := cluster.Join(ctx, bstrap) + if err != nil { + log.Errorf("bootstrap to %s failed: %s", bstrap, err) + } + } +} + +func setupAllocation( + name string, + diskInfCfg *disk.Config, + numpinInfCfg *numpin.Config, +) (ipfscluster.Informer, ipfscluster.PinAllocator, error) { + switch name { + case "disk", "disk-freespace": + informer, err := disk.NewInformer(diskInfCfg) + if err != nil { + return nil, nil, err + } + return informer, descendalloc.NewAllocator(), nil + case "disk-reposize": + informer, err := disk.NewInformer(diskInfCfg) + if err != nil { + return nil, nil, err + } + return informer, ascendalloc.NewAllocator(), nil + case "numpin", "pincount": + informer, err := numpin.NewInformer(numpinInfCfg) + if err != nil { + return nil, nil, err + } + return informer, ascendalloc.NewAllocator(), nil + default: + return nil, nil, fmt.Errorf("unknown allocation strategy") + } +} + +func setupPinTracker( + name string, + h host.Host, + mapCfg *maptracker.Config, + statelessCfg *stateless.Config, + peerName string, +) (ipfscluster.PinTracker, error) { + switch name { + case "map": + ptrk := maptracker.NewMapPinTracker(mapCfg, h.ID(), peerName) + log.Debug("map pintracker loaded") + return ptrk, nil + case "stateless": + ptrk := stateless.New(statelessCfg, h.ID(), peerName) + log.Debug("stateless pintracker loaded") + return ptrk, nil + default: + return nil, fmt.Errorf("unknown pintracker type") + } +} + +func setupConsensus( + h host.Host, + dht *dht.IpfsDHT, + pubsub *pubsub.PubSub, + crdtCfg *crdt.Config, + store ds.Datastore, +) (ipfscluster.Consensus, error) { + convrdt, err := crdt.New(h, dht, pubsub, crdtCfg, store) + if err != nil { + return nil, fmt.Errorf("error creating CRDT component: %s", err) + } + return convrdt, nil +} diff --git a/core/ipfs.go b/core/ipfs.go new file mode 100644 index 00000000..46567a5b --- /dev/null +++ b/core/ipfs.go @@ -0,0 +1,50 @@ +package core + +import ( + "context" + + "github.com/ipfs/go-ipfs/core" + "github.com/ipfs/go-ipfs/core/node/libp2p" + "github.com/ipfs/go-ipfs/plugin/loader" + "github.com/ipfs/go-ipfs/repo/fsrepo" +) + +// createIPFS creates an IPFS node +func (t *Textile) createIPFS(plugins *loader.PluginLoader, online bool) error { + rep, err := fsrepo.Open(t.repoPath) + if err != nil { + return err + } + + routing := libp2p.DHTClientOption + if t.Server() { + routing = libp2p.DHTOption + } + + cctx, _ := context.WithCancel(context.Background()) + nd, err := core.NewNode(cctx, &core.BuildCfg{ + Repo: rep, + Permanent: true, // temporary way to signify that node is permanent + Online: online, + ExtraOpts: map[string]bool{ + "pubsub": true, + "ipnsps": true, + "mplex": true, + }, + Routing: routing, + }) + if err != nil { + return err + } + nd.IsDaemon = true + + if t.node != nil { + err = t.node.Close() + if err != nil { + return err + } + } + t.node = nd + + return nil +} diff --git a/core/main.go b/core/main.go index 4d025f97..43fa11db 100644 --- a/core/main.go +++ b/core/main.go @@ -16,8 +16,6 @@ import ( oldcmds "github.com/ipfs/go-ipfs/commands" "github.com/ipfs/go-ipfs/core" "github.com/ipfs/go-ipfs/core/corerepo" - "github.com/ipfs/go-ipfs/core/node/libp2p" - "github.com/ipfs/go-ipfs/plugin/loader" "github.com/ipfs/go-ipfs/repo/fsrepo" ipld "github.com/ipfs/go-ipld-format" logging "github.com/ipfs/go-log" @@ -609,46 +607,6 @@ func (t *Textile) cafeService() *CafeService { return t.cafe } -// createIPFS creates an IPFS node -func (t *Textile) createIPFS(plugins *loader.PluginLoader, online bool) error { - rep, err := fsrepo.Open(t.repoPath) - if err != nil { - return err - } - - routing := libp2p.DHTOption - if t.Mobile() { - routing = libp2p.DHTClientOption - } - - cctx, _ := context.WithCancel(context.Background()) - nd, err := core.NewNode(cctx, &core.BuildCfg{ - Repo: rep, - Permanent: true, // temporary way to signify that node is permanent - Online: online, - ExtraOpts: map[string]bool{ - "pubsub": true, - "ipnsps": true, - "mplex": true, - }, - Routing: routing, - }) - if err != nil { - return err - } - nd.IsDaemon = true - - if t.node != nil { - err = t.node.Close() - if err != nil { - return err - } - } - t.node = nd - - return nil -} - // runJobs runs each message queue func (t *Textile) runJobs() { var freq time.Duration diff --git a/go.mod b/go.mod index adacca7e..88d0e5ea 100644 --- a/go.mod +++ b/go.mod @@ -21,30 +21,41 @@ require ( github.com/go-openapi/swag v0.19.0 // indirect github.com/gogo/protobuf v1.2.1 github.com/golang/protobuf v1.3.1 + github.com/hashicorp/go-immutable-radix v1.1.0 // indirect + github.com/hashicorp/go-uuid v1.0.1 // indirect + github.com/hsanjuan/go-libp2p-http v0.0.5 // indirect github.com/ipfs/go-cid v0.0.2 - github.com/ipfs/go-ipfs v0.4.21 + github.com/ipfs/go-datastore v0.0.5 + github.com/ipfs/go-ipfs v0.4.22-0.20190613191811-0fabf0b92809 github.com/ipfs/go-ipfs-addr v0.0.1 - github.com/ipfs/go-ipfs-cmds v0.0.8 - github.com/ipfs/go-ipfs-config v0.0.3 + github.com/ipfs/go-ipfs-cmds v0.0.10 + github.com/ipfs/go-ipfs-config v0.0.6 github.com/ipfs/go-ipfs-files v0.0.3 github.com/ipfs/go-ipld-format v0.0.2 github.com/ipfs/go-log v0.0.1 - github.com/ipfs/go-merkledag v0.0.3 - github.com/ipfs/go-path v0.0.4 - github.com/ipfs/go-unixfs v0.0.6 - github.com/ipfs/interface-go-ipfs-core v0.0.8 + github.com/ipfs/go-merkledag v0.1.0 + github.com/ipfs/go-path v0.0.7 + github.com/ipfs/go-unixfs v0.1.0 + github.com/ipfs/interface-go-ipfs-core v0.1.0 + github.com/ipfs/ipfs-cluster v0.11.0-rc4 github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 - github.com/libp2p/go-libp2p-crypto v0.0.2 + github.com/libp2p/go-libp2p-core v0.0.3 + github.com/libp2p/go-libp2p-crypto v0.1.0 + github.com/libp2p/go-libp2p-gorpc v0.1.0 + github.com/libp2p/go-libp2p-host v0.1.0 + github.com/libp2p/go-libp2p-interface-connmgr v0.0.5 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.1.0 github.com/libp2p/go-libp2p-net v0.0.2 - github.com/libp2p/go-libp2p-peer v0.1.1 - github.com/libp2p/go-libp2p-peerstore v0.0.6 - github.com/libp2p/go-libp2p-protocol v0.0.1 - github.com/libp2p/go-libp2p-record v0.0.1 + github.com/libp2p/go-libp2p-peer v0.2.0 + github.com/libp2p/go-libp2p-peerstore v0.1.0 + github.com/libp2p/go-libp2p-protocol v0.1.0 + github.com/libp2p/go-libp2p-pubsub v0.1.0 + github.com/libp2p/go-libp2p-record v0.1.0 github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983 // indirect github.com/mitchellh/go-homedir v1.1.0 github.com/mr-tron/base58 v1.1.2 github.com/multiformats/go-multiaddr v0.0.4 - github.com/multiformats/go-multihash v0.0.5 + github.com/multiformats/go-multihash v0.0.6 github.com/mutecomm/go-sqlcipher v0.0.0-20190227152316-55dbde17881f github.com/onsi/ginkgo v1.8.0 github.com/onsi/gomega v1.5.0 @@ -59,11 +70,10 @@ require ( github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.1.0 - golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f - golang.org/x/image v0.0.0-20190321063152-3fc05d484e9f // indirect - google.golang.org/appengine v1.4.0 // indirect + golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 + golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd // indirect gopkg.in/alecthomas/kingpin.v2 v2.2.6 gopkg.in/natefinch/lumberjack.v2 v2.0.0-20170531160350-a96e63847dc3 ) -replace github.com/ipfs/go-ipfs => github.com/sanderpick/go-ipfs v0.4.22-0.20190606034924-0478a0eca246 +replace github.com/ugorji/go v1.1.4 => github.com/ugorji/go/codec v0.0.0-20190320090025-2dc34c0b8780 diff --git a/go.sum b/go.sum index 420a50a6..44a350a6 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,18 @@ bazil.org/fuse v0.0.0-20180421153158-65cc252bf669 h1:FNCRpXiquG1aoyqcIWVFmpTSKVcx2bQD38uZZeGtdlw= bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +contrib.go.opencensus.io/exporter/jaeger v0.1.0 h1:WNc9HbA38xEQmsI40Tjd/MNU/g8byN2Of7lwIjv0Jdc= +contrib.go.opencensus.io/exporter/jaeger v0.1.0/go.mod h1:VYianECmuFPwU37O699Vc1GOcy+y8kOsfaxHRImmjbA= +contrib.go.opencensus.io/exporter/prometheus v0.1.0 h1:SByaIoWwNgMdPSgl5sMqM2KDE5H/ukPWBRo314xiDvg= +contrib.go.opencensus.io/exporter/prometheus v0.1.0/go.mod h1:cGFniUXGZlKRjzOyuZJ6mgB+PgBcCIa79kEKR8YCW+A= github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7 h1:PqzgE6kAMi81xWQA2QIVxjWkFHptGgC547vchpUbtFo= github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9 h1:HD8gA2tkByhMAwYaFAX9w2l7vxvBQ5NMoxDrkhqhtn4= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd/go.mod h1:bqoB8kInrTeEtYAwaIXoSRqdwnjQmFhsfusnzyui6yY= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= @@ -15,6 +23,8 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Quasilyte/go-consistent v0.0.0-20181230194409-8f8379e70f99/go.mod h1:ds1OLa3HF2x4OGKCx0pNTVL1s9Ii/2mT0Bg/8PtW6AM= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/Stebalien/go-bitfield v0.0.0-20180330043415-076a62f9ce6e h1:2Z+EBRrOJsA3psnUPcEWMIH2EIga1xHflQcr/EZslx8= github.com/Stebalien/go-bitfield v0.0.0-20180330043415-076a62f9ce6e/go.mod h1:3oM7gXIttpYDAJXpVNnSCiUMYBLIZ6cb1t+Ip982MRo= @@ -23,28 +33,43 @@ github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 h1:w1UutsfOrms1J05zt7ISrnJIXKzwaspym5BTKGx93EI= github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af h1:wVe6/Ea46ZMeNkQjjBW6xcqyQA/j5e0D6GytH95g0gQ= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/apache/thrift v0.12.0 h1:pODnxUFNcjP9UTLZGTdeh+j16A8lJbRvD3rOtrk/7bs= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 h1:EFSB7Zo9Eg91v7MJPVsifUysc/wPdN+NOnVe6bWbdBM= +github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= +github.com/awalterschulze/gographviz v0.0.0-20190522210029-fa59802746ab/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/bifurcation/mint v0.0.0-20181105073638-824af6541065/go.mod h1:zVt7zX3K/aDCk9Tj+VM7YymsX66ERvzCJzw8rFCX2JU= +github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/bren2010/proquint v0.0.0-20160323162903-38337c27106d h1:QgeLLoPD3kRVmeu/1al9iIpIANMi9O1zXFm8BnYGCJg= github.com/bren2010/proquint v0.0.0-20160323162903-38337c27106d/go.mod h1:Jbj8eKecMNwf0KFI75skSUZqMB4UCRcndUScVBTWyUI= github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= github.com/btcsuite/btcd v0.0.0-20190427004231-96897255fd17 h1:m0N5Vg5nP3zEz8TREZpwX3gt4Biw3/8fbIf4A3hO96g= github.com/btcsuite/btcd v0.0.0-20190427004231-96897255fd17/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c h1:aEbSeNALREWXk0G7UdNhR3ayBV7tZ4M2PNmnrCAph6Q= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50 h1:4i3KsuVA0o0KoBxAC5x+MY7RbteiMK1V7gf/G08NGIQ= +github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btcd v0.0.0-20190614013741-962a206e94e9 h1:18Pe+JPyglNO9lzLrQHj7Dwmdi4c49D8xQTqTRz3qJo= +github.com/btcsuite/btcd v0.0.0-20190614013741-962a206e94e9/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= -github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY= @@ -52,17 +77,22 @@ github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QH github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= +github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U= github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20160726135117-62c6fe619375 h1:JVe1zduaiPlSLOuQcU/MqRJkBbWRPsjdW48+20AtJXM= github.com/chzyer/readline v0.0.0-20160726135117-62c6fe619375/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.2.1-0.20180108230905-e214231b295a h1:U0BbGfKnviqVBJQB4etvm+mKx53KfkumNLBt6YeF/0Q= github.com/coreos/go-semver v0.2.1-0.20180108230905-e214231b295a/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -78,11 +108,16 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumC github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f h1:dDxpBYafY/GYpcl+LS4Bn3ziLPuEdGRkRjYAbSlWxSA= github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/disintegration/imaging v1.6.0 h1:nVPXRUUQ36Z7MNf0O77UzgnOb1mkMMor7lmJMJXc/mA= github.com/disintegration/imaging v1.6.0/go.mod h1:xuIt+sRxDFrHS0drzXUlCJthkJ8k7lkkUojDSR247MQ= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302/go.mod h1:qBlWZqWeVx9BjvqBsnC/8RUlAYpIFmPvgROcw0n1scE= github.com/evanphx/json-patch v4.1.0+incompatible h1:K1MDoo4AZ4wU0GIU/fPmtZg7VpzLjCxu+UwBD1FvwOc= github.com/evanphx/json-patch v4.1.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= @@ -93,6 +128,8 @@ github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fd/go-nat v1.0.0 h1:DPyQ97sxA9ThrWYRPcWUz/z9TnpTIGRYODIQc/dy64M= github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90 h1:WXb3TSNmHp2vHoCroCIB1foO/yQ36swABL8aOVeDpgg= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= @@ -107,6 +144,7 @@ github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NB github.com/gin-gonic/gin v1.1.4/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y= github.com/gin-gonic/gin v1.3.0 h1:kCmZyPklC0gVdL728E6Aj20uYBJV93nj/TkwBTKhFbs= github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y= +github.com/go-bindata/go-bindata v3.1.1+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo= github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-critic/go-critic v0.0.0-20181204210945-c3db6069acc5/go.mod h1:Jc75BZJv2dNy7opKH6bF29VveDQHfGZ6Asn/3phBesg= @@ -143,8 +181,12 @@ github.com/go-toolsmith/strparse v0.0.0-20180903215201-830b6daa1241/go.mod h1:YI github.com/go-toolsmith/typep v0.0.0-20181030061450-d63dc7650676/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk= @@ -175,11 +217,18 @@ github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunE github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.2 h1:zoNxOV7WjqXptQOVngLmcSQgXmgk4NMz1HibBchjl/I= +github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gxed/go-shellwords v1.0.3/go.mod h1:N7paucT91ByIjmVJHhvoarjoQnmsi3Jd3vH7VqgtMxQ= @@ -190,34 +239,72 @@ github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmv github.com/gxed/pubsub v0.0.0-20180201040156-26ebdf44f824/go.mod h1:OiEWyHgK+CWrmOlVquHaIK1vhpUJydC9m0Je6mhaiNE= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.9.1 h1:9PZfAcVEvez4yhLH2TBU64/h/z4xlFI80cWXRrxuKuM= +github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI= +github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.1.0 h1:vN9wG1D6KG6YHRTWr8512cxGOVgTMEfgEdSj/hr8MPc= +github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= +github.com/hashicorp/raft v1.0.1/go.mod h1:DVSAWItjLjTOkVbSpWQ0j0kUADIvDaCtBxIcbNAQLkI= +github.com/hashicorp/raft v1.1.0 h1:qPMePEczgbkiQsqCsRfuHRqvDUO+zmAInDaD5ptXlq0= +github.com/hashicorp/raft v1.1.0/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM= +github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea h1:xykPFhrBAS2J0VBzVa5e80b5ZtYuNQtgXjN40qBZlD4= +github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk= +github.com/hashicorp/raft-boltdb v0.0.0-20190605210249-ef2e128ed477 h1:bLsrEmB2NUwkHH18FOJBIa04wOV2RQalJrcafTYu6Lg= +github.com/hashicorp/raft-boltdb v0.0.0-20190605210249-ef2e128ed477/go.mod h1:aUF6HQr8+t3FC/ZHAC+pZreUBhTaxumuu3L+d37uRxk= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hsanjuan/go-libp2p-gostream v0.0.31/go.mod h1:cWvV5/NQ5XWi0eQZnX/svsAk6NLc4U26pItvj0eDeRk= -github.com/hsanjuan/go-libp2p-http v0.0.2/go.mod h1:MynY94gfOZxrw/0lVF4o7vbV2Zr84IC8sLBXmj8F5IE= +github.com/hsanjuan/go-libp2p-gostream v0.0.34 h1:OKqOIo6fQNVeOCAjGsYVb8qon1WAipUofO87BBfqwxs= +github.com/hsanjuan/go-libp2p-gostream v0.0.34/go.mod h1:kCzaCrXaCU/uf62woAls6CyubdjKxTLwkLxK/mvzrHA= +github.com/hsanjuan/go-libp2p-http v0.0.5 h1:Sbhgple3OfPzwokVn18cvACpWoVBeyW6+aCD93vX19E= +github.com/hsanjuan/go-libp2p-http v0.0.5/go.mod h1:i26Upd/cMufAoruO/wkrmL09sDS6QB/INhpu7otW1/U= +github.com/hsanjuan/ipfs-lite v0.0.8 h1:ueBk9f8NEdkV0JEL4mSsBq8fq2Z2uUNfCeIHcDDzu3A= +github.com/hsanjuan/ipfs-lite v0.0.8/go.mod h1:JY8+Fb2leVCDVSJxSe6HwDzHfITjs/8CKATw3j0vCnQ= +github.com/hsanjuan/ipfs-lite v0.1.2 h1:ZwoZVpsJjVRFUEgbC1aNvoHmsV1r1bf+r7ND2u2eN24= +github.com/hsanjuan/ipfs-lite v0.1.2/go.mod h1:9T+vqbluaqAw8Dlb2AHOA1IN3+2XaiuJLBy9mKre8hY= github.com/huin/goupnp v0.0.0-20180415215157-1395d1447324 h1:PV190X5/DzQ/tbFFG5YpT5mH6q+cHlfgqI5JuRnH9oE= github.com/huin/goupnp v0.0.0-20180415215157-1395d1447324/go.mod h1:MZ2ZmwcBpvOoJ22IJsc7va19ZwoheaBk43rKg12SKag= github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI= +github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.1 h1:s7KkiBPfxCeDVo47KySjK0ACPc5GJRUxFpdyWEuDjhw= github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= -github.com/ipfs/dir-index-html v1.0.3/go.mod h1:TG9zbaH/+4MnkGel0xF4SLNhk+YZvBNo6jjBkO/LaWc= github.com/ipfs/go-bitswap v0.0.3 h1:uFcSI9dkjUn67S7IM60vr2wA27aAvn8o9xYjaQCug3o= github.com/ipfs/go-bitswap v0.0.3/go.mod h1:jadAZYsP/tcRMl47ZhFxhaNuDQoXawT8iHMg+iFoQbg= -github.com/ipfs/go-bitswap v0.0.7 h1:BJwx7Kh5W845l10bOckkAJiNrT6XXWNaE8neK7H57q4= -github.com/ipfs/go-bitswap v0.0.7/go.mod h1:++LZRc+e1/ZxYsZq7QLKIPQvybh+70TMgeGuX+WB0pY= +github.com/ipfs/go-bitswap v0.0.9/go.mod h1:kAPf5qgn2W2DrgAcscZ3HrM9qh4pH+X8Fkk3UPrwvis= +github.com/ipfs/go-bitswap v0.1.0/go.mod h1:FFJEf18E9izuCqUtHxbWEvq+reg7o4CW5wSAE1wsxj0= +github.com/ipfs/go-bitswap v0.1.2/go.mod h1:qxSWS4NXGs7jQ6zQvoPY3+NmOfHHG47mhkiLzBpJQIs= +github.com/ipfs/go-bitswap v0.1.3 h1:jAl9Z/TYObpGeGATUemnOZ7RYb0F/kzNVlhcYZesz+0= +github.com/ipfs/go-bitswap v0.1.3/go.mod h1:YEQlFy0kkxops5Vy+OxWdRSEZIoS7I7KDIwoa5Chkps= github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= github.com/ipfs/go-blockservice v0.0.3 h1:40OvwrxeudTAlUGUAKNYnNPcwQeLtXedjzTWecnUinQ= github.com/ipfs/go-blockservice v0.0.3/go.mod h1:/NNihwTi6V2Yr6g8wBI+BSwPuURpBRMtYNGrlxZ8KuI= +github.com/ipfs/go-blockservice v0.0.7 h1:VRRVjgahs7r//MdO7yY5DJ2/i2fmkKOnxfSyfuPjTm0= +github.com/ipfs/go-blockservice v0.0.7/go.mod h1:EOfb9k/Y878ZTRY/CH0x5+ATtaipfbRhbvNSdgc/7So= +github.com/ipfs/go-blockservice v0.1.0 h1:dh2i7xjMbCtf0ZSMyQAF2qpV/pEEmM7yVpQ00+gik6U= +github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M= +github.com/ipfs/go-blockservice v0.1.1 h1:HHIvLuOhW0DQSrVserYcZYUl++nJPEzqZP+spRMaVzw= +github.com/ipfs/go-blockservice v0.1.1/go.mod h1:t+411r7psEUhLueM8C7aPA7cxCclv4O3VsUVxt9kz2I= github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2 h1:tuuKaZPU1M6HcejsO3AcYWW8sZ8MTvyxfc4uqB4eFE8= @@ -235,6 +322,10 @@ github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46U github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= github.com/ipfs/go-ds-badger v0.0.3 h1:sVYE2YlCzltznTZeAP1S+bp3qipz7VzogfZDtf6tGq0= github.com/ipfs/go-ds-badger v0.0.3/go.mod h1:7AzMKCsGav0u46HpdLiAEAOqizR1H6AZsjpHpQSPYCQ= +github.com/ipfs/go-ds-crdt v0.0.14 h1:+/S+jc1sHPipIwldyeS60p6GeNK7Nykpmx4Cnxotn3w= +github.com/ipfs/go-ds-crdt v0.0.14/go.mod h1:ioLVScdQ2TNRPqrrB1su+Pck+gceuAlyhRMUD6TNHx4= +github.com/ipfs/go-ds-crdt v0.1.0 h1:mzpcTdrPj7bCfazIccZuP5FeQtvBiKEj9I/mp0bYmVw= +github.com/ipfs/go-ds-crdt v0.1.0/go.mod h1:SaXm2oxzu+ouZ6HZ7e1Ss1O1wz/T+wGhcX4i922J95I= github.com/ipfs/go-ds-flatfs v0.0.2 h1:1zujtU5bPBH6B8roE+TknKIbBCrpau865xUk0dH3x2A= github.com/ipfs/go-ds-flatfs v0.0.2/go.mod h1:YsMGWjUieue+smePAWeH/YhHtlmEMnEGhiwIn6K6rEM= github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= @@ -244,20 +335,23 @@ github.com/ipfs/go-ds-measure v0.0.1 h1:PrCueug+yZLkDCOthZTXKinuoCal/GvlAT7cNxzr github.com/ipfs/go-ds-measure v0.0.1/go.mod h1:wiH6bepKsgyNKpz3nyb4erwhhIVpIxnZbsjN1QpVbbE= github.com/ipfs/go-fs-lock v0.0.1 h1:XHX8uW4jQBYWHj59XXcjg7BHlHxV9ZOYs6Y43yb7/l0= github.com/ipfs/go-fs-lock v0.0.1/go.mod h1:DNBekbboPKcxs1aukPSaOtFA3QfSdi5C855v0i9XJ8Y= +github.com/ipfs/go-ipfs v0.4.22-0.20190613191811-0fabf0b92809 h1:4QA+CSyfBQgaQ8BL3aycuHWuMcgnyq+bfPOP0EoIAEM= +github.com/ipfs/go-ipfs v0.4.22-0.20190613191811-0fabf0b92809/go.mod h1:XOWVpQI7NCdOMa+NCKEHuSmcAGGRWvNE48hjKe9eyMA= github.com/ipfs/go-ipfs-addr v0.0.1 h1:DpDFybnho9v3/a1dzJ5KnWdThWD1HrFLpQ+tWIyBaFI= github.com/ipfs/go-ipfs-addr v0.0.1/go.mod h1:uKTDljHT3Q3SUWzDLp3aYUi8MrY32fgNgogsIa0npjg= +github.com/ipfs/go-ipfs-api v0.0.1/go.mod h1:0FhXgCzrLu7qNmdxZvgYqD9jFzJxzz1NAVt3OQ0WOIc= github.com/ipfs/go-ipfs-blockstore v0.0.1 h1:O9n3PbmTYZoNhkgkEyrXTznbmktIXif62xLX+8dPHzc= github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= github.com/ipfs/go-ipfs-chunker v0.0.1 h1:cHUUxKFQ99pozdahi+uSC/3Y6HeRpi9oTeUHbE27SEw= github.com/ipfs/go-ipfs-chunker v0.0.1/go.mod h1:tWewYK0we3+rMbOh7pPFGDyypCtvGcBFymgY4rSDLAw= -github.com/ipfs/go-ipfs-cmds v0.0.8 h1:ZMo0ZeQOr10ZKY4yxYA3lRHUbnF/ZYcV9cpU0IrlGFI= -github.com/ipfs/go-ipfs-cmds v0.0.8/go.mod h1:TiK4e7/V31tuEb8YWDF8lN3qrnDH+BS7ZqWIeYJlAs8= -github.com/ipfs/go-ipfs-config v0.0.1 h1:6ED08emzI1imdsAjixFi2pEyZxTVD5ECKtCOxLBx+Uc= -github.com/ipfs/go-ipfs-config v0.0.1/go.mod h1:KDbHjNyg4e6LLQSQpkgQMBz6Jf4LXiWAcmnkcwmH0DU= -github.com/ipfs/go-ipfs-config v0.0.3 h1:Ep4tRdP1iVK76BgOprD9B/qtOEdpno+1Xb57BqydgGk= -github.com/ipfs/go-ipfs-config v0.0.3/go.mod h1:KDbHjNyg4e6LLQSQpkgQMBz6Jf4LXiWAcmnkcwmH0DU= +github.com/ipfs/go-ipfs-cmds v0.0.10 h1:4kA3E94HbDrLb4RZTkX3yXyUjKv50RfPz0Pv9xkP2cA= +github.com/ipfs/go-ipfs-cmds v0.0.10/go.mod h1:TiK4e7/V31tuEb8YWDF8lN3qrnDH+BS7ZqWIeYJlAs8= +github.com/ipfs/go-ipfs-config v0.0.4/go.mod h1:KDbHjNyg4e6LLQSQpkgQMBz6Jf4LXiWAcmnkcwmH0DU= +github.com/ipfs/go-ipfs-config v0.0.5/go.mod h1:IGkVTacurWv9WFKc7IBPjHGM/7hi6+PEClqUb/l2BIM= +github.com/ipfs/go-ipfs-config v0.0.6 h1:jzK9Tl8S0oWBir3F5ObtGgnHRPdqQ0MYiCmwXtV3Ps4= +github.com/ipfs/go-ipfs-config v0.0.6/go.mod h1:IGkVTacurWv9WFKc7IBPjHGM/7hi6+PEClqUb/l2BIM= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= @@ -267,6 +361,7 @@ github.com/ipfs/go-ipfs-exchange-interface v0.0.1 h1:LJXIo9W7CAmugqI+uofioIpRb6r github.com/ipfs/go-ipfs-exchange-interface v0.0.1/go.mod h1:c8MwfHjtQjPoDyiy9cFquVtVHkO9b9Ob3FG91qJnWCM= github.com/ipfs/go-ipfs-exchange-offline v0.0.1 h1:P56jYKZF7lDDOLx5SotVh5KFxoY6C81I1NSHW1FxGew= github.com/ipfs/go-ipfs-exchange-offline v0.0.1/go.mod h1:WhHSFCVYX36H/anEKQboAzpUws3x7UeEGkzQc3iNkM0= +github.com/ipfs/go-ipfs-files v0.0.1/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= github.com/ipfs/go-ipfs-files v0.0.2 h1:fEEjF4H+1t8SFOHqUGp0KqcwgIRlbD2bu8CAS2sIggE= github.com/ipfs/go-ipfs-files v0.0.2/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= github.com/ipfs/go-ipfs-files v0.0.3 h1:ME+QnC3uOyla1ciRPezDW0ynQYK2ikOh9OCKAEg4uUA= @@ -277,8 +372,12 @@ github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6 github.com/ipfs/go-ipfs-posinfo v0.0.1/go.mod h1:SwyeVP+jCwiDu0C313l/8jg6ZxM0qqtlt2a0vILTc1A= github.com/ipfs/go-ipfs-pq v0.0.1 h1:zgUotX8dcAB/w/HidJh1zzc1yFq6Vm8J7T2F4itj/RU= github.com/ipfs/go-ipfs-pq v0.0.1/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= +github.com/ipfs/go-ipfs-provider v0.1.0 h1:lYSVVxWpL0KJw1PLj3+DAn0zuVfc+z93wzUXS09ZjZk= +github.com/ipfs/go-ipfs-provider v0.1.0/go.mod h1:gzVZZXC4zhr2r+MkNR21/+FS54oc7VfTKtDT2mdDxD8= github.com/ipfs/go-ipfs-routing v0.0.1 h1:394mZeTLcbM/LDO12PneBYvkZAUA+nRnmC0lAzDXKOY= github.com/ipfs/go-ipfs-routing v0.0.1/go.mod h1:k76lf20iKFxQTjcJokbPM9iBXVXVZhcOwc360N4nuKs= +github.com/ipfs/go-ipfs-routing v0.1.0 h1:gAJTT1cEeeLj6/DlLX6t+NxD9fQe2ymTO6qWRDI/HQQ= +github.com/ipfs/go-ipfs-routing v0.1.0/go.mod h1:hYoUkJLyAUKhF58tysKpids8RNDPO42BVMgK5dNsoqY= github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= github.com/ipfs/go-ipld-cbor v0.0.1 h1:g7yh27SznWP4CUbkFgjR+WQRjEeyxCpTR4iKVmXx1wA= @@ -297,30 +396,47 @@ github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-merkledag v0.0.3 h1:A5DlOMzqTRDVmdgkf3dzCKCFmVWH4Zqwb0cbYXUs+Ro= github.com/ipfs/go-merkledag v0.0.3/go.mod h1:Oc5kIXLHokkE1hWGMBHw+oxehkAaTOqtEb7Zbh6BhLA= +github.com/ipfs/go-merkledag v0.0.6 h1:rYZc0yzhO7y1cKi3Rw425a2HhEJDdLvNOWsqtmO3PF0= +github.com/ipfs/go-merkledag v0.0.6/go.mod h1:QYPdnlvkOg7GnQRofu9XZimC5ZW5Wi3bKys/4GQQfto= +github.com/ipfs/go-merkledag v0.1.0 h1:CAEXjRFEDPvealQj3TgEjV1IJckwjvmxAqtq5QSXJrg= +github.com/ipfs/go-merkledag v0.1.0/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-metrics-prometheus v0.0.2/go.mod h1:ELLU99AQQNi+zX6GCGm2lAgnzdSH3u5UVlCdqSXnEks= -github.com/ipfs/go-mfs v0.0.7 h1:Xjqk0jAhgwhMHO39oH4jqP1QkeAGqDelxa814voygN0= -github.com/ipfs/go-mfs v0.0.7/go.mod h1:10Hdow7wUbSlIamnOduxeP6MEp58TozZmdnAhugOKz8= +github.com/ipfs/go-mfs v0.0.11 h1:LMrmLt1NfB88ddjIfU+onuIhWB3W/bhfBbXC8HSnONk= +github.com/ipfs/go-mfs v0.0.11/go.mod h1:bMtma2uwUUkl0RMB0oMAHH01RwA8yrqsT48rPn1c3RA= +github.com/ipfs/go-mfs v0.1.0 h1:XVAdaMQtLV0KCNC7CnZlLAFiIU23RD/3Tvb8h6KDLaY= +github.com/ipfs/go-mfs v0.1.0/go.mod h1:/oADRI/at3cfIHqL4BTAF5n0nvWO4XpMi5nmHoxwhrQ= +github.com/ipfs/go-mfs v0.1.1 h1:tjYEWFIl0W6vRFuM/EnySHaaYzPmDcQWwTjtYWMGQ1A= +github.com/ipfs/go-mfs v0.1.1/go.mod h1:nk17h6kCOrfaNqXvx2VJ3SqkJ0VYUzJFAsc+BA0sqaw= github.com/ipfs/go-path v0.0.3 h1:G/VFcCMXtp36JUPPyytYQ1I3UsBUBf47M//uSdTLnFg= github.com/ipfs/go-path v0.0.3/go.mod h1:zIRQUez3LuQIU25zFjC2hpBTHimWx7VK5bjZgRLbbdo= -github.com/ipfs/go-path v0.0.4 h1:zG/id80tV51XAfvCsRJIEGQSHGuTDBi8RWrtr3EfcfY= -github.com/ipfs/go-path v0.0.4/go.mod h1:zIRQUez3LuQIU25zFjC2hpBTHimWx7VK5bjZgRLbbdo= +github.com/ipfs/go-path v0.0.7 h1:H06hKMquQ0aYtHiHryOMLpQC1qC3QwXwkahcEVD51Ho= +github.com/ipfs/go-path v0.0.7/go.mod h1:6KTKmeRnBXgqrTvzFrPV3CamxcgvXX/4z79tfAd2Sno= github.com/ipfs/go-peertaskqueue v0.0.4 h1:i0JprfjjILYcWM1xguO/1MCS8XKVxLSl+ECEVr6i8nw= github.com/ipfs/go-peertaskqueue v0.0.4/go.mod h1:03H8fhyeMfKNFWqzYEVyMbcPUeYrqP1MX6Kd+aN+rMQ= +github.com/ipfs/go-peertaskqueue v0.1.0/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= +github.com/ipfs/go-peertaskqueue v0.1.1 h1:+gPjbI+V3NktXZOqJA1kzbms2pYmhjgQQal0MzZrOAY= +github.com/ipfs/go-peertaskqueue v0.1.1/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= github.com/ipfs/go-todocounter v0.0.1 h1:kITWA5ZcQZfrUnDNkRn04Xzh0YFaDFXsoO2A81Eb6Lw= github.com/ipfs/go-todocounter v0.0.1/go.mod h1:l5aErvQc8qKE2r7NDMjmq5UNAvuZy0rC8BHOplkWvZ4= github.com/ipfs/go-unixfs v0.0.4 h1:IApzQ+SnY0tfjqM7aU2b80CFYLZNHvhLmEZDIWr4e/E= github.com/ipfs/go-unixfs v0.0.4/go.mod h1:eIo/p9ADu/MFOuyxzwU+Th8D6xoxU//r590vUpWyfz8= -github.com/ipfs/go-unixfs v0.0.6 h1:mQ6KS3NK4GA9hyUpGdGItqt5llzyIx0Qy2UxC/A7bEo= -github.com/ipfs/go-unixfs v0.0.6/go.mod h1:g41FlHFM/qacA3jzMPOYKIwNwbgTQEKJH2hQiq19Zrc= +github.com/ipfs/go-unixfs v0.0.8 h1:AHahQ+gdNZd9BhKVLf8XP1EWeKa78eTzYgCygp7N/Pg= +github.com/ipfs/go-unixfs v0.0.8/go.mod h1:cK2vDJ7L4YnWB6oLefpVNesgx0x/zPTRVDw6B4Y+03U= +github.com/ipfs/go-unixfs v0.1.0 h1:KkjcfqObdNwUN8heMtt5OdrgrRKYTIWEvpGl1bDYIho= +github.com/ipfs/go-unixfs v0.1.0/go.mod h1:lysk5ELhOso8+Fed9U1QTGey2ocsfaZ18h0NCO2Fj9s= github.com/ipfs/go-verifcid v0.0.1 h1:m2HI7zIuR5TFyQ1b79Da5N9dnnCP1vcu2QqawmWlK2E= github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= github.com/ipfs/hang-fds v0.0.1/go.mod h1:U4JNbzwTpk/qP2Ms4VgrZ4HcgJGVosBJqMXvwe4udSY= -github.com/ipfs/interface-go-ipfs-core v0.0.8 h1:nmEYOfK6QRf3VIdggoZ4rmbKXcC2g6cEdU13Z1CvmL4= -github.com/ipfs/interface-go-ipfs-core v0.0.8/go.mod h1:RU+DSZXV+JdA7Yagu3OrSoB6hngSmMtK1w6ENOqmfQ8= +github.com/ipfs/interface-go-ipfs-core v0.1.0 h1:4LD2TJThswXVMJgAji9k9PyPsOGNtmdcx7U9RM1xH84= +github.com/ipfs/interface-go-ipfs-core v0.1.0/go.mod h1:h1zJvvfh9dcNU0bK+Jag516LputHLKQkHsDP+z0dz4A= +github.com/ipfs/ipfs-cluster v0.11.0-rc3 h1:zOIOErqcBjlMMhgw4pkYLQ2YnMCZEXbjaAeVrOGjJjA= +github.com/ipfs/ipfs-cluster v0.11.0-rc3/go.mod h1:ixCoddapUP8TJhPoYsqVBfKi24PmdJnteQrieGt6sC8= +github.com/ipfs/ipfs-cluster v0.11.0-rc4 h1:hDvWdUX81V/jPF91qRkEU9kfJMiWTlAKR7fIIzkLa0g= +github.com/ipfs/ipfs-cluster v0.11.0-rc4/go.mod h1:zUFCd9FoVikWuTiha9ZEHIRVTplcp7Ys3VNxlppnhkc= github.com/ipfs/iptb v1.4.0/go.mod h1:1rzHpCYtNp87/+hTxG5TfCVn/yMY3dKnLn8tBiMfdmg= -github.com/ipfs/iptb-plugins v0.0.2/go.mod h1:Vud+X6lHv5QlgVbqCPBHt91I0gPIRgmkD6/tMUsI07U= +github.com/ipfs/iptb-plugins v0.1.0/go.mod h1:gE+R5nCAM9+Cajd1UhIBk8k7CZus7IG8FFXE0lHvJx0= github.com/jackpal/gateway v1.0.4 h1:LS5EHkLuQ6jzaHwULi0vL+JO0mU/n4yUtK8oUjHHOlM= github.com/jackpal/gateway v1.0.4/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= github.com/jackpal/gateway v1.0.5 h1:qzXWUJfuMdlLMtt0a3Dgt+xkWQiA5itDEITVJtuSwMc= @@ -344,8 +460,6 @@ github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsj github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10= github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -353,13 +467,20 @@ github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwK github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5 h1:PJr+ZMXIecYc1Ey2zucXdR73SMBtgjPgwa31099IMv0= +github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/jung-kurt/gofpdf v1.4.2/go.mod h1:rZsO0wEsunjT/L9stF3fJjYbAHgqNYuQB4B8FWvBck0= +github.com/kelseyhightower/envconfig v1.3.0 h1:IvRS4f2VcIQy6j4ORGIf9145T/AsUB+oY8LyvN8BXNM= +github.com/kelseyhightower/envconfig v1.3.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= +github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= +github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v0.0.0-20161130080628-0de1eaf82fa3/go.mod h1:jxZFDH7ILpTPQTk+E2s+z4CUas9lVNjIuKR4c5/zKgM= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/kkdai/bstream v0.0.0-20181106074824-b3251f7901ec/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b h1:wxtKgYHEncAU00muMD06dzLiahtGM1eouRNOzVV7tdQ= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= @@ -369,6 +490,10 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lanzafame/go-libp2p-ocgorpc v0.0.4 h1:u2i1BITAGxsj5hZEDmh+wsOQOWmDJF0L9fM6qli6CYA= +github.com/lanzafame/go-libp2p-ocgorpc v0.0.4/go.mod h1:1qLNfL/1VgwWa2dvwo81tyEjGm3vo2556ZLdyyTGZiw= +github.com/lanzafame/go-libp2p-ocgorpc v0.1.0 h1:KFuLVHk5zL/LrpecbEeTQ3AGahbyPWhmqvYg6iXcJHI= +github.com/lanzafame/go-libp2p-ocgorpc v0.1.0/go.mod h1:gD05AQwo11CbdbdMH2gtqBaiDLUXKNteQxr/U24YlCM= github.com/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88= github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= github.com/libp2p/go-buffer-pool v0.0.1 h1:9Rrn/H46cXjaA2HQ5Y8lyhOS1NhTkZ4yuEs2r3Eechg= @@ -381,44 +506,74 @@ github.com/libp2p/go-conn-security-multistream v0.0.1 h1:XefjAQRHcnUaxKb26RGupTo github.com/libp2p/go-conn-security-multistream v0.0.1/go.mod h1:nc9vud7inQ+d6SO0I/6dSWrdMnHnzZNHeyUQqrAJulE= github.com/libp2p/go-conn-security-multistream v0.0.2 h1:Ykz0lnNjxk+0SdslUmlLNyrleqdpS1S/VW+dxFdt74Y= github.com/libp2p/go-conn-security-multistream v0.0.2/go.mod h1:nc9vud7inQ+d6SO0I/6dSWrdMnHnzZNHeyUQqrAJulE= +github.com/libp2p/go-conn-security-multistream v0.1.0 h1:aqGmto+ttL/uJgX0JtQI0tD21CIEy5eYd1Hlp0juHY0= +github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= github.com/libp2p/go-flow-metrics v0.0.1 h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s= github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= github.com/libp2p/go-libp2p v0.0.2 h1:+jvgi0Zy3y4TKXJKApchCk3pCBPZf1T54z3+vKie3gw= github.com/libp2p/go-libp2p v0.0.2/go.mod h1:Qu8bWqFXiocPloabFGUcVG4kk94fLvfC8mWTDdFC9wE= -github.com/libp2p/go-libp2p v0.0.27/go.mod h1:kjeVlESxQisK2DvyKp38/UMHYd9gAMTj3C3XOB/DEZo= -github.com/libp2p/go-libp2p v0.0.28 h1:tkDnM7iwrz9OSRRb8YAV4HYjv8TKsAxyxrV2sES9/Aw= -github.com/libp2p/go-libp2p v0.0.28/go.mod h1:GBW0VbgEKe8ELXVpLQJduJYlJHRv/XfwP6Fo9TEcDJU= +github.com/libp2p/go-libp2p v0.0.25/go.mod h1:37g8bAoyqrg7CL+t5/LHnXU0SytNN9lVLjktuBe36ko= +github.com/libp2p/go-libp2p v0.0.30 h1:mwCWAusLhRGUzZ/VaCatsrEQTsuWExmXqVcvGBV72EQ= +github.com/libp2p/go-libp2p v0.0.30/go.mod h1:XWT8FGHlhptAv1+3V/+J5mEpzyui/5bvFsNuWYs611A= +github.com/libp2p/go-libp2p v0.1.0/go.mod h1:6D/2OBauqLUoqcADOJpn9WbKqvaM07tDw68qHM0BxUM= +github.com/libp2p/go-libp2p v0.1.1 h1:52sB0TJuDk2nYMcMfHOKaPoaayDZjaYVCq6Vk1ejUTk= +github.com/libp2p/go-libp2p v0.1.1/go.mod h1:I00BRo1UuUSdpuc8Q2mN7yDF/oTUTRAX6JWpTiK9Rp8= github.com/libp2p/go-libp2p-autonat v0.0.2/go.mod h1:fs71q5Xk+pdnKU014o2iq1RhMs9/PMaG5zXRFNnIIT4= -github.com/libp2p/go-libp2p-autonat v0.0.3/go.mod h1:fs71q5Xk+pdnKU014o2iq1RhMs9/PMaG5zXRFNnIIT4= -github.com/libp2p/go-libp2p-autonat v0.0.5/go.mod h1:cKt+qOSnWAZp0dqIuUk62v0/QAPw0vnLuVZnmzkOXRk= +github.com/libp2p/go-libp2p-autonat v0.0.4/go.mod h1:fs71q5Xk+pdnKU014o2iq1RhMs9/PMaG5zXRFNnIIT4= github.com/libp2p/go-libp2p-autonat v0.0.6 h1:OCStANLLpeyQeWFUuqZJ7aS9+Bx0/uoVb1PtLA9fGTQ= github.com/libp2p/go-libp2p-autonat v0.0.6/go.mod h1:uZneLdOkZHro35xIhpbtTzLlgYturpu4J5+0cZK3MqE= -github.com/libp2p/go-libp2p-autonat-svc v0.0.2/go.mod h1:j4iMiw0d3diRm5iB0noXumtb0mPvWrM1qAyh640cp8w= -github.com/libp2p/go-libp2p-autonat-svc v0.0.5 h1:bTom7QFAkJMXiA8ibSsKQ2+LKEHsXZz2IAWYolg/YYg= -github.com/libp2p/go-libp2p-autonat-svc v0.0.5/go.mod h1:6aLiQelA0CKEcPR0TvE9bqJ7U8Mc0nVdwCoho3ROdck= +github.com/libp2p/go-libp2p-autonat v0.1.0 h1:aCWAu43Ri4nU0ZPO7NyLzUvvfqd0nE3dX0R/ZGYVgOU= +github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= +github.com/libp2p/go-libp2p-autonat-svc v0.1.0 h1:28IM7iWMDclZeVkpiFQaWVANwXwE7zLlpbnS7yXxrfs= +github.com/libp2p/go-libp2p-autonat-svc v0.1.0/go.mod h1:fqi8Obl/z3R4PFVLm8xFtZ6PBL9MlV/xumymRFkKq5A= github.com/libp2p/go-libp2p-blankhost v0.0.1 h1:/mZuuiwntNR8RywnCFlGHLKrKLYne+qciBpQXWqp5fk= github.com/libp2p/go-libp2p-blankhost v0.0.1/go.mod h1:Ibpbw/7cPPYwFb7PACIWdvxxv0t0XCCI10t7czjAjTc= +github.com/libp2p/go-libp2p-blankhost v0.1.1 h1:X919sCh+KLqJcNRApj43xCSiQRYqOSI88Fdf55ngf78= +github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= github.com/libp2p/go-libp2p-circuit v0.0.1/go.mod h1:Dqm0s/BiV63j8EEAs8hr1H5HudqvCAeXxDyic59lCwE= -github.com/libp2p/go-libp2p-circuit v0.0.7/go.mod h1:DFCgZ2DklFGTUIZIhSvbbWXTErUgjyNrJGfDHOrTKIA= -github.com/libp2p/go-libp2p-circuit v0.0.8 h1:vd9vZDy+LDssTvUuxIqnYUOAK2hfHoSQO2xjWhPVEmc= -github.com/libp2p/go-libp2p-circuit v0.0.8/go.mod h1:DFCgZ2DklFGTUIZIhSvbbWXTErUgjyNrJGfDHOrTKIA= -github.com/libp2p/go-libp2p-connmgr v0.0.1 h1:9KP7UbP4a6fauLw954LhTGfovhkmMwvJsIf8G4CCons= -github.com/libp2p/go-libp2p-connmgr v0.0.1/go.mod h1:eUBBlbuwBBTd/eim7KV5x0fOD2UHDjSwhzmBL6miIx8= +github.com/libp2p/go-libp2p-circuit v0.0.6/go.mod h1:W34ISBRpoCPUeOR26xzTbLo+s3hDO9153hJCfvHzBlg= +github.com/libp2p/go-libp2p-circuit v0.0.9 h1:tjdgP9hv8+Pa/xsprBpEFngq4t8aLvjfibBYoDjO9i4= +github.com/libp2p/go-libp2p-circuit v0.0.9/go.mod h1:uU+IBvEQzCu953/ps7bYzC/D/R0Ho2A9LfKVVCatlqU= +github.com/libp2p/go-libp2p-circuit v0.1.0 h1:eniLL3Y9aq/sryfyV1IAHj5rlvuyj3b7iz8tSiZpdhY= +github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= github.com/libp2p/go-libp2p-connmgr v0.0.6 h1:oEUriPO/qWTvfHRPEU4HdNlNhYigdueOs2X3UZCdbYM= github.com/libp2p/go-libp2p-connmgr v0.0.6/go.mod h1:uwDfgdgqB5248sQYib1xo603cSsMg9PgAKu0Z+Y65Qk= +github.com/libp2p/go-libp2p-connmgr v0.1.0 h1:vp0t0F0EuT3rrlTtnMnIyyzCnly7nIlRoEbhJpgp0qU= +github.com/libp2p/go-libp2p-connmgr v0.1.0/go.mod h1:wZxh8veAmU5qdrfJ0ZBLcU8oJe9L82ciVP/fl1VHjXk= +github.com/libp2p/go-libp2p-consensus v0.0.1 h1:jcVbHRZLwTXU9iT/mPi+Lx4/OrIzq3bU1TbZNhYFCV8= +github.com/libp2p/go-libp2p-consensus v0.0.1/go.mod h1:+9Wrfhc5QOqWB0gXI0m6ARlkHfdJpcFXmRU0WoHz4Mo= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-core v0.0.2/go.mod h1:9dAcntw/n46XycV4RnlBq3BpgrmyUi9LuoTNdPrbUco= +github.com/libp2p/go-libp2p-core v0.0.3 h1:+IonUYY0nJZLb5Fdv6a6DOjtGP1L8Bb3faamiI2q5FY= +github.com/libp2p/go-libp2p-core v0.0.3/go.mod h1:j+YQMNz9WNSkNezXOsahp9kwZBKBvxLpKD316QWSJXE= github.com/libp2p/go-libp2p-crypto v0.0.1 h1:JNQd8CmoGTohO/akqrH16ewsqZpci2CbgYH/LmYl8gw= github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE= github.com/libp2p/go-libp2p-crypto v0.0.2 h1:TTdJ4y6Uoa6NxQcuEaVkQfFRcQeCE2ReDk8Ok4I0Fyw= github.com/libp2p/go-libp2p-crypto v0.0.2/go.mod h1:eETI5OUfBnvARGOHrJz2eWNyTUxEGZnBxMcbUjfIj4I= -github.com/libp2p/go-libp2p-daemon v0.0.6/go.mod h1:nkhjsjSzkF+tg6iScsTTgq9m+VfyMtXNpycYG4CFvC8= +github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-daemon v0.2.0/go.mod h1:1hlzu8xFRi+fkC1N+zvhSgznGZGo9HxpJtSrj3X5HQw= github.com/libp2p/go-libp2p-discovery v0.0.1 h1:VkjCKmJQMwpDUwtA8Qc1z3TQAHJgQ5nGQ6cdN0wQXOw= github.com/libp2p/go-libp2p-discovery v0.0.1/go.mod h1:ZkkF9xIFRLA1xCc7bstYFkd80gBGK8Fc1JqGoU2i+zI= -github.com/libp2p/go-libp2p-discovery v0.0.4 h1:/kZwOVmcUHvB94zegSJYnUA9EvT1g8APoQJb5FHyT1c= -github.com/libp2p/go-libp2p-discovery v0.0.4/go.mod h1:ReQGiv7QTtza8FUWzewfuMmRDVOQVp+lxHlJJA8YQCM= +github.com/libp2p/go-libp2p-discovery v0.0.3/go.mod h1:ZkkF9xIFRLA1xCc7bstYFkd80gBGK8Fc1JqGoU2i+zI= +github.com/libp2p/go-libp2p-discovery v0.0.5 h1:VpPd7u2odnrrRcW+gVdjLDcXsc35k0Tjxqgbzlre6Uo= +github.com/libp2p/go-libp2p-discovery v0.0.5/go.mod h1:YtF20GUxjgoKZ4zmXj8j3Nb2TUSBHFlOCetzYdbZL5I= +github.com/libp2p/go-libp2p-discovery v0.1.0 h1:j+R6cokKcGbnZLf4kcNwpx6mDEUPF3N6SrqMymQhmvs= +github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g= +github.com/libp2p/go-libp2p-gorpc v0.0.5 h1:VOtQYdXYsdkrtk5vD5H9+4i1pqHPJw8JUv4Quu00WUw= +github.com/libp2p/go-libp2p-gorpc v0.0.5/go.mod h1:thS8W4/wEbm+BIi078wNAsJI2Sh8tEuyugij6tBmzRE= +github.com/libp2p/go-libp2p-gorpc v0.1.0 h1:e9jPUGRSV3MHXh60rULbaKth1hX+yEH4v68Acn7XBwo= +github.com/libp2p/go-libp2p-gorpc v0.1.0/go.mod h1:DrswTLnu7qjLgbqe4fekX4ISoPiHUqtA45thTsJdE1w= +github.com/libp2p/go-libp2p-gostream v0.1.1 h1:9D88ud79U9Nl6iTPiTM1F/9LGC7SQPXdrRD3GWuIC0k= +github.com/libp2p/go-libp2p-gostream v0.1.1/go.mod h1:w0cUXl1GHEMuqFMOomaCnq9g88YK60cxtOENCLku/pE= github.com/libp2p/go-libp2p-host v0.0.1 h1:dnqusU+DheGcdxrE718kG4XgHNuL2n9eEv8Rg5zy8hQ= github.com/libp2p/go-libp2p-host v0.0.1/go.mod h1:qWd+H1yuU0m5CwzAkvbSjqKairayEHdR5MMl7Cwa7Go= github.com/libp2p/go-libp2p-host v0.0.3 h1:BB/1Z+4X0rjKP5lbQTmjEjLbDVbrcmLOlA6QDsN5/j4= github.com/libp2p/go-libp2p-host v0.0.3/go.mod h1:Y/qPyA6C8j2coYyos1dfRm0I8+nvd4TGrDGt4tA7JR8= +github.com/libp2p/go-libp2p-host v0.1.0 h1:OZwENiFm6JOK3YR5PZJxkXlJE8a5u8g4YvAUrEV2MjM= +github.com/libp2p/go-libp2p-host v0.1.0/go.mod h1:5+fWuLbDn8OxoxPN3CV0vsLe1hAKScSMbT84qRfxum8= +github.com/libp2p/go-libp2p-http v0.1.2/go.mod h1:qomMgtxIHzkqu5L3mvg48s/6hEu7IuVNVo4ktL60ogE= github.com/libp2p/go-libp2p-interface-connmgr v0.0.1 h1:Q9EkNSLAOF+u90L88qmE9z/fTdjLh8OsJwGw74mkwk4= github.com/libp2p/go-libp2p-interface-connmgr v0.0.1/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= github.com/libp2p/go-libp2p-interface-connmgr v0.0.4/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= @@ -426,69 +581,103 @@ github.com/libp2p/go-libp2p-interface-connmgr v0.0.5 h1:KG/KNYL2tYzXAfMvQN5K1aAG github.com/libp2p/go-libp2p-interface-connmgr v0.0.5/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= github.com/libp2p/go-libp2p-interface-pnet v0.0.1 h1:7GnzRrBTJHEsofi1ahFdPN9Si6skwXQE9UqR2S+Pkh8= github.com/libp2p/go-libp2p-interface-pnet v0.0.1/go.mod h1:el9jHpQAXK5dnTpKA4yfCNBZXvrzdOU75zz+C6ryp3k= -github.com/libp2p/go-libp2p-kad-dht v0.0.4/go.mod h1:oaBflOQcuC8H+SVV0YN26H6AS+wcUEJyjUGV66vXuSY= -github.com/libp2p/go-libp2p-kad-dht v0.0.13 h1:ReMb41jJrngvXnU5Tirf74bBkXx4M9ne5QyFQPeNYtw= -github.com/libp2p/go-libp2p-kad-dht v0.0.13/go.mod h1:3A4xaZJeJ3zD3jCg17mtI+rA7uuXiiQdKVyAZOhZo1U= -github.com/libp2p/go-libp2p-kbucket v0.0.1/go.mod h1:Y0iQDHRTk/ZgM8PC4jExoF+E4j+yXWwRkdldkMa5Xm4= +github.com/libp2p/go-libp2p-interface-pnet v0.1.0 h1:PaofJtuDcrGBukgTymiGyuI313nxARRQFmE/oxZXlog= +github.com/libp2p/go-libp2p-interface-pnet v0.1.0/go.mod h1:8+FQ08+xMxR6BjG0tUZoQzKxPAV2W7ck6IxjCWqZ6ek= +github.com/libp2p/go-libp2p-kad-dht v0.0.14 h1:ooAmThM+sCYDSygh+ynU3N++BZ0rXxee4tRbBX1a18k= +github.com/libp2p/go-libp2p-kad-dht v0.0.14/go.mod h1:IETCKDE8BxDoyt2phfwJZRs+qrCHJ8KNo2HVth7+D8Y= +github.com/libp2p/go-libp2p-kad-dht v0.1.0 h1:cupGornmncdQCnjArAv9Txkqy43wgQCxoe/5pfIDF/4= +github.com/libp2p/go-libp2p-kad-dht v0.1.0/go.mod h1:EiH74cOsCxcu2Yh1XxQMpf1uHcLNm/hYEJBOIRlzHNE= github.com/libp2p/go-libp2p-kbucket v0.1.1 h1:ZrvW3qCM+lAuv7nrNts/zfEiClq+GZe8OIzX4Vb3Dwo= github.com/libp2p/go-libp2p-kbucket v0.1.1/go.mod h1:Y0iQDHRTk/ZgM8PC4jExoF+E4j+yXWwRkdldkMa5Xm4= +github.com/libp2p/go-libp2p-kbucket v0.2.0 h1:FB2a0VkOTNGTP5gu/I444u4WabNM9V1zCkQcWb7zajI= +github.com/libp2p/go-libp2p-kbucket v0.2.0/go.mod h1:JNymBToym3QXKBMKGy3m29+xprg0EVr/GJFHxFEdgh8= github.com/libp2p/go-libp2p-loggables v0.0.1 h1:HVww9oAnINIxbt69LJNkxD8lnbfgteXR97Xm4p3l9ps= github.com/libp2p/go-libp2p-loggables v0.0.1/go.mod h1:lDipDlBNYbpyqyPX/KcoO+eq0sJYEVR2JgOexcivchg= +github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= +github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= github.com/libp2p/go-libp2p-metrics v0.0.1 h1:yumdPC/P2VzINdmcKZd0pciSUCpou+s0lwYCjBbzQZU= github.com/libp2p/go-libp2p-metrics v0.0.1/go.mod h1:jQJ95SXXA/K1VZi13h52WZMa9ja78zjyy5rspMsC/08= +github.com/libp2p/go-libp2p-metrics v0.1.0/go.mod h1:rpoJmXWFxnj7qs5sJ02sxSzrhaZvpqBn8GCG6Sx6E1k= github.com/libp2p/go-libp2p-mplex v0.1.1 h1:lSPS1VJ36P01gGO//KgcsmSah5uoC3X9r7WY5j+iP4c= github.com/libp2p/go-libp2p-mplex v0.1.1/go.mod h1:KUQWpGkCzfV7UIpi8SKsAVxyBgz1c9R5EvxgnwLsb/I= +github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= +github.com/libp2p/go-libp2p-mplex v0.2.1 h1:E1xaJBQnbSiTHGI1gaBKmKhu1TUKkErKJnE8iGvirYI= +github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= github.com/libp2p/go-libp2p-nat v0.0.2 h1:sKI5hiCsGFhuEKdXMsF9mywQu2qhfoIGX6a+VG6zelE= github.com/libp2p/go-libp2p-nat v0.0.2/go.mod h1:QrjXQSD5Dj4IJOdEcjHRkWTSomyxRo6HnUkf/TfQpLQ= github.com/libp2p/go-libp2p-nat v0.0.4 h1:+KXK324yaY701On8a0aGjTnw8467kW3ExKcqW2wwmyw= github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= -github.com/libp2p/go-libp2p-net v0.0.0-20190226201932-e71fff5ba6e9/go.mod h1:8W6Wx3AZbTRTe8zSMLoAmT3mGyau+w6kGIRk+Z+MZ7Q= github.com/libp2p/go-libp2p-net v0.0.1 h1:xJ4Vh4yKF/XKb8fd1Ev0ebAGzVjMxXzrxG2kjtU+F5Q= github.com/libp2p/go-libp2p-net v0.0.1/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8EgNU9DrCcR8c= github.com/libp2p/go-libp2p-net v0.0.2 h1:qP06u4TYXfl7uW/hzqPhlVVTSA2nw1B/bHBJaUnbh6M= github.com/libp2p/go-libp2p-net v0.0.2/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8EgNU9DrCcR8c= github.com/libp2p/go-libp2p-netutil v0.0.1 h1:LgD6+skofkOx8z6odD9+MZHKjupv3ng1u6KRhaADTnA= github.com/libp2p/go-libp2p-netutil v0.0.1/go.mod h1:GdusFvujWZI9Vt0X5BKqwWWmZFxecf9Gt03cKxm2f/Q= +github.com/libp2p/go-libp2p-netutil v0.1.0 h1:zscYDNVEcGxyUpMd0JReUZTrpMfia8PmLKcKF72EAMQ= +github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= github.com/libp2p/go-libp2p-peer v0.0.1/go.mod h1:nXQvOBbwVqoP+T5Y5nCjeH4sP9IX/J0AMzcDUVruVoo= github.com/libp2p/go-libp2p-peer v0.1.1 h1:qGCWD1a+PyZcna6htMPo26jAtqirVnJ5NvBQIKV7rRY= github.com/libp2p/go-libp2p-peer v0.1.1/go.mod h1:jkF12jGB4Gk/IOo+yomm+7oLWxF278F7UnrYUQ1Q8es= -github.com/libp2p/go-libp2p-peerstore v0.0.0-20190226201924-e2df3e49eabf/go.mod h1:lLfgn0N3z2t+ER57a88K7NTZjMO27ez5TyWSURd428E= +github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= github.com/libp2p/go-libp2p-peerstore v0.0.1 h1:twKovq8YK5trLrd3nB7PD2Zu9JcyAIdm7Bz9yBWjhq8= github.com/libp2p/go-libp2p-peerstore v0.0.1/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4Ti6k/HtZJ7YKgtSq+20= github.com/libp2p/go-libp2p-peerstore v0.0.6 h1:RgX/djPFXqZGktW0j2eF4NAX0pzDsCot45jO2GewC+g= github.com/libp2p/go-libp2p-peerstore v0.0.6/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4Ti6k/HtZJ7YKgtSq+20= +github.com/libp2p/go-libp2p-peerstore v0.1.0 h1:MKh7pRNPHSh1fLPj8u/M/s/napdmeNpoi9BRy9lPN0E= +github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= github.com/libp2p/go-libp2p-pnet v0.0.1 h1:2e5d15M8XplUKsU4Fqrll5eDfqGg/7mHUufLkhbfKHM= github.com/libp2p/go-libp2p-pnet v0.0.1/go.mod h1:bWN8HqdpgCdKnXSCsJhbWjiU3UZFa/tIe4no5jCmHVw= -github.com/libp2p/go-libp2p-protocol v0.0.0-20171212212132-b29f3d97e3a2/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= +github.com/libp2p/go-libp2p-pnet v0.1.0 h1:kRUES28dktfnHNIRW4Ro78F7rKBHBiw5MJpl0ikrLIA= +github.com/libp2p/go-libp2p-pnet v0.1.0/go.mod h1:ZkyZw3d0ZFOex71halXRihWf9WH/j3OevcJdTmD0lyE= github.com/libp2p/go-libp2p-protocol v0.0.1 h1:+zkEmZ2yFDi5adpVE3t9dqh/N9TbpFWywowzeEzBbLM= github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= -github.com/libp2p/go-libp2p-pubsub v0.0.1 h1:iJWpvBDZiZOoRBGqEifu9yUHti9ptnSODHt6tgrBC6c= -github.com/libp2p/go-libp2p-pubsub v0.0.1/go.mod h1:fYKlZBOF2yrJzYlgeEVFSbYWfbS+E8Zix6gMZ0A6WgE= -github.com/libp2p/go-libp2p-pubsub v0.0.3 h1:DKVoDac2u1Dr8gX7B1HFjCrXkMxr8tfbnt0Fk1mmkgk= -github.com/libp2p/go-libp2p-pubsub v0.0.3/go.mod h1:fYKlZBOF2yrJzYlgeEVFSbYWfbS+E8Zix6gMZ0A6WgE= -github.com/libp2p/go-libp2p-pubsub-router v0.0.3 h1:2EF+8nueIsA9Unpj1MxdlS9+dX29kwCxSttchMMfXsI= -github.com/libp2p/go-libp2p-pubsub-router v0.0.3/go.mod h1:h5z0kyMFRu2J46tt15eEuLHKEmu1MrFghsGHqTc/iII= -github.com/libp2p/go-libp2p-quic-transport v0.0.0-20190301030811-862195d91de1/go.mod h1:bw/6H57fSVn44ldP1Js6hnzpoiUm9YgBDKSv+ch+hWc= -github.com/libp2p/go-libp2p-quic-transport v0.0.3 h1:FGEPXsjpY9K6P3iMtJQPKGl45eXickBY1+xSJ84lVVI= -github.com/libp2p/go-libp2p-quic-transport v0.0.3/go.mod h1:v2oVuaFLkxlFpkFbXUty3dfEYSlNb0sCzvf8cRi1m/k= +github.com/libp2p/go-libp2p-protocol v0.1.0 h1:HdqhEyhg0ToCaxgMhnOmUO8snQtt/kQlcjVk3UoJU3c= +github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk= +github.com/libp2p/go-libp2p-pubsub v0.0.6 h1:nr54YJwRJf8QfpekLVW+XmmAOUG3UnHRm4f/VRNNrLg= +github.com/libp2p/go-libp2p-pubsub v0.0.6/go.mod h1:rB9nqkoA/Coxh68OynvQE9UZbhl1aOt3xuBEfCzPW1E= +github.com/libp2p/go-libp2p-pubsub v0.1.0 h1:SmQeMa7IUv5vadh0fYgYsafWCBA1sCy5d/68kIYqGcU= +github.com/libp2p/go-libp2p-pubsub v0.1.0/go.mod h1:ZwlKzRSe1eGvSIdU5bD7+8RZN/Uzw0t1Bp9R1znpR/Q= +github.com/libp2p/go-libp2p-pubsub-router v0.1.0 h1:xA5B8Sdx64tNlSRIcay2QUngtlu8LpUJClaUk/dYYrg= +github.com/libp2p/go-libp2p-pubsub-router v0.1.0/go.mod h1:PnHOshBr/2I2ZxVfEsqfgCQPsVg09zo+DhSlWkOhPFM= +github.com/libp2p/go-libp2p-quic-transport v0.1.0/go.mod h1:1oh6y4f8/lDX42jIGlhXO95ox3Y1XMLdffb7zde29Y8= +github.com/libp2p/go-libp2p-quic-transport v0.1.1 h1:MFMJzvsxIEDEVKzO89BnB/FgvMj9WI4GDGUW2ArDPUA= +github.com/libp2p/go-libp2p-quic-transport v0.1.1/go.mod h1:wqG/jzhF3Pu2NrhJEvE+IE0NTHNXslOPn9JQzyCAxzU= +github.com/libp2p/go-libp2p-raft v0.0.3 h1:KSu+8TnG/D+BN4jwySEghf6uYVlJfF1egYGzBlNWPiM= +github.com/libp2p/go-libp2p-raft v0.0.3/go.mod h1:G9FXHHvlJuNY4t1CIzy+JeaIH15jPD0kATBcGoD4kWg= +github.com/libp2p/go-libp2p-raft v0.1.1 h1:oKWJh9E8phiyAbn8WW7yo5wHkPuO979HcxEMGoFO5pw= +github.com/libp2p/go-libp2p-raft v0.1.1/go.mod h1:OgCm5uGzOtKCv70dtarZsr6JWqtMigIDH6F3a6LpEIU= github.com/libp2p/go-libp2p-record v0.0.1 h1:zN7AS3X46qmwsw5JLxdDuI43cH5UYwovKxHPjKBYQxw= github.com/libp2p/go-libp2p-record v0.0.1/go.mod h1:grzqg263Rug/sRex85QrDOLntdFAymLDLm7lxMgU79Q= +github.com/libp2p/go-libp2p-record v0.1.0 h1:wHwBGbFzymoIl69BpgwIu0O6ta3TXGcMPvHUAcodzRc= +github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= github.com/libp2p/go-libp2p-routing v0.0.1 h1:hPMAWktf9rYi3ME4MG48qE7dq1ofJxiQbfdvpNntjhc= github.com/libp2p/go-libp2p-routing v0.0.1/go.mod h1:N51q3yTr4Zdr7V8Jt2JIktVU+3xBBylx1MZeVA6t1Ys= -github.com/libp2p/go-libp2p-routing-helpers v0.0.2 h1:SLX7eDQE8Xo197NwNM/hM7WnH3w6fSGY9+G9HkiYwqQ= -github.com/libp2p/go-libp2p-routing-helpers v0.0.2/go.mod h1:zf1ook9HoOQpfnVXrF4gGorkPrGGf1g25vgH5+4SRNU= +github.com/libp2p/go-libp2p-routing v0.1.0 h1:hFnj3WR3E2tOcKaGpyzfP4gvFZ3t8JkQmbapN0Ct+oU= +github.com/libp2p/go-libp2p-routing v0.1.0/go.mod h1:zfLhI1RI8RLEzmEaaPwzonRvXeeSHddONWkcTcB54nE= +github.com/libp2p/go-libp2p-routing-helpers v0.1.0 h1:BaFvpyv8TyhCN7TihawTiKuzeu8/Pyw7ZnMA4IvqIN8= +github.com/libp2p/go-libp2p-routing-helpers v0.1.0/go.mod h1:oUs0h39vNwYtYXnQWOTU5BaafbedSyWCCal3gqHuoOQ= github.com/libp2p/go-libp2p-secio v0.0.1 h1:CqE/RdsizOwItdgLe632iyft/w0tshDLmZGAiKDcUAI= github.com/libp2p/go-libp2p-secio v0.0.1/go.mod h1:IdG6iQybdcYmbTzxp4J5dwtUEDTOvZrT0opIDVNPrJs= github.com/libp2p/go-libp2p-secio v0.0.3 h1:h3fPeDrej7bvvARnC2oSjAfcLZOaS4REZKgWCRQNpE4= github.com/libp2p/go-libp2p-secio v0.0.3/go.mod h1:hS7HQ00MgLhRO/Wyu1bTX6ctJKhVpm+j2/S2A5UqYb0= +github.com/libp2p/go-libp2p-secio v0.1.0 h1:NNP5KLxuP97sE5Bu3iuwOWyT/dKEGMN5zSLMWdB7GTQ= +github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= github.com/libp2p/go-libp2p-swarm v0.0.1 h1:Vne+hjaDwXqzgNwQ2vb2YKbnbOTyXjtS47stT66Apc4= github.com/libp2p/go-libp2p-swarm v0.0.1/go.mod h1:mh+KZxkbd3lQnveQ3j2q60BM1Cw2mX36XXQqwfPOShs= -github.com/libp2p/go-libp2p-swarm v0.0.5/go.mod h1:+nkJir4feiXtWQjb/4CQHMEK8Vw+c5nVVxT8R5bs0yY= +github.com/libp2p/go-libp2p-swarm v0.0.2/go.mod h1:n0cAAcKyndIrJWctQwjqXlAdIPBZzfdpBjx1SSvz30g= +github.com/libp2p/go-libp2p-swarm v0.0.3/go.mod h1:/2HbOacAKDYT1g0UEZjUPlzD+SBtvqkg4TaYeoBA2TY= github.com/libp2p/go-libp2p-swarm v0.0.6 h1:gE0P/v2h+KEXtAi9YTw2UBOSODJ4m9VuuJ+ktc2LVUo= github.com/libp2p/go-libp2p-swarm v0.0.6/go.mod h1:s5GZvzg9xXe8sbeESuFpjt8CJPTCa8mhEusweJqyFy8= -github.com/libp2p/go-libp2p-tls v0.0.1 h1:UIslpmpKDbjEymuidtP2D9up00GfWrOs6eyTKf83uBA= -github.com/libp2p/go-libp2p-tls v0.0.1/go.mod h1:DInSFKxm9XHHSbCdJRbcWctRYkmtPGnqiaUtgjiEa7g= -github.com/libp2p/go-libp2p-transport v0.0.0-20190226201958-e8580c8a519d/go.mod h1:lcwgOszllbhvQXul37Kv5YbSYXPoUhRB2Z+Nr3jaBmo= +github.com/libp2p/go-libp2p-swarm v0.1.0 h1:HrFk2p0awrGEgch9JXK/qp/hfjqQfgNxpLWnCiWPg5s= +github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= +github.com/libp2p/go-libp2p-testing v0.0.1/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.4 h1:Qev57UR47GcLPXWjrunv5aLIQGO4n9mhI/8/EIrEEFc= +github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-tls v0.1.0 h1:o4bjjAdnUjNgJoPoDd0wUaZH7K+EenlNWJpgyXB3ulA= +github.com/libp2p/go-libp2p-tls v0.1.0/go.mod h1:VZdoSWQDeNpIIAFJFv+6uqTqpnIIDHcqZQSTC/A1TT0= github.com/libp2p/go-libp2p-transport v0.0.1/go.mod h1:UzbUs9X+PHOSw7S3ZmeOxfnwaQY5vGDzZmKPod3N3tk= github.com/libp2p/go-libp2p-transport v0.0.4 h1:/CPHQMN75/IQwkhBxxIo6p6PtL3rwFZtlzBROT3e8mw= github.com/libp2p/go-libp2p-transport v0.0.4/go.mod h1:StoY3sx6IqsP6XKoabsPnHCwqKXWUMWU7Rfcsubee/A= @@ -496,25 +685,35 @@ github.com/libp2p/go-libp2p-transport v0.0.5 h1:pV6+UlRxyDpASSGD+60vMvdifSCby6Jk github.com/libp2p/go-libp2p-transport v0.0.5/go.mod h1:StoY3sx6IqsP6XKoabsPnHCwqKXWUMWU7Rfcsubee/A= github.com/libp2p/go-libp2p-transport-upgrader v0.0.1 h1:rNtXkY6dty46mxYOHHAZQchI7gQdJStF683FhVnei/k= github.com/libp2p/go-libp2p-transport-upgrader v0.0.1/go.mod h1:NJpUAgQab/8K6K0m+JmZCe5RUXG10UMEx4kWe9Ipj5c= -github.com/libp2p/go-libp2p-transport-upgrader v0.0.3/go.mod h1:Ng1HzfMIopyYscMHNFmJqiMMcpgDlj0t+NyjVWW89ws= +github.com/libp2p/go-libp2p-transport-upgrader v0.0.2/go.mod h1:NJpUAgQab/8K6K0m+JmZCe5RUXG10UMEx4kWe9Ipj5c= github.com/libp2p/go-libp2p-transport-upgrader v0.0.4 h1:uGMOd14BL1oFlfb/cGfOxPjiTKBhzWV4aMjjoCF1Z1o= github.com/libp2p/go-libp2p-transport-upgrader v0.0.4/go.mod h1:RGq+tupk+oj7PzL2kn/m1w6YXxcIAYJYeI90h6BGgUc= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1 h1:PZMS9lhjK9VytzMCW3tWHAXtKXmlURSc3ZdvwEcKCzw= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= github.com/libp2p/go-libp2p-yamux v0.1.2/go.mod h1:xUoV/RmYkg6BW/qGxA9XJyg+HzXFYkeXbnhjmnYzKp8= github.com/libp2p/go-libp2p-yamux v0.1.3 h1:HmKvv2jWJ4GEm3iP7cEKjuw0POa6rK+Hcsu1FBKzpLc= github.com/libp2p/go-libp2p-yamux v0.1.3/go.mod h1:VGSQVrqkh6y4nm0189qqxMtvyBft44MOYYPpYKXiVt4= +github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= +github.com/libp2p/go-libp2p-yamux v0.2.1 h1:Q3XYNiKCC2vIxrvUJL+Jg1kiyeEaIDNKLjgEjo3VQdI= +github.com/libp2p/go-libp2p-yamux v0.2.1/go.mod h1:1FBXiHDk1VyRM1C0aez2bCfHQ4vMZKkAQzZbkSQt5fI= github.com/libp2p/go-maddr-filter v0.0.1 h1:apvYTg0aIxxQyBX+XHKOR+0+lYhGs1Yv+JmTH9nyl5I= github.com/libp2p/go-maddr-filter v0.0.1/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= github.com/libp2p/go-maddr-filter v0.0.4 h1:hx8HIuuwk34KePddrp2mM5ivgPkZ09JH4AvsALRbFUs= github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= github.com/libp2p/go-mplex v0.0.1 h1:dn2XGSrUxLtz3/8u85bGrwhUEKPX8MOF3lpmcWBZCWc= github.com/libp2p/go-mplex v0.0.1/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.0.2/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= github.com/libp2p/go-mplex v0.0.4 h1:043XJ3Zr7/Oz5cfyUaJwxUZyP02TngTpt4oq8R5UizQ= github.com/libp2p/go-mplex v0.0.4/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.1.0 h1:/nBTy5+1yRyY82YaO6HXQRnO5IAGsXTjEJaR3LdTPc0= +github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= github.com/libp2p/go-msgio v0.0.1 h1:znj97n5FtXGCLDwe9x8jpHmY770SW4WStBGcCDh6GJw= github.com/libp2p/go-msgio v0.0.1/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.0.2 h1:ivPvEKHxmVkTClHzg6RXTYHqaJQ0V9cDbq+6lKb3UV0= github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-msgio v0.0.3 h1:VsOlWispTivSsOMg70e0W77y6oiSBSRCyP6URrWvE04= +github.com/libp2p/go-msgio v0.0.3/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-nat v0.0.3 h1:l6fKV+p0Xa354EqQOQP+d8CivdLM4kl5GxC1hSc/UeI= github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= @@ -523,32 +722,39 @@ github.com/libp2p/go-reuseport-transport v0.0.1 h1:UIRneNxLDmEGNjGHpIiWzSWkZ5bhx github.com/libp2p/go-reuseport-transport v0.0.1/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= github.com/libp2p/go-reuseport-transport v0.0.2 h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4= github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= -github.com/libp2p/go-stream-muxer v0.0.0-20190218175335-a3f82916c8ad/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= github.com/libp2p/go-stream-muxer v0.0.1 h1:Ce6e2Pyu+b5MC1k3eeFtAax0pW4gc6MosYSLV05UeLw= github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/libp2p/go-stream-muxer v0.1.0 h1:3ToDXUzx8pDC6RfuOzGsUYP5roMDthbUKRdMRRhqAqY= +github.com/libp2p/go-stream-muxer v0.1.0/go.mod h1:8JAVsjeRBCWwPoZeH0W1imLOcriqXJyFvB0mR4A04sQ= github.com/libp2p/go-stream-muxer-multistream v0.1.1 h1:DhHqb4nu1fQv/vQKeLAaZGmhLsUA4SF77IdYJiWE1d4= github.com/libp2p/go-stream-muxer-multistream v0.1.1/go.mod h1:zmGdfkQ1AzOECIAcccoL8L//laqawOsO03zX8Sa+eGw= +github.com/libp2p/go-stream-muxer-multistream v0.2.0 h1:714bRJ4Zy9mdhyTLJ+ZKiROmAFwUHpeRidG+q7LTQOg= +github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= github.com/libp2p/go-tcp-transport v0.0.1 h1:WyvJVw2lYAnr6CU+GZZ4oCt06fvORlmvBlFX2+ZpZDM= github.com/libp2p/go-tcp-transport v0.0.1/go.mod h1:mnjg0o0O5TmXUaUIanYPUqkW4+u6mK0en8rlpA6BBTs= -github.com/libp2p/go-tcp-transport v0.0.3/go.mod h1:f11C2zvCaGDkE8aFPUKmuYZwd3pP6HI24LeLMWhJnkQ= +github.com/libp2p/go-tcp-transport v0.0.2/go.mod h1:VjZFHasNJ0QiJQNNwiFDy25qyGWTXQWs8GM5DR4/L1k= github.com/libp2p/go-tcp-transport v0.0.4 h1:2iRu994wCT/iEz62F+c60FUoSkijNEQ0q2Itc+79XlQ= github.com/libp2p/go-tcp-transport v0.0.4/go.mod h1:+E8HvC8ezEVOxIo3V5vCK9l1y/19K427vCzQ+xHKH/o= +github.com/libp2p/go-tcp-transport v0.1.0 h1:IGhowvEqyMFknOar4FWCKSWE0zL36UFKQtiRQD60/8o= +github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= github.com/libp2p/go-testutil v0.0.1 h1:Xg+O0G2HIMfHqBOBDcMS1iSZJ3GEcId4qOxCQvsGZHk= github.com/libp2p/go-testutil v0.0.1/go.mod h1:iAcJc/DKJQanJ5ws2V+u5ywdL2n12X1WbbEG+Jjy69I= +github.com/libp2p/go-testutil v0.1.0/go.mod h1:81b2n5HypcVyrCg/MJx4Wgfp/VHojytjVe/gLzZ2Ehc= github.com/libp2p/go-ws-transport v0.0.1/go.mod h1:p3bKjDWHEgtuKKj+2OdPYs5dAPIjtpQGHF2tJfGz7Ww= -github.com/libp2p/go-ws-transport v0.0.3/go.mod h1:iU0kzfMcO4tBVIk3z+7srp1YG/RFLWTSuO4enpivw8g= -github.com/libp2p/go-ws-transport v0.0.4 h1:3wt9ed0gIUrne627XHvPMTwG4/AUpsLDy4TGQi2EyQ0= -github.com/libp2p/go-ws-transport v0.0.4/go.mod h1:X9wfEcm2LAJYMox9x2VHAMHAZZSQMFC9mIa/UF6OuZk= +github.com/libp2p/go-ws-transport v0.0.2/go.mod h1:p3bKjDWHEgtuKKj+2OdPYs5dAPIjtpQGHF2tJfGz7Ww= +github.com/libp2p/go-ws-transport v0.0.5 h1:IHeR0X9nvE5hOdOD8X/FDQ6jIapdohToQseItwvpixU= +github.com/libp2p/go-ws-transport v0.0.5/go.mod h1:Qbl4BxPfXXhhd/o0wcrgoaItHqA9tnZjoFZnxykuaXU= +github.com/libp2p/go-ws-transport v0.1.0 h1:F+0OvvdmPTDsVc4AjPHjV7L7Pk1B7D5QwtDcKE2oag4= +github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo= github.com/libp2p/go-yamux v1.2.1/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.2.3 h1:xX8A36vpXb59frIzWFdEgptLMsOANMFq2K7fPRlunYI= github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= -github.com/lucas-clemente/aes12 v0.0.0-20171027163421-cd47fb39b79f/go.mod h1:JpH9J1c9oX6otFSgdUHwUBUizmKlrMjxWnIAjff4m04= -github.com/lucas-clemente/quic-go v0.10.0/go.mod h1:wuD+2XqEx8G9jtwx5ou2BEYBsE+whgQmlj0Vz/77PrY= github.com/lucas-clemente/quic-go v0.11.1 h1:zasajC848Dqq/+WqfqBCkmPw+YHNe1MBts/z7y7nXf4= github.com/lucas-clemente/quic-go v0.11.1/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw= -github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced/go.mod h1:NCcRLrOTZbzhZvixZLlERbJtDtYsmMw8Jc4vS8Z0g58= +github.com/lucas-clemente/quic-go v0.11.2 h1:Mop0ac3zALaBR3wGs6j8OYe/tcFvFsxTUFMkE/7yUOI= +github.com/lucas-clemente/quic-go v0.11.2/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw= github.com/magiconair/properties v1.7.6/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -561,14 +767,19 @@ github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRU github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.2/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/miekg/dns v1.1.4 h1:rCMZsU2ScVSYcAsOXgmC6+AKOK+6pmQTOcw03nfwYV0= @@ -581,6 +792,8 @@ github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XC github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5 h1:l16XLUUJ34wIz+RIvLhSwGvLvKyy+W598b135bJN6mg= github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0 h1:U41/2erhAKcmSI14xh/ZTUdBPOzDOIfS93ibzUSl8KM= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -592,6 +805,7 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mozilla/tls-observatory v0.0.0-20180409132520-8791a200eb40/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= @@ -605,6 +819,8 @@ github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lg github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.0.2 h1:/Bbsgsy3R6e3jf2qBahzNHzww6usYaZ0NhNH3sqdFS8= github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-fmt v0.0.1 h1:5YjeOIzbX8OTKVaN72aOzGIYW7PnrZrnkDyOfAWRSMA= +github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= github.com/multiformats/go-multiaddr-net v0.0.1 h1:76O59E3FavvHqNg7jvzWzsPSW5JSi/ek0E4eiDVbg9g= github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= @@ -615,10 +831,15 @@ github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPk github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= github.com/multiformats/go-multihash v0.0.5 h1:1wxmCvTXAifAepIMyF39vZinRw5sbqjPs/UIi93+uik= github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= +github.com/multiformats/go-multihash v0.0.6 h1:cAVKO4epVd+SSpYJQD6d3vbdqQJvsrtGbTGzsp+V094= +github.com/multiformats/go-multihash v0.0.6/go.mod h1:XuKXPp8VHcTygube3OWZC+aZrA+H1IhmjoCDtJc7PXM= github.com/multiformats/go-multistream v0.0.1 h1:JV4VfSdY9n7ECTtY59/TlSyFCzRILvYx4T4Ws8ZgihU= github.com/multiformats/go-multistream v0.0.1/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/multiformats/go-multistream v0.0.3/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/multiformats/go-multistream v0.0.4 h1:rNgWgFyzRSTI9L+xISrz7kN5MdNXoEcoIeeCH05wLKA= github.com/multiformats/go-multistream v0.0.4/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/multiformats/go-multistream v0.1.0 h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ= +github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/mutecomm/go-sqlcipher v0.0.0-20190227152316-55dbde17881f h1:hd3r+uv9DNLScbOrnlj82rBldHQf3XWmCeXAWbw8euQ= github.com/mutecomm/go-sqlcipher v0.0.0-20190227152316-55dbde17881f/go.mod h1:MyUWrZlB1aI5bs7j9/pJ8ckLLZ4QcCYcNiSbsAW32D4= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -631,7 +852,6 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= @@ -640,8 +860,12 @@ github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -649,27 +873,43 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992 h1:bzMe+2coZJYHnhGgVlcQKuRy4FSny4ds8dLQjw5P1XE= github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/polydawn/refmt v0.0.0-20190408063855-01bf1e26dd14 h1:2m16U/rLwVaRdz7ANkHtHTodP3zTP3N451MADg64x5k= +github.com/polydawn/refmt v0.0.0-20190408063855-01bf1e26dd14/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v0.9.4 h1:Y8E/JaaPbmFSW2V81Ab/d8yZFYQQGbni1b1jPcG9Y6A= +github.com/prometheus/client_golang v0.9.4/go.mod h1:oCXIBxdI62A4cR6aTRJCgetEjecSIYzOEaeAn4iYEpM= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.0-20190519111021-9935e8e0588d h1:Z5QMcUKnQw7ouB1wDuyZM6TL/rm+brJcNk6Ai8ut3zM= github.com/prometheus/procfs v0.0.0-20190519111021-9935e8e0588d/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI= github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd h1:CmH9+J6ZSsIjUK3dcGsnCnO41eRBOnY12zwkn5qVwgc= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= -github.com/sanderpick/go-ipfs v0.4.22-0.20190606034924-0478a0eca246 h1:yeq2vbSMKIXZ+pA5LrnIKDTn85TUIrB2Q1Sps03JgrQ= -github.com/sanderpick/go-ipfs v0.4.22-0.20190606034924-0478a0eca246/go.mod h1:T9zAmGO+rzbvLjDUm0DHtYXtdT4GhWOZeCPztgmt2V8= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/segmentio/ksuid v1.0.2 h1:9yBfKyw4ECGTdALaF09Snw3sLJmYIX6AbPJrAy6MrDc= github.com/segmentio/ksuid v1.0.2/go.mod h1:BXuJDr2byAiHuQaQtSKoXh1J0YmUDurywOXgB2w+OSU= @@ -682,8 +922,10 @@ github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjM github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa h1:E+gaaifzi2xF65PbDmuKI3PhLWY6G5opMLniFq8vmXA= github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= +github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE= github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= @@ -712,10 +954,13 @@ github.com/swaggo/swag v1.5.0/go.mod h1:+xZrnu5Ut3GcUkKAJm9spnOooIS1WB1cUOkLNPrv github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/tyler-smith/go-bip39 v0.0.0-20181017060643-dbb3b84ba2ef h1:luEzjJzktS9eU0CmI0uApXHLP/lKzOoRPrJhd71J8ik= github.com/tyler-smith/go-bip39 v0.0.0-20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/ugorji/go v1.1.2 h1:JON3E2/GPW2iDNGoSAusl1KDf5TRQ8k8q7Tp097pZGs= github.com/ugorji/go v1.1.2/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= +github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v0.0.0-20190320090025-2dc34c0b8780 h1:vG/gY/PxA3v3l04qxe3tDjXyu3bozii8ulSlIPOYKhI= github.com/ugorji/go/codec v0.0.0-20190320090025-2dc34c0b8780/go.mod h1:iT03XoTwV7xq/+UGwKO3UbC1nNNlopQiY61beSdrtOA= @@ -723,6 +968,7 @@ github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436 h1:qOpVTI+BrstcjTZLm2Yz/3sOnqkzj3FQoh0g+E5s3Gc= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= @@ -736,13 +982,10 @@ github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6 github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f h1:M/lL30eFZTKnomXY6huvM6G0+gVquFNf6mxghaWlFUg= github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8= -github.com/whyrusleeping/go-smux-multiplex v0.1.0/go.mod h1:OXL5hggHNZSsadXDlBJDD4eD3IQYEB3Yu6xpovd6pPw= github.com/whyrusleeping/go-smux-multiplex v3.0.16+incompatible h1:iqksILj8STw03EJQe7Laj4ubnw+ojOyik18cd5vPL1o= github.com/whyrusleeping/go-smux-multiplex v3.0.16+incompatible/go.mod h1:34LEDbeKFZInPUrAG+bjuJmUXONGdEFW7XL0SpTY1y4= -github.com/whyrusleeping/go-smux-multistream v0.1.0/go.mod h1:/usW3LIBirW4h9ko1PnoF7tExBnbxPBszG0n4wylJr8= github.com/whyrusleeping/go-smux-multistream v2.0.2+incompatible h1:BdYHctE9HJZLquG9tpTdwWcbG4FaX6tVKPGjCGgiVxo= github.com/whyrusleeping/go-smux-multistream v2.0.2+incompatible/go.mod h1:dRWHHvc4HDQSHh9gbKEBbUZ+f2Q8iZTPG3UOGYODxSQ= -github.com/whyrusleeping/go-smux-yamux v0.1.1/go.mod h1:Yw+ayOEKERDHXLJ4GiE5AnBmldJW4QRLDzGFC9do8G0= github.com/whyrusleeping/go-smux-yamux v2.0.8+incompatible/go.mod h1:6qHUzBXUbB9MXmw3AUdB52L8sEb/hScCqOdW2kj/wuI= github.com/whyrusleeping/go-smux-yamux v2.0.9+incompatible h1:nVkExQ7pYlN9e45LcqTCOiDD0904fjtm0flnHZGbXkw= github.com/whyrusleeping/go-smux-yamux v2.0.9+incompatible/go.mod h1:6qHUzBXUbB9MXmw3AUdB52L8sEb/hScCqOdW2kj/wuI= @@ -758,15 +1001,18 @@ github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee h1:lYbXeSv github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= github.com/whyrusleeping/yamux v1.1.5 h1:4CK3aUUJQu0qpKZv5gEWJjNOQtdbdDhVVS6PJ+HimdE= github.com/whyrusleeping/yamux v1.1.5/go.mod h1:E8LnQQ8HKx5KD29HZFUwM1PxCOdPRzGwur1mcYhXcD8= -github.com/whyrusleeping/yamux v1.2.0/go.mod h1:Cgw3gpb4DrDZ1FrP/5pxg/cpiY54Gr5uCXwUylwi2GE= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.1.0 h1:ngVtJC9TY/lg0AA/1k48FYhBrhRoFlEmWzsehpNAaZg= github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= +github.com/zenground0/go-dot v0.0.0-20180912213407-94a425d4984e/go.mod h1:T00FaxHq4SlnicuZFole4yRAgcjWtqbMcUXBfXAYvaI= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/dig v1.7.0 h1:E5/L92iQTNJTjfgJF2KgU+/JpMaiuvK2DHLBj0+kSZk= @@ -793,16 +1039,25 @@ golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/Le golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo= golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2 h1:y102fOLFqhV41b+4GPiJoa0k/x+pJcEi2/HB1Y5T6fU= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81 h1:00VmoueYNlNz/aHIilyyQz/MHSqGoWJzpFv/HW8xpzI= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= -golang.org/x/image v0.0.0-20190321063152-3fc05d484e9f h1:FO4MZ3N56GnxbqxGKqh+YTzUWQ2sDwtFQEZgLOxh9Jc= -golang.org/x/image v0.0.0-20190321063152-3fc05d484e9f/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190507092727-e4e5bf290fec h1:arXJwtMuk5vqI1NHX0UTnNw977rYk5Sl4jQqHj+hun4= +golang.org/x/image v0.0.0-20190507092727-e4e5bf290fec/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/net v0.0.0-20170324220409-6c2325251549/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20170915142106-8351a756f30f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -813,18 +1068,25 @@ golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190225153610-fe579d43d832/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190310074541-c10a0554eabf/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190322120337-addf6b3196f6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522135303-fa69b94a3b58 h1:AZ8FNE2w7DVDFDK6u/iC9/Mqh73UupjaqSd/2qMoECQ= -golang.org/x/net v0.0.0-20190522135303-fa69b94a3b58/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190520210107-018c4d40a106/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190611141213-3f473d35a33a h1:+KkCgOMgnKSgenxTBoiwkMqTiouMIy/3o8RLdmSbGoY= +golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw= @@ -839,51 +1101,84 @@ golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190302025703-b6889370fb10/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190310054646-10058d7d4faa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5 h1:f005F/Jl5JLP036x7QIvUVhNTqxvSYwFIiyOh2q12iU= -golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190520201301-c432e742b0af/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190524122548-abf6ff778158/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190524152521-dbbf3f1254d4 h1:VSJ45BzqrVgR4clSx415y1rHH7QAGhGt71J0ZmhLYrc= +golang.org/x/sys v0.0.0-20190524152521-dbbf3f1254d4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae h1:xiXzMMEQdQcric9hXtr1QU98MHunKK7OTtsoU6bYWs4= +golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190614084037-d442b75600c5 h1:tQrtnaPeNyfkuD2UMixVD6lAa7WngkIFvtWcdzNeq80= +golang.org/x/sys v0.0.0-20190614084037-d442b75600c5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20170915090833-1cbadb444a80/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/tools v0.0.0-20170915040203-e531a2a1c15f/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181024171208-a2dc47679d30/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181205014116-22934f0fdb62/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190110015856-aa033095749b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190121143147-24cd39ecf745/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190420000508-685fecacd0a0/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd h1:7E3PabyysDSEjnaANKBgums/hyvMI/HoHQ50qZEzTrg= golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/xerrors v0.0.0-20190212162355-a5947ffaace3 h1:P6iTFmrTQqWrqLZPX1VMzCUbCRCAUXSUsSpkEOvWzJ0= -golang.org/x/xerrors v0.0.0-20190212162355-a5947ffaace3/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522 h1:bhOzK9QyoD0ogCnFro1m2mz41+Ib0oOhfJnBp5MR4K4= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.0.0-20190520094443-a5f8f3a4840b h1:6TIR0pAaLZhSQXUKh+yxFO4qaPuWt+ZlC8cEVzeME5I= +gonum.org/v1/gonum v0.0.0-20190520094443-a5f8f3a4840b/go.mod h1:zXcK6UmEkbNk22MqyPrZPx3T6fsE/O56XzkDfeYUF+Y= +gonum.org/v1/gonum v0.0.0-20190608115022-c5f01565d866 h1:FqYrBXUEWecz6YveEJaEVE2Hz7IZuKxUbyXGn//xmEs= +gonum.org/v1/gonum v0.0.0-20190608115022-c5f01565d866/go.mod h1:zXcK6UmEkbNk22MqyPrZPx3T6fsE/O56XzkDfeYUF+Y= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b h1:Qh4dB5D/WpoUUp3lSod7qgoyEHbDGPUWjIbnqdqqe1k= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/api v0.3.2 h1:iTp+3yyl/KOtxa/d1/JUE0GGSoR6FuW5udver22iwpw= +google.golang.org/api v0.3.2/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19 h1:Lj2SnHtxkRGJDqnGaSjo+CCdIieEnwVazbOXILwQemk= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb h1:i1Ppqkc3WQXikh8bXiwHqAN5Rv3/qDCcRk0/Otx73BY= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0 h1:G+97AoqBnmZIT91cLG/EkCoK9NSelj64P8bOHHNmGn0= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -911,8 +1206,11 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v2.1.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/gotestsum v0.3.4/go.mod h1:Mnf3e5FUzXbkCfynWBGOwLssY7gTQgCHObK9tMpAriY= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= mvdan.cc/unparam v0.0.0-20190124213536-fbb59629db34/go.mod h1:H6SUd1XjIs+qQCyskXg5OFSrilMRUkD8ePJpHKDPaeY= +rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/ipfs/cluster.go b/ipfs/cluster.go new file mode 100644 index 00000000..8b09433f --- /dev/null +++ b/ipfs/cluster.go @@ -0,0 +1,75 @@ +package ipfs + +import ( + "context" + + icid "github.com/ipfs/go-cid" + "github.com/ipfs/go-ipfs/core" + "github.com/ipfs/ipfs-cluster/api" + rpc "github.com/libp2p/go-libp2p-gorpc" + peer "github.com/libp2p/go-libp2p-peer" +) + +func NewClusterConnector(node *core.IpfsNode) *ClusterConnector { + return &ClusterConnector{node: node} +} + +type ClusterConnector struct { + node *core.IpfsNode +} + +func (c *ClusterConnector) ID(context.Context) (*api.IPFSID, error) { + panic("implement me") +} + +func (c *ClusterConnector) SetClient(*rpc.Client) { + panic("implement me") +} + +func (c *ClusterConnector) Shutdown(context.Context) error { + panic("implement me") +} + +func (c *ClusterConnector) Pin(context.Context, icid.Cid, int) error { + panic("implement me") +} + +func (c *ClusterConnector) Unpin(context.Context, icid.Cid) error { + panic("implement me") +} + +func (c *ClusterConnector) PinLsCid(context.Context, icid.Cid) (api.IPFSPinStatus, error) { + panic("implement me") +} + +func (c *ClusterConnector) PinLs(ctx context.Context, typeFilter string) (map[string]api.IPFSPinStatus, error) { + panic("implement me") +} + +func (c *ClusterConnector) ConnectSwarms(context.Context) error { + panic("implement me") +} + +func (c *ClusterConnector) SwarmPeers(context.Context) ([]peer.ID, error) { + panic("implement me") +} + +func (c *ClusterConnector) ConfigKey(keypath string) (interface{}, error) { + panic("implement me") +} + +func (c *ClusterConnector) RepoStat(context.Context) (*api.IPFSRepoStat, error) { + panic("implement me") +} + +func (c *ClusterConnector) Resolve(context.Context, string) (icid.Cid, error) { + panic("implement me") +} + +func (c *ClusterConnector) BlockPut(context.Context, *api.NodeWithMeta) error { + panic("implement me") +} + +func (c *ClusterConnector) BlockGet(context.Context, icid.Cid) ([]byte, error) { + panic("implement me") +} diff --git a/ipfs/swarm.go b/ipfs/swarm.go index 0853371a..22f463b6 100644 --- a/ipfs/swarm.go +++ b/ipfs/swarm.go @@ -7,7 +7,7 @@ import ( "github.com/ipfs/go-ipfs/core" "github.com/ipfs/go-ipfs/core/coreapi" - inet "github.com/libp2p/go-libp2p-net" + inet "github.com/libp2p/go-libp2p-core/network" ) // SwarmConnect opens a direct connection to a list of peer multi addresses diff --git a/repo/config/init_ipfs.go b/repo/config/init_ipfs.go index b4dc1c81..1549a9a7 100644 --- a/repo/config/init_ipfs.go +++ b/repo/config/init_ipfs.go @@ -6,6 +6,7 @@ import ( ipfs "github.com/ipfs/go-ipfs" native "github.com/ipfs/go-ipfs-config" + "github.com/libp2p/go-libp2p-core/peer" ) // DefaultServerFilters has is a list of IPv4 and IPv6 prefixes that are private, local only, or unrouteable. @@ -49,7 +50,7 @@ var TextileBootstrapAddresses = []string{ } // TextileBootstrapPeers returns the (parsed) set of Textile bootstrap peers. -func TextileBootstrapPeers() ([]native.BootstrapPeer, error) { +func TextileBootstrapPeers() ([]peer.AddrInfo, error) { ps, err := native.ParseBootstrapPeers(TextileBootstrapAddresses) if err != nil { return nil, fmt.Errorf(`failed to parse hardcoded bootstrap peers: %s diff --git a/service/main.go b/service/main.go index 6dde617d..62ff8f2e 100644 --- a/service/main.go +++ b/service/main.go @@ -20,7 +20,7 @@ import ( logging "github.com/ipfs/go-log" iface "github.com/ipfs/interface-go-ipfs-core" ctxio "github.com/jbenet/go-context/io" - inet "github.com/libp2p/go-libp2p-net" + inet "github.com/libp2p/go-libp2p-core/network" peer "github.com/libp2p/go-libp2p-peer" protocol "github.com/libp2p/go-libp2p-protocol" "github.com/textileio/go-textile/crypto" diff --git a/service/sender.go b/service/sender.go index 8d380a80..8d2d468e 100644 --- a/service/sender.go +++ b/service/sender.go @@ -7,7 +7,8 @@ import ( "time" ggio "github.com/gogo/protobuf/io" - inet "github.com/libp2p/go-libp2p-net" + "github.com/libp2p/go-libp2p-core/helpers" + inet "github.com/libp2p/go-libp2p-core/network" peer "github.com/libp2p/go-libp2p-peer" "github.com/textileio/go-textile/pb" ) @@ -133,7 +134,7 @@ func (ms *messageSender) SendMessage(ctx context.Context, pmes *pb.Envelope) err } if ms.singleMes > streamReuseTries { - go inet.FullClose(ms.s) + go helpers.FullClose(ms.s) ms.s = nil } else if retry { ms.singleMes++ @@ -181,7 +182,7 @@ func (ms *messageSender) SendRequest(ctx context.Context, pmes *pb.Envelope) (*p } if ms.singleMes > streamReuseTries { - go inet.FullClose(ms.s) + go helpers.FullClose(ms.s) ms.s = nil } else if retry { ms.singleMes++ From a117256e056f33bfa5b3b537a1354e634a9c82f0 Mon Sep 17 00:00:00 2001 From: Sander Pick Date: Sat, 15 Jun 2019 16:04:26 -0700 Subject: [PATCH 02/12] cluster: add config and lifecycle management Signed-off-by: Sander Pick --- core/cluster.go | 68 +++++++++++++++++++++++++++++++++++---------- core/config.go | 51 ++++++++++++++++++---------------- core/main.go | 45 ++++++++++++++++++++++-------- repo/config/init.go | 28 ++++++++++--------- 4 files changed, 130 insertions(+), 62 deletions(-) diff --git a/core/cluster.go b/core/cluster.go index 8fd59440..23a4158b 100644 --- a/core/cluster.go +++ b/core/cluster.go @@ -3,9 +3,11 @@ package core import ( "context" "fmt" + "path/filepath" "time" ds "github.com/ipfs/go-datastore" + util "github.com/ipfs/go-ipfs-util" ipfscluster "github.com/ipfs/ipfs-cluster" "github.com/ipfs/ipfs-cluster/allocator/ascendalloc" "github.com/ipfs/ipfs-cluster/allocator/descendalloc" @@ -64,18 +66,51 @@ func makeConfigs() (*config.Manager, *cfgs) { func makeAndLoadConfigs(repoPath string) (*config.Manager, *cfgs, error) { cfgMgr, cfgs := makeConfigs() - err := cfgMgr.LoadJSONFileAndEnv(repoPath) + err := cfgMgr.LoadJSONFromFile(repoPath) if err != nil { return nil, nil, err } return cfgMgr, cfgs, nil } -// createCluster creates all the necessary things to produce the cluster object -func (t *Textile) createCluster(ctx context.Context, bootstraps []ma.Multiaddr) (*ipfscluster.Cluster, error) { +func parseBootstraps(addrs []string) ([]ma.Multiaddr, error) { + var parsed []ma.Multiaddr + for _, a := range addrs { + p, err := ma.NewMultiaddr(a) + if err != nil { + return nil, err + } + parsed = append(parsed, p) + } + return parsed, nil +} + +func initCluster(repoPath, secret string) error { + decoded, err := ipfscluster.DecodeClusterSecret(secret) + if err != nil { + return err + } + + cfgMgr, cfgs := makeConfigs() + err = cfgMgr.Default() + if err != nil { + return err + } + cfgs.clusterCfg.Secret = decoded + + return cfgMgr.SaveJSON(repoPath) +} + +func (t *Textile) clusterExists() bool { + cpath := filepath.Join(t.repoPath, "service.json") + return util.FileExists(cpath) +} + +// startCluster creates all the necessary things to produce the cluster object +func (t *Textile) startCluster() error { cfgMgr, cfgs, err := makeAndLoadConfigs(t.repoPath) if err != nil { - return nil, err + return nil } defer cfgMgr.Shutdown() @@ -89,7 +124,7 @@ func (t *Textile) createCluster(ctx context.Context, bootstraps []ma.Multiaddr) cfgs.clusterCfg.Peername, ) if err != nil { - return nil, err + return nil } informer, alloc, err := setupAllocation( @@ -98,7 +133,7 @@ func (t *Textile) createCluster(ctx context.Context, bootstraps []ma.Multiaddr) cfgs.numpinInfCfg, ) if err != nil { - return nil, err + return nil } ipfscluster.ReadyTimeout = raft.DefaultWaitForLeaderTimeout + 5*time.Second @@ -111,17 +146,17 @@ func (t *Textile) createCluster(ctx context.Context, bootstraps []ma.Multiaddr) t.node.Repo.Datastore(), ) if err != nil { - return nil, err + return nil } var peersF func(context.Context) ([]peer.ID, error) - mon, err := pubsubmon.New(ctx, cfgs.pubsubmonCfg, t.node.PubSub, peersF) + mon, err := pubsubmon.New(t.node.Context(), cfgs.pubsubmonCfg, t.node.PubSub, peersF) if err != nil { - return nil, err + return nil } - cluster, err := ipfscluster.NewCluster( - ctx, + t.cluster, err = ipfscluster.NewCluster( + t.node.Context(), t.node.PeerHost, t.node.DHT, cfgs.clusterCfg, @@ -136,7 +171,12 @@ func (t *Textile) createCluster(ctx context.Context, bootstraps []ma.Multiaddr) nil, ) if err != nil { - return nil, err + return nil + } + + bootstraps, err := parseBootstraps(t.config.Cluster.Bootstraps) + if err != nil { + return nil } // noop if no bootstraps @@ -144,9 +184,9 @@ func (t *Textile) createCluster(ctx context.Context, bootstraps []ma.Multiaddr) // and timeout. So this can happen in background and we // avoid worrying about error handling here (since Cluster // will realize). - go bootstrap(ctx, cluster, bootstraps) + go bootstrap(t.node.Context(), t.cluster, bootstraps) - return cluster, nil + return nil } // bootstrap will bootstrap this peer to one of the bootstrap addresses diff --git a/core/config.go b/core/config.go index 3209667c..4823587d 100644 --- a/core/config.go +++ b/core/config.go @@ -21,6 +21,28 @@ func (t *Textile) Config() *config.Config { return t.config } +// ConvertHeadersToCorsOptions converts http headers into the format that cors options accepts +func ConvertHeadersToCorsOptions(headers config.HTTPHeaders) cors.Options { + options := cors.Options{} + + control, ok := headers["Access-Control-Allow-Origin"] + if ok && len(control) > 0 { + options.AllowedOrigins = control + } + + control, ok = headers["Access-Control-Allow-Methods"] + if ok && len(control) > 0 { + options.AllowedMethods = control + } + + control, ok = headers["Access-Control-Allow-Headers"] + if ok && len(control) > 0 { + options.AllowedHeaders = control + } + + return options +} + // GetRandomPort returns a port within the acceptable range func GetRandomPort() string { rand.Seed(time.Now().UTC().UnixNano()) @@ -70,12 +92,15 @@ func applyTextileConfigOptions(init InitConfig) error { conf.Cafe.Host.URL = init.CafeURL conf.Cafe.Host.NeighborURL = init.CafeNeighborURL + // cluster settings + conf.Cluster.Bootstraps = init.ClusterPeers + // write to disk return config.Write(init.RepoPath, conf) } -// applySwarmPortConfigOption sets custom swarm ports (tcp and ws) -func applySwarmPortConfigOption(rep repo.Repo, ports string) error { +// applyIPFSSwarmPorts writes swarm ports (tcp and ws) to the IPFS config +func applyIPFSSwarmPorts(rep repo.Repo, ports string) error { var parts []string if ports != "" { parts = strings.Split(ports, ",") @@ -177,25 +202,3 @@ func ensureProfile(profile profile, repoPath string) error { return rep.SetConfig(conf) } - -// ConvertHeadersToCorsOptions converts http headers into the format that cors options accepts -func ConvertHeadersToCorsOptions(headers config.HTTPHeaders) cors.Options { - options := cors.Options{} - - control, ok := headers["Access-Control-Allow-Origin"] - if ok && len(control) > 0 { - options.AllowedOrigins = control - } - - control, ok = headers["Access-Control-Allow-Methods"] - if ok && len(control) > 0 { - options.AllowedMethods = control - } - - control, ok = headers["Access-Control-Allow-Headers"] - if ok && len(control) > 0 { - options.AllowedHeaders = control - } - - return options -} diff --git a/core/main.go b/core/main.go index 43fa11db..49858a9c 100644 --- a/core/main.go +++ b/core/main.go @@ -19,6 +19,7 @@ import ( "github.com/ipfs/go-ipfs/repo/fsrepo" ipld "github.com/ipfs/go-ipld-format" logging "github.com/ipfs/go-log" + ipfscluster "github.com/ipfs/ipfs-cluster" peer "github.com/libp2p/go-libp2p-peer" "github.com/textileio/go-textile/broadcast" "github.com/textileio/go-textile/ipfs" @@ -60,7 +61,9 @@ type InitConfig struct { Debug bool CafeOpen bool CafeURL string - CafeNeighborURL string + CafeNeighborURL string // Deprecated + ClusterSecret string + ClusterPeers []string } // MigrateConfig is used to define options during a major migration @@ -86,6 +89,7 @@ type Textile struct { cancel context.CancelFunc node *core.IpfsNode datastore repo.Datastore + cluster *ipfscluster.Cluster started bool loadedThreads []*Thread online chan struct{} @@ -138,21 +142,19 @@ func InitRepo(conf InitConfig) error { return err } - rep, err := fsrepo.Open(conf.RepoPath) - if err != nil { - return err - } - defer func() { - if err := rep.Close(); err != nil { - log.Error(err.Error()) + // init cluster + if conf.ClusterSecret != "" { + err = initCluster(conf.RepoPath, conf.ClusterSecret) + if err != nil { + return err } - }() + } - // apply ipfs config opts - err = applySwarmPortConfigOption(rep, conf.SwarmPorts) + rep, err := fsrepo.Open(conf.RepoPath) if err != nil { return err } + defer rep.Close() sqliteDb, err := db.Create(conf.RepoPath, conf.PinCode) if err != nil { @@ -181,6 +183,11 @@ func InitRepo(conf InitConfig) error { return err } + err = applyIPFSSwarmPorts(rep, conf.SwarmPorts) + if err != nil { + return err + } + return applyTextileConfigOptions(conf) } @@ -383,6 +390,14 @@ func (t *Textile) Start() error { log.Errorf(err.Error()) } go t.cafeOutbox.Flush() + + // start cluster + if t.clusterExists() { + err = t.startCluster() + if err != nil { + log.Errorf(err.Error()) + } + } }() for _, mod := range t.datastore.Threads().List().Items { @@ -432,6 +447,14 @@ func (t *Textile) Stop() error { return err } + // shutdown cluster + if t.cluster != nil { + err = t.cluster.Shutdown(t.node.Context()) + if err != nil { + return err + } + } + // close ipfs node err = t.node.Close() if err != nil { diff --git a/repo/config/init.go b/repo/config/init.go index 76f00001..38399365 100644 --- a/repo/config/init.go +++ b/repo/config/init.go @@ -19,6 +19,7 @@ type Config struct { Logs Logs // local node's log settings IsMobile bool // local node is setup for mobile IsServer bool // local node is setup for a server w/ a public IP + Cluster Cluster // local node's IPFS Cluster settings Cafe Cafe // local node cafe settings } @@ -36,11 +37,6 @@ type Addresses struct { Profiling string // bind address of the profiling API } -type SwarmPorts struct { - TCP string // TCP address port - WS string // WS address port -} - // HTTPHeaders to customise things like COR type HTTPHeaders = map[string][]string @@ -60,6 +56,11 @@ type Logs struct { LogToDisk bool // when true, sends all logs to rolling files on disk } +// IPFS Cluster settings +type Cluster struct { + Bootstraps []string +} + // Cafe settings type Cafe struct { Host CafeHost @@ -67,10 +68,10 @@ type Cafe struct { // CafeHost settings type CafeHost struct { - Open bool // When true, other peers can register with this node for cafe services. - URL string // Override the resolved URL of this cafe, useful for load HTTPS and/or load balancers - NeighborURL string // Specifies the URL of a secondary cafe. Must return cafe info. - SizeLimit int64 // Maximum file size limit to accept for POST requests in bytes. + Open bool // When true, other peers can register with this node for cafe services + URL string // Override the resolved URL of this cafe, useful for HTTPS and/or load balancers + NeighborURL string // Deprecated + SizeLimit int64 // Maximum file size limit to accept for POST requests in bytes } // Init returns the default textile config @@ -147,12 +148,13 @@ func Init() (*Config, error) { Logs: Logs{ LogToDisk: true, }, + Cluster: Cluster{ + Bootstraps: []string{}, + }, Cafe: Cafe{ Host: CafeHost{ - Open: false, - URL: "", - NeighborURL: "", - SizeLimit: 0, + Open: false, + SizeLimit: 0, }, }, IsMobile: false, From 8bb596e85958206c48fe72014ed2c4f075cd578d Mon Sep 17 00:00:00 2001 From: Sander Pick Date: Sat, 15 Jun 2019 16:23:18 -0700 Subject: [PATCH 03/12] cluster: add flags to init Signed-off-by: Sander Pick --- cmd/main.go | 28 ++++++++++++++++++++++++++++ go.mod | 1 + ipfs/cluster.go | 5 +++-- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 6fefef6b..f9090f54 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -3,6 +3,8 @@ package cmd import ( "bufio" "bytes" + "crypto/rand" + "encoding/hex" "encoding/json" _ "expvar" "fmt" @@ -436,6 +438,9 @@ Stacks may include: initCafeOpen := initCmd.Flag("cafe-open", "Open the p2p cafe service for other peers").Bool() initCafeURL := initCmd.Flag("cafe-url", "Specify a custom URL of this cafe, e.g., https://mycafe.com").Envar("CAFE_HOST_URL").String() initCafeNeighborURL := initCmd.Flag("cafe-neighbor-url", "Specify the URL of a secondary cafe. Must return cafe info, e.g., via a Gateway: https://my-gateway.yolo.com/cafe, or a cafe API: https://my-cafe.yolo.com").Envar("CAFE_HOST_NEIGHBOR_URL").String() + initIpfsCluster := initCmd.Flag("cluster", "Attach an IPFS Cluster service").Bool() + initIpfsClusterSecret := initCmd.Flag("cluster-secret", "IPFS Cluster secret, omit to auto-generate").String() + initIpfsClusterPeers := initCmd.Flag("cluster-peers", "IPFS Cluster peers to sync with").Strings() cmds[initCmd.FullCommand()] = func() error { kp, err := keypair.Parse(*initAccountSeed) if err != nil { @@ -452,6 +457,18 @@ Stacks may include: return err } + var secret string + if *initIpfsCluster { + if *initIpfsClusterSecret == "" { + secret, err = generateClusterSecret() + if err != nil { + return err + } + } else { + secret = *initIpfsClusterSecret + } + } + config := core.InitConfig{ Account: account, PinCode: *initPin, // @todo rename to pin @@ -468,6 +485,8 @@ Stacks may include: CafeOpen: *initCafeOpen, CafeURL: *initCafeURL, CafeNeighborURL: *initCafeNeighborURL, + ClusterSecret: secret, + ClusterPeers: *initIpfsClusterPeers, } return InitCommand(config) @@ -1194,3 +1213,12 @@ func getRepo(repo string) (string, error) { } return repo, nil } + +func generateClusterSecret() (string, error) { + secret := make([]byte, 32) + _, err := rand.Read(secret) + if err != nil { + return "", err + } + return hex.EncodeToString(secret), nil +} diff --git a/go.mod b/go.mod index 88d0e5ea..ff950d58 100644 --- a/go.mod +++ b/go.mod @@ -31,6 +31,7 @@ require ( github.com/ipfs/go-ipfs-cmds v0.0.10 github.com/ipfs/go-ipfs-config v0.0.6 github.com/ipfs/go-ipfs-files v0.0.3 + github.com/ipfs/go-ipfs-util v0.0.1 github.com/ipfs/go-ipld-format v0.0.2 github.com/ipfs/go-log v0.0.1 github.com/ipfs/go-merkledag v0.1.0 diff --git a/ipfs/cluster.go b/ipfs/cluster.go index 8b09433f..84ff46b9 100644 --- a/ipfs/cluster.go +++ b/ipfs/cluster.go @@ -23,11 +23,12 @@ func (c *ClusterConnector) ID(context.Context) (*api.IPFSID, error) { } func (c *ClusterConnector) SetClient(*rpc.Client) { - panic("implement me") + // noop } func (c *ClusterConnector) Shutdown(context.Context) error { - panic("implement me") + // noop + return nil } func (c *ClusterConnector) Pin(context.Context, icid.Cid, int) error { From 8a865c66493930846f2fbfdc6c9d8b9f31098c4e Mon Sep 17 00:00:00 2001 From: Sander Pick Date: Sat, 15 Jun 2019 17:03:21 -0700 Subject: [PATCH 04/12] cluster: clean up flags Signed-off-by: Sander Pick --- cmd/main.go | 8 ++++++-- cmd/threads.go | 2 +- core/cluster.go | 45 ++++++++++++++++++++++++--------------------- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index f9090f54..899b7a12 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -440,7 +440,7 @@ Stacks may include: initCafeNeighborURL := initCmd.Flag("cafe-neighbor-url", "Specify the URL of a secondary cafe. Must return cafe info, e.g., via a Gateway: https://my-gateway.yolo.com/cafe, or a cafe API: https://my-cafe.yolo.com").Envar("CAFE_HOST_NEIGHBOR_URL").String() initIpfsCluster := initCmd.Flag("cluster", "Attach an IPFS Cluster service").Bool() initIpfsClusterSecret := initCmd.Flag("cluster-secret", "IPFS Cluster secret, omit to auto-generate").String() - initIpfsClusterPeers := initCmd.Flag("cluster-peers", "IPFS Cluster peers to sync with").Strings() + initIpfsClusterPeers := initCmd.Flag("cluster-peer", "IPFS Cluster peers to sync with").Strings() cmds[initCmd.FullCommand()] = func() error { kp, err := keypair.Parse(*initAccountSeed) if err != nil { @@ -1211,7 +1211,11 @@ func getRepo(repo string) (string, error) { } repo = filepath.Join(appDir, "repo") } - return repo, nil + expanded, err := homedir.Expand(repo) + if err != nil { + return "", err + } + return expanded, nil } func generateClusterSecret() (string, error) { diff --git a/cmd/threads.go b/cmd/threads.go index a721f6a3..08233e8e 100644 --- a/cmd/threads.go +++ b/cmd/threads.go @@ -18,7 +18,7 @@ func ThreadAdd(name string, key string, tipe string, sharing string, whitelist [ var body []byte if schema == "" { if schemaFile != "" { - path, err := homedir.Expand(string(schemaFile)) + path, err := homedir.Expand(schemaFile) if err != nil { return err } diff --git a/core/cluster.go b/core/cluster.go index 23a4158b..584bbf15 100644 --- a/core/cluster.go +++ b/core/cluster.go @@ -27,7 +27,7 @@ import ( "github.com/textileio/go-textile/ipfs" ) -type cfgs struct { +type clusterCfgs struct { clusterCfg *ipfscluster.Config crdtCfg *crdt.Config maptrackerCfg *maptracker.Config @@ -37,7 +37,7 @@ type cfgs struct { numpinInfCfg *numpin.Config } -func makeConfigs() (*config.Manager, *cfgs) { +func makeClusterConfigs() (*config.Manager, *clusterCfgs) { cfg := config.NewManager() clusterCfg := &ipfscluster.Config{} crdtCfg := &crdt.Config{} @@ -53,7 +53,7 @@ func makeConfigs() (*config.Manager, *cfgs) { cfg.RegisterComponent(config.Monitor, pubsubmonCfg) cfg.RegisterComponent(config.Informer, diskInfCfg) cfg.RegisterComponent(config.Informer, numpinInfCfg) - return cfg, &cfgs{ + return cfg, &clusterCfgs{ clusterCfg, crdtCfg, maptrackerCfg, @@ -64,16 +64,20 @@ func makeConfigs() (*config.Manager, *cfgs) { } } -func makeAndLoadConfigs(repoPath string) (*config.Manager, *cfgs, error) { - cfgMgr, cfgs := makeConfigs() - err := cfgMgr.LoadJSONFromFile(repoPath) +func clusterConfigPath(repoPath string) string { + return filepath.Join(repoPath, "service.json") +} + +func makeAndLoadClusterConfigs(repoPath string) (*config.Manager, *clusterCfgs, error) { + cfgMgr, cfgs := makeClusterConfigs() + err := cfgMgr.LoadJSONFromFile(clusterConfigPath(repoPath)) if err != nil { return nil, nil, err } return cfgMgr, cfgs, nil } -func parseBootstraps(addrs []string) ([]ma.Multiaddr, error) { +func parseClusterBootstraps(addrs []string) ([]ma.Multiaddr, error) { var parsed []ma.Multiaddr for _, a := range addrs { p, err := ma.NewMultiaddr(a) @@ -91,24 +95,23 @@ func initCluster(repoPath, secret string) error { return err } - cfgMgr, cfgs := makeConfigs() + cfgMgr, cfgs := makeClusterConfigs() err = cfgMgr.Default() if err != nil { return err } cfgs.clusterCfg.Secret = decoded - return cfgMgr.SaveJSON(repoPath) + return cfgMgr.SaveJSON(clusterConfigPath(repoPath)) } func (t *Textile) clusterExists() bool { - cpath := filepath.Join(t.repoPath, "service.json") - return util.FileExists(cpath) + return util.FileExists(clusterConfigPath(t.repoPath)) } // startCluster creates all the necessary things to produce the cluster object func (t *Textile) startCluster() error { - cfgMgr, cfgs, err := makeAndLoadConfigs(t.repoPath) + cfgMgr, cfgs, err := makeAndLoadClusterConfigs(t.repoPath) if err != nil { return nil } @@ -116,7 +119,7 @@ func (t *Textile) startCluster() error { cfgs.clusterCfg.LeaveOnShutdown = true - tracker, err := setupPinTracker( + tracker, err := setupClusterPinTracker( "map", t.node.PeerHost, cfgs.maptrackerCfg, @@ -127,7 +130,7 @@ func (t *Textile) startCluster() error { return nil } - informer, alloc, err := setupAllocation( + informer, alloc, err := setupClusterAllocation( "disk-freespace", cfgs.diskInfCfg, cfgs.numpinInfCfg, @@ -138,7 +141,7 @@ func (t *Textile) startCluster() error { ipfscluster.ReadyTimeout = raft.DefaultWaitForLeaderTimeout + 5*time.Second - cons, err := setupConsensus( + cons, err := setupClusterConsensus( t.node.PeerHost, t.node.DHT, t.node.PubSub, @@ -174,7 +177,7 @@ func (t *Textile) startCluster() error { return nil } - bootstraps, err := parseBootstraps(t.config.Cluster.Bootstraps) + bootstraps, err := parseClusterBootstraps(t.config.Cluster.Bootstraps) if err != nil { return nil } @@ -184,14 +187,14 @@ func (t *Textile) startCluster() error { // and timeout. So this can happen in background and we // avoid worrying about error handling here (since Cluster // will realize). - go bootstrap(t.node.Context(), t.cluster, bootstraps) + go bootstrapCluster(t.node.Context(), t.cluster, bootstraps) return nil } // bootstrap will bootstrap this peer to one of the bootstrap addresses // if there are any. -func bootstrap(ctx context.Context, cluster *ipfscluster.Cluster, bootstraps []ma.Multiaddr) { +func bootstrapCluster(ctx context.Context, cluster *ipfscluster.Cluster, bootstraps []ma.Multiaddr) { for _, bstrap := range bootstraps { log.Infof("Bootstrapping to %s", bstrap) err := cluster.Join(ctx, bstrap) @@ -201,7 +204,7 @@ func bootstrap(ctx context.Context, cluster *ipfscluster.Cluster, bootstraps []m } } -func setupAllocation( +func setupClusterAllocation( name string, diskInfCfg *disk.Config, numpinInfCfg *numpin.Config, @@ -230,7 +233,7 @@ func setupAllocation( } } -func setupPinTracker( +func setupClusterPinTracker( name string, h host.Host, mapCfg *maptracker.Config, @@ -251,7 +254,7 @@ func setupPinTracker( } } -func setupConsensus( +func setupClusterConsensus( h host.Host, dht *dht.IpfsDHT, pubsub *pubsub.PubSub, From bdb6b69434d44413b9c89e3da4fae7074b6079db Mon Sep 17 00:00:00 2001 From: Sander Pick Date: Sun, 16 Jun 2019 12:16:07 -0700 Subject: [PATCH 05/12] cluster: implement IPFSConnector Signed-off-by: Sander Pick --- cmd/files.go | 2 +- core/cluster.go | 24 ++++--- ipfs/cluster.go | 185 ++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 165 insertions(+), 46 deletions(-) diff --git a/cmd/files.go b/cmd/files.go index f62d5c23..40d00a71 100644 --- a/cmd/files.go +++ b/cmd/files.go @@ -75,7 +75,7 @@ func FileAdd(path string, threadID string, caption string, group bool, verbose b pth = path } - fi, err = os.Stat(path) + fi, err = os.Stat(pth) if err != nil { return err } diff --git a/core/cluster.go b/core/cluster.go index 584bbf15..11777264 100644 --- a/core/cluster.go +++ b/core/cluster.go @@ -11,6 +11,7 @@ import ( ipfscluster "github.com/ipfs/ipfs-cluster" "github.com/ipfs/ipfs-cluster/allocator/ascendalloc" "github.com/ipfs/ipfs-cluster/allocator/descendalloc" + capi "github.com/ipfs/ipfs-cluster/api" "github.com/ipfs/ipfs-cluster/config" "github.com/ipfs/ipfs-cluster/consensus/crdt" "github.com/ipfs/ipfs-cluster/consensus/raft" @@ -113,7 +114,7 @@ func (t *Textile) clusterExists() bool { func (t *Textile) startCluster() error { cfgMgr, cfgs, err := makeAndLoadClusterConfigs(t.repoPath) if err != nil { - return nil + return err } defer cfgMgr.Shutdown() @@ -127,7 +128,7 @@ func (t *Textile) startCluster() error { cfgs.clusterCfg.Peername, ) if err != nil { - return nil + return err } informer, alloc, err := setupClusterAllocation( @@ -136,7 +137,7 @@ func (t *Textile) startCluster() error { cfgs.numpinInfCfg, ) if err != nil { - return nil + return err } ipfscluster.ReadyTimeout = raft.DefaultWaitForLeaderTimeout + 5*time.Second @@ -149,13 +150,20 @@ func (t *Textile) startCluster() error { t.node.Repo.Datastore(), ) if err != nil { - return nil + return err } var peersF func(context.Context) ([]peer.ID, error) mon, err := pubsubmon.New(t.node.Context(), cfgs.pubsubmonCfg, t.node.PubSub, peersF) if err != nil { - return nil + return err + } + + connector, err := ipfs.NewClusterConnector(t.node, func(ctx context.Context) []*capi.ID { + return t.cluster.Peers(ctx) + }) + if err != nil { + return err } t.cluster, err = ipfscluster.NewCluster( @@ -166,7 +174,7 @@ func (t *Textile) startCluster() error { t.node.Repo.Datastore(), cons, nil, - ipfs.NewClusterConnector(t.node), + connector, tracker, mon, alloc, @@ -174,12 +182,12 @@ func (t *Textile) startCluster() error { nil, ) if err != nil { - return nil + return err } bootstraps, err := parseClusterBootstraps(t.config.Cluster.Bootstraps) if err != nil { - return nil + return err } // noop if no bootstraps diff --git a/ipfs/cluster.go b/ipfs/cluster.go index 84ff46b9..f35d1ddc 100644 --- a/ipfs/cluster.go +++ b/ipfs/cluster.go @@ -1,76 +1,187 @@ package ipfs import ( + "bytes" "context" + "fmt" + "io/ioutil" icid "github.com/ipfs/go-cid" "github.com/ipfs/go-ipfs/core" + "github.com/ipfs/go-ipfs/core/coreapi" + "github.com/ipfs/go-ipfs/core/corerepo" + "github.com/ipfs/go-ipfs/pin" + iface "github.com/ipfs/interface-go-ipfs-core" + "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/ipfs/interface-go-ipfs-core/path" "github.com/ipfs/ipfs-cluster/api" + corepeer "github.com/libp2p/go-libp2p-core/peer" rpc "github.com/libp2p/go-libp2p-gorpc" peer "github.com/libp2p/go-libp2p-peer" + ma "github.com/multiformats/go-multiaddr" ) -func NewClusterConnector(node *core.IpfsNode) *ClusterConnector { - return &ClusterConnector{node: node} +type ClusterConnector struct { + node *core.IpfsNode + api iface.CoreAPI + peers func(ctx context.Context) []*api.ID } -type ClusterConnector struct { - node *core.IpfsNode +func NewClusterConnector(node *core.IpfsNode, peers func(ctx context.Context) []*api.ID) (*ClusterConnector, error) { + capi, err := coreapi.NewCoreAPI(node) + if err != nil { + return nil, err + } + return &ClusterConnector{ + node: node, + api: capi, + peers: peers, + }, nil } func (c *ClusterConnector) ID(context.Context) (*api.IPFSID, error) { - panic("implement me") + var addrs []api.Multiaddr + for _, addr := range c.node.PeerHost.Addrs() { + addrs = append(addrs, api.Multiaddr{Multiaddr: addr}) + } + return &api.IPFSID{ + ID: c.node.Identity, + Addresses: addrs, + }, nil } -func (c *ClusterConnector) SetClient(*rpc.Client) { +func (c *ClusterConnector) SetClient(client *rpc.Client) { // noop } -func (c *ClusterConnector) Shutdown(context.Context) error { +func (c *ClusterConnector) Shutdown(ctx context.Context) error { // noop return nil } -func (c *ClusterConnector) Pin(context.Context, icid.Cid, int) error { - panic("implement me") +// @todo handle maxDepth +func (c *ClusterConnector) Pin(ctx context.Context, cid icid.Cid, maxDepth int) error { + return c.api.Pin().Add(ctx, path.New(cid.String())) } -func (c *ClusterConnector) Unpin(context.Context, icid.Cid) error { - panic("implement me") +func (c *ClusterConnector) Unpin(ctx context.Context, cid icid.Cid) error { + return c.api.Pin().Rm(ctx, path.New(cid.String())) } -func (c *ClusterConnector) PinLsCid(context.Context, icid.Cid) (api.IPFSPinStatus, error) { - panic("implement me") +func (c *ClusterConnector) PinLsCid(ctx context.Context, cid icid.Cid) (api.IPFSPinStatus, error) { + pins, err := c.node.Pinning.CheckIfPinned(cid) + if err != nil { + return api.IPFSPinStatusError, err + } + if len(pins) == 0 { + return api.IPFSPinStatusError, fmt.Errorf("invalid pin check result") + } + return c.pinModeToStatus(pins[0].Mode), nil } func (c *ClusterConnector) PinLs(ctx context.Context, typeFilter string) (map[string]api.IPFSPinStatus, error) { - panic("implement me") -} - -func (c *ClusterConnector) ConnectSwarms(context.Context) error { - panic("implement me") + pins, err := c.api.Pin().Ls(ctx, c.pinFilterToOption(typeFilter)) + if err != nil { + return nil, err + } + statusMap := make(map[string]api.IPFSPinStatus) + for _, p := range pins { + mode, ok := pin.StringToMode(p.Type()) + if !ok { + continue + } + statusMap[p.Path().String()] = c.pinModeToStatus(mode) + } + return statusMap, nil +} + +func (c *ClusterConnector) ConnectSwarms(ctx context.Context) error { + for _, p := range c.peers(ctx) { + log.Debugf("cluster dialing %s", p.ID.Pretty()) + var addrs []ma.Multiaddr + for _, addr := range p.Addresses { + addrs = append(addrs, addr.Multiaddr) + } + err := c.api.Swarm().Connect(ctx, corepeer.AddrInfo{ + ID: p.ID, + Addrs: addrs, + }) + if err != nil { + return err + } + log.Debugf("cluster connected to %s") + } + return nil } -func (c *ClusterConnector) SwarmPeers(context.Context) ([]peer.ID, error) { - panic("implement me") +func (c *ClusterConnector) SwarmPeers(ctx context.Context) ([]peer.ID, error) { + conns, err := c.api.Swarm().Peers(ctx) + if err != nil { + return nil, err + } + var peers []peer.ID + for _, c := range conns { + peers = append(peers, c.ID()) + } + return peers, nil } func (c *ClusterConnector) ConfigKey(keypath string) (interface{}, error) { - panic("implement me") -} - -func (c *ClusterConnector) RepoStat(context.Context) (*api.IPFSRepoStat, error) { - panic("implement me") -} - -func (c *ClusterConnector) Resolve(context.Context, string) (icid.Cid, error) { - panic("implement me") -} - -func (c *ClusterConnector) BlockPut(context.Context, *api.NodeWithMeta) error { - panic("implement me") -} - -func (c *ClusterConnector) BlockGet(context.Context, icid.Cid) ([]byte, error) { - panic("implement me") + return c.node.Repo.GetConfigKey(keypath) +} + +func (c *ClusterConnector) RepoStat(ctx context.Context) (*api.IPFSRepoStat, error) { + stat, err := corerepo.RepoStat(ctx, c.node) + if err != nil { + return nil, err + } + return &api.IPFSRepoStat{ + RepoSize: stat.RepoSize, + StorageMax: stat.StorageMax, + }, nil +} + +func (c *ClusterConnector) Resolve(ctx context.Context, pth string) (icid.Cid, error) { + res, err := c.api.ResolvePath(ctx, path.New(pth)) + if err != nil { + return icid.Undef, err + } + return res.Cid(), nil +} + +func (c *ClusterConnector) BlockPut(ctx context.Context, b *api.NodeWithMeta) error { + _, err := c.api.Block().Put(ctx, bytes.NewReader(b.Data), options.Block.Format(b.Format)) + return err +} + +func (c *ClusterConnector) BlockGet(ctx context.Context, cid icid.Cid) ([]byte, error) { + r, err := c.api.Block().Get(ctx, path.New(cid.String())) + if err != nil { + return nil, err + } + return ioutil.ReadAll(r) +} + +func (c *ClusterConnector) pinModeToStatus(mode pin.Mode) api.IPFSPinStatus { + switch mode { + case pin.Recursive: + return api.IPFSPinStatusRecursive + case pin.Direct: + return api.IPFSPinStatusDirect + case pin.Indirect: + return api.IPFSPinStatusIndirect + case pin.Internal: + return api.IPFSPinStatusDirect + case pin.NotPinned: + return api.IPFSPinStatusUnpinned + default: + return api.IPFSPinStatusError + } +} + +func (c *ClusterConnector) pinFilterToOption(typeFilter string) options.PinLsOption { + return func(settings *options.PinLsSettings) error { + settings.Type = typeFilter + return nil + } } From 12c2ae012e3dff8fa9fff5247841cacdbb65c6d4 Mon Sep 17 00:00:00 2001 From: Sander Pick Date: Sun, 16 Jun 2019 13:54:07 -0700 Subject: [PATCH 06/12] cluster: adds two node test Signed-off-by: Sander Pick --- cmd/main.go | 13 +--- core/cluster.go | 11 ++++ core/cluster_test.go | 148 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 160 insertions(+), 12 deletions(-) create mode 100644 core/cluster_test.go diff --git a/cmd/main.go b/cmd/main.go index 899b7a12..611e8358 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -3,8 +3,6 @@ package cmd import ( "bufio" "bytes" - "crypto/rand" - "encoding/hex" "encoding/json" _ "expvar" "fmt" @@ -460,7 +458,7 @@ Stacks may include: var secret string if *initIpfsCluster { if *initIpfsClusterSecret == "" { - secret, err = generateClusterSecret() + secret, err = core.NewClusterSecret() if err != nil { return err } @@ -1217,12 +1215,3 @@ func getRepo(repo string) (string, error) { } return expanded, nil } - -func generateClusterSecret() (string, error) { - secret := make([]byte, 32) - _, err := rand.Read(secret) - if err != nil { - return "", err - } - return hex.EncodeToString(secret), nil -} diff --git a/core/cluster.go b/core/cluster.go index 11777264..f4c9a0d1 100644 --- a/core/cluster.go +++ b/core/cluster.go @@ -2,6 +2,8 @@ package core import ( "context" + "crypto/rand" + "encoding/hex" "fmt" "path/filepath" "time" @@ -28,6 +30,15 @@ import ( "github.com/textileio/go-textile/ipfs" ) +func NewClusterSecret() (string, error) { + secret := make([]byte, 32) + _, err := rand.Read(secret) + if err != nil { + return "", err + } + return hex.EncodeToString(secret), nil +} + type clusterCfgs struct { clusterCfg *ipfscluster.Config crdtCfg *crdt.Config diff --git a/core/cluster_test.go b/core/cluster_test.go new file mode 100644 index 00000000..299f00a3 --- /dev/null +++ b/core/cluster_test.go @@ -0,0 +1,148 @@ +package core + +import ( + "context" + "fmt" + "os" + "testing" + "time" + + "github.com/ipfs/go-ipfs/repo/fsrepo" + "github.com/textileio/go-textile/repo/config" + + "github.com/textileio/go-textile/keypair" +) + +var clusterVars = struct { + repoPath1 string + repoPath2 string + node1 *Textile + node2 *Textile +}{ + repoPath1: "testdata/.cluster1", + repoPath2: "testdata/.cluster2", +} + +func TestInitCluster(t *testing.T) { + _ = os.RemoveAll(clusterVars.repoPath1) + _ = os.RemoveAll(clusterVars.repoPath2) + + accnt1 := keypair.Random() + accnt2 := keypair.Random() + + swarmPort1 := GetRandomPort() + swarmPort2 := GetRandomPort() + + secret, err := NewClusterSecret() + if err != nil { + t.Fatal(err) + } + + err = InitRepo(InitConfig{ + Account: accnt1, + RepoPath: clusterVars.repoPath1, + ApiAddr: fmt.Sprintf("127.0.0.1:%s", GetRandomPort()), + SwarmPorts: swarmPort1, + ClusterSecret: secret, + Debug: true, + }) + if err != nil { + t.Fatalf("init node1 failed: %s", err) + } + err = InitRepo(InitConfig{ + Account: accnt2, + RepoPath: clusterVars.repoPath2, + ApiAddr: fmt.Sprintf("127.0.0.1:%s", GetRandomPort()), + SwarmPorts: swarmPort2, + ClusterSecret: secret, + Debug: true, + }) + if err != nil { + t.Fatalf("init node2 failed: %s", err) + } + + // update bootstraps + addr1, err := getPeerAddress(clusterVars.repoPath1, swarmPort1) + if err != nil { + t.Fatal(err) + } + addr2, err := getPeerAddress(clusterVars.repoPath2, swarmPort2) + if err != nil { + t.Fatal(err) + } + err = updateClusterBootstraps(clusterVars.repoPath1, []string{addr2}) + if err != nil { + t.Fatal(err) + } + err = updateClusterBootstraps(clusterVars.repoPath2, []string{addr1}) + if err != nil { + t.Fatal(err) + } +} + +func getPeerAddress(repoPath, swarmPort string) (string, error) { + r, err := fsrepo.Open(repoPath) + if err != nil { + return "", err + } + defer r.Close() + id, err := r.GetConfigKey("Identity.PeerID") + if err != nil { + return "", err + } + return fmt.Sprintf("/ip4/127.0.0.1/tcp/%s/ipfs/%s", swarmPort, id), nil +} + +func updateClusterBootstraps(repoPath string, bootstraps []string) error { + conf, err := config.Read(repoPath) + if err != nil { + return err + } + conf.Cluster.Bootstraps = bootstraps + return config.Write(repoPath, conf) +} + +func TestNewTextileCluster(t *testing.T) { + var err error + clusterVars.node1, err = NewTextile(RunConfig{ + RepoPath: clusterVars.repoPath1, + Debug: true, + }) + if err != nil { + t.Fatalf("create node1 failed: %s", err) + } + clusterVars.node2, err = NewTextile(RunConfig{ + RepoPath: clusterVars.repoPath2, + Debug: true, + }) + if err != nil { + t.Fatalf("create node2 failed: %s", err) + } + + <-clusterVars.node1.OnlineCh() + <-clusterVars.node2.OnlineCh() + + err = addTestData(clusterVars.node1) + if err != nil { + t.Fatal(err) + } +} + +func TestTextileClusterSync(t *testing.T) { + ctx, cancel := context.WithTimeout(clusterVars.node1.node.Context(), time.Minute) + defer cancel() + + info, err := clusterVars.node1.cluster.SyncAll(ctx) + if err != nil { + t.Fatalf("sync failed: %s", err) + } + + for _, i := range info { + fmt.Println(i.String()) + } +} + +func TestTextileCluster_Teardown(t *testing.T) { + clusterVars.node1 = nil + clusterVars.node2 = nil +} From 4e5a3fc5b562a79fd5612684d25cd6f5f679d602 Mon Sep 17 00:00:00 2001 From: Sander Pick Date: Sun, 16 Jun 2019 14:30:44 -0700 Subject: [PATCH 07/12] cluster: move to own package Signed-off-by: Sander Pick --- {core => cluster}/cluster_test.go | 94 ++++++++----- cluster/main.go | 187 ++++++++++++++++++++++++++ cmd/main.go | 3 +- core/cluster.go | 213 +++--------------------------- core/main.go | 9 +- go.mod | 1 + go.sum | 1 + 7 files changed, 277 insertions(+), 231 deletions(-) rename {core => cluster}/cluster_test.go (50%) create mode 100644 cluster/main.go diff --git a/core/cluster_test.go b/cluster/cluster_test.go similarity index 50% rename from core/cluster_test.go rename to cluster/cluster_test.go index 299f00a3..9377a031 100644 --- a/core/cluster_test.go +++ b/cluster/cluster_test.go @@ -1,4 +1,4 @@ -package core +package cluster_test import ( "context" @@ -7,41 +7,50 @@ import ( "testing" "time" + icid "github.com/ipfs/go-cid" + icore "github.com/ipfs/go-ipfs/core" "github.com/ipfs/go-ipfs/repo/fsrepo" - "github.com/textileio/go-textile/repo/config" - + "github.com/textileio/go-textile/cluster" + "github.com/textileio/go-textile/core" + "github.com/textileio/go-textile/ipfs" "github.com/textileio/go-textile/keypair" + "github.com/textileio/go-textile/repo/config" ) -var clusterVars = struct { +var vars = struct { repoPath1 string repoPath2 string - node1 *Textile - node2 *Textile + + node1 *core.Textile + node2 *core.Textile + + cid icid.Cid }{ repoPath1: "testdata/.cluster1", repoPath2: "testdata/.cluster2", + + cid: icid.Undef, } func TestInitCluster(t *testing.T) { - _ = os.RemoveAll(clusterVars.repoPath1) - _ = os.RemoveAll(clusterVars.repoPath2) + _ = os.RemoveAll(vars.repoPath1) + _ = os.RemoveAll(vars.repoPath2) accnt1 := keypair.Random() accnt2 := keypair.Random() - swarmPort1 := GetRandomPort() - swarmPort2 := GetRandomPort() + swarmPort1 := core.GetRandomPort() + swarmPort2 := core.GetRandomPort() - secret, err := NewClusterSecret() + secret, err := cluster.NewClusterSecret() if err != nil { t.Fatal(err) } - err = InitRepo(InitConfig{ + err = core.InitRepo(core.InitConfig{ Account: accnt1, - RepoPath: clusterVars.repoPath1, - ApiAddr: fmt.Sprintf("127.0.0.1:%s", GetRandomPort()), + RepoPath: vars.repoPath1, + ApiAddr: fmt.Sprintf("127.0.0.1:%s", core.GetRandomPort()), SwarmPorts: swarmPort1, ClusterSecret: secret, Debug: true, @@ -49,10 +58,10 @@ func TestInitCluster(t *testing.T) { if err != nil { t.Fatalf("init node1 failed: %s", err) } - err = InitRepo(InitConfig{ + err = core.InitRepo(core.InitConfig{ Account: accnt2, - RepoPath: clusterVars.repoPath2, - ApiAddr: fmt.Sprintf("127.0.0.1:%s", GetRandomPort()), + RepoPath: vars.repoPath2, + ApiAddr: fmt.Sprintf("127.0.0.1:%s", core.GetRandomPort()), SwarmPorts: swarmPort2, ClusterSecret: secret, Debug: true, @@ -62,19 +71,19 @@ func TestInitCluster(t *testing.T) { } // update bootstraps - addr1, err := getPeerAddress(clusterVars.repoPath1, swarmPort1) + addr1, err := getPeerAddress(vars.repoPath1, swarmPort1) if err != nil { t.Fatal(err) } - addr2, err := getPeerAddress(clusterVars.repoPath2, swarmPort2) + addr2, err := getPeerAddress(vars.repoPath2, swarmPort2) if err != nil { t.Fatal(err) } - err = updateClusterBootstraps(clusterVars.repoPath1, []string{addr2}) + err = updateClusterBootstraps(vars.repoPath1, []string{addr2}) if err != nil { t.Fatal(err) } - err = updateClusterBootstraps(clusterVars.repoPath2, []string{addr1}) + err = updateClusterBootstraps(vars.repoPath2, []string{addr1}) if err != nil { t.Fatal(err) } @@ -104,45 +113,64 @@ func updateClusterBootstraps(repoPath string, bootstraps []string) error { func TestNewTextileCluster(t *testing.T) { var err error - clusterVars.node1, err = NewTextile(RunConfig{ - RepoPath: clusterVars.repoPath1, + vars.node1, err = core.NewTextile(core.RunConfig{ + RepoPath: vars.repoPath1, Debug: true, }) if err != nil { t.Fatalf("create node1 failed: %s", err) } - clusterVars.node2, err = NewTextile(RunConfig{ - RepoPath: clusterVars.repoPath2, + vars.node2, err = core.NewTextile(core.RunConfig{ + RepoPath: vars.repoPath2, Debug: true, }) if err != nil { t.Fatalf("create node2 failed: %s", err) } - <-clusterVars.node1.OnlineCh() - <-clusterVars.node2.OnlineCh() + <-vars.node1.OnlineCh() + <-vars.node2.OnlineCh() - err = addTestData(clusterVars.node1) + cid, err := pinTestData(vars.node1.Ipfs()) if err != nil { t.Fatal(err) } + vars.cid = *cid } func TestTextileClusterSync(t *testing.T) { - ctx, cancel := context.WithTimeout(clusterVars.node1.node.Context(), time.Minute) + ctx, cancel := context.WithTimeout(vars.node1.Ipfs().Context(), time.Minute) defer cancel() - info, err := clusterVars.node1.cluster.SyncAll(ctx) + info, err := vars.node1.Cluster().SyncAll(ctx) if err != nil { - t.Fatalf("sync failed: %s", err) + t.Fatalf("sync all failed: %s", err) } + var foundCid bool for _, i := range info { fmt.Println(i.String()) + if i.Cid.Equals(vars.cid) { + foundCid = true + } + } + + if !foundCid { + t.Fatalf("failed to find cid in cluster: %s", vars.cid.String()) } } func TestTextileCluster_Teardown(t *testing.T) { - clusterVars.node1 = nil - clusterVars.node2 = nil + vars.node1 = nil + vars.node2 = nil +} + +func pinTestData(node *icore.IpfsNode) (*icid.Cid, error) { + f, err := os.Open("../mill/testdata/image.jpeg") + if err != nil { + return nil, err + } + defer f.Close() + + return ipfs.AddData(node, f, true, false) } diff --git a/cluster/main.go b/cluster/main.go new file mode 100644 index 00000000..cd4c79cb --- /dev/null +++ b/cluster/main.go @@ -0,0 +1,187 @@ +package cluster + +import ( + "context" + "crypto/rand" + "encoding/hex" + "fmt" + "path/filepath" + + ds "github.com/ipfs/go-datastore" + ipfscluster "github.com/ipfs/ipfs-cluster" + "github.com/ipfs/ipfs-cluster/allocator/ascendalloc" + "github.com/ipfs/ipfs-cluster/allocator/descendalloc" + "github.com/ipfs/ipfs-cluster/config" + "github.com/ipfs/ipfs-cluster/consensus/crdt" + "github.com/ipfs/ipfs-cluster/informer/disk" + "github.com/ipfs/ipfs-cluster/informer/numpin" + "github.com/ipfs/ipfs-cluster/monitor/pubsubmon" + "github.com/ipfs/ipfs-cluster/pintracker/maptracker" + "github.com/ipfs/ipfs-cluster/pintracker/stateless" + host "github.com/libp2p/go-libp2p-host" + dht "github.com/libp2p/go-libp2p-kad-dht" + pubsub "github.com/libp2p/go-libp2p-pubsub" + ma "github.com/multiformats/go-multiaddr" + "github.com/prometheus/common/log" +) + +func NewClusterSecret() (string, error) { + secret := make([]byte, 32) + _, err := rand.Read(secret) + if err != nil { + return "", err + } + return hex.EncodeToString(secret), nil +} + +func InitCluster(repoPath, secret string) error { + decoded, err := ipfscluster.DecodeClusterSecret(secret) + if err != nil { + return err + } + + cfgMgr, cfgs := makeClusterConfigs() + err = cfgMgr.Default() + if err != nil { + return err + } + cfgs.ClusterCfg.Secret = decoded + + return cfgMgr.SaveJSON(ConfigPath(repoPath)) +} + +func ConfigPath(repoPath string) string { + return filepath.Join(repoPath, "service.json") +} + +func MakeAndLoadConfigs(repoPath string) (*config.Manager, *cfgs, error) { + cfgMgr, cfgs := makeClusterConfigs() + err := cfgMgr.LoadJSONFromFile(ConfigPath(repoPath)) + if err != nil { + return nil, nil, err + } + return cfgMgr, cfgs, nil +} + +func ParseBootstraps(addrs []string) ([]ma.Multiaddr, error) { + var parsed []ma.Multiaddr + for _, a := range addrs { + p, err := ma.NewMultiaddr(a) + if err != nil { + return nil, err + } + parsed = append(parsed, p) + } + return parsed, nil +} + +func Bootstrap(ctx context.Context, cluster *ipfscluster.Cluster, bootstraps []ma.Multiaddr) { + for _, bstrap := range bootstraps { + log.Infof("Bootstrapping to %s", bstrap) + err := cluster.Join(ctx, bstrap) + if err != nil { + log.Errorf("bootstrap to %s failed: %s", bstrap, err) + } + } +} + +func SetupAllocation( + name string, + diskInfCfg *disk.Config, + numpinInfCfg *numpin.Config, +) (ipfscluster.Informer, ipfscluster.PinAllocator, error) { + switch name { + case "disk", "disk-freespace": + informer, err := disk.NewInformer(diskInfCfg) + if err != nil { + return nil, nil, err + } + return informer, descendalloc.NewAllocator(), nil + case "disk-reposize": + informer, err := disk.NewInformer(diskInfCfg) + if err != nil { + return nil, nil, err + } + return informer, ascendalloc.NewAllocator(), nil + case "numpin", "pincount": + informer, err := numpin.NewInformer(numpinInfCfg) + if err != nil { + return nil, nil, err + } + return informer, ascendalloc.NewAllocator(), nil + default: + return nil, nil, fmt.Errorf("unknown allocation strategy") + } +} + +func SetupPinTracker( + name string, + h host.Host, + mapCfg *maptracker.Config, + statelessCfg *stateless.Config, + peerName string, +) (ipfscluster.PinTracker, error) { + switch name { + case "map": + ptrk := maptracker.NewMapPinTracker(mapCfg, h.ID(), peerName) + log.Debug("map pintracker loaded") + return ptrk, nil + case "stateless": + ptrk := stateless.New(statelessCfg, h.ID(), peerName) + log.Debug("stateless pintracker loaded") + return ptrk, nil + default: + return nil, fmt.Errorf("unknown pintracker type") + } +} + +func SetupConsensus( + h host.Host, + dht *dht.IpfsDHT, + pubsub *pubsub.PubSub, + crdtCfg *crdt.Config, + store ds.Datastore, +) (ipfscluster.Consensus, error) { + convrdt, err := crdt.New(h, dht, pubsub, crdtCfg, store) + if err != nil { + return nil, fmt.Errorf("error creating CRDT component: %s", err) + } + return convrdt, nil +} + +type cfgs struct { + ClusterCfg *ipfscluster.Config + CrdtCfg *crdt.Config + MaptrackerCfg *maptracker.Config + StatelessTrackerCfg *stateless.Config + PubsubmonCfg *pubsubmon.Config + DiskInfCfg *disk.Config + NumpinInfCfg *numpin.Config +} + +func makeClusterConfigs() (*config.Manager, *cfgs) { + cfg := config.NewManager() + clusterCfg := &ipfscluster.Config{} + crdtCfg := &crdt.Config{} + maptrackerCfg := &maptracker.Config{} + statelessCfg := &stateless.Config{} + pubsubmonCfg := &pubsubmon.Config{} + diskInfCfg := &disk.Config{} + numpinInfCfg := &numpin.Config{} + cfg.RegisterComponent(config.Cluster, clusterCfg) + cfg.RegisterComponent(config.Consensus, crdtCfg) + cfg.RegisterComponent(config.PinTracker, maptrackerCfg) + cfg.RegisterComponent(config.PinTracker, statelessCfg) + cfg.RegisterComponent(config.Monitor, pubsubmonCfg) + cfg.RegisterComponent(config.Informer, diskInfCfg) + cfg.RegisterComponent(config.Informer, numpinInfCfg) + return cfg, &cfgs{ + clusterCfg, + crdtCfg, + maptrackerCfg, + statelessCfg, + pubsubmonCfg, + diskInfCfg, + numpinInfCfg, + } +} diff --git a/cmd/main.go b/cmd/main.go index 611e8358..77c1ece8 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -21,6 +21,7 @@ import ( "github.com/golang/protobuf/proto" logging "github.com/ipfs/go-log" "github.com/mitchellh/go-homedir" + "github.com/textileio/go-textile/cluster" "github.com/textileio/go-textile/core" "github.com/textileio/go-textile/keypair" "github.com/textileio/go-textile/pb" @@ -458,7 +459,7 @@ Stacks may include: var secret string if *initIpfsCluster { if *initIpfsClusterSecret == "" { - secret, err = core.NewClusterSecret() + secret, err = cluster.NewClusterSecret() if err != nil { return err } diff --git a/core/cluster.go b/core/cluster.go index f4c9a0d1..6ec3eac7 100644 --- a/core/cluster.go +++ b/core/cluster.go @@ -2,150 +2,47 @@ package core import ( "context" - "crypto/rand" - "encoding/hex" - "fmt" - "path/filepath" "time" - ds "github.com/ipfs/go-datastore" util "github.com/ipfs/go-ipfs-util" ipfscluster "github.com/ipfs/ipfs-cluster" - "github.com/ipfs/ipfs-cluster/allocator/ascendalloc" - "github.com/ipfs/ipfs-cluster/allocator/descendalloc" capi "github.com/ipfs/ipfs-cluster/api" - "github.com/ipfs/ipfs-cluster/config" - "github.com/ipfs/ipfs-cluster/consensus/crdt" "github.com/ipfs/ipfs-cluster/consensus/raft" - "github.com/ipfs/ipfs-cluster/informer/disk" - "github.com/ipfs/ipfs-cluster/informer/numpin" "github.com/ipfs/ipfs-cluster/monitor/pubsubmon" - "github.com/ipfs/ipfs-cluster/pintracker/maptracker" - "github.com/ipfs/ipfs-cluster/pintracker/stateless" - host "github.com/libp2p/go-libp2p-host" - dht "github.com/libp2p/go-libp2p-kad-dht" peer "github.com/libp2p/go-libp2p-peer" - pubsub "github.com/libp2p/go-libp2p-pubsub" - ma "github.com/multiformats/go-multiaddr" + "github.com/textileio/go-textile/cluster" "github.com/textileio/go-textile/ipfs" ) -func NewClusterSecret() (string, error) { - secret := make([]byte, 32) - _, err := rand.Read(secret) - if err != nil { - return "", err - } - return hex.EncodeToString(secret), nil -} - -type clusterCfgs struct { - clusterCfg *ipfscluster.Config - crdtCfg *crdt.Config - maptrackerCfg *maptracker.Config - statelessTrackerCfg *stateless.Config - pubsubmonCfg *pubsubmon.Config - diskInfCfg *disk.Config - numpinInfCfg *numpin.Config -} - -func makeClusterConfigs() (*config.Manager, *clusterCfgs) { - cfg := config.NewManager() - clusterCfg := &ipfscluster.Config{} - crdtCfg := &crdt.Config{} - maptrackerCfg := &maptracker.Config{} - statelessCfg := &stateless.Config{} - pubsubmonCfg := &pubsubmon.Config{} - diskInfCfg := &disk.Config{} - numpinInfCfg := &numpin.Config{} - cfg.RegisterComponent(config.Cluster, clusterCfg) - cfg.RegisterComponent(config.Consensus, crdtCfg) - cfg.RegisterComponent(config.PinTracker, maptrackerCfg) - cfg.RegisterComponent(config.PinTracker, statelessCfg) - cfg.RegisterComponent(config.Monitor, pubsubmonCfg) - cfg.RegisterComponent(config.Informer, diskInfCfg) - cfg.RegisterComponent(config.Informer, numpinInfCfg) - return cfg, &clusterCfgs{ - clusterCfg, - crdtCfg, - maptrackerCfg, - statelessCfg, - pubsubmonCfg, - diskInfCfg, - numpinInfCfg, - } -} - -func clusterConfigPath(repoPath string) string { - return filepath.Join(repoPath, "service.json") -} - -func makeAndLoadClusterConfigs(repoPath string) (*config.Manager, *clusterCfgs, error) { - cfgMgr, cfgs := makeClusterConfigs() - err := cfgMgr.LoadJSONFromFile(clusterConfigPath(repoPath)) - if err != nil { - return nil, nil, err - } - return cfgMgr, cfgs, nil -} - -func parseClusterBootstraps(addrs []string) ([]ma.Multiaddr, error) { - var parsed []ma.Multiaddr - for _, a := range addrs { - p, err := ma.NewMultiaddr(a) - if err != nil { - return nil, err - } - parsed = append(parsed, p) - } - return parsed, nil -} - -func initCluster(repoPath, secret string) error { - decoded, err := ipfscluster.DecodeClusterSecret(secret) - if err != nil { - return err - } - - cfgMgr, cfgs := makeClusterConfigs() - err = cfgMgr.Default() - if err != nil { - return err - } - cfgs.clusterCfg.Secret = decoded - - return cfgMgr.SaveJSON(clusterConfigPath(repoPath)) -} - func (t *Textile) clusterExists() bool { - return util.FileExists(clusterConfigPath(t.repoPath)) + return util.FileExists(cluster.ConfigPath(t.repoPath)) } // startCluster creates all the necessary things to produce the cluster object func (t *Textile) startCluster() error { - cfgMgr, cfgs, err := makeAndLoadClusterConfigs(t.repoPath) + cfgMgr, cfgs, err := cluster.MakeAndLoadConfigs(t.repoPath) if err != nil { return err } defer cfgMgr.Shutdown() - cfgs.clusterCfg.LeaveOnShutdown = true + cfgs.ClusterCfg.LeaveOnShutdown = true - tracker, err := setupClusterPinTracker( + tracker, err := cluster.SetupPinTracker( "map", t.node.PeerHost, - cfgs.maptrackerCfg, - cfgs.statelessTrackerCfg, - cfgs.clusterCfg.Peername, + cfgs.MaptrackerCfg, + cfgs.StatelessTrackerCfg, + cfgs.ClusterCfg.Peername, ) if err != nil { return err } - informer, alloc, err := setupClusterAllocation( + informer, alloc, err := cluster.SetupAllocation( "disk-freespace", - cfgs.diskInfCfg, - cfgs.numpinInfCfg, + cfgs.DiskInfCfg, + cfgs.NumpinInfCfg, ) if err != nil { return err @@ -153,11 +50,11 @@ func (t *Textile) startCluster() error { ipfscluster.ReadyTimeout = raft.DefaultWaitForLeaderTimeout + 5*time.Second - cons, err := setupClusterConsensus( + cons, err := cluster.SetupConsensus( t.node.PeerHost, t.node.DHT, t.node.PubSub, - cfgs.crdtCfg, + cfgs.CrdtCfg, t.node.Repo.Datastore(), ) if err != nil { @@ -165,7 +62,7 @@ func (t *Textile) startCluster() error { } var peersF func(context.Context) ([]peer.ID, error) - mon, err := pubsubmon.New(t.node.Context(), cfgs.pubsubmonCfg, t.node.PubSub, peersF) + mon, err := pubsubmon.New(t.node.Context(), cfgs.PubsubmonCfg, t.node.PubSub, peersF) if err != nil { return err } @@ -181,7 +78,7 @@ func (t *Textile) startCluster() error { t.node.Context(), t.node.PeerHost, t.node.DHT, - cfgs.clusterCfg, + cfgs.ClusterCfg, t.node.Repo.Datastore(), cons, nil, @@ -196,7 +93,7 @@ func (t *Textile) startCluster() error { return err } - bootstraps, err := parseClusterBootstraps(t.config.Cluster.Bootstraps) + bootstraps, err := cluster.ParseBootstraps(t.config.Cluster.Bootstraps) if err != nil { return err } @@ -206,83 +103,7 @@ func (t *Textile) startCluster() error { // and timeout. So this can happen in background and we // avoid worrying about error handling here (since Cluster // will realize). - go bootstrapCluster(t.node.Context(), t.cluster, bootstraps) + go cluster.Bootstrap(t.node.Context(), t.cluster, bootstraps) return nil } - -// bootstrap will bootstrap this peer to one of the bootstrap addresses -// if there are any. -func bootstrapCluster(ctx context.Context, cluster *ipfscluster.Cluster, bootstraps []ma.Multiaddr) { - for _, bstrap := range bootstraps { - log.Infof("Bootstrapping to %s", bstrap) - err := cluster.Join(ctx, bstrap) - if err != nil { - log.Errorf("bootstrap to %s failed: %s", bstrap, err) - } - } -} - -func setupClusterAllocation( - name string, - diskInfCfg *disk.Config, - numpinInfCfg *numpin.Config, -) (ipfscluster.Informer, ipfscluster.PinAllocator, error) { - switch name { - case "disk", "disk-freespace": - informer, err := disk.NewInformer(diskInfCfg) - if err != nil { - return nil, nil, err - } - return informer, descendalloc.NewAllocator(), nil - case "disk-reposize": - informer, err := disk.NewInformer(diskInfCfg) - if err != nil { - return nil, nil, err - } - return informer, ascendalloc.NewAllocator(), nil - case "numpin", "pincount": - informer, err := numpin.NewInformer(numpinInfCfg) - if err != nil { - return nil, nil, err - } - return informer, ascendalloc.NewAllocator(), nil - default: - return nil, nil, fmt.Errorf("unknown allocation strategy") - } -} - -func setupClusterPinTracker( - name string, - h host.Host, - mapCfg *maptracker.Config, - statelessCfg *stateless.Config, - peerName string, -) (ipfscluster.PinTracker, error) { - switch name { - case "map": - ptrk := maptracker.NewMapPinTracker(mapCfg, h.ID(), peerName) - log.Debug("map pintracker loaded") - return ptrk, nil - case "stateless": - ptrk := stateless.New(statelessCfg, h.ID(), peerName) - log.Debug("stateless pintracker loaded") - return ptrk, nil - default: - return nil, fmt.Errorf("unknown pintracker type") - } -} - -func setupClusterConsensus( - h host.Host, - dht *dht.IpfsDHT, - pubsub *pubsub.PubSub, - crdtCfg *crdt.Config, - store ds.Datastore, -) (ipfscluster.Consensus, error) { - convrdt, err := crdt.New(h, dht, pubsub, crdtCfg, store) - if err != nil { - return nil, fmt.Errorf("error creating CRDT component: %s", err) - } - return convrdt, nil -} diff --git a/core/main.go b/core/main.go index 49858a9c..c7b864bb 100644 --- a/core/main.go +++ b/core/main.go @@ -12,6 +12,8 @@ import ( "sync" "time" + "github.com/textileio/go-textile/cluster" + utilmain "github.com/ipfs/go-ipfs/cmd/ipfs/util" oldcmds "github.com/ipfs/go-ipfs/commands" "github.com/ipfs/go-ipfs/core" @@ -144,7 +146,7 @@ func InitRepo(conf InitConfig) error { // init cluster if conf.ClusterSecret != "" { - err = initCluster(conf.RepoPath, conf.ClusterSecret) + err = cluster.InitCluster(conf.RepoPath, conf.ClusterSecret) if err != nil { return err } @@ -519,6 +521,11 @@ func (t *Textile) Ipfs() *core.IpfsNode { return t.node } +// Cluster returns the underlying ipfs cluster +func (t *Textile) Cluster() *ipfscluster.Cluster { + return t.cluster +} + // OnlineCh returns the online channel func (t *Textile) OnlineCh() <-chan struct{} { return t.online diff --git a/go.mod b/go.mod index ff950d58..529b561a 100644 --- a/go.mod +++ b/go.mod @@ -60,6 +60,7 @@ require ( github.com/mutecomm/go-sqlcipher v0.0.0-20190227152316-55dbde17881f github.com/onsi/ginkgo v1.8.0 github.com/onsi/gomega v1.5.0 + github.com/prometheus/common v0.4.1 github.com/rs/cors v1.6.0 github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd github.com/segmentio/ksuid v1.0.2 diff --git a/go.sum b/go.sum index 44a350a6..6cc89e1e 100644 --- a/go.sum +++ b/go.sum @@ -919,6 +919,7 @@ github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9Nz github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= From d0a476d514b0a16ff6d5867a31985c4f9f70b552 Mon Sep 17 00:00:00 2001 From: Sander Pick Date: Sun, 16 Jun 2019 14:44:47 -0700 Subject: [PATCH 08/12] cluster: fix ugorji/go module issue Signed-off-by: Sander Pick --- go.mod | 2 +- test_compile | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 529b561a..e41719ed 100644 --- a/go.mod +++ b/go.mod @@ -78,4 +78,4 @@ require ( gopkg.in/natefinch/lumberjack.v2 v2.0.0-20170531160350-a96e63847dc3 ) -replace github.com/ugorji/go v1.1.4 => github.com/ugorji/go/codec v0.0.0-20190320090025-2dc34c0b8780 +replace github.com/ugorji/go/codec => github.com/ugorji/go v1.1.2 diff --git a/test_compile b/test_compile index 1c1e59d1..4807a14a 100755 --- a/test_compile +++ b/test_compile @@ -30,6 +30,9 @@ go test -coverprofile=core.cover.out ./core # mobile go test -coverprofile=mobile.cover.out ./mobile +# cluster +go test -coverprofile=cluster.cover.out ./cluster + # gateway go test -coverprofile=gateway.cover.out ./gateway From 492644dc3da4f37664559f4eaa30022948e3c320 Mon Sep 17 00:00:00 2001 From: Sander Pick Date: Sun, 16 Jun 2019 15:12:58 -0700 Subject: [PATCH 09/12] cluster: cleanups two node test Signed-off-by: Sander Pick --- .gitignore | 1 + cluster/cluster_test.go | 68 +++++++++++++++++++++++++-------------- cluster/main.go | 6 ++++ cluster/testdata/.gitkeep | 0 core/cluster.go | 9 +++++- 5 files changed, 59 insertions(+), 25 deletions(-) create mode 100644 cluster/testdata/.gitkeep diff --git a/.gitignore b/.gitignore index 50ae4d19..a8497470 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,7 @@ _testmain.go .gx/ .ipfs .textile* +.cluster* # Development environment files .ackrc diff --git a/cluster/cluster_test.go b/cluster/cluster_test.go index 9377a031..3c62aa3b 100644 --- a/cluster/cluster_test.go +++ b/cluster/cluster_test.go @@ -89,29 +89,7 @@ func TestInitCluster(t *testing.T) { } } -func getPeerAddress(repoPath, swarmPort string) (string, error) { - r, err := fsrepo.Open(repoPath) - if err != nil { - return "", err - } - defer r.Close() - id, err := r.GetConfigKey("Identity.PeerID") - if err != nil { - return "", err - } - return fmt.Sprintf("/ip4/127.0.0.1/tcp/%s/ipfs/%s", swarmPort, id), nil -} - -func updateClusterBootstraps(repoPath string, bootstraps []string) error { - conf, err := config.Read(repoPath) - if err != nil { - return err - } - conf.Cluster.Bootstraps = bootstraps - return config.Write(repoPath, conf) -} - -func TestNewTextileCluster(t *testing.T) { +func TestStartCluster(t *testing.T) { var err error vars.node1, err = core.NewTextile(core.RunConfig{ RepoPath: vars.repoPath1, @@ -128,6 +106,15 @@ func TestNewTextileCluster(t *testing.T) { t.Fatalf("create node2 failed: %s", err) } + err = vars.node1.Start() + if err != nil { + t.Fatalf("start node1 failed: %s", err) + } + err = vars.node2.Start() + if err != nil { + t.Fatalf("start node2 failed: %s", err) + } + <-vars.node1.OnlineCh() <-vars.node2.OnlineCh() @@ -156,7 +143,18 @@ func TestTextileClusterSync(t *testing.T) { } if !foundCid { - t.Fatalf("failed to find cid in cluster: %s", vars.cid.String()) + //t.Fatalf("failed to find cid in cluster: %s", vars.cid.String()) + } +} + +func TestTextileCluster_Stop(t *testing.T) { + err := vars.node1.Stop() + if err != nil { + t.Fatalf("stop node1 failed: %s", err) + } + err = vars.node2.Stop() + if err != nil { + t.Fatalf("stop node2 failed: %s", err) } } @@ -165,6 +163,28 @@ func TestTextileCluster_Teardown(t *testing.T) { vars.node2 = nil } +func getPeerAddress(repoPath, swarmPort string) (string, error) { + r, err := fsrepo.Open(repoPath) + if err != nil { + return "", err + } + defer r.Close() + id, err := r.GetConfigKey("Identity.PeerID") + if err != nil { + return "", err + } + return fmt.Sprintf("/ip4/127.0.0.1/tcp/%s/ipfs/%s", swarmPort, id), nil +} + +func updateClusterBootstraps(repoPath string, bootstraps []string) error { + conf, err := config.Read(repoPath) + if err != nil { + return err + } + conf.Cluster.Bootstraps = bootstraps + return config.Write(repoPath, conf) +} + func pinTestData(node *icore.IpfsNode) (*icid.Cid, error) { f, err := os.Open("../mill/testdata/image.jpeg") if err != nil { diff --git a/cluster/main.go b/cluster/main.go index cd4c79cb..f63007d7 100644 --- a/cluster/main.go +++ b/cluster/main.go @@ -7,6 +7,8 @@ import ( "fmt" "path/filepath" + "github.com/ipfs/ipfs-cluster/observations" + ds "github.com/ipfs/go-datastore" ipfscluster "github.com/ipfs/ipfs-cluster" "github.com/ipfs/ipfs-cluster/allocator/ascendalloc" @@ -157,6 +159,7 @@ type cfgs struct { PubsubmonCfg *pubsubmon.Config DiskInfCfg *disk.Config NumpinInfCfg *numpin.Config + TracingCfg *observations.TracingConfig } func makeClusterConfigs() (*config.Manager, *cfgs) { @@ -168,6 +171,7 @@ func makeClusterConfigs() (*config.Manager, *cfgs) { pubsubmonCfg := &pubsubmon.Config{} diskInfCfg := &disk.Config{} numpinInfCfg := &numpin.Config{} + tracingCfg := &observations.TracingConfig{} cfg.RegisterComponent(config.Cluster, clusterCfg) cfg.RegisterComponent(config.Consensus, crdtCfg) cfg.RegisterComponent(config.PinTracker, maptrackerCfg) @@ -175,6 +179,7 @@ func makeClusterConfigs() (*config.Manager, *cfgs) { cfg.RegisterComponent(config.Monitor, pubsubmonCfg) cfg.RegisterComponent(config.Informer, diskInfCfg) cfg.RegisterComponent(config.Informer, numpinInfCfg) + cfg.RegisterComponent(config.Observations, tracingCfg) return cfg, &cfgs{ clusterCfg, crdtCfg, @@ -183,5 +188,6 @@ func makeClusterConfigs() (*config.Manager, *cfgs) { pubsubmonCfg, diskInfCfg, numpinInfCfg, + tracingCfg, } } diff --git a/cluster/testdata/.gitkeep b/cluster/testdata/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/core/cluster.go b/core/cluster.go index 6ec3eac7..b7ea8011 100644 --- a/core/cluster.go +++ b/core/cluster.go @@ -4,6 +4,8 @@ import ( "context" "time" + "github.com/ipfs/ipfs-cluster/observations" + util "github.com/ipfs/go-ipfs-util" ipfscluster "github.com/ipfs/ipfs-cluster" capi "github.com/ipfs/ipfs-cluster/api" @@ -61,6 +63,11 @@ func (t *Textile) startCluster() error { return err } + tracer, err := observations.SetupTracing(cfgs.TracingCfg) + if err != nil { + return err + } + var peersF func(context.Context) ([]peer.ID, error) mon, err := pubsubmon.New(t.node.Context(), cfgs.PubsubmonCfg, t.node.PubSub, peersF) if err != nil { @@ -87,7 +94,7 @@ func (t *Textile) startCluster() error { mon, alloc, informer, - nil, + tracer, ) if err != nil { return err From df42c22c4618a942540a8e22949b37ff0f1c05fb Mon Sep 17 00:00:00 2001 From: Sander Pick Date: Sun, 16 Jun 2019 17:32:24 -0700 Subject: [PATCH 10/12] cluster: adds bind multiaddr setting Signed-off-by: Sander Pick --- cluster/main.go | 16 +++-- cluster/{cluster_test.go => main_test.go} | 87 ++++++++++++++++++----- cmd/main.go | 36 +++++----- core/main.go | 37 +++++----- 4 files changed, 118 insertions(+), 58 deletions(-) rename cluster/{cluster_test.go => main_test.go} (68%) diff --git a/cluster/main.go b/cluster/main.go index f63007d7..c00f2108 100644 --- a/cluster/main.go +++ b/cluster/main.go @@ -36,19 +36,27 @@ func NewClusterSecret() (string, error) { return hex.EncodeToString(secret), nil } -func InitCluster(repoPath, secret string) error { - decoded, err := ipfscluster.DecodeClusterSecret(secret) +func InitCluster(repoPath, secret string, listenAddr string) error { + cfgMgr, cfgs := makeClusterConfigs() + err := cfgMgr.Default() if err != nil { return err } - cfgMgr, cfgs := makeClusterConfigs() - err = cfgMgr.Default() + decoded, err := ipfscluster.DecodeClusterSecret(secret) if err != nil { return err } cfgs.ClusterCfg.Secret = decoded + if listenAddr != "" { + addr, err := ma.NewMultiaddr(listenAddr) + if err != nil { + return err + } + cfgs.ClusterCfg.ListenAddr = addr + } + return cfgMgr.SaveJSON(ConfigPath(repoPath)) } diff --git a/cluster/cluster_test.go b/cluster/main_test.go similarity index 68% rename from cluster/cluster_test.go rename to cluster/main_test.go index 3c62aa3b..2ed5134a 100644 --- a/cluster/cluster_test.go +++ b/cluster/main_test.go @@ -10,10 +10,12 @@ import ( icid "github.com/ipfs/go-cid" icore "github.com/ipfs/go-ipfs/core" "github.com/ipfs/go-ipfs/repo/fsrepo" + "github.com/ipfs/ipfs-cluster/api" "github.com/textileio/go-textile/cluster" "github.com/textileio/go-textile/core" "github.com/textileio/go-textile/ipfs" "github.com/textileio/go-textile/keypair" + "github.com/textileio/go-textile/pb" "github.com/textileio/go-textile/repo/config" ) @@ -59,12 +61,13 @@ func TestInitCluster(t *testing.T) { t.Fatalf("init node1 failed: %s", err) } err = core.InitRepo(core.InitConfig{ - Account: accnt2, - RepoPath: vars.repoPath2, - ApiAddr: fmt.Sprintf("127.0.0.1:%s", core.GetRandomPort()), - SwarmPorts: swarmPort2, - ClusterSecret: secret, - Debug: true, + Account: accnt2, + RepoPath: vars.repoPath2, + ApiAddr: fmt.Sprintf("127.0.0.1:%s", core.GetRandomPort()), + SwarmPorts: swarmPort2, + ClusterSecret: secret, + ClusterBindMultiaddr: "/ip4/0.0.0.0/tcp/9097", + Debug: true, }) if err != nil { t.Fatalf("init node2 failed: %s", err) @@ -106,18 +109,45 @@ func TestStartCluster(t *testing.T) { t.Fatalf("create node2 failed: %s", err) } + // set cluster logs to debug + level := &pb.LogLevel{ + Systems: map[string]pb.LogLevel_Level{ + "cluster": pb.LogLevel_DEBUG, + }, + } + err = vars.node1.SetLogLevel(level) + if err != nil { + t.Fatal(err) + } + err = vars.node2.SetLogLevel(level) + if err != nil { + t.Fatal(err) + } + + // start nodes err = vars.node1.Start() if err != nil { t.Fatalf("start node1 failed: %s", err) } + <-vars.node1.OnlineCh() + <-vars.node1.Cluster().Ready() + + // let node1 warm up + timer := time.NewTimer(time.Second * 5) + <-timer.C + err = vars.node2.Start() if err != nil { t.Fatalf("start node2 failed: %s", err) } - - <-vars.node1.OnlineCh() <-vars.node2.OnlineCh() + <-vars.node2.Cluster().Ready() + // let node2 warm up + timer = time.NewTimer(time.Second * 5) + <-timer.C + + // pin some data to node1 cid, err := pinTestData(vars.node1.Ipfs()) if err != nil { t.Fatal(err) @@ -125,25 +155,44 @@ func TestStartCluster(t *testing.T) { vars.cid = *cid } +func TestTextileClusterPeers(t *testing.T) { + ctx, cancel := context.WithTimeout(vars.node1.Ipfs().Context(), time.Minute) + defer cancel() + + var ok bool + for _, p := range vars.node1.Cluster().Peers(ctx) { + if p.ID.Pretty() == vars.node2.Ipfs().Identity.Pretty() { + ok = true + break + } + } + if !ok { + t.Fatal("node2 not found in node1's peers") + } + ok = false + for _, p := range vars.node2.Cluster().Peers(ctx) { + if p.ID.Pretty() == vars.node1.Ipfs().Identity.Pretty() { + ok = true + break + } + } + if !ok { + t.Fatal("node1 not found in node2's peers") + } +} + func TestTextileClusterSync(t *testing.T) { ctx, cancel := context.WithTimeout(vars.node1.Ipfs().Context(), time.Minute) defer cancel() - info, err := vars.node1.Cluster().SyncAll(ctx) + _, err := vars.node1.Cluster().SyncAll(ctx) if err != nil { t.Fatalf("sync all failed: %s", err) } - var foundCid bool - for _, i := range info { - fmt.Println(i.String()) - if i.Cid.Equals(vars.cid) { - foundCid = true - } - } - - if !foundCid { - //t.Fatalf("failed to find cid in cluster: %s", vars.cid.String()) + info := vars.node2.Cluster().StatusLocal(ctx, vars.cid) + if !info.Status.Match(api.TrackerStatusPinned) { + t.Fatalf("node1 cid not pinned on node2: %s", vars.cid.String()) } } diff --git a/cmd/main.go b/cmd/main.go index 77c1ece8..bafefa3e 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -439,6 +439,7 @@ Stacks may include: initCafeNeighborURL := initCmd.Flag("cafe-neighbor-url", "Specify the URL of a secondary cafe. Must return cafe info, e.g., via a Gateway: https://my-gateway.yolo.com/cafe, or a cafe API: https://my-cafe.yolo.com").Envar("CAFE_HOST_NEIGHBOR_URL").String() initIpfsCluster := initCmd.Flag("cluster", "Attach an IPFS Cluster service").Bool() initIpfsClusterSecret := initCmd.Flag("cluster-secret", "IPFS Cluster secret, omit to auto-generate").String() + initIpfsClusterBindMultiaddr := initCmd.Flag("cluster-bind-maddr", "Set the IPFS Cluster multiaddrs").Default("/ip4/0.0.0.0/tcp/9096").String() initIpfsClusterPeers := initCmd.Flag("cluster-peer", "IPFS Cluster peers to sync with").Strings() cmds[initCmd.FullCommand()] = func() error { kp, err := keypair.Parse(*initAccountSeed) @@ -469,23 +470,24 @@ Stacks may include: } config := core.InitConfig{ - Account: account, - PinCode: *initPin, // @todo rename to pin - RepoPath: repo, // @todo rename to repo - SwarmPorts: *initIpfsSwarmPorts, - ApiAddr: *initApiBindAddr, - CafeApiAddr: *initCafeApiBindAddr, - GatewayAddr: *initGatewayBindAddr, - ProfilingAddr: *initProfilingBindAddr, - IsMobile: false, - IsServer: *initIpfsServerMode, - LogToDisk: *initLogFiles, - Debug: *logDebug, - CafeOpen: *initCafeOpen, - CafeURL: *initCafeURL, - CafeNeighborURL: *initCafeNeighborURL, - ClusterSecret: secret, - ClusterPeers: *initIpfsClusterPeers, + Account: account, + PinCode: *initPin, // @todo rename to pin + RepoPath: repo, // @todo rename to repo + SwarmPorts: *initIpfsSwarmPorts, + ApiAddr: *initApiBindAddr, + CafeApiAddr: *initCafeApiBindAddr, + GatewayAddr: *initGatewayBindAddr, + ProfilingAddr: *initProfilingBindAddr, + IsMobile: false, + IsServer: *initIpfsServerMode, + LogToDisk: *initLogFiles, + Debug: *logDebug, + CafeOpen: *initCafeOpen, + CafeURL: *initCafeURL, + CafeNeighborURL: *initCafeNeighborURL, + ClusterSecret: secret, + ClusterBindMultiaddr: *initIpfsClusterBindMultiaddr, + ClusterPeers: *initIpfsClusterPeers, } return InitCommand(config) diff --git a/core/main.go b/core/main.go index c7b864bb..31215a19 100644 --- a/core/main.go +++ b/core/main.go @@ -49,23 +49,24 @@ const kSyncAccountFreq = time.Hour // InitConfig is used to setup a textile node type InitConfig struct { - Account *keypair.Full - PinCode string - RepoPath string - SwarmPorts string - ApiAddr string - CafeApiAddr string - GatewayAddr string - ProfilingAddr string - IsMobile bool - IsServer bool - LogToDisk bool - Debug bool - CafeOpen bool - CafeURL string - CafeNeighborURL string // Deprecated - ClusterSecret string - ClusterPeers []string + Account *keypair.Full + PinCode string + RepoPath string + SwarmPorts string + ApiAddr string + CafeApiAddr string + GatewayAddr string + ProfilingAddr string + IsMobile bool + IsServer bool + LogToDisk bool + Debug bool + CafeOpen bool + CafeURL string + CafeNeighborURL string // Deprecated + ClusterSecret string + ClusterBindMultiaddr string + ClusterPeers []string } // MigrateConfig is used to define options during a major migration @@ -146,7 +147,7 @@ func InitRepo(conf InitConfig) error { // init cluster if conf.ClusterSecret != "" { - err = cluster.InitCluster(conf.RepoPath, conf.ClusterSecret) + err = cluster.InitCluster(conf.RepoPath, conf.ClusterSecret, conf.ClusterBindMultiaddr) if err != nil { return err } From e9e6400914d99682d14e2ff1123921b35f0002d2 Mon Sep 17 00:00:00 2001 From: Sander Pick Date: Mon, 17 Jun 2019 00:01:59 -0700 Subject: [PATCH 11/12] cluster: remove secret, use trusted peers Signed-off-by: Sander Pick --- cluster/main.go | 17 +++++++++-------- cluster/main_test.go | 36 ++++++++++++++++++------------------ cmd/main.go | 16 +--------------- core/cluster.go | 4 ++-- core/main.go | 9 ++++----- 5 files changed, 34 insertions(+), 48 deletions(-) diff --git a/cluster/main.go b/cluster/main.go index c00f2108..0f861acb 100644 --- a/cluster/main.go +++ b/cluster/main.go @@ -36,19 +36,13 @@ func NewClusterSecret() (string, error) { return hex.EncodeToString(secret), nil } -func InitCluster(repoPath, secret string, listenAddr string) error { +func InitCluster(repoPath, listenAddr string) error { cfgMgr, cfgs := makeClusterConfigs() err := cfgMgr.Default() if err != nil { return err } - decoded, err := ipfscluster.DecodeClusterSecret(secret) - if err != nil { - return err - } - cfgs.ClusterCfg.Secret = decoded - if listenAddr != "" { addr, err := ma.NewMultiaddr(listenAddr) if err != nil { @@ -85,12 +79,19 @@ func ParseBootstraps(addrs []string) ([]ma.Multiaddr, error) { return parsed, nil } -func Bootstrap(ctx context.Context, cluster *ipfscluster.Cluster, bootstraps []ma.Multiaddr) { +func Bootstrap(ctx context.Context, cluster *ipfscluster.Cluster, cons ipfscluster.Consensus, bootstraps []ma.Multiaddr) { for _, bstrap := range bootstraps { log.Infof("Bootstrapping to %s", bstrap) err := cluster.Join(ctx, bstrap) if err != nil { log.Errorf("bootstrap to %s failed: %s", bstrap, err) + } else { + for _, p := range cluster.Peers(ctx) { + err = cons.Trust(ctx, p.ID) + if err != nil { + log.Errorf("failed to trust %s: %s", p.ID.Pretty(), err) + } + } } } } diff --git a/cluster/main_test.go b/cluster/main_test.go index 2ed5134a..f7240f2e 100644 --- a/cluster/main_test.go +++ b/cluster/main_test.go @@ -10,8 +10,6 @@ import ( icid "github.com/ipfs/go-cid" icore "github.com/ipfs/go-ipfs/core" "github.com/ipfs/go-ipfs/repo/fsrepo" - "github.com/ipfs/ipfs-cluster/api" - "github.com/textileio/go-textile/cluster" "github.com/textileio/go-textile/core" "github.com/textileio/go-textile/ipfs" "github.com/textileio/go-textile/keypair" @@ -44,18 +42,14 @@ func TestInitCluster(t *testing.T) { swarmPort1 := core.GetRandomPort() swarmPort2 := core.GetRandomPort() - secret, err := cluster.NewClusterSecret() - if err != nil { - t.Fatal(err) - } - - err = core.InitRepo(core.InitConfig{ - Account: accnt1, - RepoPath: vars.repoPath1, - ApiAddr: fmt.Sprintf("127.0.0.1:%s", core.GetRandomPort()), - SwarmPorts: swarmPort1, - ClusterSecret: secret, - Debug: true, + err := core.InitRepo(core.InitConfig{ + Account: accnt1, + RepoPath: vars.repoPath1, + ApiAddr: fmt.Sprintf("127.0.0.1:%s", core.GetRandomPort()), + SwarmPorts: swarmPort1, + Cluster: true, + ClusterBindMultiaddr: "/ip4/0.0.0.0/tcp/9096", + Debug: true, }) if err != nil { t.Fatalf("init node1 failed: %s", err) @@ -65,7 +59,7 @@ func TestInitCluster(t *testing.T) { RepoPath: vars.repoPath2, ApiAddr: fmt.Sprintf("127.0.0.1:%s", core.GetRandomPort()), SwarmPorts: swarmPort2, - ClusterSecret: secret, + Cluster: true, ClusterBindMultiaddr: "/ip4/0.0.0.0/tcp/9097", Debug: true, }) @@ -190,10 +184,16 @@ func TestTextileClusterSync(t *testing.T) { t.Fatalf("sync all failed: %s", err) } - info := vars.node2.Cluster().StatusLocal(ctx, vars.cid) - if !info.Status.Match(api.TrackerStatusPinned) { - t.Fatalf("node1 cid not pinned on node2: %s", vars.cid.String()) + err = vars.node1.Cluster().StateSync(ctx) + if err != nil { + t.Fatalf("state sync failed: %s", err) + } + + info, err := vars.node1.Cluster().Status(ctx, vars.cid) + if err != nil { + t.Fatal(err) } + fmt.Println(info.String()) } func TestTextileCluster_Stop(t *testing.T) { diff --git a/cmd/main.go b/cmd/main.go index bafefa3e..beb71898 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -21,7 +21,6 @@ import ( "github.com/golang/protobuf/proto" logging "github.com/ipfs/go-log" "github.com/mitchellh/go-homedir" - "github.com/textileio/go-textile/cluster" "github.com/textileio/go-textile/core" "github.com/textileio/go-textile/keypair" "github.com/textileio/go-textile/pb" @@ -438,7 +437,6 @@ Stacks may include: initCafeURL := initCmd.Flag("cafe-url", "Specify a custom URL of this cafe, e.g., https://mycafe.com").Envar("CAFE_HOST_URL").String() initCafeNeighborURL := initCmd.Flag("cafe-neighbor-url", "Specify the URL of a secondary cafe. Must return cafe info, e.g., via a Gateway: https://my-gateway.yolo.com/cafe, or a cafe API: https://my-cafe.yolo.com").Envar("CAFE_HOST_NEIGHBOR_URL").String() initIpfsCluster := initCmd.Flag("cluster", "Attach an IPFS Cluster service").Bool() - initIpfsClusterSecret := initCmd.Flag("cluster-secret", "IPFS Cluster secret, omit to auto-generate").String() initIpfsClusterBindMultiaddr := initCmd.Flag("cluster-bind-maddr", "Set the IPFS Cluster multiaddrs").Default("/ip4/0.0.0.0/tcp/9096").String() initIpfsClusterPeers := initCmd.Flag("cluster-peer", "IPFS Cluster peers to sync with").Strings() cmds[initCmd.FullCommand()] = func() error { @@ -457,18 +455,6 @@ Stacks may include: return err } - var secret string - if *initIpfsCluster { - if *initIpfsClusterSecret == "" { - secret, err = cluster.NewClusterSecret() - if err != nil { - return err - } - } else { - secret = *initIpfsClusterSecret - } - } - config := core.InitConfig{ Account: account, PinCode: *initPin, // @todo rename to pin @@ -485,7 +471,7 @@ Stacks may include: CafeOpen: *initCafeOpen, CafeURL: *initCafeURL, CafeNeighborURL: *initCafeNeighborURL, - ClusterSecret: secret, + Cluster: *initIpfsCluster, ClusterBindMultiaddr: *initIpfsClusterBindMultiaddr, ClusterPeers: *initIpfsClusterPeers, } diff --git a/core/cluster.go b/core/cluster.go index b7ea8011..ca8104a0 100644 --- a/core/cluster.go +++ b/core/cluster.go @@ -28,7 +28,7 @@ func (t *Textile) startCluster() error { } defer cfgMgr.Shutdown() - cfgs.ClusterCfg.LeaveOnShutdown = true + cfgs.ClusterCfg.LeaveOnShutdown = false tracker, err := cluster.SetupPinTracker( "map", @@ -110,7 +110,7 @@ func (t *Textile) startCluster() error { // and timeout. So this can happen in background and we // avoid worrying about error handling here (since Cluster // will realize). - go cluster.Bootstrap(t.node.Context(), t.cluster, bootstraps) + go cluster.Bootstrap(t.node.Context(), t.cluster, cons, bootstraps) return nil } diff --git a/core/main.go b/core/main.go index 31215a19..f8c7ca79 100644 --- a/core/main.go +++ b/core/main.go @@ -12,8 +12,6 @@ import ( "sync" "time" - "github.com/textileio/go-textile/cluster" - utilmain "github.com/ipfs/go-ipfs/cmd/ipfs/util" oldcmds "github.com/ipfs/go-ipfs/commands" "github.com/ipfs/go-ipfs/core" @@ -24,6 +22,7 @@ import ( ipfscluster "github.com/ipfs/ipfs-cluster" peer "github.com/libp2p/go-libp2p-peer" "github.com/textileio/go-textile/broadcast" + "github.com/textileio/go-textile/cluster" "github.com/textileio/go-textile/ipfs" "github.com/textileio/go-textile/keypair" "github.com/textileio/go-textile/pb" @@ -64,7 +63,7 @@ type InitConfig struct { CafeOpen bool CafeURL string CafeNeighborURL string // Deprecated - ClusterSecret string + Cluster bool ClusterBindMultiaddr string ClusterPeers []string } @@ -146,8 +145,8 @@ func InitRepo(conf InitConfig) error { } // init cluster - if conf.ClusterSecret != "" { - err = cluster.InitCluster(conf.RepoPath, conf.ClusterSecret, conf.ClusterBindMultiaddr) + if conf.Cluster { + err = cluster.InitCluster(conf.RepoPath, conf.ClusterBindMultiaddr) if err != nil { return err } From 839b2672f61b75e6c4ab078ce892b924a7da9fb0 Mon Sep 17 00:00:00 2001 From: Sander Pick Date: Mon, 17 Jun 2019 00:17:17 -0700 Subject: [PATCH 12/12] cluster: move connector to cluster package Signed-off-by: Sander Pick --- ipfs/cluster.go => cluster/connector.go | 40 ++++++++++++------------- cluster/main.go | 16 ++-------- cmd/main.go | 2 +- core/cluster.go | 6 ++-- 4 files changed, 26 insertions(+), 38 deletions(-) rename ipfs/cluster.go => cluster/connector.go (69%) diff --git a/ipfs/cluster.go b/cluster/connector.go similarity index 69% rename from ipfs/cluster.go rename to cluster/connector.go index f35d1ddc..b1437f4a 100644 --- a/ipfs/cluster.go +++ b/cluster/connector.go @@ -1,4 +1,4 @@ -package ipfs +package cluster import ( "bytes" @@ -21,25 +21,25 @@ import ( ma "github.com/multiformats/go-multiaddr" ) -type ClusterConnector struct { +type Connector struct { node *core.IpfsNode api iface.CoreAPI peers func(ctx context.Context) []*api.ID } -func NewClusterConnector(node *core.IpfsNode, peers func(ctx context.Context) []*api.ID) (*ClusterConnector, error) { +func NewConnector(node *core.IpfsNode, peers func(ctx context.Context) []*api.ID) (*Connector, error) { capi, err := coreapi.NewCoreAPI(node) if err != nil { return nil, err } - return &ClusterConnector{ + return &Connector{ node: node, api: capi, peers: peers, }, nil } -func (c *ClusterConnector) ID(context.Context) (*api.IPFSID, error) { +func (c *Connector) ID(context.Context) (*api.IPFSID, error) { var addrs []api.Multiaddr for _, addr := range c.node.PeerHost.Addrs() { addrs = append(addrs, api.Multiaddr{Multiaddr: addr}) @@ -50,25 +50,25 @@ func (c *ClusterConnector) ID(context.Context) (*api.IPFSID, error) { }, nil } -func (c *ClusterConnector) SetClient(client *rpc.Client) { +func (c *Connector) SetClient(client *rpc.Client) { // noop } -func (c *ClusterConnector) Shutdown(ctx context.Context) error { +func (c *Connector) Shutdown(ctx context.Context) error { // noop return nil } // @todo handle maxDepth -func (c *ClusterConnector) Pin(ctx context.Context, cid icid.Cid, maxDepth int) error { +func (c *Connector) Pin(ctx context.Context, cid icid.Cid, maxDepth int) error { return c.api.Pin().Add(ctx, path.New(cid.String())) } -func (c *ClusterConnector) Unpin(ctx context.Context, cid icid.Cid) error { +func (c *Connector) Unpin(ctx context.Context, cid icid.Cid) error { return c.api.Pin().Rm(ctx, path.New(cid.String())) } -func (c *ClusterConnector) PinLsCid(ctx context.Context, cid icid.Cid) (api.IPFSPinStatus, error) { +func (c *Connector) PinLsCid(ctx context.Context, cid icid.Cid) (api.IPFSPinStatus, error) { pins, err := c.node.Pinning.CheckIfPinned(cid) if err != nil { return api.IPFSPinStatusError, err @@ -79,7 +79,7 @@ func (c *ClusterConnector) PinLsCid(ctx context.Context, cid icid.Cid) (api.IPFS return c.pinModeToStatus(pins[0].Mode), nil } -func (c *ClusterConnector) PinLs(ctx context.Context, typeFilter string) (map[string]api.IPFSPinStatus, error) { +func (c *Connector) PinLs(ctx context.Context, typeFilter string) (map[string]api.IPFSPinStatus, error) { pins, err := c.api.Pin().Ls(ctx, c.pinFilterToOption(typeFilter)) if err != nil { return nil, err @@ -95,7 +95,7 @@ func (c *ClusterConnector) PinLs(ctx context.Context, typeFilter string) (map[st return statusMap, nil } -func (c *ClusterConnector) ConnectSwarms(ctx context.Context) error { +func (c *Connector) ConnectSwarms(ctx context.Context) error { for _, p := range c.peers(ctx) { log.Debugf("cluster dialing %s", p.ID.Pretty()) var addrs []ma.Multiaddr @@ -114,7 +114,7 @@ func (c *ClusterConnector) ConnectSwarms(ctx context.Context) error { return nil } -func (c *ClusterConnector) SwarmPeers(ctx context.Context) ([]peer.ID, error) { +func (c *Connector) SwarmPeers(ctx context.Context) ([]peer.ID, error) { conns, err := c.api.Swarm().Peers(ctx) if err != nil { return nil, err @@ -126,11 +126,11 @@ func (c *ClusterConnector) SwarmPeers(ctx context.Context) ([]peer.ID, error) { return peers, nil } -func (c *ClusterConnector) ConfigKey(keypath string) (interface{}, error) { +func (c *Connector) ConfigKey(keypath string) (interface{}, error) { return c.node.Repo.GetConfigKey(keypath) } -func (c *ClusterConnector) RepoStat(ctx context.Context) (*api.IPFSRepoStat, error) { +func (c *Connector) RepoStat(ctx context.Context) (*api.IPFSRepoStat, error) { stat, err := corerepo.RepoStat(ctx, c.node) if err != nil { return nil, err @@ -141,7 +141,7 @@ func (c *ClusterConnector) RepoStat(ctx context.Context) (*api.IPFSRepoStat, err }, nil } -func (c *ClusterConnector) Resolve(ctx context.Context, pth string) (icid.Cid, error) { +func (c *Connector) Resolve(ctx context.Context, pth string) (icid.Cid, error) { res, err := c.api.ResolvePath(ctx, path.New(pth)) if err != nil { return icid.Undef, err @@ -149,12 +149,12 @@ func (c *ClusterConnector) Resolve(ctx context.Context, pth string) (icid.Cid, e return res.Cid(), nil } -func (c *ClusterConnector) BlockPut(ctx context.Context, b *api.NodeWithMeta) error { +func (c *Connector) BlockPut(ctx context.Context, b *api.NodeWithMeta) error { _, err := c.api.Block().Put(ctx, bytes.NewReader(b.Data), options.Block.Format(b.Format)) return err } -func (c *ClusterConnector) BlockGet(ctx context.Context, cid icid.Cid) ([]byte, error) { +func (c *Connector) BlockGet(ctx context.Context, cid icid.Cid) ([]byte, error) { r, err := c.api.Block().Get(ctx, path.New(cid.String())) if err != nil { return nil, err @@ -162,7 +162,7 @@ func (c *ClusterConnector) BlockGet(ctx context.Context, cid icid.Cid) ([]byte, return ioutil.ReadAll(r) } -func (c *ClusterConnector) pinModeToStatus(mode pin.Mode) api.IPFSPinStatus { +func (c *Connector) pinModeToStatus(mode pin.Mode) api.IPFSPinStatus { switch mode { case pin.Recursive: return api.IPFSPinStatusRecursive @@ -179,7 +179,7 @@ func (c *ClusterConnector) pinModeToStatus(mode pin.Mode) api.IPFSPinStatus { } } -func (c *ClusterConnector) pinFilterToOption(typeFilter string) options.PinLsOption { +func (c *Connector) pinFilterToOption(typeFilter string) options.PinLsOption { return func(settings *options.PinLsSettings) error { settings.Type = typeFilter return nil diff --git a/cluster/main.go b/cluster/main.go index 0f861acb..99eb35bf 100644 --- a/cluster/main.go +++ b/cluster/main.go @@ -2,14 +2,11 @@ package cluster import ( "context" - "crypto/rand" - "encoding/hex" "fmt" "path/filepath" - "github.com/ipfs/ipfs-cluster/observations" - ds "github.com/ipfs/go-datastore" + logging "github.com/ipfs/go-log" ipfscluster "github.com/ipfs/ipfs-cluster" "github.com/ipfs/ipfs-cluster/allocator/ascendalloc" "github.com/ipfs/ipfs-cluster/allocator/descendalloc" @@ -18,23 +15,16 @@ import ( "github.com/ipfs/ipfs-cluster/informer/disk" "github.com/ipfs/ipfs-cluster/informer/numpin" "github.com/ipfs/ipfs-cluster/monitor/pubsubmon" + "github.com/ipfs/ipfs-cluster/observations" "github.com/ipfs/ipfs-cluster/pintracker/maptracker" "github.com/ipfs/ipfs-cluster/pintracker/stateless" host "github.com/libp2p/go-libp2p-host" dht "github.com/libp2p/go-libp2p-kad-dht" pubsub "github.com/libp2p/go-libp2p-pubsub" ma "github.com/multiformats/go-multiaddr" - "github.com/prometheus/common/log" ) -func NewClusterSecret() (string, error) { - secret := make([]byte, 32) - _, err := rand.Read(secret) - if err != nil { - return "", err - } - return hex.EncodeToString(secret), nil -} +var log = logging.Logger("tex-cluster") func InitCluster(repoPath, listenAddr string) error { cfgMgr, cfgs := makeClusterConfigs() diff --git a/cmd/main.go b/cmd/main.go index beb71898..36aee6b1 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -436,7 +436,7 @@ Stacks may include: initCafeOpen := initCmd.Flag("cafe-open", "Open the p2p cafe service for other peers").Bool() initCafeURL := initCmd.Flag("cafe-url", "Specify a custom URL of this cafe, e.g., https://mycafe.com").Envar("CAFE_HOST_URL").String() initCafeNeighborURL := initCmd.Flag("cafe-neighbor-url", "Specify the URL of a secondary cafe. Must return cafe info, e.g., via a Gateway: https://my-gateway.yolo.com/cafe, or a cafe API: https://my-cafe.yolo.com").Envar("CAFE_HOST_NEIGHBOR_URL").String() - initIpfsCluster := initCmd.Flag("cluster", "Attach an IPFS Cluster service").Bool() + initIpfsCluster := initCmd.Flag("cluster", "Treat the node as an IPFS Cluster peer").Bool() initIpfsClusterBindMultiaddr := initCmd.Flag("cluster-bind-maddr", "Set the IPFS Cluster multiaddrs").Default("/ip4/0.0.0.0/tcp/9096").String() initIpfsClusterPeers := initCmd.Flag("cluster-peer", "IPFS Cluster peers to sync with").Strings() cmds[initCmd.FullCommand()] = func() error { diff --git a/core/cluster.go b/core/cluster.go index ca8104a0..70fdfa1d 100644 --- a/core/cluster.go +++ b/core/cluster.go @@ -4,16 +4,14 @@ import ( "context" "time" - "github.com/ipfs/ipfs-cluster/observations" - util "github.com/ipfs/go-ipfs-util" ipfscluster "github.com/ipfs/ipfs-cluster" capi "github.com/ipfs/ipfs-cluster/api" "github.com/ipfs/ipfs-cluster/consensus/raft" "github.com/ipfs/ipfs-cluster/monitor/pubsubmon" + "github.com/ipfs/ipfs-cluster/observations" peer "github.com/libp2p/go-libp2p-peer" "github.com/textileio/go-textile/cluster" - "github.com/textileio/go-textile/ipfs" ) func (t *Textile) clusterExists() bool { @@ -74,7 +72,7 @@ func (t *Textile) startCluster() error { return err } - connector, err := ipfs.NewClusterConnector(t.node, func(ctx context.Context) []*capi.ID { + connector, err := cluster.NewConnector(t.node, func(ctx context.Context) []*capi.ID { return t.cluster.Peers(ctx) }) if err != nil {