private void StoreTraces(ParityLikeBlockTracer blockTracer) { if (blockTracer == null) { throw new ArgumentNullException(nameof(blockTracer)); } IReadOnlyCollection <ParityLikeTxTrace> traces = blockTracer.BuildResult(); try { _traceDb.StartBatch(); List <ParityLikeTxTrace> rewardTraces = new List <ParityLikeTxTrace>(); foreach (ParityLikeTxTrace parityLikeTxTrace in traces) { if (parityLikeTxTrace.TransactionHash != null) { _traceDb.Set(parityLikeTxTrace.TransactionHash, Rlp.Encode(parityLikeTxTrace).Bytes); } else { rewardTraces.Add(parityLikeTxTrace); } } if (rewardTraces.Any()) { _traceDb.Set(rewardTraces[0].BlockHash, Rlp.Encode(rewardTraces.ToArray()).Bytes); } } finally { _traceDb.CommitBatch(); } }
private ParityLikeTxTrace ParityTrace(Block block, Keccak txHash, ParityTraceTypes traceTypes) { ParityLikeBlockTracer listener = new ParityLikeBlockTracer(txHash, traceTypes); _processor.Process(block, ProcessingOptions.ForceProcessing | ProcessingOptions.WithRollback | ProcessingOptions.ReadOnlyChain, listener); return(listener.BuildResult().SingleOrDefault()); }
private void LogDiagnosticTrace(IBlockTracer blockTracer) { GethLikeBlockTracer gethTracer = blockTracer as GethLikeBlockTracer; ParityLikeBlockTracer parityTracer = blockTracer as ParityLikeBlockTracer; if (gethTracer != null) { var serializer = new EthereumJsonSerializer(); var trace = gethTracer.BuildResult(); var serialized = serializer.Serialize(trace, true); if (_logger.IsInfo) { _logger.Info(serialized); } } if (parityTracer != null) { var serializer = new EthereumJsonSerializer(); var trace = parityTracer.BuildResult(); var serialized = serializer.Serialize(trace, true); if (_logger.IsInfo) { _logger.Info(serialized); } } }
private void LogDiagnosticTrace(IBlockTracer blockTracer, Block block) { FileStream GetDiagnosticFile() => new FileStream($"trace_{block}.txt", FileMode.Create, FileAccess.Write); GethLikeBlockTracer gethTracer = blockTracer as GethLikeBlockTracer; ParityLikeBlockTracer parityTracer = blockTracer as ParityLikeBlockTracer; if (gethTracer != null) { using var diagnosticFile = GetDiagnosticFile(); var serializer = new EthereumJsonSerializer(); var trace = gethTracer.BuildResult(); serializer.Serialize(diagnosticFile, trace, true); if (_logger.IsInfo) { _logger.Info($"Created trace of block {block} in file {diagnosticFile.Name}"); } } if (parityTracer != null) { using var diagnosticFile = GetDiagnosticFile(); var serializer = new EthereumJsonSerializer(); var trace = parityTracer.BuildResult(); serializer.Serialize(diagnosticFile, trace, true); if (_logger.IsInfo) { _logger.Info($"Created trace of block {block} in file {diagnosticFile.Name}"); } } }
public void Is_tracing_rewards_only_when_rewards_trace_type_selected() { ParityLikeBlockTracer tracer = new ParityLikeBlockTracer(ParityTraceTypes.All ^ ParityTraceTypes.Rewards); Assert.False(tracer.IsTracingRewards); ParityLikeBlockTracer tracer2 = new ParityLikeBlockTracer(ParityTraceTypes.Rewards); Assert.True(tracer2.IsTracingRewards); }
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}"); }
private ParityLikeTxTrace[] ParityTraceBlock(Block block, ParityTraceTypes traceTypes) { if (block == null) { throw new InvalidOperationException("Only canonical, historical blocks supported"); } if (block.Number != 0) { Block parent = _blockTree.FindParent(block); if (!_blockTree.IsMainChain(parent.Hash)) { throw new InvalidOperationException("Cannot trace orphaned blocks"); } } ParityLikeBlockTracer listener = new ParityLikeBlockTracer(traceTypes); _processor.Process(block, ProcessingOptions.ForceProcessing | ProcessingOptions.WithRollback | ProcessingOptions.ReadOnlyChain | ProcessingOptions.NoValidation, listener); return(listener.BuildResult().ToArray()); }
private void RunProcessingLoop() { _stats.Start(); if (_logger.IsDebug) { _logger.Debug($"Starting block processor - {_blockQueue.Count} blocks waiting in the queue."); } if (_blockQueue.Count == 0) { ProcessingQueueEmpty?.Invoke(this, EventArgs.Empty); } foreach (BlockRef blockRef in _blockQueue.GetConsumingEnumerable(_loopCancellationSource.Token)) { if (blockRef.IsInDb || blockRef.Block == null) { throw new InvalidOperationException("Processing loop expects only resolved blocks"); } Block block = blockRef.Block; if (_logger.IsTrace) { _logger.Trace($"Processing block {block.ToString(Block.Format.Short)})."); } IBlockTracer tracer = NullBlockTracer.Instance; if ((blockRef.ProcessingOptions & ProcessingOptions.StoreTraces) != 0) { tracer = new ParityLikeBlockTracer(ParityTraceTypes.Trace | ParityTraceTypes.StateDiff); } Block processedBlock = Process(block, blockRef.ProcessingOptions, tracer); if (processedBlock == null) { if (_logger.IsTrace) { _logger.Trace($"Failed / skipped processing {block.ToString(Block.Format.Full)}"); } } else { if (_logger.IsTrace) { _logger.Trace($"Processed block {block.ToString(Block.Format.Full)}"); } _stats.UpdateStats(block, _recoveryQueue.Count, _blockQueue.Count); } if (_logger.IsTrace) { _logger.Trace($"Now {_blockQueue.Count} blocks waiting in the queue."); } if (_blockQueue.Count == 0) { ProcessingQueueEmpty?.Invoke(this, EventArgs.Empty); } } if (_logger.IsTrace) { _logger.Trace($"Returns from processing loop"); } }