示例#1
0
        private async Task AddTransactionResultsWithPreMiningAsync(Block block, IEnumerable <TransactionResult> results)
        {
            var merkleRoot = block.Header.MerkleTreeRootOfTransactions;

            // Set block to pre mining
            block.Header.MerkleTreeRootOfTransactions = null;

            // // TransactionResults are added during execution
            foreach (var result in results)
            {
                // Add TransactionResult before completing and adding block
                await _transactionResultService.AddTransactionResultAsync(result, block.Header);
            }

            // Set block back to post mining
            block.Header.MerkleTreeRootOfTransactions = merkleRoot;

            // Add block to chain
            var chain = await _blockchainService.GetChainAsync();

            await _blockchainService.AddBlockAsync(block);

            await _blockchainService.AttachBlockToChainAsync(chain, block);

            await _blockchainService.SetBestChainAsync(chain, block.Height, block.GetHash());
        }
示例#2
0
        public async Task TokenTransferParallelTest()
        {
            var chain = await _blockchainService.GetChainAsync();

            var tokenAmount = _transactionCount / _groupCount;

            var(prepareTransactions, keyPairs) =
                await _parallelTestHelper.PrepareTokenForParallel(_groupCount, tokenAmount);

            await _parallelTestHelper.BroadcastTransactions(prepareTransactions);

            var block = _parallelTestHelper.GenerateBlock(chain.BestChainHash, chain.BestChainHeight,
                                                          prepareTransactions);

            block = await _blockExecutingService.ExecuteBlockAsync(block.Header, prepareTransactions);

            await _blockchainService.AddBlockAsync(block);

            await _blockAttachService.AttachBlockAsync(block);

            var systemTransactions = await _parallelTestHelper.GenerateTransferTransactions(1);

            var cancellableTransactions =
                _parallelTestHelper.GenerateTransactionsWithoutConflict(keyPairs, tokenAmount);
            var allTransaction = systemTransactions.Concat(cancellableTransactions).ToList();
            await _parallelTestHelper.BroadcastTransactions(allTransaction);

            var groupedTransactions = await _grouper.GroupAsync(
                new ChainContext { BlockHash = block.GetHash(), BlockHeight = block.Height },
                cancellableTransactions);

            groupedTransactions.Parallelizables.Count.ShouldBe(_groupCount);
            groupedTransactions.NonParallelizables.Count.ShouldBe(0);

            block = _parallelTestHelper.GenerateBlock(block.GetHash(), block.Height, allTransaction);
            block = await _blockExecutingService.ExecuteBlockAsync(block.Header, systemTransactions,
                                                                   cancellableTransactions, CancellationToken.None);

            await _blockchainService.AddBlockAsync(block);

            await _blockAttachService.AttachBlockAsync(block);

            var codeRemarks =
                await _codeRemarksManager.GetCodeRemarksAsync(Hash.FromRawBytes(_parallelTestHelper.TokenContractCode));

            codeRemarks.ShouldBeNull();

            groupedTransactions = await _grouper.GroupAsync(
                new ChainContext { BlockHash = block.GetHash(), BlockHeight = block.Height },
                cancellableTransactions);

            groupedTransactions.Parallelizables.Count.ShouldBe(_groupCount);
            groupedTransactions.NonParallelizables.Count.ShouldBe(0);

            block.TransactionIds.Count().ShouldBe(allTransaction.Count);
        }
