Search in sources :

Example 1 with TransactionTrace

use of org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace in project besu by hyperledger.

the class DebugTraceBlockByHashTest method shouldReturnCorrectResponse.

@Test
public void shouldReturnCorrectResponse() {
    final Object[] params = new Object[] { blockHash };
    final JsonRpcRequestContext request = new JsonRpcRequestContext(new JsonRpcRequest("2.0", "debug_traceBlockByHash", params));
    final TraceFrame traceFrame = new TraceFrame(12, Optional.of("NONE"), 45L, OptionalLong.of(56L), 0L, 2, Optional.empty(), null, Wei.ZERO, Bytes.EMPTY, Bytes.EMPTY, Optional.empty(), Optional.empty(), Optional.empty(), null, Optional.empty(), Optional.empty(), Optional.empty(), 0, Optional.empty(), false, Optional.empty(), Optional.empty());
    final TransactionProcessingResult transaction1Result = mock(TransactionProcessingResult.class);
    final TransactionProcessingResult transaction2Result = mock(TransactionProcessingResult.class);
    final TransactionTrace transaction1Trace = mock(TransactionTrace.class);
    final TransactionTrace transaction2Trace = mock(TransactionTrace.class);
    BlockTrace blockTrace = new BlockTrace(Arrays.asList(transaction1Trace, transaction2Trace));
    when(transaction1Trace.getTraceFrames()).thenReturn(Arrays.asList(traceFrame));
    when(transaction2Trace.getTraceFrames()).thenReturn(Arrays.asList(traceFrame));
    when(transaction1Trace.getResult()).thenReturn(transaction1Result);
    when(transaction2Trace.getResult()).thenReturn(transaction2Result);
    when(transaction1Result.getOutput()).thenReturn(Bytes.fromHexString("1234"));
    when(transaction2Result.getOutput()).thenReturn(Bytes.fromHexString("1234"));
    when(blockTracer.trace(eq(blockHash), any())).thenReturn(Optional.of(blockTrace));
    final JsonRpcSuccessResponse response = (JsonRpcSuccessResponse) debugTraceBlockByHash.response(request);
    final Collection<?> result = (Collection<?>) response.getResult();
    assertThat(result).hasSize(2);
}
Also used : JsonRpcRequestContext(org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext) JsonRpcRequest(org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest) TransactionTrace(org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace) Collection(java.util.Collection) BlockTrace(org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTrace) JsonRpcSuccessResponse(org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse) TraceFrame(org.hyperledger.besu.ethereum.debug.TraceFrame) TransactionProcessingResult(org.hyperledger.besu.ethereum.processing.TransactionProcessingResult) Test(org.junit.Test)

Example 2 with TransactionTrace

use of org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace in project besu by hyperledger.

the class DebugTraceBlockByNumberTest method shouldReturnCorrectResponse.

@Test
public void shouldReturnCorrectResponse() {
    final long blockNumber = 1L;
    final Object[] params = new Object[] { Long.toHexString(blockNumber) };
    final JsonRpcRequestContext request = new JsonRpcRequestContext(new JsonRpcRequest("2.0", "debug_traceBlockByNumber", params));
    final TraceFrame traceFrame = new TraceFrame(12, Optional.of("NONE"), 45L, OptionalLong.of(56L), 0L, 2, Optional.empty(), null, Wei.ZERO, Bytes.EMPTY, Bytes.EMPTY, Optional.empty(), Optional.empty(), Optional.empty(), null, Optional.empty(), Optional.empty(), Optional.empty(), 0, Optional.empty(), false, Optional.empty(), Optional.empty());
    final TransactionProcessingResult transaction1Result = mock(TransactionProcessingResult.class);
    final TransactionProcessingResult transaction2Result = mock(TransactionProcessingResult.class);
    final TransactionTrace transaction1Trace = mock(TransactionTrace.class);
    final TransactionTrace transaction2Trace = mock(TransactionTrace.class);
    final BlockTrace blockTrace = new BlockTrace(asList(transaction1Trace, transaction2Trace));
    when(transaction1Trace.getTraceFrames()).thenReturn(singletonList(traceFrame));
    when(transaction2Trace.getTraceFrames()).thenReturn(singletonList(traceFrame));
    when(transaction1Trace.getResult()).thenReturn(transaction1Result);
    when(transaction2Trace.getResult()).thenReturn(transaction2Result);
    when(transaction1Result.getOutput()).thenReturn(Bytes.fromHexString("1234"));
    when(transaction2Result.getOutput()).thenReturn(Bytes.fromHexString("1234"));
    when(blockchain.getBlockHashByNumber(blockNumber)).thenReturn(Optional.of(blockHash));
    when(blockTracer.trace(eq(blockHash), any())).thenReturn(Optional.of(blockTrace));
    final JsonRpcSuccessResponse response = (JsonRpcSuccessResponse) debugTraceBlockByNumber.response(request);
    final Collection<DebugTraceTransactionResult> result = getResult(response);
    assertThat(result).usingFieldByFieldElementComparator().isEqualTo(DebugTraceTransactionResult.of(blockTrace.getTransactionTraces()));
}
Also used : DebugTraceTransactionResult(org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.DebugTraceTransactionResult) JsonRpcRequestContext(org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext) JsonRpcRequest(org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest) TransactionTrace(org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace) BlockTrace(org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTrace) JsonRpcSuccessResponse(org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse) TraceFrame(org.hyperledger.besu.ethereum.debug.TraceFrame) TransactionProcessingResult(org.hyperledger.besu.ethereum.processing.TransactionProcessingResult) Test(org.junit.Test)

