Add support for 4byteTracer in debug_trace* methods#9642
Add support for 4byteTracer in debug_trace* methods#9642usmansaleem merged 29 commits intobesu-eth:mainfrom
Conversation
Add support for the 4byteTracer which collects function selectors (first 4 bytes of call data) from all internal calls during transaction execution, along with the size of the remaining call data. Implementation includes: - Add FOUR_BYTE_TRACER to TracerType enum - Create FourByteTracerResult class for JSON output - Create FourByteTracerResultConverter to process transaction traces - Wire 4ByteTracer into DebugTraceTransactionStepFactory - Add comprehensive unit tests The implementation matches Geth's behavior by: - Only processing CALL-type operations (CALL, CALLCODE, DELEGATECALL, STATICCALL) - Excluding CREATE/CREATE2 operations and precompiled contracts - Only counting calls that successfully enter (depth increases) - Calculating size as input length minus 4 bytes (the selector) - Excluding the initial transaction call (only internal calls) Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
...rg/hyperledger/besu/ethereum/api/jsonrpc/internal/results/FourByteTracerResultConverter.java
Outdated
Show resolved
Hide resolved
Signed-off-by: Usman Saleem <usman@usmans.info>
Update FourByteTracerResultConverter to use ProtocolSpec's precompile contract registry instead of hardcoded address checks when detecting precompiled contracts. This ensures correct precompile detection across different protocol specs. - Add ProtocolSpec parameter to convert() method - Use protocolSpec.getPrecompileContractRegistry().get() for precompile detection - Update all tests to pass mock ProtocolSpec - Add test coverage for null ProtocolSpec parameter Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
...rg/hyperledger/besu/ethereum/api/jsonrpc/internal/results/FourByteTracerResultConverter.java
Outdated
Show resolved
Hide resolved
lu-pinto
left a comment
There was a problem hiding this comment.
I see that you are using a post processing approach where you are collecting all traces and then filtering out/picking up the information you are interested on afterwards. I would have done an in-EVM approach to build this data while tracing. The current approach could easily blow up memory usage for transactions with large enough executions.
I have already bumped into a case on hoodi where tracing timed out with one of the blocks. To debug that block I added an in-EVM tracing option to only capture specific selected opcodes and ignore all others that I didn't need. Idea: maybe these tracer types could be implemented with that feature.
Having said that, I understand that what I ask above should not be part of this PR since it's a lot of work. Pretty much all TracerTypes are already implemented with post processing so makes sense to be consistent too. Just letting you know my thoughts about this code.
...yperledger/besu/ethereum/api/jsonrpc/internal/results/FourByteTracerResultConverterTest.java
Outdated
Show resolved
Hide resolved
|
|
||
| @Test | ||
| @DisplayName("should handle nested sub-calls and count multiple occurrences") | ||
| void shouldHandleNestedSubCallsAndCountMultipleOccurrences() { |
There was a problem hiding this comment.
tests named with ...And... generally mean you need 2 separate tests. This test is more than 100 lines long!
I'm even for duplicating setup code that asserts different things, this way unit tests are cleaner.
There was a problem hiding this comment.
👍🏼 Refactored it into two methods.
lu-pinto
left a comment
There was a problem hiding this comment.
Would have liked to see at least a test end to end showing the new tracer type working.
Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Usman Saleem <usman@usmans.info>
|
@lu-pinto I've also added spec tests generated against Geth for 4ByteTracer. |
Signed-off-by: Usman Saleem <usman@usmans.info>
Implement 4ByteTracer in Besu --------- Signed-off-by: Usman Saleem <usman@usmans.info>
PR description
Implements Geth's
4byteTracerfordebug_traceTransaction,debug_traceBlock, and related debug trace methods. The 4byteTracer collects function selectors (the first 4 bytes of call data) from all internal calls made during transaction execution, along with the size of the remaining call data (excluding the 4-byte selector).Changes
FOUR_BYTE_TRACERtoTracerTypeenumFourByteTracerResultclass for JSON output formattingFourByteTracerResultConverterto process transaction tracesDebugTraceTransactionStepFactoryImplementation Details
The implementation matches Geth's 4byteTracer behavior:
input_length - 4(excluding the selector)Output Format
Returns a map where keys are in the format
"0x[4-byte-selector]-[remaining-size]"and values are occurrence counts:{ "0x27dc297e-128": 1, "0x38cc4831-0": 2, "0x524f3889-96": 1 }Testing
References
Acknowledgements
Based on original contribution PR: #9202 by @JukLee0ira
Fixed Issue(s)
Thanks for sending a pull request! Have you done the following?
doc-change-requiredlabel to this PR if updates are required.Locally, you can run these tests to catch failures early:
./gradlew spotlessApply./gradlew build./gradlew acceptanceTest./gradlew integrationTest./gradlew ethereum:referenceTests:referenceTests