Beispiel #1
0
        public async Task SubscribedPeers_AllTopics()
        {
            var topic1 = Guid.NewGuid().ToString();
            var topic2 = Guid.NewGuid().ToString();
            var ns     = new PubSubService {
                LocalPeer = self
            };
            var router = new FloodRouter {
                SwarmService = new SwarmService()
            };

            router.RemoteTopics.AddInterest(topic1, other1);
            router.RemoteTopics.AddInterest(topic2, other2);
            ns.Routers.Add(router);
            await ns.StartAsync();

            try
            {
                var peers = (await ns.PeersAsync()).ToArray();
                Assert.AreEqual(2, peers.Length);
            }
            finally
            {
                await ns.StopAsync();
            }
        }
Beispiel #2
0
        public async Task DuplicateMessagesAreIgnored()
        {
            var ns = new PubSubService {
                LocalPeer = self
            };

            ns.Routers.Add(new LoopbackRouter());
            await ns.StartAsync();

            try
            {
                var topic        = Guid.NewGuid().ToString();
                var cs           = new CancellationTokenSource();
                var messageCount = 0;
                await ns.SubscribeAsync(topic, msg => { ++messageCount; }, cs.Token);

                await ns.PublishAsync(topic, "", cs.Token);

                Assert.AreEqual(1, messageCount);
                Assert.AreEqual(2ul, ns.MesssagesReceived);
                Assert.AreEqual(1ul, ns.DuplicateMesssagesReceived);
            }
            finally
            {
                await ns.StopAsync();
            }
        }
Beispiel #3
0
        public async Task Subscribe_HandlerExceptionIsIgnored()
        {
            var ns = new PubSubService {
                LocalPeer = self
            };
            await ns.StartAsync();

            try
            {
                var topic        = Guid.NewGuid().ToString();
                var cs           = new CancellationTokenSource();
                var messageCount = 0;
                await ns.SubscribeAsync(topic, msg =>
                {
                    ++messageCount;
                    throw new Exception();
                }, cs.Token);

                await ns.PublishAsync(topic, "", cs.Token);

                Assert.AreEqual(1, messageCount);
            }
            finally
            {
                await ns.StopAsync();
            }
        }
Beispiel #4
0
        public async Task MessageID_Increments()
        {
            var ns = new PubSubService {
                LocalPeer = self
            };
            await ns.StartAsync();

            try
            {
                var a = ns.CreateMessage("topic", new byte[0]);
                var b = ns.CreateMessage("topic", new byte[0]);
                Assert.IsTrue(string.Compare(b.MessageId, a.MessageId, StringComparison.Ordinal) > 0);
            }
            finally
            {
                await ns.StopAsync();
            }
        }
Beispiel #5
0
        public async Task Topics()
        {
            var ns = new PubSubService {
                LocalPeer = self
            };
            await ns.StartAsync();

            try
            {
                var topicA = Guid.NewGuid().ToString();
                var topicB = Guid.NewGuid().ToString();
                var csA    = new CancellationTokenSource();
                var csB    = new CancellationTokenSource();

                await ns.SubscribeAsync(topicA, msg => { }, csA.Token);

                await ns.SubscribeAsync(topicA, msg => { }, csA.Token);

                await ns.SubscribeAsync(topicB, msg => { }, csB.Token);

                var topics = (await ns.SubscribedTopicsAsync(csA.Token)).ToArray();
                Assert.AreEqual(2, topics.Length);
                CollectionAssert.Contains(topics, topicA);
                CollectionAssert.Contains(topics, topicB);

                csA.Cancel();
                topics = (await ns.SubscribedTopicsAsync(csA.Token)).ToArray();
                Assert.AreEqual(1, topics.Length);
                CollectionAssert.Contains(topics, topicB);

                csB.Cancel();
                topics = (await ns.SubscribedTopicsAsync(csA.Token)).ToArray();
                Assert.AreEqual(0, topics.Length);
            }
            finally
            {
                await ns.StopAsync();
            }
        }
Beispiel #6
0
        public async Task Publish()
        {
            var ns = new PubSubService {
                LocalPeer = self
            };
            await ns.StartAsync();

            try
            {
                await ns.PublishAsync("topic", "foo");

                await ns.PublishAsync("topic", new byte[] { 1, 2, 3 });

                await ns.PublishAsync("topic", new MemoryStream(new byte[] { 1, 2, 3 }));

                Assert.AreEqual(3ul, ns.MesssagesPublished);
                Assert.AreEqual(3ul, ns.MesssagesReceived);
            }
            finally
            {
                await ns.StopAsync();
            }
        }
