Пример #1
0
        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
            });
        }
Пример #2
0
        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();
            }
        }
Пример #3
0
        /// <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);
            }
        }
Пример #4
0
        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);
        }
Пример #5
0
        private bool TryExecutableTransaction(Transaction transaction, BlockHeader block, long gasLimit)
        {
            OutOfGasTracer tracer = new();

            transaction.GasLimit = (long)gasLimit;
            _transactionProcessor.CallAndRestore(transaction, block, tracer);

            return(!tracer.OutOfGas);
        }
Пример #6
0
        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}.");
                }
            }
        }
Пример #7
0
 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();
     }
 }
Пример #8
0
        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();
            }
        }
Пример #9
0
 public void CallAndRestore(Transaction transaction, BlockHeader block, ITxTracer txTracer)
 {
     _transactionProcessor.CallAndRestore(transaction, block, txTracer);
 }