1
+ package nesting
2
+
3
+ import (
4
+ "context"
5
+ "fmt"
6
+ "github.com/hashicorp/go-multierror"
7
+ "github.com/ipfs/go-cid"
8
+ ci "github.com/libp2p/go-libp2p-core/crypto"
9
+ "github.com/libp2p/go-libp2p-core/routing"
10
+ "github.com/pkg/errors"
11
+
12
+ "github.com/libp2p/go-libp2p-core/host"
13
+ "github.com/libp2p/go-libp2p-core/peer"
14
+
15
+ "github.com/libp2p/go-libp2p-kad-dht"
16
+ )
17
+
18
+ // DHT implements the routing interface to
19
+ type DHT struct {
20
+ Inner , Outer * dht.IpfsDHT
21
+ }
22
+
23
+ // Assert that IPFS assumptions about interfaces aren't broken. These aren't a
24
+ // guarantee, but we can use them to aid refactoring.
25
+ var (
26
+ _ routing.ContentRouting = (* DHT )(nil )
27
+ _ routing.Routing = (* DHT )(nil )
28
+ _ routing.PeerRouting = (* DHT )(nil )
29
+ _ routing.PubKeyFetcher = (* DHT )(nil )
30
+ _ routing.ValueStore = (* DHT )(nil )
31
+ )
32
+
33
+ func New (ctx context.Context , h host.Host , innerOptions []dht.Option , outerOptions []dht.Option ) (* DHT , error ) {
34
+ inner , err := dht .New (ctx , h , innerOptions ... )
35
+ if err != nil {
36
+ return nil , err
37
+ }
38
+
39
+ outer , err := dht .New (ctx , h , outerOptions ... )
40
+ if err != nil {
41
+ return nil , err
42
+ }
43
+
44
+ d := & DHT {
45
+ Inner : inner ,
46
+ Outer : outer ,
47
+ }
48
+
49
+ return d , nil
50
+ }
51
+
52
+ func (dht * DHT ) GetClosestPeers (ctx context.Context , key string ) ([]peer.ID , error ) {
53
+ var innerResult []peer.ID
54
+ peerCh , err := dht .Inner .GetClosestPeersSeeded (ctx , key , nil )
55
+ if err == nil {
56
+ innerResult = getPeersFromCh (peerCh )
57
+ }
58
+
59
+ outerResultCh , err := dht .Outer .GetClosestPeersSeeded (ctx , key , innerResult )
60
+ if err != nil {
61
+ return nil , err
62
+ }
63
+
64
+ return getPeersFromCh (outerResultCh ), nil
65
+ }
66
+
67
+ func getPeersFromCh (peerCh <- chan peer.ID ) []peer.ID {
68
+ var peers []peer.ID
69
+ for p := range peerCh {
70
+ peers = append (peers , p )
71
+ }
72
+ return peers
73
+ }
74
+
75
+ func (dht * DHT ) GetPublicKey (ctx context.Context , id peer.ID ) (ci.PubKey , error ) {
76
+ panic ("implement me" )
77
+ }
78
+
79
+ func (dht * DHT ) Provide (ctx context.Context , cid cid.Cid , b bool ) error {
80
+ panic ("implement me" )
81
+ }
82
+
83
+ func (dht * DHT ) FindProvidersAsync (ctx context.Context , cid cid.Cid , i int ) <- chan peer.AddrInfo {
84
+ panic ("implement me" )
85
+ }
86
+
87
+ func (dht * DHT ) FindPeer (ctx context.Context , id peer.ID ) (peer.AddrInfo , error ) {
88
+ panic ("implement me" )
89
+ }
90
+
91
+ func (dht * DHT ) PutValue (ctx context.Context , s string , bytes []byte , option ... routing.Option ) error {
92
+ panic ("implement me" )
93
+ }
94
+
95
+ func (dht * DHT ) GetValue (ctx context.Context , s string , option ... routing.Option ) ([]byte , error ) {
96
+ panic ("implement me" )
97
+ }
98
+
99
+ func (dht * DHT ) SearchValue (ctx context.Context , s string , option ... routing.Option ) (<- chan []byte , error ) {
100
+ panic ("implement me" )
101
+ }
102
+
103
+ func (dht * DHT ) Bootstrap (ctx context.Context ) error {
104
+ errI := dht .Inner .Bootstrap (ctx )
105
+ errO := dht .Outer .Bootstrap (ctx )
106
+
107
+ errs := make ([]error , 0 , 2 )
108
+ if errI != nil {
109
+ errs = append (errs , errors .Wrap (errI , fmt .Sprintf ("failed to bootstrap inner dht" )))
110
+ }
111
+ if errO != nil {
112
+ errs = append (errs , errors .Wrap (errI , fmt .Sprintf ("failed to bootstrap outer dht" )))
113
+ }
114
+
115
+ switch len (errs ) {
116
+ case 0 :
117
+ return nil
118
+ case 1 :
119
+ return errs [0 ]
120
+ default :
121
+ return multierror .Append (errs [0 ], errs [1 :]... )
122
+ }
123
+ }
0 commit comments