Beispiel #7
0
        public async Task Sends_Hello_OnConnect()
        {
            var topic = Guid.NewGuid().ToString();

            var swarm1 = new SwarmService {
                LocalPeer = self
            };
            var router1 = new FloodRouter {
                SwarmService = swarm1
            };
            var ns1 = new PubSubService {
                LocalPeer = self
            };

            ns1.Routers.Add(router1);
            await swarm1.StartAsync();

            await ns1.StartAsync();

            var swarm2 = new SwarmService {
                LocalPeer = other
            };
            var router2 = new FloodRouter {
                SwarmService = swarm2
            };
            var ns2 = new PubSubService {
                LocalPeer = other
            };

            ns2.Routers.Add(router2);
            await swarm2.StartAsync();

            await ns2.StartAsync();

            try
            {
                await swarm1.StartListeningAsync("/ip4/127.0.0.1/tcp/0");

                await swarm2.StartListeningAsync("/ip4/127.0.0.1/tcp/0");

                var cs = new CancellationTokenSource();
                await ns1.SubscribeAsync(topic, msg => { }, cs.Token);

                await swarm1.ConnectAsync(other, cs.Token);

                var peers   = new Peer[0];
                var endTime = DateTime.Now.AddSeconds(3);
                while (peers.Length == 0)
                {
                    if (DateTime.Now > endTime)
                    {
                        Assert.Fail("timeout");
                    }

                    await Task.Delay(100, cs.Token);

                    peers = (await ns2.PeersAsync(topic, cs.Token)).ToArray();
                }

                CollectionAssert.Contains(peers, self);
            }
            finally
            {
                await swarm1.StopAsync();

                await ns1.StopAsync();

                await swarm2.StopAsync();

                await ns2.StopAsync();
            }
        }
Beispiel #8
0
        public async Task Relays_PublishedMessage()
        {
            var topic = Guid.NewGuid().ToString();

            var swarm1 = new SwarmService {
                LocalPeer = self
            };
            var router1 = new FloodRouter {
                SwarmService = swarm1
            };
            var ns1 = new PubSubService {
                LocalPeer = self
            };

            ns1.Routers.Add(router1);
            await swarm1.StartAsync();

            await ns1.StartAsync();

            var swarm2 = new SwarmService {
                LocalPeer = other
            };
            var router2 = new FloodRouter {
                SwarmService = swarm2
            };
            var ns2 = new PubSubService {
                LocalPeer = other
            };

            ns2.Routers.Add(router2);
            await swarm2.StartAsync();

            await ns2.StartAsync();

            var swarm3 = new SwarmService {
                LocalPeer = other1
            };
            var router3 = new FloodRouter {
                SwarmService = swarm3
            };
            var ns3 = new PubSubService {
                LocalPeer = other1
            };

            ns3.Routers.Add(router3);
            await swarm3.StartAsync();

            await ns3.StartAsync();

            try
            {
                IPublishedMessage lastMessage2 = null;
                IPublishedMessage lastMessage3 = null;
                await swarm1.StartListeningAsync("/ip4/127.0.0.1/tcp/0");

                await swarm2.StartListeningAsync("/ip4/127.0.0.1/tcp/0");

                await swarm3.StartListeningAsync("/ip4/127.0.0.1/tcp/0");

                var cs = new CancellationTokenSource();
                await ns2.SubscribeAsync(topic, msg => lastMessage2 = msg, cs.Token);

                await ns3.SubscribeAsync(topic, msg => lastMessage3 = msg, cs.Token);

                await swarm1.ConnectAsync(other, cs.Token);

                await swarm3.ConnectAsync(other, cs.Token);

                var peers   = new Peer[0];
                var endTime = DateTime.Now.AddSeconds(3);
                while (peers.Length == 0)
                {
                    if (DateTime.Now > endTime)
                    {
                        Assert.Fail("timeout");
                    }

                    await Task.Delay(100, cs.Token);

                    peers = (await ns2.PeersAsync(topic, cs.Token)).ToArray();
                }

                CollectionAssert.Contains(peers, other1);

                await ns1.PublishAsync(topic, new byte[] { 1 }, cs.Token);

                endTime = DateTime.Now.AddSeconds(3);
                while (lastMessage2 == null || lastMessage3 == null)
                {
                    if (DateTime.Now > endTime)
                    {
                        Assert.Fail("timeout");
                    }

                    await Task.Delay(100, cs.Token);
                }

                Assert.IsNotNull(lastMessage2);
                Assert.AreEqual(self, lastMessage2.Sender);
                CollectionAssert.AreEqual(new byte[] { 1 }, lastMessage2.DataBytes);
                CollectionAssert.Contains(lastMessage2.Topics.ToArray(), topic);

                Assert.IsNotNull(lastMessage3);
                Assert.AreEqual(self, lastMessage3.Sender);
                CollectionAssert.AreEqual(new byte[] { 1 }, lastMessage3.DataBytes);
                CollectionAssert.Contains(lastMessage3.Topics.ToArray(), topic);
            }
            finally
            {
                await swarm1.StopAsync();

                await ns1.StopAsync();

                await swarm2.StopAsync();

                await ns2.StopAsync();

                await swarm3.StopAsync();

                await ns3.StopAsync();
            }
        }
