private async Task ExecuteInlineTransactions(int depth, Timestamp currentBlockTime,
                                                     ITransactionContext txContext, TieredStateCache internalStateCache,
                                                     IChainContext internalChainContext, CancellationToken cancellationToken)
        {
            var trace = txContext.Trace;

            internalStateCache.Update(txContext.Trace.GetStateSets());
            foreach (var inlineTx in txContext.Trace.InlineTransactions)
            {
                var singleTxExecutingDto = new SingleTransactionExecutingDto
                {
                    Depth            = depth + 1,
                    ChainContext     = internalChainContext,
                    Transaction      = inlineTx,
                    CurrentBlockTime = currentBlockTime,
                    Origin           = txContext.Origin
                };
                var inlineTrace = await ExecuteOneAsync(singleTxExecutingDto, cancellationToken);

                if (inlineTrace == null)
                {
                    break;
                }
                trace.InlineTraces.Add(inlineTrace);
                if (!inlineTrace.IsSuccessful())
                {
                    Logger.LogWarning($"Method name: {inlineTx.MethodName}, {inlineTrace.Error}");
                    // Already failed, no need to execute remaining inline transactions
                    break;
                }

                internalStateCache.Update(inlineTrace.GetStateSets());
            }
        }
        private async Task <SmartContractRegistration> GetSmartContractRegistrationFromZeroAsync(
            IExecutive executiveZero, IChainContext chainContext, Address address)
        {
            var transaction = new Transaction()
            {
                From       = _defaultContractZeroCodeProvider.ContractZeroAddress,
                To         = _defaultContractZeroCodeProvider.ContractZeroAddress,
                MethodName = "GetSmartContractRegistrationByAddress",
                Params     = address.ToByteString()
            };


            var txContext = _transactionContextFactory.Create(transaction, chainContext);

            await executiveZero.ApplyAsync(txContext);

            var returnBytes = txContext.Trace?.ReturnValue;

            if (returnBytes != null && returnBytes != ByteString.Empty)
            {
                return(SmartContractRegistration.Parser.ParseFrom(returnBytes));
            }

            throw new SmartContractFindRegistrationException(
                      $"failed to find registration from zero contract {txContext.Trace.Error}");
        }
Beispiel #3
0
        private async Task ExecuteInlineTransactions(int depth, Timestamp currentBlockTime,
                                                     ITransactionContext txContext, TieredStateCache internalStateCache,
                                                     IChainContext internalChainContext, CancellationToken cancellationToken)
        {
            var trace = txContext.Trace;

            if (txContext.Trace.IsSuccessful() && txContext.Trace.InlineTransactions.Count > 0)
            {
                internalStateCache.Update(txContext.Trace.GetFlattenedWrites()
                                          .Select(x => new KeyValuePair <string, byte[]>(x.Key, x.Value.ToByteArray())));
                foreach (var inlineTx in txContext.Trace.InlineTransactions)
                {
                    var inlineTrace = await ExecuteOneAsync(depth + 1, internalChainContext, inlineTx,
                                                            currentBlockTime, cancellationToken, txContext.Origin);

                    trace.InlineTraces.Add(inlineTrace);
                    if (!inlineTrace.IsSuccessful())
                    {
                        Logger.LogError($"Method name: {inlineTx.MethodName}, {inlineTrace.Error}");
                        // Already failed, no need to execute remaining inline transactions
                        break;
                    }

                    internalStateCache.Update(inlineTrace.GetFlattenedWrites()
                                              .Select(x => new KeyValuePair <string, byte[]>(x.Key, x.Value.ToByteArray())));
                }
            }
        }