示例#3
0
        public async Task WrongParallelTest()
        {
            var chain = await _blockchainService.GetChainAsync();

            await _blockchainService.SetIrreversibleBlockAsync(chain, chain.BestChainHeight, chain.BestChainHash);

            var transactions =
                _parallelTestHelper.GenerateBasicFunctionWithParallelTransactions(_groupCount, _transactionCount);
            await _parallelTestHelper.BroadcastTransactions(transactions);

            var poolSize = await _txHub.GetTransactionPoolSizeAsync();

            poolSize.ShouldBe(transactions.Count);

            var groupedTransactions = await _grouper.GroupAsync(
                new ChainContext { BlockHash = chain.BestChainHash, BlockHeight = chain.BestChainHeight },
                transactions);

            groupedTransactions.Parallelizables.Count.ShouldBe(_transactionCount);
            groupedTransactions.NonParallelizables.Count.ShouldBe(0);

            var block = await _minerService.MineAsync(chain.BestChainHash, chain.BestChainHeight, TimestampHelper.GetUtcNow(),
                                                      TimestampHelper.DurationFromSeconds(4));

            block.TransactionIds.Count().ShouldBe(_groupCount);
            await _blockchainService.AddBlockAsync(block);

            await _blockAttachService.AttachBlockAsync(block);

            var codeRemarks =
                await _codeRemarksManager.GetCodeRemarksAsync(
                    Hash.FromRawBytes(_parallelTestHelper.BasicFunctionWithParallelContractCode));

            codeRemarks.ShouldNotBeNull();
            codeRemarks.NonParallelizable.ShouldBeTrue();

            groupedTransactions = await _grouper.GroupAsync(new ChainContext { BlockHash = block.GetHash(), BlockHeight = block.Height },
                                                            transactions);

            groupedTransactions.Parallelizables.Count.ShouldBe(0);
            groupedTransactions.NonParallelizables.Count.ShouldBe(_transactionCount);

            poolSize = await _txHub.GetTransactionPoolSizeAsync();

            poolSize.ShouldBe(transactions.Count - block.TransactionIds.Count());

            block = await _minerService.MineAsync(block.GetHash(), block.Height, TimestampHelper.GetUtcNow(),
                                                  TimestampHelper.DurationFromSeconds(4));

            block.TransactionIds.Count().ShouldBe(poolSize);
        }
示例#4
0
        public async Task IterationSetup()
        {
            var transactions = await _osTestHelper.GenerateTransferTransactions(TransactionCount);

            await _txHub.HandleTransactionsReceivedAsync(new TransactionsReceivedEvent
            {
                Transactions = transactions
            });

            var chain = await _blockchainService.GetChainAsync();

            _block = _osTestHelper.GenerateBlock(chain.BestChainHash, chain.BestChainHeight, transactions);
            await _blockchainService.AddBlockAsync(_block);

            await _chainBlockLinks.SetAsync(
                chain.Id.ToStorageKey() + KernelConstants.StorageKeySeparator + _block.GetHash().ToStorageKey(),
                new ChainBlockLink()
            {
                BlockHash         = _block.GetHash(),
                Height            = _block.Height,
                PreviousBlockHash = _block.Header.PreviousBlockHash,
                IsLinked          = true
            });

            await _blockchainService.SetBestChainAsync(chain, _block.Height, _block.GetHash());
        }
        public async Task AttachBlockWithTransactionsAsync(BlockWithTransactions blockWithTransactions,
                                                           Func <Task> attachFinishedCallback = null)
        {
            var valid = await _validationService.ValidateBlockBeforeAttachAsync(blockWithTransactions);

            if (!valid)
            {
                throw new InvalidOperationException(
                          $"The block was invalid, block hash: {blockWithTransactions}.");
            }

            await _blockchainService.AddTransactionsAsync(blockWithTransactions.Transactions);

            var block = blockWithTransactions.ToBlock();
            await _blockchainService.AddBlockAsync(block);

            _blockSyncQueueService.Enqueue(async() =>
            {
                try
                {
                    await _blockAttachService.AttachBlockAsync(block);
                }
                finally
                {
                    if (attachFinishedCallback != null)
                    {
                        await attachFinishedCallback();
                    }
                }
            },
                                           KernelConstants.UpdateChainQueueName);
        }
        public async Task ExecuteBlocksAttachedToLongestChain_ExecuteFailed()
        {
            var chain = await _blockchainService.GetChainAsync();

            var bestChainHeight = chain.BestChainHeight;
            var bestChainHash   = chain.BestChainHash;

            var newBlock = _kernelTestHelper.GenerateBlock(chain.BestChainHeight, chain.BestChainHash,
                                                           new List <Transaction> {
                _kernelTestHelper.GenerateTransaction()
            });

            await _blockchainService.AddBlockAsync(newBlock);

            var status = await _blockchainService.AttachBlockToChainAsync(chain, newBlock);

            var attachResult =
                await _fullBlockchainExecutingService.ExecuteBlocksAttachedToLongestChain(chain, status);

            attachResult.Count.ShouldBe(1);
            attachResult.Last().Height.ShouldBe(16);
            attachResult.Last().BlockHash.ShouldBe(newBlock.GetHash());

            chain = await _blockchainService.GetChainAsync();

            var newBlockLink = await _chainManager.GetChainBlockLinkAsync(newBlock.GetHash());

            newBlockLink.ExecutionStatus.ShouldBe(ChainBlockLinkExecutionStatus.ExecutionFailed);
            chain.BestChainHash.ShouldBe(bestChainHash);
            chain.BestChainHeight.ShouldBe(bestChainHeight);
        }
