예제 #1
0
        /// <summary>
        ///   Process a get provider request.
        /// </summary>
        public DhtMessage ProcessGetProviders(DhtMessage request, DhtMessage response)
        {
            // Find providers for the content.
            var cid = new Cid {
                Hash = new MultiHash(request.Key)
            };

            response.ProviderPeers = ContentRouter
                                     .Get(cid)
                                     .Select(pid =>
            {
                var peer = pid == SwarmService.LocalPeer.Id
                        ? SwarmService.LocalPeer
                        : SwarmService.RegisterPeer(new Peer {
                    Id = pid
                });
                return(new DhtPeerMessage
                {
                    Id = peer.Id.ToArray(),
                    Addresses = peer.Addresses.Select(a => a.WithoutPeerId().ToArray()).ToArray()
                });
            })
                                     .Take(20)
                                     .ToArray();

            // Also return the closest peers
            return(ProcessFindNode(request, response));
        }
예제 #2
0
        public async Task ProcessGetProvidersMessage_HasProvider()
        {
            var swarm = new SwarmService {
                LocalPeer = self
            };
            var dht = new DhtService {
                SwarmService = swarm
            };
            await dht.StartAsync();

            try
            {
                swarm.RegisterPeer(other);
                Cid cid =
                    "zBunRGrmCGokA1oMESGGTfrtcMFsVA8aEtcNzM54akPWXF97uXCqTjF3GZ9v8YzxHrG66J8QhtPFWwZebRZ2zeUEELu67";
                dht.ContentRouter.Add(cid, other.Id);
                var request = new DhtMessage
                {
                    Type = MessageType.GetProviders,
                    Key  = cid.Hash.ToArray()
                };
                var response = dht.ProcessGetProviders(request, new DhtMessage());
                Assert.AreEqual(1, response.ProviderPeers.Length);
                response.ProviderPeers[0].TryToPeer(out var found);
                Assert.AreEqual(other, found);
                Assert.AreNotEqual(0, found.Addresses.Count());
            }
            finally
            {
                await dht.StopAsync();
            }
        }
예제 #3
0
#pragma warning disable VSTHRD100 // Avoid async void methods
        /// <summary>
        ///     Fired when a peer is discovered.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="peer"></param>
        /// <remarks>
        ///     Registers the peer with the <see cref="SwarmService" />.
        /// </remarks>
        private void OnPeerDiscovered(object sender, Peer peer)
#pragma warning restore VSTHRD100 // Avoid async void methods
        {
            try
            {
                SwarmService.RegisterPeer(peer);
            }
            catch (Exception ex)
            {
                Log.Warning("failed to register peer " + peer, ex);

                // eat it, nothing we can do.
            }
        }
예제 #4
0
        public void PeerDiscovered()
        {
            var swarm = new SwarmService {
                LocalPeer = _self
            };
            var peerCount = 0;

            swarm.PeerDiscovered += (s, e) => { ++peerCount; };
            swarm.RegisterPeerAddress("/ip4/127.0.0.1/tcp/4001/ipfs/QmdpwjdB94eNm2Lcvp9JqoCxswo3AKQqjLuNZyLixmCM1h");
            swarm.RegisterPeerAddress("/ip4/127.0.0.2/tcp/4001/ipfs/QmdpwjdB94eNm2Lcvp9JqoCxswo3AKQqjLuNZyLixmCM1h");
            swarm.RegisterPeerAddress("/ip4/127.0.0.3/tcp/4001/ipfs/QmdpwjdB94eNm2Lcvp9JqoCxswo3AKQqjLuNZyLixmCM1h");
            swarm.RegisterPeerAddress("/ip4/127.0.0.1/tcp/4001/ipfs/QmdpwjdB94eNm2Lcvp9JqoCxswo3AKQqjLuNZyLixmCM1i");
            swarm.RegisterPeerAddress("/ip4/127.0.0.2/tcp/4001/ipfs/QmdpwjdB94eNm2Lcvp9JqoCxswo3AKQqjLuNZyLixmCM1i");
            swarm.RegisterPeerAddress("/ip4/127.0.0.3/tcp/4001/ipfs/QmdpwjdB94eNm2Lcvp9JqoCxswo3AKQqjLuNZyLixmCM1i");
            swarm.RegisterPeer(new Peer {
                Id = "QmdpwjdB94eNm2Lcvp9JqoCxswo3AKQqjLuNZyLixmCM1j"
            });
            swarm.RegisterPeer(new Peer {
                Id = "QmdpwjdB94eNm2Lcvp9JqoCxswo3AKQqjLuNZyLixmCM1j"
            });

            Assert.AreEqual(3, peerCount);
        }
예제 #5
0
        public void DeregisterPeer()
        {
            var swarm = new SwarmService {
                LocalPeer = _self
            };

            swarm.RegisterPeer(_other);
            Assert.IsTrue(swarm.KnownPeers.Contains(_other));

            Peer removedPeer = null;

            swarm.PeerRemoved += (s, e) => removedPeer = e;
            swarm.DeregisterPeer(_other);
            Assert.IsFalse(swarm.KnownPeers.Contains(_other));
            Assert.AreEqual(_other, removedPeer);
        }
예제 #6
0
        /// <inheritdoc />
        public async Task <IEnumerable <Peer> > FindProvidersAsync(Cid id,
                                                                   int limit                = 20,
                                                                   Action <Peer> action     = null,
                                                                   CancellationToken cancel = default)
        {
            var dQuery = new DistributedQuery <Peer>
            {
                QueryType     = MessageType.GetProviders,
                QueryKey      = id.Hash,
                Dht           = this,
                AnswersNeeded = limit,
            };

            if (action != null)
            {
                dQuery.AnswerObtained += (s, e) => action.Invoke(e);
            }

            // Add any providers that we already know about.
            var providers = ContentRouter
                            .Get(id)
                            .Select(pid => pid == SwarmService.LocalPeer.Id
                    ? SwarmService.LocalPeer
                    : SwarmService.RegisterPeer(new Peer {
                Id = pid
            }));

            foreach (var provider in providers)
            {
                dQuery.AddAnswer(provider);
            }

            // Ask our peers for more providers.
            if (limit > dQuery.Answers.Count())
            {
                await dQuery.RunAsync(cancel).ConfigureAwait(false);
            }

            return(dQuery.Answers.Take(limit));
        }
예제 #7
0
        /// <summary>
        ///   Process an add provider request.
        /// </summary>
        public DhtMessage ProcessAddProvider(Peer remotePeer, DhtMessage request, DhtMessage response)
        {
            if (request.ProviderPeers == null)
            {
                return(null);
            }

            Cid cid;

            try
            {
                cid = new Cid {
                    Hash = new MultiHash(request.Key)
                };
            }
            catch (Exception)
            {
                _log.Error($"Bad AddProvider request key {request.Key.ToHexString()}");
                return(null);
            }

            var providers = request.ProviderPeers
                            .Select(p => p.TryToPeer(out var peer) ? peer : (Peer)null)
                            .Where(p => p != null)
                            .Where(p => p == remotePeer)
                            .Where(p => p.Addresses.Any());

            //.Where(p => SwarmService.IsAllowed(p));

            foreach (var provider in providers)
            {
                SwarmService.RegisterPeer(provider);
                ContentRouter.Add(cid, provider.Id);
            }

            // There is no response for this request.
            return(null);
        }