Beispiel #4
0
 public TokenContractMethodStubFactory(ITransactionReadOnlyExecutionService transactionReadOnlyExecutionService,
                                       ISmartContractAddressService smartContractAddressService, IChainContext chainContext)
 {
     _transactionReadOnlyExecutionService = transactionReadOnlyExecutionService;
     _smartContractAddressService         = smartContractAddressService;
     _chainContext = chainContext;
 }
 public ITransactionContext Create(Transaction transaction, IChainContext chainContext, Timestamp blockTime = null,
                                   int callDepth = 0)
 {
     return(new TransactionContext
     {
         Trace = new TransactionTrace
         {
             TransactionId = transaction.GetHash()
         },
         Transaction = transaction,
         PreviousBlockHash = chainContext.BlockHash,
         BlockHeight = chainContext.BlockHeight + 1,
         CurrentBlockTime = blockTime ?? TimestampHelper.GetUtcNow(),
         CallDepth = callDepth,
         MaxCallDepth = 64,
         Origin = transaction.From,
         OriginTransactionId = transaction.GetHash(),
         ExecutionObserverThreshold = new ExecutionObserverThreshold
         {
             ExecutionBranchThreshold = SmartContractConstants.ExecutionBranchThreshold,
             ExecutionCallThreshold = SmartContractConstants.ExecutionCallThreshold
         },
         StateCache = chainContext.StateCache
     });
 }
Beispiel #6
0
        public async Task <bool> ValidateTransactionAsync(Transaction transaction, IChainContext chainContext)
        {
            var transactionId = transaction.GetHash();

            if (!transaction.VerifySignature())
            {
                await LocalEventBus.PublishAsync(new TransactionValidationStatusChangedEvent
                {
                    TransactionId           = transactionId,
                    TransactionResultStatus = TransactionResultStatus.NodeValidationFailed,
                    Error = "Incorrect transaction signature."
                });

                return(false);
            }

            if (transaction.CalculateSize() > TransactionPoolConsts.TransactionSizeLimit)
            {
                await LocalEventBus.PublishAsync(new TransactionValidationStatusChangedEvent
                {
                    TransactionId           = transactionId,
                    TransactionResultStatus = TransactionResultStatus.NodeValidationFailed,
                    Error = "Transaction size exceeded."
                });

                return(false);
            }

            return(true);
        }
Beispiel #7
0
        private async Task <bool> ExecutePluginOnPostTransactionStageAsync(IExecutive executive,
                                                                           ITransactionContext txContext,
                                                                           Timestamp currentBlockTime,
                                                                           IChainContext internalChainContext,
                                                                           TieredStateCache internalStateCache,
                                                                           CancellationToken cancellationToken)
        {
            var trace = txContext.Trace;

            foreach (var plugin in _postPlugins)
            {
                var transactions = await plugin.GetPostTransactionsAsync(executive.Descriptors, txContext);

                foreach (var postTx in transactions)
                {
                    var postTrace = await ExecuteOneAsync(0, internalChainContext, postTx, currentBlockTime,
                                                          cancellationToken, isCancellable : false);

                    trace.PostTransactions.Add(postTx);
                    trace.PostTraces.Add(postTrace);
                    if (!postTrace.IsSuccessful())
                    {
                        trace.ExecutionStatus = ExecutionStatus.Postfailed;
                        postTrace.SurfaceUpError();
                        trace.Error += postTrace.Error;
                        return(false);
                    }

                    internalStateCache.Update(postTrace.GetFlattenedWrites()
                                              .Select(x => new KeyValuePair <string, byte[]>(x.Key, x.Value.ToByteArray())));
                }
            }

            return(true);
        }
        private SmartContractRegistrationCache GetSmartContractRegistrationCacheFromForkCache(
            IChainContext chainContext, Address address)
        {
            if (!_smartContractRegistrationCacheProvider.TryGetForkCache(address, out var caches))
            {
                return(null);
            }
            var cacheList = caches.ToList();

            if (cacheList.Count == 0)
            {
                return(null);
            }
            var minHeight   = cacheList.Min(s => s.BlockHeight);
            var blockHashes = cacheList.Select(s => s.BlockHash).ToList();
            var blockHash   = chainContext.BlockHash;
            var blockHeight = chainContext.BlockHeight;

            do
            {
                if (blockHashes.Contains(blockHash))
                {
                    return(cacheList.Last(s => s.BlockHash == blockHash));
                }

                var link = _chainBlockLinkService.GetCachedChainBlockLink(blockHash);
                blockHash = link?.PreviousBlockHash;
                blockHeight--;
            } while (blockHash != null && blockHeight >= minHeight);

            return(null);
        }
        private async Task <SmartContractRegistration> GetSmartContractRegistrationFromZeroAsync(
            IChainContext chainContext, Address address, Hash codeHash)
        {
            IExecutive executiveZero = null;

            try
            {
                if (address == _defaultContractZeroCodeProvider.ContractZeroAddress)
                {
                    executiveZero =
                        await GetExecutiveAsync(_defaultContractZeroCodeProvider.DefaultContractZeroRegistration);
                }
                else
                {
                    executiveZero =
                        await GetHistoryExecutiveAsync(chainContext, _defaultContractZeroCodeProvider.ContractZeroAddress);
                }

                return(await GetSmartContractRegistrationFromZeroAsync(executiveZero, chainContext, codeHash));
            }
            finally
            {
                if (executiveZero != null)
                {
                    await PutExecutiveAsync(_defaultContractZeroCodeProvider.ContractZeroAddress, executiveZero);
                }
            }
        }
        /// <summary>
        /// Schedule execution of transaction
        /// </summary>
        public void Schedule(List <Transaction> transactions, IChainContext chainContext)
        {
            // reset
            _pending      = new Dictionary <Address, List <Transaction> >();
            ExecutingPlan = new Dictionary <int, List <Transaction> >();
            _graph        = new UndirectedGraph <Transaction, Edge <Transaction> >(false);

            foreach (var tx in transactions)
            {
                var conflicts = new List <Address> {
                    tx.From, tx.To
                };
                _graph.AddVertex(tx);
                foreach (var res in conflicts)
                {
                    if (!_pending.ContainsKey(res))
                    {
                        _pending[res] = new List <Transaction>();
                    }
                    foreach (var t in _pending[res])
                    {
                        _graph.AddEdge(new Edge <Transaction>(t, tx));
                    }
                    _pending[res].Add(tx);
                }
            }
            ColorGraph(transactions, chainContext);
        }