示例#7
0
        public async Task ExecuteBlocks_ValidateFailed()
        {
            var chain = await _blockchainService.GetChainAsync();

            var previousHash   = chain.BestChainHash;
            var previousHeight = chain.BestChainHeight;

            var blockList = new List <Block>();

            for (var i = 0; i < 3; i++)
            {
                var transactions = new List <Transaction> {
                    _kernelTestHelper.GenerateTransaction()
                };
                var lastBlock = _kernelTestHelper.GenerateBlock(previousHeight, previousHash, transactions);

                await _blockchainService.AddBlockAsync(lastBlock);

                await _blockchainService.AddTransactionsAsync(transactions);

                await _blockchainService.AttachBlockToChainAsync(chain, lastBlock);

                previousHash   = lastBlock.GetHash();
                previousHeight = lastBlock.Height;
                blockList.Add(lastBlock);
            }

            var executionResult =
                await _fullBlockchainExecutingService.ExecuteBlocksAsync(blockList);

            executionResult.SuccessBlockExecutedSets.Count.ShouldBe(0);
            executionResult.ExecutedFailedBlocks.Count.ShouldBe(1);
            executionResult.ExecutedFailedBlocks[0].GetHash().ShouldBe(blockList[0].GetHash());
        }
示例#8
0
        public void Setup(BenchmarkContext context)
        {
            _blockchainService          = GetRequiredService <IBlockchainService>();
            _blockchainExecutingService = GetRequiredService <IBlockchainExecutingService>();
            _chainManager = GetRequiredService <IChainManager>();
            _osTestHelper = GetRequiredService <OSTestHelper>();

            _counter = context.GetCounter("TestCounter");

            AsyncHelper.RunSync(async() =>
            {
                var chain = await _blockchainService.GetChainAsync();

                var transactions = await _osTestHelper.GenerateTransferTransactions(1000);

                _block = _osTestHelper.GenerateBlock(chain.BestChainHash, chain.BestChainHeight, transactions);

                await _blockchainService.AddTransactionsAsync(transactions);
                await _blockchainService.AddBlockAsync(_block);

                chain = await _blockchainService.GetChainAsync();

                await _blockchainService.AttachBlockToChainAsync(chain, _block);
            });
        }
示例#9
0
        private async Task <Block> ExecuteAsync(Transaction transaction, long previousBlockHeight, Hash previousBlockHash)
        {
            var transactionList = new List <Transaction>();

            if (transaction != null)
            {
                transactionList.Add(transaction);
            }
            var block = await _miningService.MineAsync(
                new RequestMiningDto
            {
                PreviousBlockHash  = previousBlockHash, PreviousBlockHeight = previousBlockHeight,
                BlockExecutionTime = TimestampHelper.DurationFromMilliseconds(int.MaxValue)
            },
                transactionList,
                DateTime.UtcNow.ToTimestamp());

            if (transaction != null)
            {
                await _blockchainService.AddTransactionsAsync(new List <Transaction> {
                    transaction
                });
            }
            await _blockchainService.AddBlockAsync(block);

            return(block);
        }
        public async Task <BlockExecutedSet> ExecuteTransactionAsync(Transaction transaction, Chain chain = null)
        {
            chain ??= await _blockchainService.GetChainAsync();

            var blockHeader = new BlockHeader
            {
                Height            = chain.BestChainHeight + 1,
                PreviousBlockHash = chain.BestChainHash,
                Time         = TimestampHelper.GetUtcNow(),
                SignerPubkey = ByteString.CopyFrom(CryptoHelper.GenerateKeyPair().PublicKey)
            };

            var transactions = new List <Transaction>
            {
                transaction
            };

            var blockExecutedSet = await _blockExecutingService.ExecuteBlockAsync(blockHeader, transactions);

            await _blockchainService.AddTransactionsAsync(transactions);

            await _blockchainService.AddBlockAsync(blockExecutedSet.Block);

            await _blockchainService.AttachBlockToChainAsync(chain, blockExecutedSet.Block);

            var blockExecutionResult = await _blockchainExecutingService.ExecuteBlocksAsync(new[] { blockExecutedSet.Block });

            await _blockExecutionResultProcessingService.ProcessBlockExecutionResultAsync(chain, blockExecutionResult);

            return(blockExecutionResult.SuccessBlockExecutedSets.Single());
        }
