Пример #1
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);
        }
Пример #2
0
        // TODO: block processor pipeline
        private void ApplyMinerRewards(Block block, IBlockTracer tracer, IReleaseSpec spec)
        {
            if (_logger.IsTrace)
            {
                _logger.Trace("Applying miner rewards:");
            }
            BlockReward[] rewards = _rewardCalculator.CalculateRewards(block);
            for (int i = 0; i < rewards.Length; i++)
            {
                BlockReward reward = rewards[i];

                ITxTracer txTracer = NullTxTracer.Instance;
                if (tracer.IsTracingRewards)
                {
                    // we need this tracer to be able to track any potential miner account creation
                    txTracer = tracer.StartNewTxTrace(null);
                }

                ApplyMinerReward(block, reward, spec);

                if (tracer.IsTracingRewards)
                {
                    tracer.EndTxTrace();
                    tracer.ReportReward(reward.Address, reward.RewardType.ToLowerString(), reward.Value);
                    if (txTracer.IsTracingState)
                    {
                        _stateProvider.Commit(spec, txTracer);
                    }
                }
            }
        }
Пример #3
0
        private void ApplyMinerRewards(Block block, IBlockTracer tracer)
        {
            if (_logger.IsTrace)
            {
                _logger.Trace("Applying miner rewards:");
            }
            var rewards = _rewardCalculator.CalculateRewards(block);

            for (int i = 0; i < rewards.Length; i++)
            {
                BlockReward reward = rewards[i];

                ITxTracer txTracer = null;
                if (tracer.IsTracingRewards)
                {
                    txTracer = tracer.StartNewTxTrace(null);
                }

                ApplyMinerReward(block, reward, tracer.IsTracingRewards ? tracer : NullBlockTracer.Instance);

                if (tracer.IsTracingRewards)
                {
                    tracer.EndTxTrace();
                    tracer.ReportReward(reward.Address, reward.RewardType.ToLowerString(), (UInt256)reward.Value);
                    if (txTracer?.IsTracingState ?? false)
                    {
                        _stateProvider.Commit(_specProvider.GetSpec(block.Number), txTracer);
                    }
                }
            }
        }
Пример #4
0
        private void ApplyMinerRewards(Block block, IBlockTracer tracer)
        {
            if (_logger.IsTrace)
            {
                _logger.Trace("Applying miner rewards:");
            }
            var rewards = _rewardCalculator.CalculateRewards(block);

            for (int i = 0; i < rewards.Length; i++)
            {
                BlockReward reward = rewards[i];

                ITxTracer txTracer = null;
                if (tracer.IsTracingRewards)
                {
                    // we need this tracer to be able to track any potential miner account creation
                    txTracer = tracer.StartNewTxTrace(null);
                }

                ApplyMinerReward(block, reward);

                if (tracer.IsTracingRewards)
                {
                    tracer.EndTxTrace();
                    tracer.ReportReward(reward.Address, reward.RewardType.ToLowerString(), reward.Value);
                    if (txTracer?.IsTracingState ?? false)
                    {
                        _stateProvider.Commit(_specProvider.GetSpec(block.Number), txTracer);
                    }
                }
            }
        }
 public void BuildUp(Transaction transaction, BlockHeader block, ITxTracer txTracer)
 {
     // we need to treat the result of previous transaction as the original value of next transaction
     // when we do not commit
     _worldState.TakeSnapshot(true);
     Execute(transaction, block, txTracer, ExecutionOptions.None);
 }
Пример #6
0
 private static void QuickFail(PublicEntry entry, ExecutionEnvironment env, ITxTracer txTracer)
 {
     // here we need to propagate back to Delta
     env.CurrentBlock.GasUsed += (long)entry.GasLimit;
     if (txTracer.IsTracingReceipt)
     {
         txTracer.MarkAsFailed(env.ExecutingAccount, (long)entry.GasLimit, Bytes.Empty, "invalid");
     }
 }
Пример #7
0
        private void QuickFail(Transaction tx, StateUpdate block, ITxTracer txTracer, bool readOnly)
        {
            block.GasUsed += (long)tx.GasLimit;
            Address recipient = tx.To ?? Address.OfContract(tx.SenderAddress, _stateProvider.GetNonce(tx.SenderAddress));

            if (txTracer.IsTracingReceipt)
            {
                txTracer.MarkAsFailed(recipient, (long)tx.GasLimit, Bytes.Empty, "invalid");
            }
        }
