Exemplo n.º 1
0
        public IEnumerator CoMiner()
        {
            while (true)
            {
                var txs = new HashSet <Transaction <PolymorphicAction <ActionBase> > >();

                var task = Task.Run(() =>
                {
                    var block = _blocks.MineBlock(Address);
                    _swarm.BroadcastBlocks(new[] { block });
                    return(block);
                });
                yield return(new WaitUntil(() => task.IsCompleted));

                if (!task.IsCanceled && !task.IsFaulted)
                {
                    var block = task.Result;
                    Debug.Log($"created block index: {block.Index}, difficulty: {block.Difficulty}");
#if BLOCK_LOG_USE
                    FileHelper.AppendAllText("Block.log", task.Result.ToVerboseString());
#endif
                }
                else
                {
                    var invalidTxs   = txs;
                    var retryActions = new HashSet <IImmutableList <PolymorphicAction <ActionBase> > >();

                    if (task.IsFaulted)
                    {
                        foreach (var ex in task.Exception.InnerExceptions)
                        {
                            if (ex is InvalidTxNonceException invalidTxNonceException)
                            {
                                var invalidNonceTx = _blocks.Transactions[invalidTxNonceException.TxId];

                                if (invalidNonceTx.Signer == Address)
                                {
                                    Debug.Log($"Tx[{invalidTxNonceException.TxId}] nonce is invalid. Retry it.");
                                    retryActions.Add(invalidNonceTx.Actions);
                                }
                            }

                            if (ex is InvalidTxException invalidTxException)
                            {
                                Debug.Log($"Tx[{invalidTxException.TxId}] is invalid. mark to unstage.");
                                invalidTxs.Add(_blocks.Transactions[invalidTxException.TxId]);
                            }

                            Debug.LogException(ex);
                        }
                    }
                    _blocks.UnstageTransactions(invalidTxs);

                    foreach (var retryAction in retryActions)
                    {
                        MakeTransaction(retryAction, true);
                    }
                }
            }
        }
Exemplo n.º 2
0
        public IEnumerator CoMiner()
        {
            while (true)
            {
                var txs = new HashSet <Transaction <PolymorphicAction <ActionBase> > >();

                var task = Task.Run(async() =>
                {
                    var block = await _blocks.MineBlock(Address);

                    if (_swarm?.Running ?? false)
                    {
                        _swarm.BroadcastBlocks(new[] { block });
                    }

                    return(block);
                });
                yield return(new WaitUntil(() => task.IsCompleted));

                if (!task.IsCanceled && !task.IsFaulted)
                {
                    var block = task.Result;
                    Debug.Log($"created block index: {block.Index}, difficulty: {block.Difficulty}");
                }
                else
                {
                    var invalidTxs   = txs;
                    var retryActions = new HashSet <IImmutableList <PolymorphicAction <ActionBase> > >();

                    if (task.IsFaulted)
                    {
                        foreach (var ex in task.Exception.InnerExceptions)
                        {
                            if (ex is InvalidTxNonceException invalidTxNonceException)
                            {
                                var invalidNonceTx =
                                    _store.GetTransaction <PolymorphicAction <ActionBase> >(invalidTxNonceException.TxId);

                                if (invalidNonceTx.Signer == Address)
                                {
                                    Debug.Log($"Tx[{invalidTxNonceException.TxId}] nonce is invalid. Retry it.");
                                    retryActions.Add(invalidNonceTx.Actions);
                                }
                            }

                            if (ex is InvalidTxException invalidTxException)
                            {
                                Debug.Log($"Tx[{invalidTxException.TxId}] is invalid. mark to unstage.");
                                invalidTxs.Add(
                                    _store.GetTransaction <PolymorphicAction <ActionBase> >(invalidTxException.TxId));
                            }

                            Debug.LogException(ex);
                        }
                    }

                    _blocks.UnstageTransactions(invalidTxs);

                    foreach (var retryAction in retryActions)
                    {
                        MakeTransaction(retryAction, true);
                    }
                }
            }
        }
Exemplo n.º 3
0
        public async Task CanBroadcastBlock()
        {
            Swarm <DumbAction> swarmA = _swarms[0];
            Swarm <DumbAction> swarmB = _swarms[1];
            Swarm <DumbAction> swarmC = _swarms[2];

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

            // chainA, chainB and chainC shares genesis block.
            Block <DumbAction> 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);
                await StartAsync(swarmB);
                await StartAsync(swarmC);

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

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

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

                swarmB.BroadcastBlocks(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);

                swarmA.BroadcastBlocks(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());
            }
        }