示例#11
0
        public async Task Attach_Block_To_Chain_FoundBestChain()
        {
            var chain = await _blockchainService.GetChainAsync();

            var transactions = new List <Transaction> {
                _kernelTestHelper.GenerateTransaction()
            };
            var newBlock = _kernelTestHelper.GenerateBlock(chain.BestChainHeight, chain.BestChainHash, transactions);

            await _blockchainService.AddBlockAsync(newBlock);

            await _blockchainService.AddTransactionsAsync(transactions);

            var status = await _blockchainService.AttachBlockToChainAsync(chain, newBlock);

            var attachResult =
                await _fullBlockchainExecutingService.ExecuteBlocksAttachedToLongestChain(chain, status);

            attachResult.Count.ShouldBe(1);
            attachResult.Last().Height.ShouldBe(newBlock.Height);

            chain = await _blockchainService.GetChainAsync();

            chain.BestChainHash.ShouldBe(newBlock.GetHash());
            chain.BestChainHeight.ShouldBe(newBlock.Height);
        }
示例#12
0
        public async Task <Block> AttachBlock(long previousBlockHeight, Hash previousBlockHash,
                                              List <Transaction> transactions = null, List <TransactionResult> transactionResults = null)
        {
            if (transactions == null || transactions.Count == 0)
            {
                transactions = new List <Transaction>();
            }

            if (transactions.Count == 0)
            {
                transactions.Add(GenerateTransaction());
            }

            if (transactionResults == null)
            {
                transactionResults = new List <TransactionResult>();
            }

            if (transactionResults.Count == 0)
            {
                foreach (var transaction in transactions)
                {
                    transactionResults.Add(GenerateTransactionResult(transaction, TransactionResultStatus.Mined));
                }
            }

            var newBlock = GenerateBlock(previousBlockHeight, previousBlockHash, transactions);

            var bloom = new Bloom();

            foreach (var transactionResult in transactionResults)
            {
                transactionResult.UpdateBloom();
                if (transactionResult.Status == TransactionResultStatus.Mined)
                {
                    bloom.Combine(new[] { new Bloom(transactionResult.Bloom.ToByteArray()) });
                }
            }

            newBlock.Header.Bloom = ByteString.CopyFrom(bloom.Data);

            foreach (var transactionResult in transactionResults)
            {
                await _transactionResultService.AddTransactionResultAsync(transactionResult, newBlock.Header);
            }

            await _blockchainService.AddBlockAsync(newBlock);

            await _blockchainService.AddTransactionsAsync(transactions);

            var chain = await _blockchainService.GetChainAsync();

            await _blockchainService.AttachBlockToChainAsync(chain, newBlock);

            return(newBlock);
        }
示例#13
0
        public async Task IterationSetup()
        {
            var transactions = await _osTestHelper.GenerateTransferTransactions(TransactionCount);

            await _blockchainService.AddTransactionsAsync(transactions);

            _block = _osTestHelper.GenerateBlock(_chain.BestChainHash, _chain.BestChainHeight, transactions);

            await _blockchainService.AddBlockAsync(_block);
        }
示例#14
0
        internal async Task <Block> GenerateBlockAsync(long previousBlockHeight, Hash previousBlockHash,
                                                       List <Transaction> transactions = null)
        {
            var block = _kernelTestHelper.GenerateBlock(previousBlockHeight, previousBlockHash, transactions);
            await _blockchainService.AddBlockAsync(block);

            await _blockchainService.AddTransactionsAsync(transactions);

            return(block);
        }
        public Task HandleEventAsync(ConsensusRequestMiningEventData eventData)
        {
            _taskQueueManager.Enqueue(async() =>
            {
                var chain = await _blockchainService.GetChainAsync();
                if (eventData.PreviousBlockHash != chain.BestChainHash)
                {
                    Logger.LogDebug("Mining canceled because best chain already updated.");
                    return;
                }

                try
                {
                    var block = await _miningRequestService.RequestMiningAsync(new ConsensusRequestMiningDto
                    {
                        BlockTime           = eventData.BlockTime,
                        BlockExecutionTime  = eventData.BlockExecutionTime,
                        MiningDueTime       = eventData.MiningDueTime,
                        PreviousBlockHash   = eventData.PreviousBlockHash,
                        PreviousBlockHeight = eventData.PreviousBlockHeight
                    });

                    if (block != null)
                    {
                        await _blockchainService.AddBlockAsync(block);

                        Logger.LogTrace("Before enqueue attach job.");
                        _taskQueueManager.Enqueue(async() => await _blockAttachService.AttachBlockAsync(block),
                                                  KernelConstants.UpdateChainQueueName);

                        Logger.LogTrace("Before publish block.");

                        await LocalEventBus.PublishAsync(new BlockMinedEventData
                        {
                            BlockHeader = block.Header,
                        });
                    }
                    else
                    {
                        await TriggerConsensusEventAsync(chain.BestChainHash, chain.BestChainHeight);
                    }
                }
                catch (Exception)
                {
                    await TriggerConsensusEventAsync(chain.BestChainHash, chain.BestChainHeight);
                    throw;
                }
            }, KernelConstants.ConsensusRequestMiningQueueName);

            return(Task.CompletedTask);
        }
