github.com/amazechain/amc@v0.1.3/internal/network/kad_dht.go (about) 1 // Copyright 2022 The AmazeChain Authors 2 // This file is part of the AmazeChain library. 3 // 4 // The AmazeChain library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The AmazeChain library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the AmazeChain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package network 18 19 import ( 20 "context" 21 "fmt" 22 "github.com/amazechain/amc/log" 23 "time" 24 25 kademliaDHT "github.com/libp2p/go-libp2p-kad-dht" 26 "github.com/libp2p/go-libp2p/core/peer" 27 discovery "github.com/libp2p/go-libp2p/p2p/discovery/routing" 28 ) 29 30 type KadDHT struct { 31 *kademliaDHT.IpfsDHT 32 33 service *Service 34 35 routingDiscovery *discovery.RoutingDiscovery 36 37 ctx context.Context 38 cancel context.CancelFunc 39 } 40 41 func NewKadDht(ctx context.Context, s *Service, isServer bool, bootstrappers ...peer.AddrInfo) (*KadDHT, error) { 42 43 c, cancel := context.WithCancel(ctx) 44 var mode kademliaDHT.ModeOpt 45 if isServer { 46 mode = kademliaDHT.ModeServer 47 } else { 48 mode = kademliaDHT.ModeClient 49 } 50 51 dht, err := kademliaDHT.New(c, s.host, kademliaDHT.Mode(mode), kademliaDHT.BootstrapPeers(bootstrappers...)) 52 53 if err != nil { 54 log.Error("create dht failed", err) 55 cancel() 56 return nil, err 57 } 58 59 kDHT := &KadDHT{ 60 IpfsDHT: dht, 61 routingDiscovery: discovery.NewRoutingDiscovery(dht), 62 ctx: c, 63 cancel: cancel, 64 service: s, 65 } 66 67 return kDHT, nil 68 } 69 70 func (k *KadDHT) Start() error { 71 err := k.Bootstrap(k.ctx) 72 if err != nil { 73 log.Error("setup bootstrap failed", err) 74 return err 75 } 76 77 //todo 78 //if err := k.discoverLocal(); err != nil { 79 // log.Error("setup mdns discover failed", err) 80 // return err 81 //} 82 83 k.routingDiscovery.Advertise(k.ctx, DiscoverProtocol) 84 go k.loopDiscoverRemote() 85 86 return nil 87 } 88 89 func (k *KadDHT) loopDiscoverRemote() { 90 91 ticker := time.NewTicker(10 * time.Second) 92 defer ticker.Stop() 93 for { 94 select { 95 case <-k.ctx.Done(): 96 return 97 case <-ticker.C: 98 peerChan, err := k.routingDiscovery.FindPeers(k.ctx, DiscoverProtocol) 99 if err != nil { 100 log.Warn("find peers failed", err) 101 } else { 102 for p := range peerChan { 103 if p.ID != k.service.host.ID() { 104 log.Tracef("find peer %s", fmt.Sprintf("info: %s", p.String())) 105 k.service.HandlePeerFound(p) 106 } 107 } 108 } 109 110 ticker.Reset(60 * time.Second) 111 } 112 } 113 } 114 115 //func (k *KadDHT) findPeers() []peer.AddrInfo { 116 //peers, err := k.routingDiscovery.FindPeers(k.ctx, DiscoverProtocol) 117 //if err != nil { 118 // return nil 119 //} else { 120 // return peers 121 //} 122 //} 123 124 func (k *KadDHT) discoverLocal() error { 125 126 //m := mdns.NewMdnsService(k.service.host, "", k.service.HandlePeerFound) 127 //if err := m.Start(); err != nil { 128 // log.Error("mdns start failed", err) 129 // return err 130 //} 131 // 132 return nil 133 }