Example 3 with TransactionTrace

use of org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace in project besu by hyperledger.

the class FlatTraceGenerator method handleReturn.

private static FlatTrace.Context handleReturn(final ProtocolSchedule protocolSchedule, final TransactionTrace transactionTrace, final Block block, final TraceFrame traceFrame, final Deque<FlatTrace.Context> tracesContexts, final FlatTrace.Context currentContext) {
    final FlatTrace.Builder traceFrameBuilder = currentContext.getBuilder();
    final Result.Builder resultBuilder = traceFrameBuilder.getResultBuilder();
    final Action.Builder actionBuilder = traceFrameBuilder.getActionBuilder();
    actionBuilder.value(Quantity.create(traceFrame.getValue()));
    currentContext.setGasUsed(computeGasUsed(tracesContexts, currentContext, transactionTrace, traceFrame));
    if ("STOP".equals(traceFrame.getOpcode()) && resultBuilder.isGasUsedEmpty()) {
        final long callStipend = protocolSchedule.getByBlockNumber(block.getHeader().getNumber()).getGasCalculator().getAdditionalCallStipend();
        tracesContexts.stream().filter(context -> !tracesContexts.getFirst().equals(context) && !tracesContexts.getLast().equals(context)).forEach(context -> context.decGasUsed(callStipend));
    }
    final Bytes outputData = traceFrame.getOutputData();
    if (resultBuilder.getCode() == null) {
        resultBuilder.output(outputData.toHexString());
    }
    // set value for contract creation TXes, CREATE, and CREATE2
    if (actionBuilder.getCallType() == null && traceFrame.getMaybeCode().isPresent()) {
        actionBuilder.init(traceFrame.getMaybeCode().get().getBytes().toHexString());
        resultBuilder.code(outputData.toHexString());
        if (currentContext.isCreateOp()) {
            // this is from a CREATE/CREATE2, so add code deposit cost.
            currentContext.incGasUsed(outputData.size() * 200L);
        }
    }
    tracesContexts.removeLast();
    final FlatTrace.Context nextContext = tracesContexts.peekLast();
    if (nextContext != null) {
        nextContext.getBuilder().incSubTraces();
    }
    return nextContext;
}
Also used : ExceptionalHaltReason(org.hyperledger.besu.evm.frame.ExceptionalHaltReason) Bytes(org.apache.tuweni.bytes.Bytes) Deque(java.util.Deque) Address(org.hyperledger.besu.datatypes.Address) AtomicReference(java.util.concurrent.atomic.AtomicReference) Quantity(org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity) ArrayList(java.util.ArrayList) ProtocolSchedule(org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule) OptionalLong(java.util.OptionalLong) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Locale(java.util.Locale) TraceFrame(org.hyperledger.besu.ethereum.debug.TraceFrame) Atomics(com.google.common.util.concurrent.Atomics) Wei(org.hyperledger.besu.datatypes.Wei) Words.toAddress(org.hyperledger.besu.evm.internal.Words.toAddress) Trace(org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.tracing.Trace) Block(org.hyperledger.besu.ethereum.core.Block) Code(org.hyperledger.besu.evm.Code) TracingUtils(org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.tracing.TracingUtils) TransactionTrace(org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace) Iterator(java.util.Iterator) Streams(com.google.common.collect.Streams) Collectors(java.util.stream.Collectors) Consumer(java.util.function.Consumer) List(java.util.List) Stream(java.util.stream.Stream) Optional(java.util.Optional) ArrayDeque(java.util.ArrayDeque) Transaction(org.hyperledger.besu.ethereum.core.Transaction) Bytes(org.apache.tuweni.bytes.Bytes)