示例#16
0
 public void Cleanup()
 {
     AsyncHelper.RunSync(async() =>
     {
         await _blockchainService.AddBlockAsync(_block);
         await _blockAttachService.AttachBlockAsync(_block);
         var chain = await _blockchainService.GetChainAsync();
         await _txHub.HandleBestChainFoundAsync(new BestChainFoundEventData
         {
             BlockHash   = chain.BestChainHash,
             BlockHeight = chain.BestChainHeight
         });
     });
 }
示例#17
0
        public async Task ExecuteBlocksAttachedToLongestChain_ValidateFailed()
        {
            var chain = await _blockchainService.GetChainAsync();

            var bestChainHeight = chain.BestChainHeight;
            var bestChainHash   = chain.BestChainHash;

            var previousHash   = chain.BestChainHash;
            var previousHeight = chain.BestChainHeight;

            BlockAttachOperationStatus status = BlockAttachOperationStatus.None;
            var blockList = new List <Block>();
//            Block lastBlock = null;
            int count = 0;

            while (!status.HasFlag(BlockAttachOperationStatus.LongestChainFound))
            {
                var transactions = new List <Transaction> {
                    _kernelTestHelper.GenerateTransaction()
                };
                var lastBlock = _kernelTestHelper.GenerateBlock(previousHeight, previousHash, transactions);

                await _blockchainService.AddBlockAsync(lastBlock);

                await _blockchainService.AddTransactionsAsync(transactions);

                status = await _blockchainService.AttachBlockToChainAsync(chain, lastBlock);

                count++;
                previousHash   = lastBlock.GetHash();
                previousHeight = lastBlock.Height;
                blockList.Add(lastBlock);
            }

            var attachResult =
                await _fullBlockchainExecutingService.ExecuteBlocksAttachedToLongestChain(chain, status);

            attachResult.ShouldBeNull();

            chain = await _blockchainService.GetChainAsync();

            var newBlockLink = await _chainManager.GetChainBlockLinkAsync(blockList.First().GetHash());

            newBlockLink.ExecutionStatus.ShouldBe(ChainBlockLinkExecutionStatus.ExecutionFailed);
            chain.BestChainHash.ShouldBe(bestChainHash);
            chain.BestChainHeight.ShouldBe(bestChainHeight);
            chain.LongestChainHash.ShouldBe(bestChainHash);
            chain.LongestChainHeight.ShouldBe(bestChainHeight);
            chain.Branches.ShouldNotContainKey(previousHash.ToStorageKey());
        }
示例#18
0
        private async Task ExecuteBlocksAsync(List <Block> blockList)
        {
            foreach (var block in blockList)
            {
                await _blockchainService.AddBlockAsync(block);
            }

            var executionResult =
                await _fullBlockchainExecutingService.ExecuteBlocksAsync(blockList);

            executionResult.SuccessBlockExecutedSets.Count.ShouldBe(blockList.Count());
            for (var i = 0; i < blockList.Count; i++)
            {
                executionResult.SuccessBlockExecutedSets[i].GetHash().ShouldBe(blockList[i].GetHash());
            }
            executionResult.ExecutedFailedBlocks.Count.ShouldBe(0);
        }
