-
Notifications
You must be signed in to change notification settings - Fork 127
Add debug tracers needed for modularized workflow #11477
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
steven-sheehy
merged 23 commits into
main
from
11424-add-tracers-for-modularized-workflow
Jul 10, 2025
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
7f6b200
feat: add tracers needed for debug_traceTransaction to be compliant w…
IvanKavaldzhiev a1a8f1c
fix: unit tests
IvanKavaldzhiev ddd1086
refactor: remove unnecessary code and extract common code in an utili…
IvanKavaldzhiev c03a405
Merge remote-tracking branch 'origin/main' into 11424-fix-tracer-with…
IvanKavaldzhiev fbc394d
Merge remote-tracking branch 'origin/main' into 11424-fix-tracer-with…
IvanKavaldzhiev d82f723
nit: copy CustomMessageCallProcessor from upstream
IvanKavaldzhiev 8f25f5f
feat: add support for OpcodeActionTracer in modularized workflow
IvanKavaldzhiev 5dd3038
Merge remote-tracking branch 'origin/main' into 11424-fix-tracer-with…
IvanKavaldzhiev 4f89b5b
Merge remote-tracking branch 'origin/main' into 11424-fix-tracer-with…
IvanKavaldzhiev 5760ce5
fix: unit tests
IvanKavaldzhiev 50e2a5e
Merge remote-tracking branch 'origin/main' into 11424-fix-tracer-with…
IvanKavaldzhiev de03967
nit: resolve PR comments
IvanKavaldzhiev 7ad4ec8
feat: add missing modularized header in OpcodesController
IvanKavaldzhiev 4a9f6f8
fix: adapt opcode tracer to work with nested transactions
IvanKavaldzhiev 40d3b4c
Merge remote-tracking branch 'origin/main' into 11424-fix-tracer-with…
IvanKavaldzhiev 78fd0a9
style: add given,when,then separation in tests
IvanKavaldzhiev 89fc1ec
Merge remote-tracking branch 'origin/main' into 11424-fix-tracer-with…
IvanKavaldzhiev e7ee181
nit: resolve PR comments
IvanKavaldzhiev add64cd
Merge remote-tracking branch 'origin/main' into 11424-fix-tracer-with…
IvanKavaldzhiev f07e1c5
nit: remove conditional bean declaration
IvanKavaldzhiev 8cb1803
Merge remote-tracking branch 'origin/main' into 11424-fix-tracer-with…
IvanKavaldzhiev 4742d1b
nit: resolve PR comments
IvanKavaldzhiev 89e3b14
nit: add missing final statement
IvanKavaldzhiev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
376 changes: 376 additions & 0 deletions
376
...com/hedera/node/app/service/contract/impl/exec/processors/CustomMessageCallProcessor.java
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
86 changes: 86 additions & 0 deletions
86
...java/org/hiero/mirror/web3/evm/contracts/execution/traceability/AbstractOpcodeTracer.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package org.hiero.mirror.web3.evm.contracts.execution.traceability; | ||
|
||
import com.hederahashgraph.api.proto.java.ResponseCodeEnum; | ||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import org.apache.tuweni.bytes.Bytes; | ||
import org.hiero.mirror.common.domain.contract.ContractAction; | ||
import org.hiero.mirror.web3.common.ContractCallContext; | ||
import org.hiero.mirror.web3.convert.BytesDecoder; | ||
import org.hyperledger.besu.evm.frame.MessageFrame; | ||
import org.springframework.util.CollectionUtils; | ||
|
||
public abstract class AbstractOpcodeTracer { | ||
|
||
protected final List<Bytes> captureMemory(final MessageFrame frame, final OpcodeTracerOptions options) { | ||
if (!options.isMemory()) { | ||
return Collections.emptyList(); | ||
} | ||
|
||
int size = frame.memoryWordSize(); | ||
var memory = new ArrayList<Bytes>(size); | ||
for (int i = 0; i < size; i++) { | ||
memory.add(frame.readMemory(i * 32L, 32)); | ||
} | ||
|
||
return memory; | ||
} | ||
|
||
protected final List<Bytes> captureStack(final MessageFrame frame, final OpcodeTracerOptions options) { | ||
if (!options.isStack()) { | ||
return Collections.emptyList(); | ||
} | ||
|
||
int size = frame.stackSize(); | ||
var stack = new ArrayList<Bytes>(size); | ||
for (int i = 0; i < size; ++i) { | ||
stack.add(frame.getStackItem(size - 1 - i)); | ||
} | ||
|
||
return stack; | ||
} | ||
|
||
protected final Optional<Bytes> getRevertReasonFromContractActions(final ContractCallContext context) { | ||
final var contractActions = context.getContractActions(); | ||
|
||
if (CollectionUtils.isEmpty(contractActions)) { | ||
return Optional.empty(); | ||
} | ||
|
||
return contractActions.stream() | ||
.filter(ContractAction::hasRevertReason) | ||
.map(action -> Bytes.of(action.getResultData())) | ||
.map(this::formatRevertReason) | ||
.findFirst(); | ||
} | ||
|
||
/** | ||
* Formats the revert reason to be consistent with the revert reason format in the EVM. <a | ||
* href="https://besu.hyperledger.org/23.10.2/private-networks/how-to/send-transactions/revert-reason#revert-reason-format">...</a> | ||
* | ||
* @param revertReason the revert reason | ||
* @return the formatted revert reason | ||
*/ | ||
protected final Bytes formatRevertReason(final Bytes revertReason) { | ||
if (revertReason == null || revertReason.isZero()) { | ||
return Bytes.EMPTY; | ||
} | ||
|
||
// covers an edge case where the reason in the contract actions is a response code number (as a plain string) | ||
// so we convert this number to an ABI-encoded string of the corresponding response code name, | ||
// to at least give some relevant information to the user in the valid EVM format | ||
final var trimmedReason = revertReason.trimLeadingZeros(); | ||
if (trimmedReason.size() <= Integer.BYTES) { | ||
final var responseCode = ResponseCodeEnum.forNumber(trimmedReason.toInt()); | ||
if (responseCode != null) { | ||
return BytesDecoder.getAbiEncodedRevertReason(responseCode.name()); | ||
} | ||
} | ||
|
||
return BytesDecoder.getAbiEncodedRevertReason(revertReason); | ||
} | ||
} |
90 changes: 90 additions & 0 deletions
90
...g/hiero/mirror/web3/evm/contracts/execution/traceability/MirrorOperationActionTracer.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package org.hiero.mirror.web3.evm.contracts.execution.traceability; | ||
|
||
import com.hedera.hapi.streams.ContractActionType; | ||
import com.hedera.hapi.streams.ContractActions; | ||
import com.hedera.node.app.service.contract.impl.exec.ActionSidecarContentTracer; | ||
import com.hedera.services.utils.EntityIdUtils; | ||
import edu.umd.cs.findbugs.annotations.NonNull; | ||
import jakarta.inject.Named; | ||
import java.util.Optional; | ||
import lombok.CustomLog; | ||
import lombok.RequiredArgsConstructor; | ||
import org.apache.commons.lang3.StringUtils; | ||
import org.hiero.mirror.common.domain.entity.Entity; | ||
import org.hiero.mirror.web3.evm.properties.TraceProperties; | ||
import org.hiero.mirror.web3.state.CommonEntityAccessor; | ||
import org.hyperledger.besu.evm.frame.MessageFrame; | ||
import org.hyperledger.besu.evm.operation.Operation; | ||
|
||
@Named | ||
@CustomLog | ||
@RequiredArgsConstructor | ||
public class MirrorOperationActionTracer implements ActionSidecarContentTracer { | ||
|
||
private final TraceProperties traceProperties; | ||
private final CommonEntityAccessor commonEntityAccessor; | ||
|
||
@Override | ||
public void tracePostExecution( | ||
@NonNull final MessageFrame frame, @NonNull final Operation.OperationResult operationResult) { | ||
if (!traceProperties.isEnabled()) { | ||
return; | ||
} | ||
|
||
if (traceProperties.stateFilterCheck(frame.getState())) { | ||
return; | ||
} | ||
|
||
final var recipientAddress = frame.getRecipientAddress(); | ||
final var recipientNum = recipientAddress != null | ||
? commonEntityAccessor.get( | ||
com.hedera.pbj.runtime.io.buffer.Bytes.wrap(recipientAddress.toArray()), Optional.empty()) | ||
: Optional.empty(); | ||
|
||
if (recipientNum.isPresent() | ||
&& traceProperties.contractFilterCheck( | ||
EntityIdUtils.asHexedEvmAddress(((Entity) recipientNum.get()).getId()))) { | ||
return; | ||
} | ||
|
||
log.info( | ||
Check warning on line 52 in web3/src/main/java/org/hiero/mirror/web3/evm/contracts/execution/traceability/MirrorOperationActionTracer.java
|
||
"type={} operation={}, callDepth={}, contract={}, sender={}, recipient={}, remainingGas={}, revertReason={}, input={}, output={}, return={}", | ||
frame.getType(), | ||
frame.getCurrentOperation() != null | ||
? frame.getCurrentOperation().getName() | ||
: StringUtils.EMPTY, | ||
frame.getDepth(), | ||
frame.getContractAddress().toShortHexString(), | ||
frame.getSenderAddress().toShortHexString(), | ||
frame.getRecipientAddress().toShortHexString(), | ||
frame.getRemainingGas(), | ||
frame.getRevertReason() | ||
.orElse(org.apache.tuweni.bytes.Bytes.EMPTY) | ||
.toHexString(), | ||
frame.getInputData().toShortHexString(), | ||
frame.getOutputData().toShortHexString(), | ||
frame.getReturnData().toShortHexString()); | ||
} | ||
|
||
@Override | ||
public void traceOriginAction(@NonNull MessageFrame frame) { | ||
// NO-OP | ||
} | ||
|
||
@Override | ||
public void sanitizeTracedActions(@NonNull MessageFrame frame) { | ||
// NO-OP | ||
} | ||
|
||
@Override | ||
public void tracePrecompileResult(@NonNull MessageFrame frame, @NonNull ContractActionType type) { | ||
// NO-OP | ||
} | ||
|
||
@Override | ||
public ContractActions contractActions() { | ||
return null; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.