Example 4 with TransactionTrace

use of org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace in project besu by hyperledger.

the class TraceCallMany method getSingleCallResult.

private JsonNode getSingleCallResult(final JsonCallParameter callParameter, final TraceTypeParameter traceTypeParameter, final BlockHeader header, final WorldUpdater worldUpdater) {
    final Set<TraceTypeParameter.TraceType> traceTypes = traceTypeParameter.getTraceTypes();
    final DebugOperationTracer tracer = new DebugOperationTracer(buildTraceOptions(traceTypes));
    final Optional<TransactionSimulatorResult> maybeSimulatorResult = transactionSimulator.processWithWorldUpdater(callParameter, buildTransactionValidationParams(), tracer, header, worldUpdater);
    LOG.trace("Executing {} call for transaction {}", traceTypeParameter, callParameter);
    if (maybeSimulatorResult.isEmpty()) {
        throw new EmptySimulatorResultException();
    }
    final TransactionSimulatorResult simulatorResult = maybeSimulatorResult.get();
    if (simulatorResult.isInvalid()) {
        throw new TransactionInvalidException();
    }
    final TransactionTrace transactionTrace = new TransactionTrace(simulatorResult.getTransaction(), simulatorResult.getResult(), tracer.getTraceFrames());
    final Block block = blockchainQueriesSupplier.get().getBlockchain().getChainHeadBlock();
    return getTraceCallResult(protocolSchedule, traceTypes, maybeSimulatorResult, transactionTrace, block);
}
Also used : TransactionSimulatorResult(org.hyperledger.besu.ethereum.transaction.TransactionSimulatorResult) DebugOperationTracer(org.hyperledger.besu.ethereum.vm.DebugOperationTracer) TransactionTrace(org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace) Block(org.hyperledger.besu.ethereum.core.Block)

Example 5 with TransactionTrace

use of org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace in project besu by hyperledger.

the class FlatTraceGeneratorTest method testGenerateFromTransactionTraceWithRevertReason.

@Test
public void testGenerateFromTransactionTraceWithRevertReason() {
    final Bytes revertReason = Bytes.random(32);
    Mockito.when(transaction.getSender()).thenReturn(Address.ZERO);
    Mockito.when(transactionProcessingResult.getRevertReason()).thenReturn(Optional.of(revertReason));
    final TransactionTrace transactionTrace = new TransactionTrace(transaction, transactionProcessingResult, Collections.emptyList());
    final Stream<Trace> traceStream = FlatTraceGenerator.generateFromTransactionTrace(null, transactionTrace, null, new AtomicInteger());
    final List<Trace> traces = traceStream.collect(Collectors.toList());
    Assertions.assertThat(traces.isEmpty()).isFalse();
    Assertions.assertThat(traces.get(0)).isNotNull();
    Assertions.assertThat(traces.get(0) instanceof FlatTrace).isTrue();
    Assertions.assertThat(((FlatTrace) traces.get(0)).getRevertReason()).isEqualTo(revertReason.toHexString());
}
Also used : TransactionTrace(org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace) Trace(org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.tracing.Trace) Bytes(org.apache.tuweni.bytes.Bytes) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TransactionTrace(org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace) Test(org.junit.Test)

Aggregations

TransactionTrace (org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace)11 JsonRpcRequestContext (org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext)6 JsonRpcSuccessResponse (org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse)6 TraceFrame (org.hyperledger.besu.ethereum.debug.TraceFrame)6 DebugOperationTracer (org.hyperledger.besu.ethereum.vm.DebugOperationTracer)6 Test (org.junit.Test)6 JsonRpcRequest (org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest)5 Block (org.hyperledger.besu.ethereum.core.Block)5 TransactionProcessingResult (org.hyperledger.besu.ethereum.processing.TransactionProcessingResult)5 Bytes (org.apache.tuweni.bytes.Bytes)4 BlockTrace (org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTrace)4 JsonRpcErrorResponse (org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse)3 TransactionSimulatorResult (org.hyperledger.besu.ethereum.transaction.TransactionSimulatorResult)3 Collection (java.util.Collection)2 HashMap (java.util.HashMap)2 List (java.util.List)2 Optional (java.util.Optional)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 Address (org.hyperledger.besu.datatypes.Address)2 TraceTypeParameter (org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TraceTypeParameter)2