示例#19
0
        public async Task AttachBlockAsync_Test()
        {
            var chain = await _smartContractExecutionHelper.CreateChainAsync();

            await _blockAttachService.AttachBlockAsync(_kernelTestHelper.GenerateBlock(0, Hash.Empty));

            var blockHeader = new BlockHeader
            {
                Height            = chain.BestChainHeight + 1,
                PreviousBlockHash = chain.BestChainHash,
                Time         = TimestampHelper.GetUtcNow(),
                SignerPubkey = ByteString.CopyFrom(CryptoHelper.GenerateKeyPair().PublicKey)
            };

            var transactions = new List <Transaction>
            {
                new Transaction
                {
                    From       = _smartContractAddressService.GetZeroSmartContractAddress(),
                    To         = _smartContractAddressService.GetZeroSmartContractAddress(),
                    MethodName = nameof(ACS0Container.ACS0Stub.DeploySmartContract),
                    Params     = new ContractDeploymentInput
                    {
                        Category = KernelConstants.DefaultRunnerCategory,
                        Code     = ByteString.CopyFrom(
                            _smartContractExecutionHelper.ContractCodes["AElf.Contracts.MultiToken"])
                    }.ToByteString()
                }
            };

            var blockExecutedSet = await _blockExecutingService.ExecuteBlockAsync(blockHeader, transactions);

            await _blockchainService.AddBlockAsync(blockExecutedSet.Block);

            _blockAttachService.AttachBlockAsync(blockExecutedSet.Block).ShouldThrow <Exception>();

            await _blockchainService.AddTransactionsAsync(transactions);

            await _blockAttachService.AttachBlockAsync(blockExecutedSet.Block);

            var newChain = await _blockchainService.GetChainAsync();

            newChain.BestChainHeight.ShouldBe(chain.BestChainHeight + 1);
        }
示例#20
0
        public async Task <Block> MinedOneBlock(Hash previousBlockHash = null, long previousBlockHeight = 0)
        {
            if (previousBlockHash == null || previousBlockHeight == 0)
            {
                var chain = await _blockchainService.GetChainAsync();

                previousBlockHash   = chain.BestChainHash;
                previousBlockHeight = chain.BestChainHeight;
            }

            var block = await _minerService.MineAsync(previousBlockHash, previousBlockHeight,
                                                      TimestampHelper.GetUtcNow(), TimestampHelper.DurationFromMilliseconds(4000));

            await _blockchainService.AddBlockAsync(block);

            await _blockAttachService.AttachBlockAsync(block);

            return(block);
        }
        public async Task ExecuteBlocksAttachedToLongestChain_ValidateFailed()
        {
            var chain = await _blockchainService.GetChainAsync();

            var bestChainHeight = chain.BestChainHeight;
            var bestChainHash   = chain.BestChainHash;

            var transactions = new List <Transaction> {
                _kernelTestHelper.GenerateTransaction()
            };

            var newBlock = _kernelTestHelper.GenerateBlock(chain.BestChainHeight, chain.BestChainHash,
                                                           transactions);

            await _blockchainService.AddBlockAsync(newBlock);

            await _blockchainService.AddTransactionsAsync(transactions);

            var status = await _blockchainService.AttachBlockToChainAsync(chain, newBlock);

            chain = await _blockchainService.GetChainAsync();

            chain.LongestChainHash.ShouldBe(newBlock.GetHash());
            chain.LongestChainHeight.ShouldBe(newBlock.Height);
            chain.Branches.ShouldContainKey(newBlock.GetHash().ToStorageKey());

            var attachResult =
                await _fullBlockchainExecutingService.ExecuteBlocksAttachedToLongestChain(chain, status);

            attachResult.ShouldBeNull();

            chain = await _blockchainService.GetChainAsync();

            var newBlockLink = await _chainManager.GetChainBlockLinkAsync(newBlock.GetHash());

            newBlockLink.ExecutionStatus.ShouldBe(ChainBlockLinkExecutionStatus.ExecutionFailed);
            chain.BestChainHash.ShouldBe(bestChainHash);
            chain.BestChainHeight.ShouldBe(bestChainHeight);
            chain.LongestChainHash.ShouldBe(bestChainHash);
            chain.LongestChainHeight.ShouldBe(bestChainHeight);
            chain.Branches.ShouldNotContainKey(newBlock.GetHash().ToStorageKey());
        }
        public async Task GetBlockTransactions_Test()
        {
            var transactions = new List <Transaction>();

            for (var i = 0; i < 3; i++)
            {
                var transaction = _kernelTestHelper.GenerateTransaction();
                transactions.Add(transaction);
            }

            var block = _kernelTestHelper.GenerateBlock(0, Hash.Empty, transactions);

            await _blockchainService.AddBlockAsync(block);

            await _blockchainService.AddTransactionsAsync(transactions);

            var blockTransactions = await _smartContractBridgeService.GetBlockTransactions(block.GetHash());

            blockTransactions.ShouldBe(transactions);
        }