Пример #8
0
 public void SetOperationStack(List <string> stackTrace)
 {
     for (int index = 0; index < _txTracers.Count; index++)
     {
         ITxTracer innerTracer = _txTracers[index];
         if (innerTracer.IsTracingStack)
         {
             innerTracer.SetOperationStack(stackTrace);
         }
     }
 }
Пример #9
0
 public void ReportOperationRemainingGas(long gas)
 {
     for (int index = 0; index < _txTracers.Count; index++)
     {
         ITxTracer innerTracer = _txTracers[index];
         if (innerTracer.IsTracingInstructions)
         {
             innerTracer.ReportOperationRemainingGas(gas);
         }
     }
 }
Пример #10
0
 public void ReportOperationError(EvmExceptionType error)
 {
     for (int index = 0; index < _txTracers.Count; index++)
     {
         ITxTracer innerTracer = _txTracers[index];
         if (innerTracer.IsTracingInstructions)
         {
             innerTracer.ReportOperationError(error);
         }
     }
 }
Пример #11
0
 public void MarkAsFailed(Address recipient, long gasSpent, byte[] output, string error, Keccak?stateRoot = null)
 {
     for (int index = 0; index < _txTracers.Count; index++)
     {
         ITxTracer innerTracer = _txTracers[index];
         if (innerTracer.IsTracingReceipt)
         {
             innerTracer.MarkAsFailed(recipient, gasSpent, output, error, stateRoot);
         }
     }
 }
Пример #12
0
 public void ReportStorageRead(StorageCell storageCell)
 {
     for (int index = 0; index < _txTracers.Count; index++)
     {
         ITxTracer innerTracer = _txTracers[index];
         if (innerTracer.IsTracingStorage)
         {
             innerTracer.ReportStorageRead(storageCell);
         }
     }
 }
Пример #13
0
 public void ReportStorageChange(StorageCell storageCell, byte[] before, byte[] after)
 {
     for (int index = 0; index < _txTracers.Count; index++)
     {
         ITxTracer innerTracer = _txTracers[index];
         if (innerTracer.IsTracingStorage)
         {
             innerTracer.ReportStorageChange(storageCell, before, after);
         }
     }
 }
Пример #14
0
 public void ReportAccountRead(Address address)
 {
     for (int index = 0; index < _txTracers.Count; index++)
     {
         ITxTracer innerTracer = _txTracers[index];
         if (innerTracer.IsTracingState)
         {
             innerTracer.ReportAccountRead(address);
         }
     }
 }
Пример #15
0
 public void ReportCodeChange(Address address, byte[] before, byte[] after)
 {
     for (int index = 0; index < _txTracers.Count; index++)
     {
         ITxTracer innerTracer = _txTracers[index];
         if (innerTracer.IsTracingState)
         {
             innerTracer.ReportCodeChange(address, before, after);
         }
     }
 }
Пример #16
0
 public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Keccak?stateRoot = null)
 {
     for (int index = 0; index < _txTracers.Count; index++)
     {
         ITxTracer innerTracer = _txTracers[index];
         if (innerTracer.IsTracingReceipt)
         {
             innerTracer.MarkAsSuccess(recipient, gasSpent, output, logs, stateRoot);
         }
     }
 }
Пример #17
0
 public void StartOperation(int depth, long gas, Instruction opcode, int pc)
 {
     for (int index = 0; index < _txTracers.Count; index++)
     {
         ITxTracer innerTracer = _txTracers[index];
         if (innerTracer.IsTracingInstructions)
         {
             innerTracer.StartOperation(depth, gas, opcode, pc);
         }
     }
 }
Пример #18
0
 public void ReportBalanceChange(Address address, UInt256?before, UInt256?after)
 {
     for (int index = 0; index < _txTracers.Count; index++)
     {
         ITxTracer innerTracer = _txTracers[index];
         if (innerTracer.IsTracingState)
         {
             innerTracer.ReportBalanceChange(address, before, after);
         }
     }
 }
Пример #19
0
        private bool ValidateSender(PublicEntry entry, ExecutionEnvironment env, ITxTracer txTracer)
        {
            if (env.Sender != null)
            {
                return(true);
            }

            TraceLogInvalidTx(entry, "SENDER_NOT_SPECIFIED");
            QuickFail(entry, env, txTracer);
            return(false);
        }
Пример #20
0
        private bool ValidateNonce(PublicEntry entry, ExecutionEnvironment env, ITxTracer txTracer)
        {
            if (entry.Nonce == _stateProvider.GetNonce(env.Sender))
            {
                return(true);
            }

            TraceLogInvalidTx(entry,
                              $"WRONG_TRANSACTION_NONCE: {entry.Nonce.ToString()} (expected {_stateProvider.GetNonce(env.Sender).ToString()})");
            QuickFail(entry, env, txTracer);
            return(false);
        }
