public async Task CompleteWithCrashingPeers()
        {
            ImmutableArray <Block <DumbAction> > fixture =
                GenerateBlocks <DumbAction>(15).ToImmutableArray();
            var bc = new BlockCompletion <char, DumbAction>(_ => false, 5);

            bc.Demand(fixture.Select(b => b.Hash));

            BlockCompletion <char, DumbAction> .BlockFetcher blockFetcher =
                (peer, blockHashes, token) => new AsyncEnumerable <Block <DumbAction> >(async yield =>
            {
                // Peer A does crash and Peer B does respond.
                if (peer == 'A')
                {
                    throw new Exception("Peer A can't respond.");
                }

                foreach (Block <DumbAction> b in fixture)
                {
                    if (blockHashes.Contains(b.Hash))
                    {
                        await yield.ReturnAsync(b);
                    }
                }
            });

            Tuple <Block <DumbAction>, char>[] result =
                await AsyncEnumerable.ToArrayAsync(bc.Complete(new[] { 'A', 'B' }, blockFetcher));

            Assert.Equal(
                fixture.Select(b => Tuple.Create(b, 'B')).ToHashSet(),
                result.ToHashSet()
                );
        }
        public async Task CompleteWithBlockFetcherGivingWrongBlocks()
        {
            Block <DumbAction> genesis = TestUtils.MineGenesis <DumbAction>(),
                               demand  = TestUtils.MineNext(genesis),
                               wrong   = TestUtils.MineNext(genesis);

            _logger.Debug("Genesis: #{Index} {Hash}", genesis.Index, genesis.Hash);
            _logger.Debug("Demand:  #{Index} {Hash}", demand.Index, demand.Hash);
            _logger.Debug("Wrong:   #{Index} {Hash}", wrong.Index, wrong.Hash);
            var bc = new BlockCompletion <char, DumbAction>(
                ((IEquatable <HashDigest <SHA256> >)genesis.Hash).Equals,
                5
                );

            bc.Demand(demand.Hash);

            long counter = 0;

            BlockCompletion <char, DumbAction> .BlockFetcher wrongBlockFetcher =
                (peer, blockHashes, token) => new AsyncEnumerable <Block <DumbAction> >(async yield =>
            {
                // Provides a wrong block (i.e., not corresponding to the demand) at first call,
                // and then provide a proper block later calls.
                await yield.ReturnAsync(Interlocked.Read(ref counter) < 1 ? wrong : demand);
                Interlocked.Increment(ref counter);
            });

            Tuple <Block <DumbAction>, char>[] result =
                await AsyncEnumerable.ToArrayAsync(bc.Complete(new[] { 'A' }, wrongBlockFetcher));

            Assert.Equal(new[] { Tuple.Create(demand, 'A') }, result);
        }
        public async Task CompleteWithNonRespondingPeers()
        {
            ImmutableArray <Block <DumbAction> > fixture =
                GenerateBlocks <DumbAction>(15).ToImmutableArray();
            var bc = new BlockCompletion <char, DumbAction>(_ => false, 5);

            bc.Demand(fixture.Select(b => b.Hash));

            BlockCompletion <char, DumbAction> .BlockFetcher blockFetcher =
                (peer, blockHashes, token) => new AsyncEnumerable <Block <DumbAction> >(async yield =>
            {
                // Peer A does not respond and Peer B does respond.
                if (peer == 'A')
                {
                    while (true)
                    {
                        await Task.Delay(5000, yield.CancellationToken);
                    }
                }

                foreach (Block <DumbAction> b in fixture)
                {
                    if (blockHashes.Contains(b.Hash))
                    {
                        await yield.ReturnAsync(b);
                    }
                }
            });

            Tuple <Block <DumbAction>, char>[] result =
                await AsyncEnumerable.ToArrayAsync(
                    bc.Complete(
                        new[] { 'A', 'B' }, blockFetcher, millisecondsSingleSessionTimeout: 3000
                        )
                    );

            Assert.Equal(
                fixture.Select(b => Tuple.Create(b, 'B')).ToHashSet(),
                result.ToHashSet()
                );
        }
Esempio n. 4
0
 public static ValueTask <TSource[]> ToArrayAsync <TSource>(this IAsyncEnumerable <TSource> source) =>
 LinqEnumerable.ToArrayAsync(source);