示例#23
0
        public void Get_GetPreviousBlock_Success()
        {
            var newBlock = new Block
            {
                Height = 2,
                Header = new BlockHeader
                {
                    PreviousBlockHash = Hash.Empty
                },
                Body = new BlockBody()
            };

            _blockchainService.AddBlockAsync(newBlock);

            _bridgeContext.TransactionContext.PreviousBlockHash = newBlock.GetHash();

            var previousBlock = _bridgeContext.GetPreviousBlock();

            previousBlock.GetHash().ShouldBe(newBlock.GetHash());
        }
        public void Get_GetPreviousTransactions_Success()
        {
            var transaction = GetNewTransaction();

            var newBlock = _kernelTestHelper.GenerateBlock(0, Hash.Empty, new List <Transaction> {
                transaction
            });

            _blockchainService.AddTransactionsAsync(new List <Transaction> {
                transaction
            });
            _blockchainService.AddBlockAsync(newBlock);

            _bridgeContext.TransactionContext.PreviousBlockHash = newBlock.GetHash();

            var previousBlockTransactions = _bridgeContext.GetPreviousBlockTransactions();

            previousBlockTransactions.ShouldNotBeNull();
            previousBlockTransactions.ShouldContain(transaction);
        }
示例#25
0
        public async Task HandleEventAsync(ConsensusRequestMiningEventData eventData)
        {
            try
            {
                _taskQueueManager.Enqueue(async() =>
                {
                    if (eventData.BlockTime > new Timestamp {
                        Seconds = 3600
                    } &&
                        eventData.BlockTime + eventData.BlockExecutionTime <
                        TimestampHelper.GetUtcNow())
                    {
                        Logger.LogTrace(
                            $"Will cancel mining due to timeout: Actual mining time: {eventData.BlockTime}, " +
                            $"execution limit: {eventData.BlockExecutionTime.Milliseconds()} ms.");
                    }

                    var block = await _minerService.MineAsync(eventData.PreviousBlockHash,
                                                              eventData.PreviousBlockHeight,
                                                              eventData.BlockTime, eventData.BlockExecutionTime);

                    await _blockchainService.AddBlockAsync(block);

                    var chain = await _blockchainService.GetChainAsync();
                    await LocalEventBus.PublishAsync(new BlockMinedEventData()
                    {
                        BlockHeader = block.Header,
                        HasFork     = block.Height <= chain.BestChainHeight
                    });

                    // Self mined block do not need do verify
                    _taskQueueManager.Enqueue(async() => await _blockAttachService.AttachBlockAsync(block),
                                              KernelConstants.UpdateChainQueueName);
                }, KernelConstants.ConsensusRequestMiningQueueName);
            }
            catch (Exception e)
            {
                Logger.LogError(e.ToString());
                throw;
            }
        }
        private async Task <BlockExecutedSet> MineAsync(List <Transaction> txs, Timestamp blockTime, Hash preBlockHash,
                                                        long preBlockHeight)
        {
            var blockExecutedSet = await _miningService.MineAsync(
                new RequestMiningDto
            {
                PreviousBlockHash     = preBlockHash, PreviousBlockHeight = preBlockHeight,
                BlockExecutionTime    = TimestampHelper.DurationFromMilliseconds(int.MaxValue),
                TransactionCountLimit = Int32.MaxValue
            }, txs, blockTime ?? DateTime.UtcNow.ToTimestamp());

            var block = blockExecutedSet.Block;

            await _blockchainService.AddTransactionsAsync(txs);

            await _blockchainService.AddBlockAsync(block);

            await _blockAttachService.AttachBlockAsync(block);

            return(blockExecutedSet);
        }
        public async Task AttachBlockWithTransactionsAsync(BlockWithTransactions blockWithTransactions,
                                                           string senderPubkey, Func <Task> attachFinishedCallback = null)
        {
            var blockValid = await _blockSyncValidationService.ValidateBlockBeforeAttachAsync(blockWithTransactions);

            if (!blockValid)
            {
                Logger.LogDebug(
                    $"Sync block validation failed, peer: {senderPubkey}, block hash: {blockWithTransactions.GetHash()}, block height: {blockWithTransactions.Height}");
                await LocalEventBus.PublishAsync(new AbnormalPeerFoundEventData
                {
                    BlockHash   = blockWithTransactions.GetHash(),
                    BlockHeight = blockWithTransactions.Height,
                    PeerPubkey  = senderPubkey
                });

                return;
            }

            await _blockchainService.AddTransactionsAsync(blockWithTransactions.Transactions);

            var block = blockWithTransactions.ToBlock();
            await _blockchainService.AddBlockAsync(block);

            _blockSyncQueueService.Enqueue(async() =>
            {
                try
                {
                    await _blockAttachService.AttachBlockAsync(block);
                }
                finally
                {
                    if (attachFinishedCallback != null)
                    {
                        await attachFinishedCallback();
                    }
                }
            },
                                           KernelConstants.UpdateChainQueueName);
        }
        public async Task Attach_Block_To_Chain_FoundBestChain()
        {
            var chain = await _blockchainService.GetChainAsync();

            var previousHash   = chain.BestChainHash;
            var previousHeight = chain.BestChainHeight;

            BlockAttachOperationStatus status = BlockAttachOperationStatus.None;
//            Block lastBlock = null;
            int count = 0;

            while (!status.HasFlag(BlockAttachOperationStatus.LongestChainFound))
            {
                var transactions = new List <Transaction> {
                    _kernelTestHelper.GenerateTransaction()
                };
                var lastBlock = _kernelTestHelper.GenerateBlock(previousHeight, previousHash, transactions);

                await _blockchainService.AddBlockAsync(lastBlock);

                await _blockchainService.AddTransactionsAsync(transactions);

                status = await _blockchainService.AttachBlockToChainAsync(chain, lastBlock);

                count++;
                previousHash   = lastBlock.GetHash();
                previousHeight = lastBlock.Height;
            }

            var attachResult =
                await _fullBlockchainExecutingService.ExecuteBlocksAttachedToLongestChain(chain, status);

            attachResult.Count.ShouldBe(count);
            attachResult.Last().Height.ShouldBe(previousHeight);

            chain = await _blockchainService.GetChainAsync();

            chain.BestChainHash.ShouldBe(previousHash);
            chain.BestChainHeight.ShouldBe(previousHeight);
        }