Beispiel #11
0
        public async Task <int> GetLimitAsync(IChainContext chainContext)
        {
            var keys = _forkCache.Keys.ToArray();

            if (keys.Length == 0)
            {
                return(await GetLimitAsync());
            }
            var minHeight  = keys.Select(k => k.BlockHeight).Min();
            int?limit      = null;
            var blockIndex = new BlockIndex
            {
                BlockHash   = chainContext.BlockHash,
                BlockHeight = chainContext.BlockHeight
            };

            do
            {
                if (_forkCache.TryGetValue(blockIndex, out var value))
                {
                    limit = value;
                    break;
                }

                var link = _chainBlockLinkService.GetCachedChainBlockLink(blockIndex.BlockHash);
                blockIndex.BlockHash = link?.PreviousBlockHash;
                blockIndex.BlockHeight--;
            } while (blockIndex.BlockHash != null && blockIndex.BlockHeight >= minHeight);

            return(limit ?? await GetLimitAsync());
        }
        public Task <TotalResourceTokensMaps> GetTotalResourceTokensMapsAsync(IChainContext chainContext)
        {
            var totalTxFeesMap = GetBlockExecutedData(chainContext);

            Logger.LogDebug($"Get TotalResourceTokensMaps: {totalTxFeesMap}");
            return(Task.FromResult(totalTxFeesMap));
        }
Beispiel #13
0
        public Task <BlockValidationResult> ValidateBlockAsync(IBlock block, IChainContext context)
        {
            if (block?.Header == null || block.Body == null)
            {
                return(Task.FromResult(BlockValidationResult.BlockIsNull));
            }

            if (block.Body.TransactionsCount == 0)
            {
                return(Task.FromResult(BlockValidationResult.NoTransaction));
            }

            if (block.Body.CalculateMerkleTreeRoots() != block.Header.MerkleTreeRootOfTransactions)
            {
                return(Task.FromResult(BlockValidationResult.IncorrectTxMerkleTreeRoot));
            }

            if (block.Body.SideChainTransactionsRoot != block.Header.SideChainTransactionsRoot ||
                block.Body.SideChainBlockHeadersRoot != block.Header.SideChainBlockHeadersRoot)
            {
                return(Task.FromResult(BlockValidationResult.IncorrectSideChainInfo));
            }

            return(Task.FromResult(BlockValidationResult.Success));
        }
