예제 #1
0
        public async Task Listening_Event()
        {
            var peer = new Peer
            {
                Id           = _self.Id,
                PublicKey    = _self.PublicKey,
                AgentVersion = _self.AgentVersion
            };
            MultiAddress addr  = "/ip4/127.0.0.1/tcp/0";
            var          swarm = new SwarmService {
                LocalPeer = peer
            };
            Peer listeningPeer = null;

            swarm.ListenerEstablished += (s, e) => { listeningPeer = e; };
            try
            {
                await swarm.StartListeningAsync(addr);

                Assert.AreEqual(peer, listeningPeer);
                Assert.AreNotEqual(0, peer.Addresses.Count());
            }
            finally
            {
                await swarm.StopAsync();
            }
        }
예제 #2
0
        public async Task Dial_Peer_UnknownProtocol()
        {
            var peerB = new Peer
            {
                AgentVersion = "peerB",
                Id           = "QmdpwjdB94eNm2Lcvp9JqoCxswo3AKQqjLuNZyLixmCM1h",
                PublicKey    =
                    "CAASXjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDlTSgVLprWaXfmxDr92DJE1FP0wOexhulPqXSTsNh5ot6j+UiuMgwb0shSPKzLx9AuTolCGhnwpTBYHVhFoBErAgMBAAE="
            };
            var swarmB = new SwarmService {
                LocalPeer = peerB
            };
            var _ = await swarmB.StartListeningAsync("/ip4/127.0.0.1/tcp/0");

            var swarm = new SwarmService {
                LocalPeer = _self
            };
            await swarm.StartAsync();

            try
            {
                ExceptionAssert.Throws <Exception>(() => { swarm.DialAsync(peerB, "/foo/0.42.0").Wait(); });
            }
            finally
            {
                await swarm.StopAsync();

                await swarmB.StopAsync();
            }
        }
예제 #3
0
        public async Task Provide()
        {
            Cid cid   = "zBunRGrmCGokA1oMESGGTfrtcMFsVA8aEtcNzM54akPWXF97uXCqTjF3GZ9v8YzxHrG66J8QhtPFWwZebRZ2zeUEELu67";
            var swarm = new SwarmService {
                LocalPeer = self
            };
            var dht = new DhtService {
                SwarmService = swarm
            };
            await dht.StartAsync();

            try
            {
                await swarm.StartAsync();

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

                await dht.ProvideAsync(cid);

                var peers = (await dht.FindProvidersAsync(cid, 1)).ToArray();
                Assert.AreEqual(1, peers.Length);
                Assert.AreEqual(self, peers[0]);
            }
            finally
            {
                await dht.StopAsync();

                await swarm.StopAsync();
            }
        }
예제 #4
0
        public async Task ConnectionEstablished()
        {
            var peerB = new Peer
            {
                AgentVersion = "peerB",
                Id           = "QmdpwjdB94eNm2Lcvp9JqoCxswo3AKQqjLuNZyLixmCM1h",
                PublicKey    =
                    "CAASXjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDlTSgVLprWaXfmxDr92DJE1FP0wOexhulPqXSTsNh5ot6j+UiuMgwb0shSPKzLx9AuTolCGhnwpTBYHVhFoBErAgMBAAE="
            };
            var swarmB = new SwarmService {
                LocalPeer = peerB
            };
            var swarmBConnections = 0;

            swarmB.ConnectionEstablished += (s, e) => { ++swarmBConnections; };
            await swarmB.StartAsync();

            var peerBAddress = await swarmB.StartListeningAsync("/ip4/127.0.0.1/tcp/0");

            var swarm = new SwarmService {
                LocalPeer = _self
            };
            var swarmConnections = 0;

            swarm.ConnectionEstablished += (s, e) => { ++swarmConnections; };
            await swarm.StartAsync();

            try
            {
                var _ = await swarm.ConnectAsync(peerBAddress);

                Assert.AreEqual(1, swarmConnections);

                // wait for swarmB to settle
                var endTime = DateTime.Now.AddSeconds(3);
                while (true)
                {
                    if (DateTime.Now > endTime)
                    {
                        Assert.Fail("swarmB did not raise event.");
                    }

                    if (swarmBConnections == 1)
                    {
                        break;
                    }

                    await Task.Delay(100).ConfigureAwait(false);
                }
            }
            finally
            {
                await swarm.StopAsync();

                await swarmB.StopAsync();
            }
        }