Пример #21
0
 public static CancellationTxTracer WithCancellation(this ITxTracer txTracer, CancellationToken cancellationToken, bool setDefaultCancellations = true)
 {
     return(!setDefaultCancellations
         ? new(txTracer, cancellationToken)
         : new (txTracer, cancellationToken)
     {
         IsTracingActions = true,
         IsTracingOpLevelStorage = true,
         IsTracingInstructions = true,     // a little bit costly but almost all are simple calls
         IsTracingRefunds = true
     });
 }
Пример #22
0
        private void QuickFail(Transaction tx, BlockHeader block, ITxTracer txTracer, string reason)
        {
            block.GasUsed += tx.GasLimit;
            Address recipient = tx.To ?? ContractAddress.From(tx.SenderAddress, _stateProvider.GetNonce(tx.SenderAddress));

            _stateProvider.RecalculateStateRoot();
            Keccak stateRoot = _specProvider.GetSpec(block.Number).IsEip658Enabled ? null : _stateProvider.StateRoot;

            if (txTracer.IsTracingReceipt)
            {
                txTracer.MarkAsFailed(recipient, tx.GasLimit, Array.Empty <byte>(), reason ?? "invalid", stateRoot);
            }
        }
        public void Can_serialize_reward()
        {
            Block        block       = Build.A.Block.WithNumber(long.Parse("4563918244f40000".AsSpan(), NumberStyles.AllowHexSpecifier)).TestObject;
            IBlockTracer blockTracer = new ParityLikeBlockTracer(ParityTraceTypes.Trace | ParityTraceTypes.StateDiff);

            blockTracer.StartNewBlockTrace(block);
            ITxTracer txTracer = blockTracer.StartNewTxTrace(null);

            txTracer.ReportBalanceChange(TestItem.AddressA, 0, 3.Ether());
            blockTracer.EndTxTrace();
            blockTracer.ReportReward(TestItem.AddressA, "block", UInt256.One);

            ParityLikeTxTrace trace = ((ParityLikeBlockTracer)blockTracer).BuildResult().SingleOrDefault();

            TestOneWaySerialization(trace, "{\"trace\":[{\"action\":{\"callType\":\"reward\",\"from\":null,\"gas\":\"0x0\",\"input\":null,\"to\":null,\"value\":\"0x1\"},\"blockHash\":\"0xfed4f714d3626e046786ef043cbb30a4b87cdc288469d0b70e4529bbd4e15396\",\"blockNumber\":\"0x4563918244f40000\",\"result\":{\"gasUsed\":\"0x0\",\"output\":null},\"subtraces\":0,\"traceAddress\":\"[]\",\"transactionHash\":null,\"transactionPosition\":null,\"type\":\"reward\"}],\"stateDiff\":{\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\":{\"balance\":{\"*\":{\"from\":\"0x0\",\"to\":\"0x29a2241af62c0000\"}},\"code\":\"=\",\"nonce\":\"=\",\"storage\":{}}}}");
        }
        public void Can_serialize_reward_state_only()
        {
            Block        block       = Build.A.Block.WithNumber(long.Parse("4563918244f40000".AsSpan(), NumberStyles.AllowHexSpecifier)).TestObject;
            IBlockTracer blockTracer = new ParityLikeBlockTracer(ParityTraceTypes.StateDiff);

            blockTracer.StartNewBlockTrace(block);
            ITxTracer txTracer = blockTracer.StartNewTxTrace(null);

            txTracer.ReportBalanceChange(TestItem.AddressA, 0, 3.Ether());
            blockTracer.EndTxTrace();
            blockTracer.ReportReward(TestItem.AddressA, "block", UInt256.One);

            ParityLikeTxTrace trace = ((ParityLikeBlockTracer)blockTracer).BuildResult().SingleOrDefault();

            TestOneWaySerialization(trace, "{\"trace\":null,\"stateDiff\":{\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\":{\"balance\":{\"*\":{\"from\":\"0x0\",\"to\":\"0x29a2241af62c0000\"}},\"code\":\"=\",\"nonce\":\"=\",\"storage\":{}}}}");
        }
        public void Can_serialize_reward()
        {
            Block        block       = Build.A.Block.WithNumber(long.Parse("4563918244f40000".AsSpan(), NumberStyles.AllowHexSpecifier)).TestObject;
            IBlockTracer blockTracer = new ParityLikeBlockTracer(ParityTraceTypes.Trace | ParityTraceTypes.StateDiff);

            blockTracer.StartNewBlockTrace(block);
            ITxTracer txTracer = blockTracer.StartNewTxTrace(null);

            txTracer.ReportBalanceChange(TestItem.AddressA, 0, 3.Ether());
            blockTracer.EndTxTrace();
            blockTracer.ReportReward(TestItem.AddressA, "block", UInt256.One);

            ParityLikeTxTrace trace = ((ParityLikeBlockTracer)blockTracer).BuildResult().SingleOrDefault();

            TestToJson(new ParityTxTraceFromReplay(trace), "{\"output\":null,\"stateDiff\":{\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\":{\"balance\":{\"*\":{\"from\":\"0x0\",\"to\":\"0x29a2241af62c0000\"}},\"code\":\"=\",\"nonce\":\"=\",\"storage\":{}}},\"trace\":[{\"action\":{\"author\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"rewardType\":\"block\",\"value\":\"0x1\"},\"result\":null,\"subtraces\":0,\"traceAddress\":[],\"type\":\"reward\"}],\"vmTrace\":null}");
        }
