Пример #1
0
        public void AttachBroadcastedBlock(BlockSyncApiModel block, string nodeAddress)
        {
            bool isPastBlock = block.Index <= LastBlock.Index;

            if (isPastBlock)
            {
                return;
            }

            Block minedBlock = Block.ReCreateBlock(block);

            ValidateBlockHash(minedBlock, minedBlock.Nonce, minedBlock.BlockHash);

            // replace blockchain if another blockain is longer
            int nodeDifference = minedBlock.Index - BlockChain.Count;

            if (nodeDifference >= 6)
            {
                int          startIndex   = minedBlock.Index - nodeDifference;
                List <Block> forkedBlocks = NodeSynchornizator.GetBlocksForSync(nodeAddress);

                foreach (var bl in forkedBlocks)
                {
                    RevalidateBlock(bl);
                    BlockChain.AddOrUpdate(bl.Index, bl, (index, curBlock) => { return(bl); });
                }

                List <string> blockTxs = forkedBlocks.SelectMany(b => b.Transactions).Select(t => t.TransactionHash).ToList();

                PendingTransactions = new ConcurrentBag <Transaction>(PendingTransactions.
                                                                      Where(t => !blockTxs.Contains(t.TransactionHash)));
            }
            else
            {
                bool isFutureBlock = LastBlock.BlockHash != minedBlock.PreviousBlockHash;
                if (isFutureBlock)
                {
                    return;
                }

                RevalidateBlock(minedBlock);

                // remove mined transactions from pending transactions
                List <string> minedTxIds = minedBlock.Transactions.Select(t => t.TransactionHash).ToList();
                PendingTransactions = new ConcurrentBag <Transaction>(PendingTransactions.Where(t => !minedTxIds.Contains(t.TransactionHash)).ToList());

                BlockChain.TryAdd(minedBlock.Index, minedBlock);
            }
        }