public async Task AttachBlockWithTransactions_Test() { var chain = await _blockchainService.GetChainAsync(); var transactions = await _osTestHelper.GenerateTransferTransactions(2); var block = _osTestHelper.GenerateBlock(chain.BestChainHash, chain.BestChainHeight, transactions); var executedBlock = (await _blockExecutingService.ExecuteBlockAsync(block.Header, transactions)).Block; var blockWithTransactions = new BlockWithTransactions { Header = executedBlock.Header, Transactions = { transactions } }; var attachFinished = false; await _blockSyncAttachService.AttachBlockWithTransactionsAsync(blockWithTransactions, "pubkey", () => { attachFinished = true; return(Task.CompletedTask); }); chain = await _blockchainService.GetChainAsync(); chain.BestChainHash.ShouldBe(blockWithTransactions.GetHash()); chain.BestChainHeight.ShouldBe(blockWithTransactions.Height); attachFinished.ShouldBeTrue(); var txs = await _blockchainService.GetTransactionsAsync(transactions.Select(t => t.GetHash())); txs.Count.ShouldBe(2); }
public async Task <bool> FetchBlockAsync(Hash blockHash, long blockHeight, string suggestedPeerPubKey) { var localBlock = await _blockchainService.GetBlockByHashAsync(blockHash); if (localBlock != null) { Logger.LogDebug($"Block {localBlock} already know."); return(true); } var response = await _networkService.GetBlockByHashAsync(blockHash, suggestedPeerPubKey); var blockWithTransactions = response.Payload; if (blockWithTransactions == null) { return(false); } _blockSyncQueueService.Enqueue( async() => { await _blockSyncAttachService.AttachBlockWithTransactionsAsync(blockWithTransactions, suggestedPeerPubKey); }, OSConstants.BlockSyncAttachQueueName); return(true); }
private void EnqueueSyncBlockJob(BlockWithTransactions blockWithTransactions) { _blockSyncQueueService.Enqueue(async() => { Logger.LogTrace($"Block sync: sync block, block: {blockWithTransactions}."); await _blockSyncAttachService.AttachBlockWithTransactionsAsync(blockWithTransactions); }, OSConstants.BlockSyncAttachQueueName); }
private void EnqueueAttachBlockJob(BlockWithTransactions blockWithTransactions, string senderPubkey) { _blockSyncQueueService.Enqueue(async() => { Logger.LogDebug($"Block sync: sync block, block: {blockWithTransactions}."); await _blockSyncAttachService.AttachBlockWithTransactionsAsync(blockWithTransactions, senderPubkey); }, OSConstants.BlockSyncAttachQueueName); }
public async Task Attach_InvalidBlock() { var badPeerPubkey = "BadPeerPubkey"; var badBlock = _osTestHelper.GenerateBlockWithTransactions(Hash.FromString("BadBlock"), 10000); var badPeer = _networkService.GetPeerByPubkey(badPeerPubkey); badPeer.ShouldNotBeNull(); await _blockSyncAttachService.AttachBlockWithTransactionsAsync(badBlock, badPeerPubkey); badPeer = _networkService.GetPeerByPubkey(badPeerPubkey); badPeer.ShouldBeNull(); }
public async Task Attach_InvalidBlock() { var abnormalPeerPubkey = "AbnormalPeerPubkey"; var badBlock = _osTestHelper.GenerateBlockWithTransactions(HashHelper.ComputeFrom("BadBlock"), 10000); var abnormalPeer = _networkService.GetPeerByPubkey(abnormalPeerPubkey); abnormalPeer.ShouldNotBeNull(); await _blockSyncAttachService.AttachBlockWithTransactionsAsync(badBlock, abnormalPeerPubkey); abnormalPeer = _networkService.GetPeerByPubkey(abnormalPeerPubkey); abnormalPeer.ShouldBeNull(); }
private void EnqueueAttachBlockJob(BlockWithTransactions blockWithTransactions, string senderPubkey) { _blockSyncQueueService.Enqueue( async() => { await _blockSyncAttachService.AttachBlockWithTransactionsAsync(blockWithTransactions, senderPubkey, () => { _blockSyncStateProvider.TryUpdateDownloadJobTargetState( blockWithTransactions.GetHash(), true); return(Task.CompletedTask); }); }, OSConstants.BlockSyncAttachQueueName); }
public async Task <bool> FetchBlockAsync(Hash blockHash, long blockHeight, string suggestedPeerPubKey) { var hasBlock = await _blockchainService.HasBlockAsync(blockHash); if (hasBlock) { Logger.LogDebug($"Block {blockHash} already know."); return(true); } var response = await _networkService.GetBlockByHashAsync(blockHash, suggestedPeerPubKey); if (!response.Success || response.Payload == null) { return(false); } var blockWithTransactions = response.Payload; if (blockWithTransactions.GetHash() != blockHash || blockWithTransactions.Height != blockHeight) { Logger.LogWarning( $"Fetched invalid block, peer: {suggestedPeerPubKey}, block hash: {blockWithTransactions.GetHash()}, block height: {blockWithTransactions.Height}"); await LocalEventBus.PublishAsync(new BadPeerFoundEventData { BlockHash = blockWithTransactions.GetHash(), BlockHeight = blockWithTransactions.Height, PeerPubkey = suggestedPeerPubKey }); return(false); } _blockSyncQueueService.Enqueue( async() => { await _blockSyncAttachService.AttachBlockWithTransactionsAsync(blockWithTransactions, suggestedPeerPubKey); }, OSConstants.BlockSyncAttachQueueName); return(true); }
public async Task <DownloadBlocksResult> DownloadBlocksAsync(DownloadBlockDto downloadBlockDto) { var downloadBlockCount = 0; var lastDownloadBlockHash = downloadBlockDto.PreviousBlockHash; var lastDownloadBlockHeight = downloadBlockDto.PreviousBlockHeight; while (downloadBlockCount < downloadBlockDto.MaxBlockDownloadCount) { Logger.LogDebug( $"Request blocks start with block hash: {lastDownloadBlockHash}, block height: {lastDownloadBlockHeight}"); var blocksWithTransactions = await _networkService.GetBlocksAsync(lastDownloadBlockHash, downloadBlockDto.BatchRequestBlockCount, downloadBlockDto.SuggestedPeerPubkey); if (blocksWithTransactions == null || !blocksWithTransactions.Any()) { Logger.LogWarning("No blocks returned."); break; } if (blocksWithTransactions.First().Header.PreviousBlockHash != lastDownloadBlockHash) { throw new InvalidOperationException( $"Previous block not match previous {lastDownloadBlockHash}, network back {blocksWithTransactions.First().Header.PreviousBlockHash}"); } foreach (var blockWithTransactions in blocksWithTransactions) { Logger.LogDebug($"Processing block {blockWithTransactions}."); _blockSyncQueueService.Enqueue( async() => { await _blockSyncAttachService.AttachBlockWithTransactionsAsync(blockWithTransactions, async() => { _blockSyncStateProvider.TryUpdateDownloadJobTargetState(blockWithTransactions.GetHash(), true); }); }, OSConstants.BlockSyncAttachQueueName); downloadBlockCount++; } var lastBlock = blocksWithTransactions.Last(); lastDownloadBlockHash = lastBlock.GetHash(); lastDownloadBlockHeight = lastBlock.Height; } if (lastDownloadBlockHash != null) { _blockSyncStateProvider.SetDownloadJobTargetState(lastDownloadBlockHash, false); } return(new DownloadBlocksResult { DownloadBlockCount = downloadBlockCount, LastDownloadBlockHash = lastDownloadBlockHash, LastDownloadBlockHeight = lastDownloadBlockHeight }); }