public CallOutput Call(BlockHeader blockHeader, Transaction transaction) { if (transaction.SenderAddress == null) { transaction.SenderAddress = Address.Zero; } BlockHeader header = new BlockHeader(blockHeader.Hash, Keccak.OfAnEmptySequenceRlp, blockHeader.Beneficiary, blockHeader.Difficulty, blockHeader.Number + 1, (long)transaction.GasLimit, blockHeader.Timestamp + 1, Bytes.Empty); _stateProvider.StateRoot = blockHeader.StateRoot; if (transaction.Nonce == 0) { transaction.Nonce = GetNonce(blockHeader.StateRoot, transaction.SenderAddress); } transaction.Hash = Transaction.CalculateHash(transaction); CallOutputTracer callOutputTracer = new CallOutputTracer(); _transactionProcessor.CallAndRestore(transaction, header, callOutputTracer); _stateProvider.Reset(); _storageProvider.Reset(); return(new CallOutput { Error = callOutputTracer.Error, GasSpent = callOutputTracer.GasSpent, OutputData = callOutputTracer.ReturnValue }); }
private void CallAndRestore(BlockHeader blockHeader, Transaction transaction, ITxTracer tracer) { if (transaction.SenderAddress == null) { transaction.SenderAddress = Address.SystemUser; } _stateProvider.StateRoot = blockHeader.StateRoot; try { if (transaction.Nonce == 0) { transaction.Nonce = GetNonce(_stateProvider.StateRoot, transaction.SenderAddress); } BlockHeader callHeader = new BlockHeader( blockHeader.Hash, Keccak.OfAnEmptySequenceRlp, Address.Zero, 0, blockHeader.Number + 1, blockHeader.GasLimit, blockHeader.Timestamp, Bytes.Empty); transaction.Hash = transaction.CalculateHash(); _transactionProcessor.CallAndRestore(transaction, callHeader, tracer); } finally { _stateProvider.Reset(); _storageProvider.Reset(); } }
/// <summary> /// Helper method that actually does the actual call to <see cref="ITransactionProcessor"/>. /// </summary> /// <param name="transactionProcessor">Actual transaction processor to be called upon.</param> /// <param name="header">Header in which context the call is done.</param> /// <param name="transaction">Transaction to be executed.</param> /// <param name="callAndRestore">Is it restore call.</param> /// <returns>Bytes with result.</returns> /// <exception cref="AbiException">Thrown when there is an exception during execution or <see cref="CallOutputTracer.StatusCode"/> is <see cref="StatusCode.Failure"/>.</exception> protected static byte[] CallCore(ITransactionProcessor transactionProcessor, BlockHeader header, Transaction transaction, bool callAndRestore = false) { bool failure; CallOutputTracer tracer = new CallOutputTracer(); try { if (callAndRestore) { transactionProcessor.CallAndRestore(transaction, header, tracer); } else { transactionProcessor.Execute(transaction, header, tracer); } failure = tracer.StatusCode != StatusCode.Success; } catch (Exception e) { throw new AbiException($"System call returned an exception '{e.Message}' at block {header.Number}.", e); } if (failure) { throw new AbiException($"System call returned error '{tracer.Error}' at block {header.Number}."); } else { return(tracer.ReturnValue); } }
private (bool success, UserOperationAccessList accessList, string?error) SimulateValidation( Transaction transaction, UserOperation userOperation, BlockHeader parent, ITransactionProcessor transactionProcessor) { UserOperationBlockTracer blockTracer = CreateBlockTracer(parent, userOperation); ITxTracer txTracer = blockTracer.StartNewTxTrace(transaction); transactionProcessor.CallAndRestore(transaction, parent, txTracer); blockTracer.EndTxTrace(); string?error = null; if (!blockTracer.Success) { if (blockTracer.FailedOp is not null) { error = blockTracer.FailedOp.ToString() !; } else { error = blockTracer.Error; } return(false, UserOperationAccessList.Empty, error); } UserOperationAccessList userOperationAccessList = new(blockTracer.AccessedStorage); return(true, userOperationAccessList, error); }
private bool TryExecutableTransaction(Transaction transaction, BlockHeader block, long gasLimit) { OutOfGasTracer tracer = new(); transaction.GasLimit = (long)gasLimit; _transactionProcessor.CallAndRestore(transaction, block, tracer); return(!tracer.OutOfGas); }
public void InvokeTransaction(BlockHeader header, ITransactionProcessor transactionProcessor, Transaction transaction, CallOutputTracer tracer, bool isReadOnly = false) { if (transaction != null) { if (isReadOnly) { transactionProcessor.CallAndRestore(transaction, header, tracer); } else { transactionProcessor.Execute(transaction, header, tracer); } if (tracer.StatusCode != StatusCode.Success) { throw new AuRaException($"System call returned error '{tracer.Error}' at block {header.Number}."); } } }
public byte[] Call(Block block, Transaction transaction) { try { _readerWriterLockSlim.EnterWriteLock(); _stateProvider.StateRoot = _blockTree.Head.StateRoot; BlockHeader header = new BlockHeader(block.Hash, Keccak.OfAnEmptySequenceRlp, block.Beneficiary, block.Difficulty, block.Number + 1, (long)transaction.GasLimit, block.Timestamp + 1, Bytes.Empty); transaction.Nonce = _stateProvider.GetNonce(transaction.SenderAddress); transaction.Hash = Transaction.CalculateHash(transaction); CallOutputTracer callOutputTracer = new CallOutputTracer(); _transactionProcessor.CallAndRestore(transaction, header, callOutputTracer); _stateProvider.Reset(); return(callOutputTracer.ReturnValue); } finally { _readerWriterLockSlim.ExitWriteLock(); } }
private void CallAndRestore( BlockHeader blockHeader, long number, UInt256 timestamp, Transaction transaction, ITxTracer tracer) { if (transaction.SenderAddress == null) { transaction.SenderAddress = Address.SystemUser; } _stateProvider.StateRoot = blockHeader.StateRoot; try { if (transaction.Nonce == 0) { transaction.Nonce = GetNonce(_stateProvider.StateRoot, transaction.SenderAddress); } BlockHeader callHeader = new BlockHeader( blockHeader.Hash, Keccak.OfAnEmptySequenceRlp, Address.Zero, 0, number, blockHeader.GasLimit, timestamp, Array.Empty <byte>()); transaction.Hash = transaction.CalculateHash(); _transactionProcessor.CallAndRestore(transaction, callHeader, tracer); } finally { _processingEnv.Reset(); } }
public void CallAndRestore(Transaction transaction, BlockHeader block, ITxTracer txTracer) { _transactionProcessor.CallAndRestore(transaction, block, txTracer); }