Beispiel #14
0
        private static TransactionContext GetTransactionContext(IChainContext chainContext, Address to,
                                                                ByteString param, out TransactionTrace trace)
        {
            var generatedTxn = new Transaction
            {
                From       = FromAddress,
                To         = to,
                MethodName = nameof(ACS2BaseContainer.ACS2BaseStub.GetResourceInfo),
                Params     = param,
                Signature  = ByteString.CopyFromUtf8(KernelConstants.SignaturePlaceholder)
            };

            trace = new TransactionTrace
            {
                TransactionId = generatedTxn.GetHash()
            };

            return(new TransactionContext
            {
                PreviousBlockHash = chainContext.BlockHash,
                CurrentBlockTime = TimestampHelper.GetUtcNow(),
                Transaction = generatedTxn,
                BlockHeight = chainContext.BlockHeight + 1,
                Trace = trace,
                CallDepth = 0,
                StateCache = chainContext.StateCache
            });
        }
Beispiel #15
0
        public CodeRemark GetCodeRemark(IChainContext chainContext, Address address)
        {
            var blockHash   = chainContext.BlockHash;
            var blockHeight = chainContext.BlockHeight;

            if (_forkCache.TryGetValue(address, out var codeRemarks))
            {
                var blockHashes = codeRemarks.Select(c => c.BlockHash).ToList();
                var minHeight   = codeRemarks.Select(s => s.BlockHeight).Min();
                do
                {
                    if (blockHashes.Contains(blockHash))
                    {
                        return(codeRemarks.First(c => c.BlockHash == blockHash));
                    }

                    var block = _chainBlockLinkCacheProvider.GetChainBlockLink(blockHash);
                    blockHash = block?.PreviousBlockHash;
                    blockHeight--;
                } while (blockHash != null && blockHeight >= minHeight);
            }

            _cache.TryGetValue(address, out var codeRemark);
            return(codeRemark);
        }
Beispiel #16
0
        public async Task <BlockValidationResult> ValidateBlockAsync(IBlock block, IChainContext context)
        {
            if (_doingRollback)
            {
                _logger?.Trace("Could not validate block during rollbacking!");
                return(BlockValidationResult.DoingRollback);
            }

            MessageHub.Instance.Publish(new ValidationStateChanged(block.BlockHashToHex, block.Index, true,
                                                                   BlockValidationResult.Success));

            var resultCollection = new List <BlockValidationResult>();

            foreach (var filter in _filters)
            {
                var result = await filter.ValidateBlockAsync(block, context);

                if (result != BlockValidationResult.Success)
                {
                    _logger?.Warn($"Result of {filter.GetType().Name}: {result} - {block.BlockHashToHex}");
                }
                resultCollection.Add(result);
            }

            var finalResult = resultCollection.Max();

            MessageHub.Instance.Publish(new ValidationStateChanged(block.BlockHashToHex, block.Index, false,
                                                                   finalResult));

            return(finalResult);
        }
