Пример #1
0
        public async Task InitialBlockDownload()
        {
            Swarm <DumbAction> minerSwarm    = _swarms[0];
            Swarm <DumbAction> receiverSwarm = _swarms[1];

            BlockChain <DumbAction> minerChain    = _blockchains[0];
            BlockChain <DumbAction> receiverChain = _blockchains[1];

            foreach (int i in Enumerable.Range(0, 10))
            {
                minerChain.MineBlock(_fx1.Address1);
            }

            try
            {
                await StartAsync(minerSwarm);

                await receiverSwarm.AddPeersAsync(new[] { minerSwarm.AsPeer });

                await receiverSwarm.PreloadAsync();

                Assert.Equal(minerChain.AsEnumerable(), receiverChain.AsEnumerable());
            }
            finally
            {
                await minerSwarm.StopAsync();
            }
        }
Пример #2
0
        public async Task InitialBlockDownload()
        {
            Swarm minerSwarm    = _swarms[0];
            Swarm receiverSwarm = _swarms[1];

            BlockChain <DumbAction> minerChain    = _blockchains[0];
            BlockChain <DumbAction> receiverChain = _blockchains[1];

            foreach (int i in Enumerable.Range(0, 10))
            {
                minerChain.MineBlock(_fx1.Address1);
            }

            try
            {
                await StartAsync(minerSwarm, minerChain);

                receiverSwarm.Add(minerSwarm.AsPeer);

                await StartAsync(receiverSwarm, receiverChain);

                await Task.Delay(TimeSpan.FromSeconds(10));

                Assert.Equal(minerChain.AsEnumerable(), receiverChain.AsEnumerable());
            }
            finally
            {
                await Task.WhenAll(
                    minerSwarm.StopAsync(),
                    receiverSwarm.StopAsync());
            }
        }
Пример #3
0
        public async Task Preload()
        {
            Swarm <DumbAction> minerSwarm    = _swarms[0];
            Swarm <DumbAction> receiverSwarm = _swarms[1];

            BlockChain <DumbAction> minerChain    = _blockchains[0];
            BlockChain <DumbAction> receiverChain = _blockchains[1];

            foreach (int i in Enumerable.Range(0, 10))
            {
                minerChain.MineBlock(_fx1.Address1);
            }

            var actualStates = new List <BlockDownloadState>();
            var progress     = new Progress <BlockDownloadState>(state =>
            {
                lock (actualStates)
                {
                    actualStates.Add(state);
                }
            });

            try
            {
                await StartAsync(minerSwarm);

                await receiverSwarm.AddPeersAsync(new[] { minerSwarm.AsPeer });

                await receiverSwarm.PreloadAsync(progress);

                Assert.Equal(minerChain.AsEnumerable(), receiverChain.AsEnumerable());

                IEnumerable <BlockDownloadState> expectedStates = minerChain.Select((b, i) =>
                {
                    return(new BlockDownloadState()
                    {
                        ReceivedBlockHash = b.Hash,
                        TotalBlockCount = 10,
                        ReceivedBlockCount = i + 1,
                    });
                });

                Assert.Equal(expectedStates, actualStates);
            }
            finally
            {
                await Task.WhenAll(
                    minerSwarm.StopAsync(),
                    receiverSwarm.StopAsync());
            }
        }
Пример #4
0
        public async Task InitialBlockDownloadStates()
        {
            Swarm <DumbAction> minerSwarm    = _swarms[0];
            Swarm <DumbAction> receiverSwarm = _swarms[1];

            BlockChain <DumbAction> minerChain    = _blockchains[0];
            BlockChain <DumbAction> receiverChain = _blockchains[1];

            var key     = new PrivateKey();
            var address = key.PublicKey.ToAddress();

            minerChain.MakeTransaction(key, new[] { new DumbAction(address, "foo") });
            minerChain.MineBlock(_fx1.Address1);

            minerChain.MakeTransaction(key, new[] { new DumbAction(address, "bar") });
            minerChain.MineBlock(_fx1.Address1);

            minerChain.MakeTransaction(key, new[] { new DumbAction(address, "baz") });
            minerChain.MineBlock(_fx1.Address1);

            try
            {
                await StartAsync(minerSwarm);

                await receiverSwarm.AddPeersAsync(new[] { minerSwarm.AsPeer });

                var trustedStateValidators = new[] { minerSwarm.Address }.ToImmutableHashSet();

                await receiverSwarm.PreloadAsync(trustedStateValidators : trustedStateValidators);

                await receiverSwarm.PreloadAsync(true);

                var states = receiverChain.GetStates(new[] { address });

                Assert.Equal("foo,bar,baz", states[address]);
                Assert.Equal(minerChain.AsEnumerable(), receiverChain.AsEnumerable());
            }
            finally
            {
                await minerSwarm.StopAsync();
            }
        }