예제 #5
0
        public async Task Stop_Closes_Listeners()
        {
            var peer = new Peer
            {
                Id           = _self.Id,
                PublicKey    = _self.PublicKey,
                AgentVersion = _self.AgentVersion
            };
            MultiAddress addr  = "/ip4/0.0.0.0/tcp/0";
            var          swarm = new SwarmService {
                LocalPeer = peer
            };

            try
            {
                await swarm.StartAsync();

                await swarm.StartListeningAsync(addr);

                Assert.IsTrue(peer.Addresses.Any());
                await swarm.StopAsync();

                Assert.AreEqual(0, peer.Addresses.Count());

                await swarm.StartAsync();

                await swarm.StartListeningAsync(addr);

                Assert.IsTrue(peer.Addresses.Any());
                await swarm.StopAsync();

                Assert.AreEqual(0, peer.Addresses.Count());
            }
            catch (Exception)
            {
                await swarm.StopAsync();

                throw;
            }
        }
예제 #6
0
        public async Task Listening_Start_Stop()
        {
            var peer = new Peer
            {
                Id           = _self.Id,
                PublicKey    = _self.PublicKey,
                AgentVersion = _self.AgentVersion
            };
            MultiAddress addr  = "/ip4/0.0.0.0/tcp/0";
            var          swarm = new SwarmService {
                LocalPeer = peer
            };
            await swarm.StartAsync();

            try
            {
                await swarm.StartListeningAsync(addr);

                Assert.IsTrue(peer.Addresses.Any());

                await swarm.StopListeningAsync(addr);

                Assert.AreEqual(0, peer.Addresses.Count());

                await swarm.StartListeningAsync(addr);

                Assert.IsTrue(peer.Addresses.Any());

                await swarm.StopListeningAsync(addr);

                Assert.AreEqual(0, peer.Addresses.Count());
            }
            finally
            {
                await swarm.StopAsync();
            }
        }
예제 #7
0
        public async Task Listening_IPv6Any()
        {
            var peerA = new Peer
            {
                Id           = _self.Id,
                PublicKey    = _self.PublicKey,
                AgentVersion = _self.AgentVersion
            };
            MultiAddress addr   = "/ip6/::/tcp/0";
            var          swarmA = new SwarmService {
                LocalPeer = peerA
            };
            var peerB = new Peer
            {
                Id           = _other.Id,
                PublicKey    = _other.PublicKey,
                AgentVersion = _other.AgentVersion
            };
            var swarmB = new SwarmService {
                LocalPeer = peerB
            };
            await swarmA.StartAsync();

            await swarmB.StartAsync();

            try
            {
                var another = await swarmA.StartListeningAsync(addr);

                Assert.IsFalse(peerA.Addresses.Contains(addr));
                Assert.IsTrue(peerA.Addresses.Contains(another));

                await swarmB.ConnectAsync(another);

                Assert.IsTrue(swarmB.KnownPeers.Contains(peerA));

                // TODO: Assert.IsTrue(swarmA.KnownPeers.Contains(peerB));

                await swarmA.StopListeningAsync(addr);

                Assert.AreEqual(0, peerA.Addresses.Count());
            }
            finally
            {
                await swarmA.StopAsync();

                await swarmB.StopAsync();
            }
        }