Beispiel #17
0
        public async Task <SmartContractAddressDto> GetSmartContractAddressAsync(IChainContext chainContext, string name)
        {
            var smartContractAddress =
                await _smartContractAddressProvider.GetSmartContractAddressAsync(chainContext, name);

            if (smartContractAddress != null)
            {
                var smartContractAddressDto = new SmartContractAddressDto
                {
                    SmartContractAddress = smartContractAddress,
                    Irreversible         = await CheckSmartContractAddressIrreversibleAsync(smartContractAddress)
                };

                return(smartContractAddressDto);
            }

            var address = await GetSmartContractAddressFromStateAsync(chainContext, name);

            if (address == null)
            {
                return(null);
            }
            return(new SmartContractAddressDto
            {
                SmartContractAddress = new SmartContractAddress
                {
                    Address = address
                }
            });
        }
        public async Task <IExecutive> GetExecutiveAsync(IChainContext chainContext, Address address)
        {
            if (address == null)
            {
                throw new ArgumentNullException(nameof(address));
            }

            var pool = GetPool(address);

            if (!pool.TryTake(out var executive))
            {
                var reg = await GetSmartContractRegistrationAsync(chainContext, address);

                executive = await GetExecutiveAsync(address, reg);

                if (chainContext.BlockHeight > KernelConstants.GenesisBlockHeight && //already register zero to zero
                    address == _defaultContractZeroCodeProvider.ContractZeroAddress &&
                    !_addressSmartContractRegistrationMappingCache.ContainsKey(address)
                    )
                {
                    //executive's registration is from code, not from contract
                    reg = await GetSmartContractRegistrationFromZeroAsync(executive, chainContext, address);

                    _addressSmartContractRegistrationMappingCache.TryAdd(address, reg);
                    executive = await GetExecutiveAsync(address, reg);
                }
            }

            return(executive);
        }
        private async Task <List <Transaction> > FindContractOfWrongResourcesAsync(IChainContext chainContext,
                                                                                   List <ExecutionReturnSet> returnSets)
        {
            var transactionIds = returnSets.Select(rs => rs.TransactionId);
            var transactions   = await _blockchainService.GetTransactionsAsync(transactionIds);

            var txnWithResources =
                await _resourceExtractionService.GetResourcesAsync(chainContext, transactions, CancellationToken.None);

            var returnSetLookup = returnSets.ToDictionary(rs => rs.TransactionId, rs => rs);
            var wrongTxns       = new List <Transaction>();

            foreach (var txnWithResource in txnWithResources)
            {
                var extracted = new HashSet <string>(txnWithResource.Item2.Paths.Select(p => p.ToStateKey()));
                var actual    = GetKeys(returnSetLookup[txnWithResource.Item1.GetHash()]);
                actual.ExceptWith(extracted);
                if (actual.Count > 0)
                {
                    Logger.LogWarning($"Conflict keys:{string.Join(";", actual)}");
                    wrongTxns.Add(txnWithResource.Item1);
                }
            }

            return(wrongTxns);
        }
        public async Task <long> GetUnitPriceAsync(IChainContext chainContext)
        {
            var keys = _forkCache.Keys.ToArray();

            if (keys.Length == 0)
            {
                return(await GetUnitPriceAsync());
            }
            var  minHeight  = keys.Select(k => k.BlockHeight).Min();
            long?unitPrice  = null;
            var  blockIndex = new BlockIndex
            {
                BlockHash   = chainContext.BlockHash,
                BlockHeight = chainContext.BlockHeight
            };

            do
            {
                if (_forkCache.TryGetValue(blockIndex, out var value))
                {
                    unitPrice = value;
                }

                var link = _chainBlockLinkService.GetCachedChainBlockLink(blockIndex.BlockHash);
                blockIndex.BlockHash = link?.PreviousBlockHash;
                blockIndex.BlockHeight--;
            } while (blockIndex.BlockHash != null && blockIndex.BlockHeight >= minHeight);

            if (unitPrice == null)
            {
                unitPrice = await GetUnitPriceAsync();
            }
            Logger.LogTrace($"Get tx size fee unit price: {unitPrice.Value}");
            return(unitPrice.Value);
        }
        public async Task <List <AvailableTokenInfoInCache> > GetExtraAcceptedTokensInfoAsync(
            IChainContext chainContext)
        {
            var keys = _cacheProvider.GetForkCacheKeys();

            if (keys.Length == 0)
            {
                return(await GetExtraAcceptedTokensInfoFromCacheAsync());
            }
            var blockIndex = new BlockIndex
            {
                BlockHash   = chainContext.BlockHash,
                BlockHeight = chainContext.BlockHeight
            };
            var minHeight = keys.Select(k => k.BlockHeight).Min();
            List <AvailableTokenInfoInCache> tokenInfoDic = null;

            do
            {
                if (_cacheProvider.TryGetExtraAcceptedTokensInfoFromForkCache(blockIndex, out var value))
                {
                    tokenInfoDic = value;
                    break;
                }

                var link = _chainBlockLinkService.GetCachedChainBlockLink(blockIndex.BlockHash);
                blockIndex.BlockHash = link?.PreviousBlockHash;
                blockIndex.BlockHeight--;
            } while (blockIndex.BlockHash != null && blockIndex.BlockHeight >= minHeight);

            return(tokenInfoDic ?? await GetExtraAcceptedTokensInfoFromCacheAsync());
        }
        public async Task <TransactionTrace> ExecuteAsync(IChainContext chainContext, Transaction transaction,
                                                          Timestamp currentBlockTime)
        {
            var trace = new TransactionTrace()
            {
                TransactionId = transaction.GetHash()
            };

            var transactionContext = new TransactionContext
            {
                PreviousBlockHash = chainContext.BlockHash,
                CurrentBlockTime  = currentBlockTime,
                Transaction       = transaction,
                BlockHeight       = chainContext.BlockHeight + 1,
                Trace             = trace,
                CallDepth         = 0,
                StateCache        = chainContext.StateCache
            };

            var executive = await _smartContractExecutiveService.GetExecutiveAsync(
                chainContext, transaction.To);

            try
            {
                await executive.ApplyAsync(transactionContext);
            }
            finally
            {
                await _smartContractExecutiveService.PutExecutiveAsync(chainContext, transaction.To, executive);
            }

            return(trace);
        }
        public override async Task <InterestedEvent> GetInterestedEventAsync(IChainContext chainContext)
        {
            if (InterestedEvent != null)
            {
                return(InterestedEvent);
            }

            var smartContractAddressDto = await _smartContractAddressService.GetSmartContractAddressAsync(
                chainContext, TokenSmartContractAddressNameProvider.StringName);

            if (smartContractAddressDto == null)
            {
                return(null);
            }
            var interestedEvent =
                GetInterestedEvent <CalculateFeeAlgorithmUpdated>(smartContractAddressDto.SmartContractAddress.Address);

            if (!smartContractAddressDto.Irreversible)
            {
                return(interestedEvent);
            }

            InterestedEvent = interestedEvent;

            return(InterestedEvent);
        }
