protected virtual async Task TriggerLocalEvents(List <DomainEventEntry> localEvents) { foreach (var localEvent in localEvents) { await LocalEventBus.PublishAsync(localEvent.EventData.GetType(), localEvent.EventData); } }
protected virtual async Task TriggerDomainEventsAsync(object entity) { var generatesDomainEventsEntity = entity as IGeneratesDomainEvents; if (generatesDomainEventsEntity == null) { return; } var localEvents = generatesDomainEventsEntity.GetLocalEvents()?.ToArray(); if (localEvents != null && localEvents.Any()) { foreach (var localEvent in localEvents) { await LocalEventBus.PublishAsync(localEvent.GetType(), localEvent); } generatesDomainEventsEntity.ClearLocalEvents(); } var distributedEvents = generatesDomainEventsEntity.GetDistributedEvents()?.ToArray(); if (distributedEvents != null && distributedEvents.Any()) { foreach (var distributedEvent in distributedEvents) { await DistributedEventBus.PublishAsync(distributedEvent.GetType(), distributedEvent); } generatesDomainEventsEntity.ClearDistributedEvents(); } }
public async Task <bool> ValidateConsensusBeforeExecutionAsync(ChainContext chainContext, byte[] consensusExtraData) { var now = TimestampHelper.GetUtcNow(); _blockTimeProvider.SetBlockTime(now); Logger.LogTrace($"Set block time to utc now: {now.ToDateTime():hh:mm:ss.ffffff}. Validate Before."); var validationResult = await _readerFactory.Create(chainContext).ValidateConsensusBeforeExecution .CallAsync(new BytesValue { Value = ByteString.CopyFrom(consensusExtraData) }); if (validationResult == null) { Logger.LogWarning("Validation of consensus failed before execution."); return(false); } if (!validationResult.Success) { Logger.LogWarning($"Consensus validating before execution failed: {validationResult.Message}"); await LocalEventBus.PublishAsync(new ConsensusValidationFailedEventData { ValidationResultMessage = validationResult.Message }); } return(validationResult.Success); }
private async Task PublishEventAsync(int currentStep, string message) { await LocalEventBus.PublishAsync(new ModuleInstallingProgressEvent { CurrentStep = currentStep, Message = message }, false); }
public async Task ProcessBlockExecutionResultAsync(Chain chain, BlockExecutionResult blockExecutionResult) { if (blockExecutionResult.ExecutedFailedBlocks.Any() || blockExecutionResult.SuccessBlockExecutedSets.Count == 0 || blockExecutionResult.SuccessBlockExecutedSets.Last().Height < chain.BestChainHeight) { await SetBlockExecutionStatusAsync(blockExecutionResult.ExecutedFailedBlocks.Select(b => b.GetHash()), ChainBlockLinkExecutionStatus.ExecutionFailed); await _blockchainService.RemoveLongestBranchAsync(chain); Logger.LogDebug("No block executed successfully or no block is higher than best chain."); return; } var lastExecutedSuccessBlock = blockExecutionResult.SuccessBlockExecutedSets.Last(); await _blockchainService.SetBestChainAsync(chain, lastExecutedSuccessBlock.Height, lastExecutedSuccessBlock.GetHash()); await SetBlockExecutionStatusAsync(blockExecutionResult.SuccessBlockExecutedSets.Select(b => b.GetHash()), ChainBlockLinkExecutionStatus.ExecutionSuccess); await LocalEventBus.PublishAsync(new BlocksExecutionSucceededEvent { BlockExecutedSets = blockExecutionResult.SuccessBlockExecutedSets }); Logger.LogInformation( $"Attach blocks to best chain, best chain hash: {chain.BestChainHash}, height: {chain.BestChainHeight}"); }
public async Task <bool> ValidateBlockAfterExecuteAsync(IBlock block) { if (block.Header.Height == Constants.GenesisBlockHeight) { return(true); } var isParentChainBlockDataIndexed = _indexedCrossChainBlockDataDiscoveryService.TryDiscoverIndexedParentChainBlockDataAsync(block); Logger.LogTrace($"Try discovery indexed parent chain block data: {isParentChainBlockDataIndexed}"); var isSideChainBlockDataIndexed = _indexedCrossChainBlockDataDiscoveryService.TryDiscoverIndexedSideChainBlockDataAsync(block); Logger.LogTrace($"Try discovery indexed side chain block data: {isSideChainBlockDataIndexed}"); var extraData = ExtractCrossChainExtraData(block.Header); try { if (isSideChainBlockDataIndexed ^ (extraData != null)) { // cross chain extra data in block header should be null if no side chain block data indexed in contract return(false); } if (!isParentChainBlockDataIndexed && !isSideChainBlockDataIndexed) { return(true); } var indexedCrossChainBlockData = await _crossChainIndexingDataService.GetIndexedCrossChainBlockDataAsync(block.Header.GetHash(), block.Header.Height); var res = true; if (isSideChainBlockDataIndexed) { res = ValidateBlockExtraDataAsync(indexedCrossChainBlockData, extraData); } if (res) { res = await ValidateCrossChainBlockDataAsync(indexedCrossChainBlockData, block.Header.PreviousBlockHash, block.Header.Height - 1); } return(res); } catch (ValidateNextTimeBlockValidationException ex) { throw new BlockValidationException( $"Cross chain data is not ready at height: {block.Header.Height}, hash: {block.GetHash()}.", ex); } finally { await LocalEventBus.PublishAsync(new CrossChainDataValidatedEvent()); } }
public async Task PubAndUnSub() { int count = 0; var mq = new LocalEventBus(CreateLogger <LocalEventBus>()); mq.Subscribe("topic", msg => { Interlocked.Increment(ref count); }); int i = 0; Task.Factory.StartNew(async() => { for (; i < 50; ++i) { await mq.PublishAsync("topic", "a"); await Task.Delay(100); } }).ConfigureAwait(false).GetAwaiter(); await Task.Delay(1500); mq.Unsubscribe("topic"); while (i < 50) { await Task.Delay(100); } Assert.True(count < 100); }
public async Task SetIrreversibleBlockAsync(Chain chain, long irreversibleBlockHeight, Hash irreversibleBlockHash) { // Create before IChainManager.SetIrreversibleBlockAsync so that we can correctly get the previous LIB info var eventDataToPublish = new NewIrreversibleBlockFoundEvent() { PreviousIrreversibleBlockHash = chain.LastIrreversibleBlockHash, PreviousIrreversibleBlockHeight = chain.LastIrreversibleBlockHeight, BlockHash = irreversibleBlockHash, BlockHeight = irreversibleBlockHeight }; var success = await _chainManager.SetIrreversibleBlockAsync(chain, irreversibleBlockHash); if (!success) { return; } // TODO: move to background job, it will slow down our system // Clean last branches and not linked var toCleanBlocks = await _chainManager.CleanBranchesAsync(chain, eventDataToPublish.PreviousIrreversibleBlockHash, eventDataToPublish.PreviousIrreversibleBlockHeight); await RemoveBlocksAsync(toCleanBlocks); await LocalEventBus.PublishAsync(eventDataToPublish); }
public async Task Should_Not_Call_Action_After_Unregister_2() { var totalData = 0; var action = new Func <MySimpleEventData, Task>( eventData => { totalData += eventData.Value; return(Task.CompletedTask); }); LocalEventBus.Subscribe(action); await LocalEventBus.PublishAsync(new MySimpleEventData(1)); await LocalEventBus.PublishAsync(new MySimpleEventData(2)); await LocalEventBus.PublishAsync(new MySimpleEventData(3)); LocalEventBus.Unsubscribe(action); await LocalEventBus.PublishAsync(new MySimpleEventData(4)); Assert.Equal(6, totalData); }
/// <summary> /// Download and attach blocks /// UseSuggestedPeer == true: Download blocks from suggested peer directly; /// Target download height > peer lib height, download blocks from suggested peer; /// Target download height <= peer lib height, select a random peer to download. /// </summary> /// <param name="downloadBlockDto"></param> /// <returns></returns> public async Task <DownloadBlocksResult> DownloadBlocksAsync(DownloadBlockDto downloadBlockDto) { var downloadResult = new DownloadBlocksResult(); var peerPubkey = downloadBlockDto.SuggestedPeerPubkey; try { if (UseSuggestedPeer(downloadBlockDto)) { downloadResult = await DownloadBlocksAsync(peerPubkey, downloadBlockDto); } else { // If cannot get the blocks, there should be network problems or bad peer, // because we have selected peer with lib height greater than or equal to the target height. // 1. network problems, need to retry from other peer. // 2. not network problems, this peer or the last peer is bad peer, we need to remove it. var downloadTargetHeight = downloadBlockDto.PreviousBlockHeight + downloadBlockDto.MaxBlockDownloadCount; var exceptedPeers = new List <string> { _blockSyncStateProvider.LastRequestPeerPubkey }; var retryTimes = 2; while (true) { peerPubkey = GetRandomPeerPubkey(downloadBlockDto.SuggestedPeerPubkey, downloadTargetHeight, exceptedPeers); downloadResult = await DownloadBlocksAsync(peerPubkey, downloadBlockDto); if (downloadResult.Success || retryTimes <= 0) { break; } exceptedPeers.Add(peerPubkey); retryTimes--; } if (downloadResult.Success && downloadResult.DownloadBlockCount == 0) { await CheckBadPeerAsync(peerPubkey, downloadBlockDto.PreviousBlockHash, downloadBlockDto.PreviousBlockHeight); } } } catch (BlockDownloadException e) { await LocalEventBus.PublishAsync(new BadPeerFoundEventData { BlockHash = e.BlockHash, BlockHeight = e.BlockHeight, PeerPubkey = e.PeerPubkey }); } return(downloadResult); }
public virtual async Task <NoContentResult> OnPostRefreshConfigurationAsync() { await LocalEventBus.PublishAsync( new CurrentApplicationConfigurationCacheResetEventData() ); return(NoContent()); }
private async Task <string[]> PublishTransactionsAsync(string[] rawTransactions) { var txIds = new string[rawTransactions.Length]; var transactions = new List <Transaction>(); for (var i = 0; i < rawTransactions.Length; i++) { Transaction transaction; try { var hexString = ByteArrayHelper.HexStringToByteArray(rawTransactions[i]); transaction = Transaction.Parser.ParseFrom(hexString); } catch { throw new UserFriendlyException(Error.Message[Error.InvalidTransaction], Error.InvalidTransaction.ToString()); } if (!IsValidMessage(transaction)) { throw new UserFriendlyException(Error.Message[Error.InvalidTransaction], Error.InvalidTransaction.ToString()); } var contractMethodDescriptor = await GetContractMethodDescriptorAsync(transaction.To, transaction.MethodName); if (contractMethodDescriptor == null) { throw new UserFriendlyException(Error.Message[Error.NoMatchMethodInContractAddress], Error.NoMatchMethodInContractAddress.ToString()); } var parameters = contractMethodDescriptor.InputType.Parser.ParseFrom(transaction.Params); if (!IsValidMessage(parameters)) { throw new UserFriendlyException(Error.Message[Error.InvalidParams], Error.InvalidParams.ToString()); } if (!transaction.VerifySignature()) { throw new UserFriendlyException(Error.Message[Error.InvalidTransaction], Error.InvalidTransaction.ToString()); } transactions.Add(transaction); txIds[i] = transaction.GetHash().ToHex(); } await LocalEventBus.PublishAsync(new TransactionsReceivedEvent() { Transactions = transactions }); return(txIds); }
private async Task PublishBestChainFoundEventAsync(Chain chain, List <Block> successBlocks) { await LocalEventBus.PublishAsync(new BestChainFoundEventData { BlockHash = chain.BestChainHash, BlockHeight = chain.BestChainHeight, ExecutedBlocks = successBlocks }); }
private Task PublishCrossChainRequestReceivedEvent(string host, int port, int chainId) { return(LocalEventBus.PublishAsync(new NewChainConnectionEvent { RemoteServerHost = host, RemoteServerPort = port, RemoteChainId = chainId })); }
public async Task SetBestChainAsync(Chain chain, long bestChainHeight, Hash bestChainHash) { await _chainManager.SetBestChainAsync(chain, bestChainHeight, bestChainHash); await LocalEventBus.PublishAsync(new BestChainFoundEventData { BlockHash = bestChainHash, BlockHeight = bestChainHeight }); }
public void NewEvent(long countingMilliseconds, ConsensusRequestMiningEventData consensusRequestMiningEventData) { JobManager.UseUtcTime(); var registry = new Registry(); registry.Schedule(() => LocalEventBus.PublishAsync(consensusRequestMiningEventData)) .ToRunOnceAt(TimestampHelper.GetUtcNow().AddMilliseconds(countingMilliseconds).ToDateTime()); JobManager.Initialize(registry); }
public async Task Should_Throw_Single_Exception_If_Only_One_Of_Handlers_Fails() { LocalEventBus.Subscribe <MySimpleEventData>(eventData => throw new Exception("This exception is intentionally thrown!")); var appException = await Assert.ThrowsAsync <Exception>(async() => { await LocalEventBus.PublishAsync(new MySimpleEventData(1)); }); appException.Message.ShouldBe("This exception is intentionally thrown!"); }
public async Task Should_Change_TenantId_If_EventData_Is_MultiTenant() { var tenantId = Guid.NewGuid(); var handler = new MyEventHandler(GetRequiredService <ICurrentTenant>()); LocalEventBus.Subscribe <EntityChangedEventData <MyEntity> >(handler); await LocalEventBus.PublishAsync(new EntityCreatedEventData <MyEntity>(new MyEntity(tenantId))); handler.TenantId.ShouldBe(tenantId); }
public async Task Should_Automatically_Register_EventHandlers_From_Services() { await LocalEventBus.PublishAsync(new MySimpleEventData(1)); await LocalEventBus.PublishAsync(new MySimpleEventData(2)); await LocalEventBus.PublishAsync(new MySimpleEventData(3)); await LocalEventBus.PublishAsync(new MySimpleEventData(4)); GetRequiredService <MySimpleEventDataHandler>().TotalData.ShouldBe(10); }
public async Task Should_Call_Created_And_Changed_Once() { var handler = new MyEventHandler(); LocalEventBus.Subscribe <EntityChangedEventData <MyEntity> >(handler); LocalEventBus.Subscribe <EntityCreatedEventData <MyEntity> >(handler); await LocalEventBus.PublishAsync(new EntityCreatedEventData <MyEntity>(new MyEntity())); handler.EntityCreatedEventCount.ShouldBe(1); handler.EntityChangedEventCount.ShouldBe(1); }
public async Task Should_Call_Handler_AndDispose() { LocalEventBus.Subscribe <MySimpleEventData, MySimpleTransientEventHandler>(); await LocalEventBus.PublishAsync(new MySimpleEventData(1)); await LocalEventBus.PublishAsync(new MySimpleEventData(2)); await LocalEventBus.PublishAsync(new MySimpleEventData(3)); Assert.Equal(3, MySimpleTransientEventHandler.HandleCount); Assert.Equal(3, MySimpleTransientEventHandler.DisposeCount); }
public async Task <bool> ValidateTransactionAsync(Transaction transaction, IChainContext chainContext = null) { var isView = await _transactionReadOnlyExecutionService.IsViewTransactionAsync(chainContext, transaction); if (isView) { await LocalEventBus.PublishAsync(new TransactionValidationStatusChangedEvent { TransactionId = transaction.GetHash(), TransactionResultStatus = TransactionResultStatus.NodeValidationFailed, Error = "View transaction is not allowed." }); } return(!isView); }
public async Task Should_Trigger_For_Inherited_Generic_2() { var triggeredEvent = false; LocalEventBus.Subscribe <EntityChangedEventData <Person> >( eventData => { eventData.Entity.Id.ShouldBe(42); triggeredEvent = true; return(Task.CompletedTask); }); await LocalEventBus.PublishAsync(new EntityChangedEventData <Student>(new Student(42))); triggeredEvent.ShouldBe(true); }
public async Task Should_Throw_Aggregate_Exception_If_More_Than_One_Of_Handlers_Fail() { LocalEventBus.Subscribe <MySimpleEventData>( eventData => throw new Exception("This exception is intentionally thrown #1!")); LocalEventBus.Subscribe <MySimpleEventData>( eventData => throw new Exception("This exception is intentionally thrown #2!")); var aggrException = await Assert.ThrowsAsync <AggregateException>(async() => { await LocalEventBus.PublishAsync(new MySimpleEventData(1)); }); aggrException.InnerExceptions.Count.ShouldBe(2); aggrException.InnerExceptions[0].Message.ShouldBe("This exception is intentionally thrown #1!"); aggrException.InnerExceptions[1].Message.ShouldBe("This exception is intentionally thrown #2!"); }
public async Task <bool> ValidateBlockAfterExecuteAsync(IBlock block) { if (block.Header.Height == AElfConstants.GenesisBlockHeight) { return(true); } try { var isSideChainBlockDataIndexed = TryDiscoverIndexedSideChainBlockData(block); Logger.LogDebug($"Try discovery indexed side chain block data: {isSideChainBlockDataIndexed}"); var extraData = ExtractCrossChainExtraData(block.Header); var validationResult = true; if (!isSideChainBlockDataIndexed && !extraData.IsNullOrEmpty()) { // cross chain extra data in block header should be null if no side chain block data indexed in contract validationResult = false; } else if (isSideChainBlockDataIndexed) { var indexedCrossChainBlockData = await _crossChainIndexingDataService.GetIndexedCrossChainBlockDataAsync(block.Header.GetHash(), block.Header.Height); if (indexedCrossChainBlockData.IsNullOrEmpty() ^ extraData.IsNullOrEmpty()) { validationResult = false; } else if (!indexedCrossChainBlockData.IsNullOrEmpty()) { validationResult = ValidateBlockExtraDataAsync(indexedCrossChainBlockData, extraData); } } if (!validationResult) { Logger.LogWarning( $"Invalid cross chain extra data, block height {block.Header.Height}, hash {block.GetHash()}."); } return(validationResult); } finally { await LocalEventBus.PublishAsync(new CrossChainDataValidatedEvent()); } }
protected override async Task <TransactionTrace> ExecuteOneAsync(SingleTransactionExecutingDto singleTxExecutingDto, CancellationToken cancellationToken) { TransactionTrace trace = null; try { trace = await base.ExecuteOneAsync(singleTxExecutingDto, cancellationToken); } finally { await LocalEventBus.PublishAsync(new TransactionExecutedEventData { TransactionTrace = trace }); } return(trace); }
private async Task SetBestChainAsync(List <ChainBlockLink> successLinks, Chain chain) { if (successLinks.Count == 0) { return; } Logger.LogTrace($"Set best chain for block height {string.Join(",", successLinks.Select(l => l.Height))}"); var blockLink = successLinks.Last(); await _blockchainService.SetBestChainAsync(chain, blockLink.Height, blockLink.BlockHash); await LocalEventBus.PublishAsync(new BestChainFoundEventData { BlockHash = chain.BestChainHash, BlockHeight = chain.BestChainHeight, ExecutedBlocks = successLinks.Select(p => p.BlockHash).ToList() }); }
public async Task Should_Call_Handler_With_Non_Generic_Trigger() { var totalData = 0; LocalEventBus.Subscribe <MySimpleEventData>( eventData => { totalData += eventData.Value; return(Task.CompletedTask); }); await LocalEventBus.PublishAsync(typeof(MySimpleEventData), new MySimpleEventData(1)); await LocalEventBus.PublishAsync(typeof(MySimpleEventData), new MySimpleEventData(2)); await LocalEventBus.PublishAsync(typeof(MySimpleEventData), new MySimpleEventData(3)); await LocalEventBus.PublishAsync(typeof(MySimpleEventData), new MySimpleEventData(4)); Assert.Equal(10, totalData); }
public async Task Should_Not_Handle_Events_For_Base_Classes() { var totalData = 0; LocalEventBus.Subscribe <MyDerivedEventData>( eventData => { totalData += eventData.Value; return(Task.CompletedTask); }); await LocalEventBus.PublishAsync(new MySimpleEventData(1)); //Should not handle await LocalEventBus.PublishAsync(new MySimpleEventData(2)); //Should not handle await LocalEventBus.PublishAsync(new MyDerivedEventData(3)); //Should handle await LocalEventBus.PublishAsync(new MyDerivedEventData(4)); //Should handle Assert.Equal(7, totalData); }
public async Task Should_Handle_Events_For_Derived_Classes() { var totalData = 0; LocalEventBus.Subscribe <MySimpleEventData>( eventData => { totalData += eventData.Value; return(Task.CompletedTask); }); await LocalEventBus.PublishAsync(new MySimpleEventData(1)); //Should handle directly registered class await LocalEventBus.PublishAsync(new MySimpleEventData(2)); //Should handle directly registered class await LocalEventBus.PublishAsync(new MyDerivedEventData(3)); //Should handle derived class too await LocalEventBus.PublishAsync(new MyDerivedEventData(4)); //Should handle derived class too Assert.Equal(10, totalData); }