예제 #8
0
        public async Task RemotePeer_Contains_ConnectedAddress2()
        {
            // Only works on Windows because connecting to 127.0.0.100 is allowed
            // when listening on 0.0.0.0
            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                return;
            }

            var peerB = new Peer
            {
                AgentVersion = "peerB",
                Id           = "QmdpwjdB94eNm2Lcvp9JqoCxswo3AKQqjLuNZyLixmCM1h",
                PublicKey    =
                    "CAASXjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDlTSgVLprWaXfmxDr92DJE1FP0wOexhulPqXSTsNh5ot6j+UiuMgwb0shSPKzLx9AuTolCGhnwpTBYHVhFoBErAgMBAAE="
            };
            var swarmB = new SwarmService {
                LocalPeer = peerB
            };
            await swarmB.StartAsync();

            var peerBAddress = await swarmB.StartListeningAsync("/ip4/0.0.0.0/tcp/0");

            var peerBPort = peerBAddress.Protocols[1].Value;

            Assert.IsTrue(peerB.Addresses.Any());

            var swarm = new SwarmService {
                LocalPeer = _self
            };
            await swarm.StartAsync();

            try
            {
                MultiAddress ma         = $"/ip4/127.0.0.100/tcp/{peerBPort}/ipfs/{peerB.Id}";
                var          connection = await swarm.ConnectAsync(ma);

                var remote = connection.RemotePeer;
                Assert.AreEqual(remote.ConnectedAddress, ma);
                CollectionAssert.Contains(remote.Addresses.ToArray(), ma);
            }
            finally
            {
                await swarm.StopAsync();

                await swarmB.StopAsync();
            }
        }
예제 #9
0
        public async Task Noop_OnPeerDiscovered_When_NotBelow_MinConnections()
        {
            var swarmA = new SwarmService {
                LocalPeer = peerA
            };
            await swarmA.StartAsync();

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

            var swarmB = new SwarmService {
                LocalPeer = peerB
            };
            await swarmB.StartAsync();

            var peerBAddress = await swarmB.StartListeningAsync("/ip4/127.0.0.1/tcp/0");

            try
            {
                using (new AutoDialer(swarmA)
                {
                    MinConnections = 0
                })
                {
                    var other = swarmA.RegisterPeerAddress(peerBAddress);

                    // wait for the connection.
                    var endTime = DateTime.Now.AddSeconds(3);
                    while (other.ConnectedAddress == null)
                    {
                        if (DateTime.Now > endTime)
                        {
                            return;
                        }

                        await Task.Delay(100);
                    }

                    Assert.Fail("Autodial should not happen");
                }
            }
            finally
            {
                await swarmA.StopAsync();

                await swarmB.StopAsync();
            }
        }
예제 #10
0
        public void Listening_MissingTransport()
        {
            var peer = new Peer
            {
                Id           = _self.Id,
                PublicKey    = _self.PublicKey,
                AgentVersion = _self.AgentVersion
            };
            var swarm = new SwarmService {
                LocalPeer = peer
            };

            ExceptionAssert.Throws <ArgumentException>(() =>
            {
                var _ = swarm.StartListeningAsync("/ip4/127.0.0.1").Result;
            });
            Assert.AreEqual(0, peer.Addresses.Count());
        }
예제 #11
0
        public async Task Connect_WithSomeUnreachableAddresses()
        {
            const string bid   = "QmdpwjdB94eNm2Lcvp9JqoCxswo3AKQqjLuNZyLixmCM1h";
            var          peerB = new Peer
            {
                AgentVersion = "peerB",
                Id           = bid,
                PublicKey    =
                    "CAASXjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDlTSgVLprWaXfmxDr92DJE1FP0wOexhulPqXSTsNh5ot6j+UiuMgwb0shSPKzLx9AuTolCGhnwpTBYHVhFoBErAgMBAAE=",
                Addresses = new MultiAddress[]
                {
                    $"/ip4/127.0.0.2/tcp/2/ipfs/{bid}",
                    $"/ip4/127.0.0.3/tcp/3/ipfs/{bid}"
                }
            };
            var swarmB = new SwarmService {
                LocalPeer = peerB
            };
            await swarmB.StartAsync();

            var _ = await swarmB.StartListeningAsync("/ip4/127.0.0.1/tcp/0");

            Assert.IsTrue(peerB.Addresses.Any());

            var swarm = new SwarmService {
                LocalPeer = _self
            };
            await swarm.StartAsync();

            try
            {
                var remotePeer = (await swarm.ConnectAsync(peerB)).RemotePeer;
                Assert.IsNotNull(remotePeer.ConnectedAddress);
                Assert.AreEqual(peerB.PublicKey, remotePeer.PublicKey);
                Assert.IsTrue(remotePeer.IsValid());
                Assert.IsTrue(swarm.KnownPeers.Contains(peerB));
            }
            finally
            {
                await swarm.StopAsync();

                await swarmB.StopAsync();
            }
        }