示例#29
0
        public async Task ProcessDownloadJob_SyncFromLongestChain_Success()
        {
            var chain = await _blockchainService.GetChainAsync();

            var originalBestChainHash   = chain.BestChainHash;
            var originalBestChainHeight = chain.BestChainHeight;
            var response = await _networkService.GetBlocksAsync(chain.LastIrreversibleBlockHash, 30, null);

            var peerBlocks = response.Payload;

            foreach (var peerBlockWithTransaction in peerBlocks)
            {
                chain = await _blockchainService.GetChainAsync();

                var peerBlock = peerBlockWithTransaction.ToBlock();
                await _blockchainService.AddBlockAsync(peerBlock);

                var result = await _blockchainService.AttachBlockToChainAsync(chain, peerBlock);

                if (result == BlockAttachOperationStatus.LongestChainFound)
                {
                    break;
                }
            }

            var lastPeerBlock = peerBlocks.Last();
            await _blockDownloadJobManager.EnqueueAsync(lastPeerBlock.GetHash(), lastPeerBlock.Height, 5, null);

            await _blockDownloadWorker.ProcessDownloadJobAsync();

            chain = await _blockchainService.GetChainAsync();

            chain.BestChainHeight.ShouldBe(30);
            chain.BestChainHash.ShouldBe(lastPeerBlock.GetHash());

            var block = await _blockchainService.GetBlockByHeightInBestChainBranchAsync(originalBestChainHeight);

            block.GetHash().ShouldNotBe(originalBestChainHash);
        }
示例#30
0
        public async Task AttachBlockAsync(Block block)
        {
            var existBlock = await _blockchainService.GetBlockHeaderByHashAsync(block.GetHash());

            if (existBlock != null)
            {
                Logger.LogDebug($"Try attaching block but already exist, {block}");
                return;
            }
            if (!await _blockValidationService.ValidateBlockBeforeAttachAsync(block))
            {
                Logger.LogWarning($"Validate block failed (before attach to chain), {block}");
                return;
            }

            await _blockchainService.AddBlockAsync(block);

            var chain = await _blockchainService.GetChainAsync();

            var status = await _blockchainService.AttachBlockToChainAsync(chain, block);

            await _blockchainExecutingService.ExecuteBlocksAttachedToLongestChain(chain, status);
        }