Пример #5
0
        public async Task CanBroadcastBlock()
        {
            Swarm swarmA = _swarms[0];
            Swarm swarmB = _swarms[1];
            Swarm swarmC = _swarms[2];

            BlockChain <BaseAction> chainA = _blockchains[0];
            BlockChain <BaseAction> chainB = _blockchains[1];
            BlockChain <BaseAction> chainC = _blockchains[2];

            // chainA, chainB and chainC shares genesis block.
            Block <BaseAction> genesis = chainA.MineBlock(_fx1.Address1);

            chainB.Append(genesis);
            chainC.Append(genesis);

            foreach (int i in Enumerable.Range(0, 10))
            {
                chainA.MineBlock(_fx1.Address1);
                await Task.Delay(100);
            }

            foreach (int i in Enumerable.Range(0, 3))
            {
                chainB.MineBlock(_fx2.Address1);
                await Task.Delay(100);
            }

            try
            {
                await StartAsync(swarmA, chainA);
                await StartAsync(swarmB, chainB);
                await StartAsync(swarmC, chainC);

                await swarmA.AddPeersAsync(new[] { swarmB.AsPeer });

                await swarmA.AddPeersAsync(new[] { swarmC.AsPeer });

                await EnsureExchange(swarmA, swarmB);
                await EnsureExchange(swarmA, swarmC);
                await EnsureExchange(swarmB, swarmC);

                await swarmB.BroadcastBlocksAsync(new[] { chainB.Last() });

                await swarmC.BlockReceived.WaitAsync();

                await swarmA.BlockReceived.WaitAsync();

                Assert.Equal(chainB.AsEnumerable(), chainC);

                // chainB doesn't applied to chainA since chainB is shorter
                // than chainA
                Assert.NotEqual(chainB.AsEnumerable(), chainA);

                await swarmA.BroadcastBlocksAsync(new[] { chainA.Last() });

                await swarmB.BlockReceived.WaitAsync();

                await swarmC.BlockReceived.WaitAsync();

                Assert.Equal(chainA.AsEnumerable(), chainB);
                Assert.Equal(chainA.AsEnumerable(), chainC);
            }
            finally
            {
                await Task.WhenAll(
                    swarmA.StopAsync(),
                    swarmB.StopAsync(),
                    swarmC.StopAsync());
            }
        }
Пример #6
0
        public async Task CanBroadcastWhlieMining()
        {
            Swarm a = _swarms[0];
            Swarm b = _swarms[1];

            BlockChain <BaseAction> chainA = _blockchains[0];
            BlockChain <BaseAction> chainB = _blockchains[1];

            Task CreateMiner(
                Swarm swarm,
                BlockChain <BaseAction> chain,
                int delay,
                CancellationToken cancellationToken
                )
            {
                return(Task.Run(async() =>
                {
                    while (!cancellationToken.IsCancellationRequested)
                    {
                        var block = chain.MineBlock(_fx1.Address1);
                        Log.Debug(
                            $"Block mined. " +
                            $"[Swarm: {swarm.Address}, Block: {block.Hash}]");
                        await swarm.BroadcastBlocksAsync(new[] { block });
                        await Task.Delay(delay);
                    }

                    await swarm.BroadcastBlocksAsync(new[] { chain.Last() });
                    Log.Debug("Mining complete.");
                }));
            }

            var  minerCanceller = new CancellationTokenSource();
            Task miningA        = CreateMiner(a, chainA, 5000, minerCanceller.Token);
            Task miningB        = CreateMiner(b, chainB, 8000, minerCanceller.Token);

            try
            {
                await StartAsync(a, chainA);
                await StartAsync(b, chainB);

                await b.AddPeersAsync(new[] { a.AsPeer });
                await EnsureExchange(a, b);

                await Task.Delay(10000);

                minerCanceller.Cancel();

                await Task.WhenAll(miningA, miningB);

                await Task.Delay(5000);
            }
            finally
            {
                await a.StopAsync();

                await b.StopAsync();
            }

            Log.Debug($"chainA: {string.Join(",", chainA)}");
            Log.Debug($"chainB: {string.Join(",", chainB)}");

            Assert.Subset(
                chainA.AsEnumerable().ToHashSet(),
                chainB.AsEnumerable().ToHashSet());
        }
Пример #7
0
        public async Task Preload()
        {
            Swarm <DumbAction> minerSwarm    = _swarms[0];
            Swarm <DumbAction> receiverSwarm = _swarms[1];

            BlockChain <DumbAction> minerChain    = _blockchains[0];
            BlockChain <DumbAction> receiverChain = _blockchains[1];

            foreach (int i in Enumerable.Range(0, 10))
            {
                minerChain.MineBlock(_fx1.Address1);
            }

            var actualStates = new List <PreloadState>();
            var progress     = new Progress <PreloadState>(state =>
            {
                lock (actualStates)
                {
                    actualStates.Add(state);

                    if (actualStates.Count == 8)
                    {
                        minerChain.MineBlock(_fx1.Address1);
                    }
                }
            });

            try
            {
                await StartAsync(minerSwarm);

                await receiverSwarm.AddPeersAsync(new[] { minerSwarm.AsPeer });

                minerChain.FindNextHashesChunkSize = 2;
                await receiverSwarm.PreloadAsync(progress);

                Assert.Equal(minerChain.AsEnumerable(), receiverChain.AsEnumerable());

                PreloadState[] expectedStates = minerChain.Select((b, i) =>
                {
                    return(new BlockDownloadState
                    {
                        ReceivedBlockHash = b.Hash,
                        TotalBlockCount = 10,
                        ReceivedBlockCount = i + 1,
                    });
                }).ToArray();
                (expectedStates[10] as BlockDownloadState).TotalBlockCount = 11;

                expectedStates = expectedStates.Concat(minerChain.Select(
                                                           (b, i) => new ActionExecutionState()
                {
                    ExecutedBlockHash  = b.Hash,
                    TotalBlockCount    = 11,
                    ExecutedBlockCount = i + 1,
                })).ToArray();

                Assert.True(expectedStates.ToImmutableHashSet()
                            .SetEquals(actualStates.ToImmutableHashSet()));
            }
            finally
            {
                await Task.WhenAll(
                    minerSwarm.StopAsync(),
                    receiverSwarm.StopAsync());
            }
        }