/// <summary> /// Execute the contract and add all relevant fees and refunds to the block. /// </summary> /// <remarks>TODO: At some point we need to change height to a ulong.</remarks> private ISmartContractExecutionResult ExecuteSmartContract(TxMempoolEntry mempoolEntry) { this.logger.LogTrace("()"); GetSenderUtil.GetSenderResult getSenderResult = GetSenderUtil.GetSender(mempoolEntry.Transaction, this.coinView, this.inBlock.Select(x => x.Transaction).ToList()); if (!getSenderResult.Success) { throw new ConsensusErrorException(new ConsensusError("sc-block-assembler-addcontracttoblock", getSenderResult.Error)); } ISmartContractTransactionContext transactionContext = new SmartContractTransactionContext((ulong)this.height, this.coinbaseAddress, mempoolEntry.Fee, getSenderResult.Sender, mempoolEntry.Transaction); ISmartContractExecutor executor = this.executorFactory.CreateExecutor(this.stateSnapshot, transactionContext); ISmartContractExecutionResult result = executor.Execute(transactionContext); // As we're not storing receipts, can use only consensus fields. var receipt = new Receipt( new uint256(this.stateSnapshot.Root), result.GasConsumed, result.Logs.ToArray() ); this.receipts.Add(receipt); this.logger.LogTrace("(-)"); return(result); }
/// <summary> /// Execute the contract and add all relevant fees and refunds to the block. /// </summary> /// <remarks>TODO: At some point we need to change height to a ulong.</remarks> private ISmartContractExecutionResult ExecuteSmartContract(TxMempoolEntry mempoolEntry) { this.logger.LogTrace("()"); GetSenderUtil.GetSenderResult getSenderResult = GetSenderUtil.GetSender(mempoolEntry.Transaction, this.coinView, this.inBlock.Select(x => x.Transaction).ToList()); if (!getSenderResult.Success) { throw new ConsensusErrorException(new ConsensusError("sc-block-assembler-addcontracttoblock", getSenderResult.Error)); } ISmartContractTransactionContext transactionContext = new SmartContractTransactionContext((ulong)this.height, this.coinbaseAddress, mempoolEntry.Fee, getSenderResult.Sender, mempoolEntry.Transaction); ISmartContractExecutor executor = this.executorFactory.CreateExecutor(this.stateSnapshot, transactionContext); ISmartContractExecutionResult result = executor.Execute(transactionContext); this.logger.LogTrace("(-)"); return(result); }
/// <summary> /// Retrieves the context object to be given to the contract executor. /// </summary> private ISmartContractTransactionContext GetSmartContractTransactionContext(RuleContext context, Transaction transaction) { ulong blockHeight = Convert.ToUInt64(context.ValidationContext.ChainedHeader.Height); GetSenderUtil.GetSenderResult getSenderResult = GetSenderUtil.GetSender(transaction, ((PowConsensusRules)this.Parent).UtxoSet, this.blockTxsProcessed); if (!getSenderResult.Success) { throw new ConsensusErrorException(new ConsensusError("sc-consensusvalidator-executecontracttransaction-sender", getSenderResult.Error)); } Script coinbaseScriptPubKey = context.ValidationContext.Block.Transactions[0].Outputs[0].ScriptPubKey; GetSenderUtil.GetSenderResult getCoinbaseResult = GetSenderUtil.GetAddressFromScript(coinbaseScriptPubKey); if (!getCoinbaseResult.Success) { throw new ConsensusErrorException(new ConsensusError("sc-consensusvalidator-executecontracttransaction-coinbase", getCoinbaseResult.Error)); } Money mempoolFee = transaction.GetFee(((UtxoRuleContext)context).UnspentOutputSet); return(new SmartContractTransactionContext(blockHeight, getCoinbaseResult.Sender, mempoolFee, getSenderResult.Sender, transaction)); }