Skip to content
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

Feat/native 4byte tracer #6864

Merged
merged 10 commits into from
Mar 28, 2024
Merged

Feat/native 4byte tracer #6864

merged 10 commits into from
Mar 28, 2024

Conversation

natebeauregard
Copy link
Contributor

Changes

  • Sets up infrastructure to create and register custom native tracers
  • Adds a native 4byte tracer implementation
    • The 4byteTracer collects the function selectors of every function executed in the lifetime of a transaction, along with the size of the supplied call data. The result is a dictionary where the keys are SELECTOR-CALLDATASIZE and the values are number of occurrences of this key.
  • Renames the 4byte tracer JS implementation to be 4byteTracer_legacy

Types of changes

What types of changes does your code introduce?

  • Bugfix (a non-breaking change that fixes an issue)
  • New feature (a non-breaking change that adds functionality)
  • Breaking change (a change that causes existing functionality not to work as expected)
  • Optimization
  • Refactoring
  • Documentation update
  • Build-related changes
  • Other: Description

Testing

Requires testing

  • Yes
  • No

If yes, did you write tests?

  • Yes
  • No

Notes on testing

I repurposed a script that @Marchhilloriginally wrote for automating testing the JS tracer implementations. The script listens for new blocks/transactions, sends a request to get the 4byteTracer results, and compares the native and legacy tracer results and checks for any differences.

We'll also want to do some performance testing to ensure that the performance is significantly better than the JS implementation and comparable to Geth/Reth.

Documentation

Requires documentation update

  • Yes
  • No

Requires explanation in Release Notes

  • Yes
  • No

@natebeauregard natebeauregard marked this pull request as draft March 25, 2024 18:33
@natebeauregard natebeauregard marked this pull request as ready for review March 26, 2024 14:34
Copy link
Member

@LukaszRozmej LukaszRozmej left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall very good, just few nitpicks and potential ideas to consider.


private void Store4ByteIds(ReadOnlyMemory<byte> input, int size)
{
string _4byteId = input.Span[..4].ToHexString() + '-' + size;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

micro-optimization: you could use string.create instead of concatenating strings, resulting in less allocations.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I attempted to follow the approach used to create strings in StateTestTxTracer, however I've been having some difficulty trying to implement it correctly. I may reach out for some assistance if I can't figure it out

Copy link
Member

@LukaszRozmej LukaszRozmej Mar 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if worth it as it makes it less readable:

        static int GetDigitsBase10(int n) => n == 0 ? 1 : (int)Math.Floor(Math.Log10(Math.Abs(n)) + 1);
        const int length = 4;
        string _4byteId = string.Create(length * 2 + 1 + GetDigitsBase10(size), (input, size), (span, state) =>
        {
            ref char charsRef = ref MemoryMarshal.GetReference(span);
            ReadOnlySpan<byte> bytes = state.input.Span[..length];
            Bytes.OutputBytesToCharHex(ref MemoryMarshal.GetReference(bytes), length, ref charsRef, false, 0);
            span[length * 2] = '-';
            size.TryFormat(span.Slice(length * 2 + 1), out _);
        });

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh cool! Since the main goal of this PR is to optimize performance for the tracers then I think it makes sense to use this, even if it's less readable. I'll add a comment explaining that it's just concatenating strings

Copy link
Contributor

@Marchhill Marchhill left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few small nitpicks, looks good as long as the script isn't finding any diffs

// }
public sealed class Native4ByteTracer : GethLikeNativeTxTracer
{
public const string _4byteTracer = "4byteTracer";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: public variable starting with _

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I wasn't sure what to do here since the variable name starts with a number. Should I just rename the constant to be FourByteTracer instead?

@natebeauregard natebeauregard merged commit 55a6ec2 into master Mar 28, 2024
67 checks passed
@natebeauregard natebeauregard deleted the feat/native-4byteTracer branch March 28, 2024 14:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants