Example #1
0
 protected virtual async Task TriggerLocalEvents(List <DomainEventEntry> localEvents)
 {
     foreach (var localEvent in localEvents)
     {
         await LocalEventBus.PublishAsync(localEvent.EventData.GetType(), localEvent.EventData);
     }
 }
Example #2
0
        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();
            }
        }
Example #3
0
        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);
        }
Example #4
0
 private async Task PublishEventAsync(int currentStep, string message)
 {
     await LocalEventBus.PublishAsync(new ModuleInstallingProgressEvent {
         CurrentStep = currentStep,
         Message     = message
     }, false);
 }
Example #5
0
        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}");
        }
Example #6
0
        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);
        }
Example #8
0
        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);
        }
Example #9
0
    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);
    }
Example #10
0
        /// <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);
        }
Example #11
0
        public virtual async Task <NoContentResult> OnPostRefreshConfigurationAsync()
        {
            await LocalEventBus.PublishAsync(
                new CurrentApplicationConfigurationCacheResetEventData()
                );

            return(NoContent());
        }
Example #12
0
        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
     });
 }
Example #14
0
 private Task PublishCrossChainRequestReceivedEvent(string host, int port, int chainId)
 {
     return(LocalEventBus.PublishAsync(new NewChainConnectionEvent
     {
         RemoteServerHost = host,
         RemoteServerPort = port,
         RemoteChainId = chainId
     }));
 }
Example #15
0
        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
            });
        }
Example #16
0
        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);
        }
Example #17
0
    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);
    }
Example #19
0
    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);
    }
Example #20
0
    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);
    }
Example #21
0
    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);
        }
Example #23
0
    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);
    }
Example #24
0
    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());
            }
        }
Example #26
0
        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);
        }
Example #27
0
        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()
            });
        }
Example #28
0
    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);
    }
Example #29
0
    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);
    }
Example #30
0
    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);
    }