예제 #12
0
        public async Task PeerDisconnected()
        {
            var peerB = new Peer
            {
                AgentVersion = "peerB",
                Id           = "QmdpwjdB94eNm2Lcvp9JqoCxswo3AKQqjLuNZyLixmCM1h",
                PublicKey    =
                    "CAASXjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDlTSgVLprWaXfmxDr92DJE1FP0wOexhulPqXSTsNh5ot6j+UiuMgwb0shSPKzLx9AuTolCGhnwpTBYHVhFoBErAgMBAAE="
            };
            var swarmB = new SwarmService {
                LocalPeer = peerB
            };
            await swarmB.StartAsync();

            var peerBAddress = await swarmB.StartListeningAsync("/ip4/127.0.0.1/tcp/0");

            var swarm = new SwarmService {
                LocalPeer = _self
            };
            var swarmConnections = 0;

            swarm.ConnectionEstablished += (s, e) => { ++swarmConnections; };
            swarm.PeerDisconnected      += (s, e) => { --swarmConnections; };
            await swarm.StartAsync();

            try
            {
                var _ = await swarm.ConnectAsync(peerBAddress);

                Assert.AreEqual(1, swarmConnections);

                await swarm.StopAsync();

                Assert.AreEqual(0, swarmConnections);
            }
            finally
            {
                await swarm.StopAsync();

                await swarmB.StopAsync();
            }
        }
예제 #13
0
        public async Task Connecting_To_Self_Indirect()
        {
            var swarm = new SwarmService {
                LocalPeer = _self
            };
            await swarm.StartAsync();

            try
            {
                var listen = await swarm.StartListeningAsync("/ip4/127.0.0.1/tcp/0");

                var bad = listen.Clone();
                bad.Protocols[2].Value = "QmXFX2P5ammdmXQgfqGkfswtEVFsZUJ5KeHRXQYCTdiTAb";
                ExceptionAssert.Throws <Exception>(() => { swarm.ConnectAsync(bad).Wait(); });
            }
            finally
            {
                await swarm.StopAsync();
            }
        }
예제 #14
0
        public async Task MultiAddress()
        {
            var swarmB = new SwarmService {
                LocalPeer = other
            };
            await swarmB.StartAsync();

            var pingB = new Ping1(swarmB);
            await pingB.StartAsync();

            var peerBAddress = await swarmB.StartListeningAsync("/ip4/127.0.0.1/tcp/0");

            var swarm = new SwarmService {
                LocalPeer = self
            };
            await swarm.StartAsync();

            var pingA = new Ping1(swarm);
            await pingA.StartAsync();

            try
            {
                await swarm.ConnectAsync(peerBAddress);

                var result = await pingA.PingAsync(other.Id, 4);

                Assert.IsTrue(result.All(r => r.Success));
            }
            finally
            {
                await swarm.StopAsync();

                await swarmB.StopAsync();

                await pingB.StopAsync();

                await pingA.StopAsync();
            }
        }
예제 #15
0
        public async Task Dial_Peer()
        {
            var peerB = new Peer
            {
                AgentVersion = "peerB",
                Id           = "QmdpwjdB94eNm2Lcvp9JqoCxswo3AKQqjLuNZyLixmCM1h",
                PublicKey    =
                    "CAASXjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDlTSgVLprWaXfmxDr92DJE1FP0wOexhulPqXSTsNh5ot6j+UiuMgwb0shSPKzLx9AuTolCGhnwpTBYHVhFoBErAgMBAAE="
            };
            var swarmB = new SwarmService {
                LocalPeer = peerB
            };
            await swarmB.StartAsync();

            var _ = await swarmB.StartListeningAsync("/ip4/127.0.0.1/tcp/0");

            var swarm = new SwarmService {
                LocalPeer = _self
            };
            await swarm.StartAsync();

            try
            {
                await using (var stream = await swarm.DialAsync(peerB, "/ipfs/id/1.0.0"))
                {
                    Assert.IsNotNull(stream);
                    Assert.IsTrue(stream.CanRead);
                    Assert.IsTrue(stream.CanWrite);
                }
            }
            finally
            {
                await swarm.StopAsync();

                await swarmB.StopAsync();
            }
        }