Beispiel #24
0
        public override async Task <InterestedEvent> GetInterestedEventAsync(IChainContext chainContext)
        {
            if (InterestedEvent != null)
            {
                return(InterestedEvent);
            }
            var smartContractAddressDto = await _smartContractAddressService.GetSmartContractAddressAsync(
                chainContext, ConsensusSmartContractAddressNameProvider.StringName);

            if (smartContractAddressDto == null)
            {
                return(null);
            }

            var interestedEvent =
                GetInterestedEvent <SecretSharingInformation>(smartContractAddressDto.SmartContractAddress.Address);

            if (!smartContractAddressDto.Irreversible)
            {
                return(interestedEvent);
            }

            InterestedEvent = interestedEvent;
            return(InterestedEvent);
        }
Beispiel #25
0
        public async Task <IExecutive> GetExecutiveAsync(IChainContext chainContext, Address address)
        {
            if (address == null)
            {
                throw new ArgumentNullException(nameof(address));
            }

            var pool = GetPool(address);

            if (!pool.TryTake(out var executive))
            {
                var reg = await GetSmartContractRegistrationAsync(chainContext, address);

                executive = await GetExecutiveAsync(address, reg);

                if (address == _defaultContractZeroCodeProvider.ContractZeroAddress &&
                    !_addressSmartContractRegistrationMappingCache.ContainsKey(address))
                {
                    if (chainContext.BlockHeight > Constants.GenesisBlockHeight)
                    {
                        //if Height > GenesisBlockHeight, maybe there is a new zero contract, the current executive is from code,
                        //not from zero contract, so we need to load new zero contract from the old executive,
                        //and replace it
                        reg = await GetSmartContractRegistrationFromZeroAsync(executive, chainContext, address);

                        executive = await GetExecutiveAsync(address, reg);
                    }

                    //add cache for zero, because GetSmartContractRegistrationAsync method do not add zero cache
                    _addressSmartContractRegistrationMappingCache.TryAdd(address, reg);
                }
            }

            return(await GetExecutiveAsync(chainContext, address, executive));
        }
