public async Task <long> GetUnacceptableDistanceToLastIrreversibleBlockHeightAsync(Hash blockHash) { PrepareBloomForIrreversibleBlockHeightUnacceptable(); var block = await _blockchainService.GetBlockByHashAsync(blockHash); if (_bloomOfLibUnacceptable.IsIn(new Bloom(block.Header.Bloom.ToByteArray()))) { foreach (var transactionId in block.Body.TransactionIds) { var result = await _transactionResultQueryService.GetTransactionResultAsync(transactionId); if (result == null) { Logger.LogTrace($"Transaction result is null, transactionId: {transactionId}"); continue; } if (result.Status == TransactionResultStatus.Failed) { Logger.LogTrace( $"Transaction failed, transactionId: {transactionId}, error: {result.Error}"); continue; } if (result.Bloom.Length == 0 || !_bloomOfLibUnacceptable.IsIn(new Bloom(result.Bloom.ToByteArray()))) { continue; } foreach (var log in result.Logs) { if (log.Address != _contractAddress || log.Name != _logEventOfLibUnacceptable.Name) { continue; } var message = new IrreversibleBlockHeightUnacceptable(); message.MergeFrom(log); Logger.LogTrace( $"IrreversibleBlockHeightUnacceptable detected: {message}"); return(message.DistanceToIrreversibleBlockHeight); } } } return(0); }
public async Task ProcessAsync_Test() { var chain = await _smartContractExecutionHelper.CreateChainAsync(); var block = await _blockchainService.GetBlockByHashAsync(chain.BestChainHash); var tasks = block.Body.TransactionIds .Select(t => _transactionResultQueryService.GetTransactionResultAsync(t)).ToList(); var transactionResultList = await Task.WhenAll(tasks); await ProcessTransactionResultsAsync(transactionResultList, block); var 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 _smartContractExecutionHelper.ExecuteTransactionAsync(transaction); await ProcessTransactionResultsAsync(blockExecutedSet.TransactionResultMap.Values.ToArray(), blockExecutedSet.Block); await ProcessCodeUpdateAsync(chain); }
public async Task ApplyAsync(IEnumerable <Block> blocks) { Logger.LogTrace("Apply log event handler."); foreach (var block in blocks) { var blockBloom = new Bloom(block.Header.Bloom.ToByteArray()); if (!Blooms.Values.Any(b => b.IsIn(blockBloom))) { // No interested event in the block continue; } foreach (var transactionId in block.Body.TransactionIds) { var result = await _transactionResultQueryService.GetTransactionResultAsync(transactionId, block.GetHash()); if (result == null) { continue; } if (result.Status == TransactionResultStatus.Failed) { continue; } if (result.Bloom.Length == 0) { continue; } var resultBloom = new Bloom(result.Bloom.ToByteArray()); foreach (var handler in _eventHandlers) { var interestedEvent = handler.InterestedEvent; var interestedBloom = Blooms[interestedEvent]; if (!interestedBloom.IsIn(resultBloom)) { // Interested bloom is not found in the transaction result continue; } // Interested bloom is found in the transaction result, // find the log that yields the bloom and apply the handler foreach (var log in result.Logs) { if (log.Address != interestedEvent.Address || log.Name != interestedEvent.Name) { continue; } await handler.HandleAsync(block, result, log); } } } } Logger.LogTrace("Finish apply log event handler."); }
private async Task <TransactionResult> GetTransactionResult(Hash txHash) { // in storage var res = await _transactionResultQueryService.GetTransactionResultAsync(txHash); if (res != null) { return(res); } // in tx pool var receipt = await _txHub.GetTransactionReceiptAsync(txHash); if (receipt != null) { return(new TransactionResult { TransactionId = receipt.TransactionId, Status = TransactionResultStatus.Pending }); } // not existed return(new TransactionResult { TransactionId = txHash, Status = TransactionResultStatus.NotExisted }); }
public async Task <IEnumerable <T> > GetEventMessagesAsync(Hash blockHash, Address contractAddress) { try { PrepareBloom(contractAddress); var block = await _blockchainService.GetBlockByHashAsync(blockHash); var messages = new List <T>(); if (!_bloom.IsIn(new Bloom(block.Header.Bloom.ToByteArray()))) { return(messages); } foreach (var transactionId in block.Body.TransactionIds) { var transactionExecutingResult = await _transactionResultQueryService.GetTransactionResultAsync(transactionId); if (!CheckTransactionExecutingResult(transactionExecutingResult, transactionId)) { continue; } foreach (var log in transactionExecutingResult.Logs) { if (contractAddress == null || log.Address != contractAddress || log.Name != _logEvent.Name) { continue; } var message = new T(); try { message.MergeFrom(log); messages.Add(message); } catch (Exception e) { Logger.LogError($"Failed to generate message of type {message.GetType().FullName}. {e}"); throw; } } } Logger.LogTrace($"Event of type {typeof(T).FullName} found."); return(messages); } catch (Exception) { Logger.LogError($"Failed to resolve event {typeof(T).FullName}"); throw; } }
public async Task GetExecutive_With_GenesisContract_Test() { var chain = await _smartContractHelper.CreateChainWithGenesisContractAsync(); var chainContext = new ChainContext { BlockHash = chain.BestChainHash, BlockHeight = chain.BestChainHeight }; //Get executive of genesis contract by smartContractRegistration in genesis contract and blockHeight=1 var executive = await _smartContractExecutiveService .GetExecutiveAsync(chainContext, _defaultContractZeroCodeProvider.ContractZeroAddress); executive.ContractHash.ShouldBe(_defaultContractZeroCodeProvider.DefaultContractZeroRegistration.CodeHash); var transaction = _smartContractHelper.BuildDeploySystemSmartContractTransaction( ConfigurationSmartContractAddressNameProvider.Name, _smartContractHelper.Codes["AElf.Contracts.Configuration"]); var block = await _smartContractHelper.GenerateBlockAsync(chain.BestChainHeight, chain.BestChainHash, new List <Transaction> { transaction }); await _smartContractHelper.MineBlockAsync(block); chainContext = new ChainContext { BlockHash = block.GetHash(), BlockHeight = block.Height }; var transactionResult = await _transactionResultQueryService.GetTransactionResultAsync(transaction.GetHash(), block.GetHash()); var contractDeployed = new ContractDeployed(); contractDeployed.MergeFrom(transactionResult.Logs.First(l => l.Name == nameof(ContractDeployed))); //Get executive of configuration contract in genesis contract executive = await _smartContractExecutiveService.GetExecutiveAsync(chainContext, contractDeployed.Address); executive.ContractHash.ShouldBe( HashHelper.ComputeFrom(_smartContractHelper.Codes["AElf.Contracts.Configuration"])); //Get executive of genesis contract by smartContractRegistration in genesis contract and blockHeight=2 executive = await _smartContractExecutiveService .GetExecutiveAsync(chainContext, _defaultContractZeroCodeProvider.ContractZeroAddress); executive.ContractHash.ShouldBe(_defaultContractZeroCodeProvider.DefaultContractZeroRegistration.CodeHash); }
public async Task <IBlockIndex> DiscoverAndSetIrreversibleAsync(Chain chain, IEnumerable <Hash> blockIdsInOrder) { PrepareBloom(); var reverse = blockIdsInOrder.Reverse(); foreach (var blockId in reverse) { var block = await _blockchainService.GetBlockByHashAsync(blockId); Logger.LogTrace($"Check event for block {blockId} - {block.Height}"); if (!_bloom.IsIn(new Bloom(block.Header.Bloom.ToByteArray()))) { // No interested event in the block continue; } foreach (var transactionId in block.Body.TransactionIds) { var result = await _transactionResultQueryService.GetTransactionResultAsync(transactionId); if (result == null) { Logger.LogTrace($"Transaction result is null, transactionId: {transactionId}"); continue; } if (result.Status == TransactionResultStatus.Failed) { Logger.LogTrace( $"Transaction failed, transactionId: {transactionId}, error: {result.Error}"); continue; } if (result.Bloom.Length == 0 || !_bloom.IsIn(new Bloom(result.Bloom.ToByteArray()))) { continue; } foreach (var log in result.Logs) { if (log.Address != _contractAddress || log.Name != _logEvent.Name) { continue; } var message = new IrreversibleBlockFound(); message.MergeFrom(log); //var offset = message.Offset; //var libHeight = block.Height - offset; var libHeight = message.IrreversibleBlockHeight; if (chain.LastIrreversibleBlockHeight >= libHeight) { return(null); } var libBlock = await _blockchainService.GetBlockHashByHeightAsync(chain, libHeight, blockId); return(new BlockIndex(libBlock, libHeight)); } } } return(null); }
public async Task <string> GetPrimaryTokenSymbol() { PrepareBloom(); var blockHeader = await _blockchainService.GetBestChainLastBlockHeaderAsync(); if (blockHeader.Height != Constants.GenesisBlockHeight) { return(null); } var block = await _blockchainService.GetBlockByHashAsync(blockHeader.GetHash()); if (!_bloom.IsIn(new Bloom(block.Header.Bloom.ToByteArray()))) { // No interested event in the block return(null); } Logger.LogTrace("ChainPrimaryTokenSymbolSet event received."); foreach (var transactionId in block.Body.TransactionIds) { var result = await _transactionResultQueryService.GetTransactionResultAsync(transactionId); if (result == null) { Logger.LogTrace($"Transaction result is null, transactionId: {transactionId}"); continue; } if (result.Status == TransactionResultStatus.Failed) { Logger.LogTrace( $"Transaction failed, transactionId: {transactionId}, error: {result.Error}"); continue; } if (result.Bloom.Length == 0 || !_bloom.IsIn(new Bloom(result.Bloom.ToByteArray()))) { continue; } foreach (var log in result.Logs) { if (log.Address != _contractAddress || log.Name != _logEvent.Name) { continue; } var message = new ChainPrimaryTokenSymbolSet(); message.MergeFrom(log); Logger.LogTrace($"Chain primary token symbol: {message.TokenSymbol}"); return(message.TokenSymbol); } } return(null); }
public async Task <List <Address> > GetDeployedContractAddresses(Chain chain, IEnumerable <Hash> blockIdsInOrder) { PrepareBloom(); var addresses = new List <Address>(); foreach (var blockId in blockIdsInOrder) { var block = await _blockchainService.GetBlockByHashAsync(blockId); Logger.LogTrace($"Check event for block {blockId} - {block.Height}"); if (!_bloom.IsIn(new Bloom(block.Header.Bloom.ToByteArray()))) { // No interested event in the block continue; } Logger.LogTrace("ContractDeployed event received."); foreach (var transactionId in block.Body.TransactionIds) { var result = await _transactionResultQueryService.GetTransactionResultAsync(transactionId); if (result == null) { Logger.LogTrace($"Transaction result is null, transactionId: {transactionId}"); continue; } if (result.Status == TransactionResultStatus.Failed) { Logger.LogTrace( $"Transaction failed, transactionId: {transactionId}, error: {result.Error}"); continue; } if (result.Bloom.Length == 0 || !_bloom.IsIn(new Bloom(result.Bloom.ToByteArray()))) { continue; } foreach (var log in result.Logs) { if (log.Address != _contractAddress || log.Name != _logEvent.Name) { continue; } var message = new ContractDeployed(); message.MergeFrom(log); Logger.LogTrace($"Add {message.Address} to deployed contract address list."); addresses.Add(message.Address); } } } return(addresses); }