예제 #16
0
        public async Task Connect_PrivateNetwork()
        {
            var peerB = new Peer
            {
                AgentVersion = "peerB",
                Id           = "QmdpwjdB94eNm2Lcvp9JqoCxswo3AKQqjLuNZyLixmCM1h",
                PublicKey    =
                    "CAASXjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDlTSgVLprWaXfmxDr92DJE1FP0wOexhulPqXSTsNh5ot6j+UiuMgwb0shSPKzLx9AuTolCGhnwpTBYHVhFoBErAgMBAAE="
            };
            var swarmB = new SwarmService {
                LocalPeer = peerB, NetworkProtector = new OpenNetwork()
            };
            await swarmB.StartAsync();

            var peerBAddress = await swarmB.StartListeningAsync("/ip4/127.0.0.1/tcp/0");

            Assert.IsTrue(peerB.Addresses.Any());

            var swarm = new SwarmService {
                LocalPeer = _self, NetworkProtector = new OpenNetwork()
            };
            await swarm.StartAsync();

            try
            {
                var _ = await swarm.ConnectAsync(peerBAddress);

                Assert.AreEqual(2, OpenNetwork.Count);
            }
            finally
            {
                await swarm.StopAsync();

                await swarmB.StopAsync();
            }
        }
예제 #17
0
        public async Task RemotePeer_Contains_ConnectedAddress1()
        {
            var peerB = new Peer
            {
                AgentVersion = "peerB",
                Id           = "QmdpwjdB94eNm2Lcvp9JqoCxswo3AKQqjLuNZyLixmCM1h",
                PublicKey    =
                    "CAASXjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDlTSgVLprWaXfmxDr92DJE1FP0wOexhulPqXSTsNh5ot6j+UiuMgwb0shSPKzLx9AuTolCGhnwpTBYHVhFoBErAgMBAAE="
            };
            var swarmB = new SwarmService {
                LocalPeer = peerB
            };
            await swarmB.StartAsync();

            var peerBAddress = await swarmB.StartListeningAsync("/ip4/0.0.0.0/tcp/0");

            var swarm = new SwarmService {
                LocalPeer = _self
            };
            await swarm.StartAsync();

            try
            {
                var connection = await swarm.ConnectAsync(peerBAddress);

                var remote = connection.RemotePeer;
                Assert.AreEqual(remote.ConnectedAddress, peerBAddress);
                CollectionAssert.Contains(remote.Addresses.ToArray(), peerBAddress);
            }
            finally
            {
                await swarm.StopAsync();

                await swarmB.StopAsync();
            }
        }
예제 #18
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();
            }
        }
예제 #19
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();
            }
        }
예제 #20
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");
        }
예제 #21
0
        public async Task Connects_OnPeerDisconnected_When_Below_MinConnections()
        {
            var swarmA = new SwarmService {
                LocalPeer = peerA
            };
            await swarmA.StartAsync();

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

            var swarmB = new SwarmService {
                LocalPeer = peerB
            };
            await swarmB.StartAsync();

            var peerBAddress = await swarmB.StartListeningAsync("/ip4/127.0.0.1/tcp/0");

            var swarmC = new SwarmService {
                LocalPeer = peerC
            };
            await swarmC.StartAsync();

            var peerCAddress = await swarmC.StartListeningAsync("/ip4/127.0.0.1/tcp/0");

            var isBConnected = false;

            swarmA.ConnectionEstablished += (s, conn) =>
            {
                if (conn.RemotePeer == peerB)
                {
                    isBConnected = true;
                }
            };

            try
            {
                using (new AutoDialer(swarmA)
                {
                    MinConnections = 1
                })
                {
                    swarmA.RegisterPeerAddress(peerBAddress);
                    var c = swarmA.RegisterPeerAddress(peerCAddress);

                    // wait for the peer B connection.
                    var endTime = DateTime.Now.AddSeconds(3);
                    while (!isBConnected)
                    {
                        if (DateTime.Now > endTime)
                        {
                            Assert.Fail("Did not do autodial on peer discovered");
                        }

                        await Task.Delay(100); // get cancellaton token
                    }

                    Assert.IsNull(c.ConnectedAddress);
                    await swarmA.DisconnectAsync(peerBAddress);

                    // wait for the peer C connection.
                    endTime = DateTime.Now.AddSeconds(3);
                    while (c.ConnectedAddress == null)
                    {
                        if (DateTime.Now > endTime)
                        {
                            Assert.Fail("Did not do autodial on peer disconnected");
                        }
                        await Task.Delay(100);
                    }
                }
            }
            finally
            {
                await swarmA?.StopAsync();

                await swarmB?.StopAsync();

                await swarmC?.StopAsync();
            }
        }