Beispiel #26
0
        public override async Task <InterestedEvent> GetInterestedEventAsync(IChainContext chainContext)
        {
            if (InterestedEvent != null)
            {
                return(InterestedEvent);
            }

            var smartContractAddressDto = await _smartContractAddressService.GetSmartContractAddressAsync(
                chainContext, CrossChainSmartContractAddressNameProvider.StringName);

            if (smartContractAddressDto == null)
            {
                return(null);
            }

            var interestedEvent = GetInterestedEvent <CrossChainIndexingDataProposedEvent>(smartContractAddressDto
                                                                                           .SmartContractAddress.Address);

            if (!smartContractAddressDto.Irreversible)
            {
                return(interestedEvent);
            }
            InterestedEvent = interestedEvent;

            return(InterestedEvent);
        }
        private async Task <bool> ExecutePluginOnPreTransactionStageAsync(IExecutive executive,
                                                                          ITransactionContext txContext,
                                                                          Timestamp currentBlockTime,
                                                                          IChainContext internalChainContext,
                                                                          TieredStateCache internalStateCache,
                                                                          CancellationToken cancellationToken)
        {
            var trace = txContext.Trace;

            foreach (var plugin in _prePlugins)
            {
                var transactions = await plugin.GetPreTransactionsAsync(executive.Descriptors, txContext);

                foreach (var preTx in transactions)
                {
                    var singleTxExecutingDto = new SingleTransactionExecutingDto
                    {
                        Depth            = 0,
                        ChainContext     = internalChainContext,
                        Transaction      = preTx,
                        CurrentBlockTime = currentBlockTime
                    };
                    var preTrace = await ExecuteOneAsync(singleTxExecutingDto, cancellationToken);

                    if (preTrace == null)
                    {
                        return(false);
                    }
                    trace.PreTransactions.Add(preTx);
                    trace.PreTraces.Add(preTrace);
                    if (preTx.MethodName == "ChargeTransactionFees")
                    {
                        var txFee = new TransactionFee();
                        txFee.MergeFrom(preTrace.ReturnValue);
                        trace.TransactionFee = txFee;
                    }

                    if (!preTrace.IsSuccessful())
                    {
                        return(false);
                    }

                    var stateSets = preTrace.GetStateSets().ToList();
                    internalStateCache.Update(stateSets);
                    var parentStateCache = txContext.StateCache as TieredStateCache;
                    parentStateCache?.Update(stateSets);

                    if (trace.TransactionFee == null || !trace.TransactionFee.IsFailedToCharge)
                    {
                        continue;
                    }

                    preTrace.ExecutionStatus = ExecutionStatus.Executed;
                    return(false);
                }
            }

            return(true);
        }
Beispiel #28
0
 public CrossChainContractContainer.CrossChainContractStub Create(IChainContext chainContext)
 {
     return(new CrossChainContractContainer.CrossChainContractStub()
     {
         __factory = new MethodStubFactory(_transactionReadOnlyExecutionService, _smartContractAddressService,
                                           chainContext)
     });
 }
Beispiel #29
0
 public MethodStubFactory(ITransactionReadOnlyExecutionService transactionReadOnlyExecutionService,
                          ISmartContractAddressService smartContractAddressService, IChainContext chainContext, Address sender)
 {
     _transactionReadOnlyExecutionService = transactionReadOnlyExecutionService;
     _smartContractAddressService         = smartContractAddressService;
     _chainContext = chainContext;
     FromAddress   = sender ?? Address.FromBytes(new byte[] { }.ComputeHash());
 }
Beispiel #30
0
 public async Task <CodeRemark> GetCodeRemarkAsync(IChainContext chainContext, Address address, Hash codeHash)
 {
     return(await Task.FromResult(new CodeRemark
     {
         CodeHash = codeHash,
         NonParallelizable = NonParallelizable
     }));
 }