Пример #26
0
 private (bool Success, string Error) TryCallAndRestore(
     BlockHeader blockHeader,
     long number,
     UInt256 timestamp,
     Transaction transaction,
     ITxTracer tracer)
 {
     try
     {
         CallAndRestore(blockHeader, number, timestamp, transaction, tracer);
         return(true, string.Empty);
     }
     catch (InsufficientBalanceException ex)
     {
         return(false, ex.Message);
     }
 }
Пример #27
0
        private bool ValidateSenderBalance(PublicEntry entry,
                                           ExecutionEnvironment env,
                                           ulong intrinsicGas,
                                           ITxTracer txTracer)
        {
            var senderBalance = _stateProvider.GetBalance(env.Sender);

            if (intrinsicGas * env.GasPrice + env.Value <= senderBalance)
            {
                return(true);
            }

            TraceLogInvalidTx(entry,
                              $"INSUFFICIENT_SENDER_BALANCE: ({env.Sender})_BALANCE = {senderBalance.ToString()}");
            QuickFail(entry, env, txTracer);
            return(false);
        }
Пример #28
0
        public ITxTracer StartNewTxTrace(Transaction?tx)
        {
            IList <IBlockTracer> childBlockTracers = _childTracers;

            List <ITxTracer> tracers = new(childBlockTracers.Count);

            for (int i = 0; i < childBlockTracers.Count; i++)
            {
                IBlockTracer childBlockTracer = childBlockTracers[i];
                ITxTracer    txTracer         = childBlockTracer.StartNewTxTrace(tx);
                if (txTracer != NullTxTracer.Instance)
                {
                    tracers.Add(txTracer);
                }
            }

            return(tracers.Count > 0 ? new CompositeTxTracer(tracers) : NullTxTracer.Instance);
        }
Пример #29
0
 public CompositeTxTracer(IList <ITxTracer> txTracers)
 {
     _txTracers = txTracers;
     for (int index = 0; index < txTracers.Count; index++)
     {
         ITxTracer t = txTracers[index];
         IsTracingState          |= t.IsTracingState;
         IsTracingReceipt        |= t.IsTracingReceipt;
         IsTracingActions        |= t.IsTracingActions;
         IsTracingOpLevelStorage |= t.IsTracingOpLevelStorage;
         IsTracingMemory         |= t.IsTracingMemory;
         IsTracingInstructions   |= t.IsTracingInstructions;
         IsTracingRefunds        |= t.IsTracingRefunds;
         IsTracingCode           |= t.IsTracingCode;
         IsTracingStack          |= t.IsTracingStack;
         IsTracingBlockHash      |= t.IsTracingBlockHash;
         IsTracingStorage        |= t.IsTracingStorage;
         IsTracingAccess         |= t.IsTracingAccess;
     }
 }
Пример #30
0
        private bool ValidateIntrinsicGas(PublicEntry entry,
                                          ExecutionEnvironment env,
                                          ulong intrinsicGas,
                                          ITxTracer txTracer)
        {
            if (_logger.IsEnabled(LogEventLevel.Verbose))
            {
                _logger.Verbose("Intrinsic gas calculated for {entry}: {intrinsicGas}", entry, intrinsicGas);
            }

            if (entry.GasLimit >= intrinsicGas)
            {
                return(true);
            }

            TraceLogInvalidTx(entry,
                              $"GAS_LIMIT_BELOW_INTRINSIC_GAS {entry.GasLimit.ToString()} < {intrinsicGas.ToString()}");
            QuickFail(entry, env, txTracer);
            return(false);
        }