예제 #22
0
        public async Task Connect_Disconnect_Reconnect()
        {
            var peerB = new Peer
            {
                AgentVersion = "peerB",
                Id           = "QmdpwjdB94eNm2Lcvp9JqoCxswo3AKQqjLuNZyLixmCM1h",
                PublicKey    =
                    "CAASXjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDlTSgVLprWaXfmxDr92DJE1FP0wOexhulPqXSTsNh5ot6j+UiuMgwb0shSPKzLx9AuTolCGhnwpTBYHVhFoBErAgMBAAE="
            };
            var swarmB = new SwarmService {
                LocalPeer = peerB
            };
            await swarmB.StartAsync();

            var peerBAddress = await swarmB.StartListeningAsync("/ip4/127.0.0.1/tcp/0");

            Assert.IsTrue(peerB.Addresses.Any());

            var swarm = new SwarmService {
                LocalPeer = _self
            };
            await swarm.StartAsync();

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

            try
            {
                var remotePeer = (await swarm.ConnectAsync(peerBAddress)).RemotePeer;
                Assert.IsNotNull(remotePeer.ConnectedAddress);
                Assert.AreEqual(peerB.PublicKey, remotePeer.PublicKey);
                Assert.IsTrue(remotePeer.IsValid());
                Assert.IsTrue(swarm.KnownPeers.Contains(peerB));

                // wait for swarmB to settle
                var endTime = DateTime.Now.AddSeconds(3);
                while (true)
                {
                    if (DateTime.Now > endTime)
                    {
                        Assert.Fail("swarmB does not know about self");
                    }

                    if (swarmB.KnownPeers.Contains(_self))
                    {
                        break;
                    }

                    await Task.Delay(100);
                }

                var me = swarmB.KnownPeers.First(p => p == _self);
                Assert.AreEqual(_self.Id, me.Id);
                Assert.AreEqual(_self.PublicKey, me.PublicKey);
                Assert.IsNotNull(me.ConnectedAddress);

                // Check disconnect
                await swarm.DisconnectAsync(peerBAddress);

                Assert.IsNull(remotePeer.ConnectedAddress);
                Assert.IsTrue(swarm.KnownPeers.Contains(peerB));
                Assert.IsTrue(swarmB.KnownPeers.Contains(_self));

                // wait for swarmB to settle
                endTime = DateTime.Now.AddSeconds(3);
                while (true)
                {
                    if (DateTime.Now > endTime)
                    {
                        Assert.Fail("swarmB did not close connection.");
                    }

                    if (me.ConnectedAddress == null)
                    {
                        break;
                    }

                    await Task.Delay(100);
                }

                // Reconnect
                remotePeer = (await swarm.ConnectAsync(peerBAddress)).RemotePeer;
                Assert.IsNotNull(remotePeer.ConnectedAddress);
                Assert.AreEqual(peerB.PublicKey, remotePeer.PublicKey);
                Assert.IsTrue(remotePeer.IsValid());
                Assert.IsTrue(swarm.KnownPeers.Contains(peerB));
            }
            finally
            {
                await swarm.StopAsync();

                await swarmB.StopAsync();
            }
        }