Beispiel #9
0
        /// <summary>
        ///     Starts the network services.
        /// </summary>
        /// <returns>
        ///     A task that represents the asynchronous operation.
        /// </returns>
        /// <remarks>
        ///     Starts the various IPFS and Lib.P2P network services.  This should
        ///     be called after any configuration changes.
        /// </remarks>
        /// <exception cref="Exception">
        ///     When the engine is already started.
        /// </exception>
        public async Task StartAsync()
        {
            _dfsState.IsStarted = true;
            if (_stopTasks.Count > 0)
            {
                throw new Exception("IPFS engine is already started.");
            }

            // Repository must be at the correct version.
            await MigrationManager.MirgrateToVersionAsync(MigrationManager.LatestVersion).ConfigureAwait(false);

            Log.Debug("starting " + LocalPeer.Id);

            // Everybody needs the swarm.
            _stopTasks.Add(async() => { await SwarmService.StopAsync().ConfigureAwait(false); });
            await SwarmService.StartAsync().ConfigureAwait(false);

            var peerManager = new PeerManager
            {
                SwarmService = SwarmService
            };
            await peerManager.StartAsync().ConfigureAwait(false);

            _stopTasks.Add(async() => { await peerManager.StopAsync().ConfigureAwait(false); });

            // Start the primary services.
            var tasks = new List <Func <Task> >
            {
                async() =>
                {
                    _stopTasks.Add(async() => await BitSwapService.StopAsync().ConfigureAwait(false));
                    await BitSwapService.StartAsync().ConfigureAwait(false);
                },
                async() =>
                {
                    _stopTasks.Add(async() => await DhtService.StopAsync().ConfigureAwait(false));
                    await DhtService.StartAsync().ConfigureAwait(false);
                },
                async() =>
                {
                    _stopTasks.Add(async() => await PingService.StopAsync().ConfigureAwait(false));
                    await PingService.StartAsync().ConfigureAwait(false);
                },
                async() =>
                {
                    _stopTasks.Add(async() => await PubSubService.StopAsync().ConfigureAwait(false));
                    await PubSubService.StartAsync().ConfigureAwait(false);
                }
            };

            Log.Debug("waiting for services to start");
            await Task.WhenAll(tasks.Select(t => t())).ConfigureAwait(false);

            // Starting listening to the swarm.
            var json = await ConfigApi.GetAsync("Addresses.Swarm").ConfigureAwait(false);

            var numberListeners = 0;

            foreach (string a in json)
            {
                try
                {
                    await SwarmService.StartListeningAsync(a).ConfigureAwait(false);

                    ++numberListeners;
                }
                catch (Exception e)
                {
                    Log.Warning($"Listener failure for '{a}'", e);
                }
            }

            if (numberListeners == 0)
            {
                Log.Error("No listeners were created.");
            }

            // Now that the listener addresses are established, the discovery
            // services can begin.
            MulticastService multicast = null;

            if (!Options.Discovery.DisableMdns)
            {
                multicast = new MulticastService();
#pragma warning disable CS1998
                _stopTasks.Add(async() => multicast.Dispose());
#pragma warning restore CS1998
            }

            var autodialer = new AutoDialer(SwarmService)
            {
                MinConnections = Options.Swarm.MinConnections
            };
#pragma warning disable CS1998
            _stopTasks.Add(async() => autodialer.Dispose());
#pragma warning restore CS1998

            tasks = new List <Func <Task> >
            {
                // Bootstrap discovery
                async() =>
                {
                    var bootstrap = new Bootstrap
                    {
                        Addresses = await BootstrapApi.ListAsync()
                    };
                    bootstrap.PeerDiscovered += OnPeerDiscovered;
                    _stopTasks.Add(async() => await bootstrap.StopAsync().ConfigureAwait(false));
                    await bootstrap.StartAsync().ConfigureAwait(false);
                },

                async() =>
                {
                    if (Options.Discovery.DisableRandomWalk)
                    {
                        return;
                    }
                    var randomWalk = new RandomWalk {
                        Dht = DhtApi
                    };
                    _stopTasks.Add(async() => await randomWalk.StopAsync().ConfigureAwait(false));
                    await randomWalk.StartAsync().ConfigureAwait(false);
                }
            };
            Log.Debug("waiting for discovery services to start");
            await Task.WhenAll(tasks.Select(t => t())).ConfigureAwait(false);

            multicast?.Start();

            Log.Debug("started");
        }