public Task HandleEventAsync(NewIrreversibleBlockFoundEvent eventData) { _taskQueueManager.Enqueue(async() => { await _blockchainStateService.MergeBlockStateAsync(eventData.BlockHeight, eventData.BlockHash); }, KernelConstants.MergeBlockStateQueueName); _taskQueueManager.Enqueue(async() => { // Clean chain branch var chain = await _blockchainService.GetChainAsync(); var discardedBranch = await _blockchainService.GetDiscardedBranchAsync(chain); if (discardedBranch.BranchKeys.Count > 0 || discardedBranch.NotLinkedKeys.Count > 0) { _taskQueueManager.Enqueue( async() => { await _blockchainService.CleanChainBranchAsync(discardedBranch); }, KernelConstants.UpdateChainQueueName); } // Clean transaction block index cache await _transactionBlockIndexService.CleanTransactionBlockIndexCacheAsync(eventData.BlockHeight); }, KernelConstants.ChainCleaningQueueName); return(Task.CompletedTask); }
public Task HandleEventAsync(NewIrreversibleBlockFoundEvent eventData) { _taskQueueManager.Enqueue(async() => { await _blockchainStateService.MergeBlockStateAsync(eventData.BlockHeight, eventData.BlockHash); CleanChain(eventData.BlockHash, eventData.BlockHeight); }, KernelConstants.MergeBlockStateQueueName); return(Task.CompletedTask); }
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); }
public async Task HandleEventAsync(AnnouncementReceivedEventData eventData) { //Disable network lib return; var irreversibleBlockIndex = await _idpoSLastLastIrreversibleBlockDiscoveryService.FindLastLastIrreversibleBlockAsync( eventData.SenderPubKey); if (irreversibleBlockIndex != null) { _taskQueueManager.Enqueue(async() => { var chain = await _blockchainService.GetChainAsync(); if (chain.LastIrreversibleBlockHeight < irreversibleBlockIndex.Height) { var hash = await _blockchainService.GetBlockHashByHeightAsync(chain, irreversibleBlockIndex.Height, chain.BestChainHash); if (hash == irreversibleBlockIndex.Hash) { await _blockchainService.SetIrreversibleBlockAsync(chain, irreversibleBlockIndex.Height, irreversibleBlockIndex.Hash); } } }, KernelConstants.UpdateChainQueueName); } }
private async Task ProcessNewBlock(AnnouncementReceivedEventData header, string senderPubKey) { var blockHeight = header.Announce.BlockHeight; var blockHash = header.Announce.BlockHash; Logger.LogTrace($"Receive header {{ hash: {blockHash}, height: {blockHeight} }} from {senderPubKey}."); if (!VerifyAnnouncement(header.Announce)) { return; } var chain = await _blockchainService.GetChainAsync(); if (blockHeight < chain.LastIrreversibleBlockHeight) { Logger.LogTrace($"Receive lower header {{ hash: {blockHash}, height: {blockHeight} }} " + $"form {senderPubKey}, ignore."); return; } _taskQueueManager.Enqueue(async() => { await _blockSyncJob.ExecuteAsync(new BlockSyncJobArgs { SuggestedPeerPubKey = senderPubKey, BlockHash = blockHash, BlockHeight = blockHeight }); }, OSConsts.BlockSyncQueueName); }
public Task HandleEventAsync(NewIrreversibleBlockFoundEvent eventData) { _taskQueueManager.Enqueue( async() => { await _resourceExtractionService.HandleNewIrreversibleBlockFoundAsync(eventData); }, KernelConstants.ChainCleaningQueueName); return(Task.CompletedTask); }
public async Task HandleEventAsync(NewIrreversibleBlockFoundEvent eventData) { _taskQueueManager.Enqueue(async() => { await _blockchainStateMergingService.MergeBlockStateAsync(eventData.BlockHeight, eventData.BlockHash); }, KernelConsts.MergeBlockStateQueueName); }
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 ProcessLogEventAsync(Block block, IrreversibleBlockFound irreversibleBlockFound) { try { var chain = await _blockchainService.GetChainAsync(); if (chain.LastIrreversibleBlockHeight > irreversibleBlockFound.IrreversibleBlockHeight) { return; } var libBlockHash = await _blockchainService.GetBlockHashByHeightAsync(chain, irreversibleBlockFound.IrreversibleBlockHeight, block.GetHash()); if (libBlockHash == null) { return; } // enable transaction packing _transactionPackingService.EnableTransactionPacking(); if (chain.LastIrreversibleBlockHeight == irreversibleBlockFound.IrreversibleBlockHeight) { return; } if (chain.LastIrreversibleBlockHeight == irreversibleBlockFound.IrreversibleBlockHeight) { return; } var blockIndex = new BlockIndex(libBlockHash, irreversibleBlockFound.IrreversibleBlockHeight); Logger.LogDebug($"About to set new lib height: {blockIndex.BlockHeight} " + $"Event: {irreversibleBlockFound} " + $"BlockIndex: {blockIndex.BlockHash} - {blockIndex.BlockHeight}"); _taskQueueManager.Enqueue( async() => { var currentChain = await _blockchainService.GetChainAsync(); if (currentChain.LastIrreversibleBlockHeight < blockIndex.BlockHeight) { await _blockchainService.SetIrreversibleBlockAsync(currentChain, blockIndex.BlockHeight, blockIndex.BlockHash); } }, KernelConstants.UpdateChainQueueName); } catch (Exception e) { Logger.LogError(e, "Failed to resolve IrreversibleBlockFound event."); throw; } }
public async Task HandleEventAsync(ConsensusRequestMiningEventData eventData) { try { var block = await _minerService.MineAsync(eventData.PreviousBlockHash, eventData.PreviousBlockHeight, eventData.BlockTime, eventData.TimeSpan); //TODO: Before attach block should add block signature verify _taskQueueManager.Enqueue(async() => await _blockAttachService.AttachBlockAsync(block), KernelConsts.UpdateChainQueueName); } catch (Exception e) { Logger.LogError(e.ToString()); throw; } }
public Task HandleEventAsync(BlockAcceptedEvent eventData) { if (_syncStateService.SyncState == SyncState.Finished) { // if sync is finished we announce the block _networkService.BroadcastAnnounceAsync(eventData.Block.Header); } else if (_syncStateService.SyncState == SyncState.Syncing) { // if syncing and the block is higher the current target, try and update. if (_syncStateService.GetCurrentSyncTarget() <= eventData.Block.Header.Height) { _taskQueueManager.Enqueue(async() => { await _syncStateService.UpdateSyncStateAsync(); }, OSConstants.InitialSyncQueueName); } } return(Task.CompletedTask); }
public void Enqueue(Func <Task> task, string queueName) { var enqueueTime = TimestampHelper.GetUtcNow(); _taskQueueManager.Enqueue(async() => { try { Logger.LogTrace($"Execute block sync job: {queueName}, enqueue time: {enqueueTime}"); _blockSyncStateProvider.SetEnqueueTime(queueName, enqueueTime); await task(); } finally { _blockSyncStateProvider.SetEnqueueTime(queueName, null); } }, queueName); }
public async Task HandleEventAsync(BestChainFoundEventData eventData) { var chain = await _blockchainService.GetChainAsync(); var index = await _irreversibleBlockDiscoveryService.DiscoverAndSetIrreversibleAsync(chain, eventData.ExecutedBlocks); if (index != null) { _taskQueueManager.Enqueue( async() => { var currentChain = await _blockchainService.GetChainAsync(); if (currentChain.LastIrreversibleBlockHeight < index.Height) { await _blockchainService.SetIrreversibleBlockAsync(currentChain, index.Height, index.Hash); } }, KernelConsts.UpdateChainQueueName); } }
public async Task HandleEventAsync(BestChainFoundEventData eventData) { Logger.LogDebug( $"Handle best chain found for lib: BlockHeight: {eventData.BlockHeight}, BlockHash: {eventData.BlockHash}"); var chain = await _blockchainService.GetChainAsync(); var index = await _irreversibleBlockRelatedEventsDiscoveryService.GetLastIrreversibleBlockIndexAsync(chain, eventData.ExecutedBlocks); var unacceptableDistanceToLib = await _irreversibleBlockRelatedEventsDiscoveryService .GetUnacceptableDistanceToLastIrreversibleBlockHeightAsync(eventData.BlockHash); if (unacceptableDistanceToLib > 0) { Logger.LogDebug($"Unacceptable distance to lib height: {unacceptableDistanceToLib}"); _transactionInclusivenessProvider.IsTransactionPackable = false; } else { _transactionInclusivenessProvider.IsTransactionPackable = true; } if (index != null) { // _transactionInclusivenessProvider.IsTransactionPackable = true; _taskQueueManager.Enqueue( async() => { var currentChain = await _blockchainService.GetChainAsync(); if (currentChain.LastIrreversibleBlockHeight < index.Height) { await _blockchainService.SetIrreversibleBlockAsync(currentChain, index.Height, index.Hash); } }, KernelConstants.UpdateChainQueueName); } Logger.LogDebug( $"Finish handle best chain found for lib : BlockHeight: {eventData.BlockHeight}, BlockHash: {eventData.BlockHash}"); }
public async Task ExecuteAsync(BlockSyncJobArgs args) { Logger.LogDebug($"Start block sync job, target height: {args.BlockHeight}, target block hash: {args.BlockHash}, peer: {args.SuggestedPeerPubKey}"); var chain = await _blockchainService.GetChainAsync(); try { if (args.BlockHash != null && args.BlockHeight < chain.BestChainHeight + 5) { var peerBlockHash = args.BlockHash; var peerBlock = await _blockchainService.GetBlockByHashAsync(peerBlockHash); if (peerBlock != null) { Logger.LogDebug($"Block {peerBlock} already know."); return; } peerBlock = await _networkService.GetBlockByHashAsync(peerBlockHash, args.SuggestedPeerPubKey); if (peerBlock == null) { Logger.LogWarning($"Get null block from peer, request block hash: {peerBlockHash}"); return; } _taskQueueManager.Enqueue(async() => await _blockAttachService.AttachBlockAsync(peerBlock), KernelConsts.UpdateChainQueueName); return; } var blockHash = chain.LastIrreversibleBlockHash; Logger.LogDebug($"Trigger sync blocks from peers, lib height: {chain.LastIrreversibleBlockHeight}, lib block hash: {blockHash}"); var blockHeight = chain.LastIrreversibleBlockHeight; var count = _networkOptions.BlockIdRequestCount; var peerBestChainHeight = await _networkService.GetBestChainHeightAsync(args.SuggestedPeerPubKey); while (true) { // Limit block sync job count, control memory usage chain = await _blockchainService.GetChainAsync(); if (chain.BestChainHeight < blockHeight - BlockSyncJobLimit) { Logger.LogWarning($"Pause sync task and wait for synced block to be processed, best chain height: {chain.BestChainHeight}"); break; } Logger.LogDebug($"Request blocks start with {blockHash}"); var blocks = await _networkService.GetBlocksAsync(blockHash, blockHeight, count, args.SuggestedPeerPubKey); if (blocks == null || !blocks.Any()) { Logger.LogDebug($"No blocks returned, current chain height: {chain.LongestChainHeight}."); break; } Logger.LogDebug($"Received [{blocks.First()},...,{blocks.Last()}] ({blocks.Count})"); if (blocks.First().Header.PreviousBlockHash != blockHash) { Logger.LogError($"Current job hash : {blockHash}"); throw new InvalidOperationException($"Previous block not match previous {blockHash}, network back {blocks.First().Header.PreviousBlockHash}"); } foreach (var block in blocks) { if (block == null) { Logger.LogWarning($"Get null block from peer, request block start: {blockHash}"); break; } Logger.LogDebug($"Processing block {block}, longest chain hash: {chain.LongestChainHash}, best chain hash : {chain.BestChainHash}"); _taskQueueManager.Enqueue(async() => await _blockAttachService.AttachBlockAsync(block), KernelConsts.UpdateChainQueueName); } peerBestChainHeight = await _networkService.GetBestChainHeightAsync(args.SuggestedPeerPubKey); if (blocks.Last().Height >= peerBestChainHeight) { break; } var lastBlock = blocks.Last(); blockHash = lastBlock.GetHash(); blockHeight = lastBlock.Height; } } catch (Exception e) { Logger.LogError(e, $"Failed to finish block sync job"); } finally { Logger.LogDebug($"Finishing block sync job, longest chain height: {chain.LongestChainHeight}"); } }
private void QueueNetworkTask(Func <Task> task) { _taskQueueManager.Enqueue(task, NetworkConstants.PeerReconnectionQueueName); }
public Task HandleEventAsync(ConsensusRequestMiningEventData eventData) { try { _taskQueueManager.Enqueue(async() => { var chain = await _blockchainService.GetChainAsync(); if (eventData.PreviousBlockHash != chain.BestChainHash) { Logger.LogWarning("Mining canceled because best chain already updated."); return; } if (!ValidateBlockMiningTime(eventData.BlockTime, eventData.MiningDueTime, eventData.BlockExecutionTime)) { await TriggerConsensusEventAsync(chain.BestChainHash, chain.BestChainHeight); return; } var blockExecutionDuration = CalculateBlockMiningDuration(eventData.BlockTime, eventData.BlockExecutionTime); Block block; try { block = await _minerService.MineAsync(eventData.PreviousBlockHash, eventData.PreviousBlockHeight, eventData.BlockTime, blockExecutionDuration); } catch (Exception) { await TriggerConsensusEventAsync(chain.BestChainHash, chain.BestChainHeight); throw; } if (TimestampHelper.GetUtcNow() <= eventData.MiningDueTime - blockExecutionDuration) { 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, // HasFork = block.Height <= chain.BestChainHeight }); } else { Logger.LogWarning( $"Discard block {block.Height} and trigger once again because mining time slot expired. " + $"MiningDueTime : {eventData.MiningDueTime}, " + $"block execution duration limit : {blockExecutionDuration}"); await TriggerConsensusEventAsync(chain.BestChainHash, chain.BestChainHeight); } }, KernelConstants.ConsensusRequestMiningQueueName); return(Task.CompletedTask); } catch (Exception e) { Logger.LogError(e.ToString()); throw; } }