Skip to content

fix(core/txpool/legacypool): fix flaky TestAllowedTxSize #31142

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

Closed

Conversation

qdm12
Copy link
Contributor

@qdm12 qdm12 commented Feb 7, 2025

First of all, my apologies for not correctly/fully fixing this in my previous PR #30975

The test was failing occasionally because:

  • the RLP encoding of the transaction data length can vary from 0 to 5 bytes (not a problem in our current test cases, but it could be a problem with more test cases)
  • the RLP encoding of the signature can vary from 3 to 68 bytes (v+r+s *big.Int components) - in practice it oscillates around 65 bytes. This is the main problem.
  • even for matching signature lengths, the size of the RLP encoding of a signed transaction is not always the same as the size of the RLP encoding of the same transaction unsigned + the signature length

To work around this, the logic to generate transaction with a target size was reworked: the transaction data content and length is changed until the desired transaction size is reached. This makes the test deterministic regarding transaction sizes.

…ally

reowrk the transaction generation logic to change the data content and length until the desired transaction size is reached.
This makes the test deterministic regarding transaction sizes, whilst keeping the random transaction data.
3 + // 3 is the minimum signature encoding size
5 - // 5 is the maximum data length encoding size
0 // 0 is the minimum data length encoding size
for range tries {
Copy link
Contributor

@jwasinger jwasinger Feb 9, 2025

Choose a reason for hiding this comment

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

I think this could be simplified by assuming that we want to find a target signature size of 65 bytes, and then in an infinite loop generate signed data transactions of targetSize - 65 and return if the signed tx size is the target size.

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'm still working on this, it's taking a bit longer than expected, please keep this opened ~24 hours and I'll get it done. Thanks!

Copy link
Contributor Author

@qdm12 qdm12 Feb 12, 2025

Choose a reason for hiding this comment

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

Done in 7c5f53e although it it is "less dumb", it is also longer and less simple unfortunately. The main reason of this complexity being that:

len(rlp(signedTx)) is not always len(rlp(unsignedTx)) + signatureLength (same signatures lengths, same unsigned transaction)

This must be due to some RLP implementation details, but I would rather not dig too much into that.
Therefore, we could also revert it to be less-clever/simpler as it was before, kind of (gently) bruteforcing until we have the desired transaction size. Any other suggestion is more than welcome though!

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for taking the time to make these changes. I think I'm only now realizing that creating a generic sizedDataTransaction function is pretty non-trivial.

Given that the test-case is really concerned about the boundary conditions (maxSize - 1, maxSize, maxSize + 1), I'm wondering if we could pair down the complexity of this test by only generating txs of these sizes.

It's not quite as nice as generating a wider variety of inputs, but it could probably suffice here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we have a fixed key and deterministic data generation (no crand.Read), there are two ways to do this:

  1. have fully pre-determined transactions, for example as hex encoding of RLP encoding. This removes a lot of logic, but makes the source code rather big given transactions are rather big in sizes. We could move these to a testdata directory. Thoughts?
  2. Keep generating with a bit less logic, given the signature length can vary with the data length, even if the key is fixed and the data is all zeroes. This is what I've done in the last commit 399949c

- Add check for a target size greater or equal to minimum size
- Generate transactions only with 65 byte signatures
- Adjust data length when signed transaction RLP encoding size varies by +- 1,2 bytes
@qdm12 qdm12 requested a review from jwasinger February 12, 2025 10:52
@MariusVanDerWijden
Copy link
Member

This seems like a very very complex solution to the problem. I would like to discuss this on triage

Comment on lines 1204 to 1212
// We use a deterministic ecdsa key to obtain signed transactions of pre-determined sizes.
key := &ecdsa.PrivateKey{
PublicKey: ecdsa.PublicKey{
Curve: elliptic.P256(),
X: new(big.Int).SetBytes(common.Hex2Bytes("78e68ff485cc934e4096f24091931e91334d6841c6c2be93d1a930e59783902d")),
Y: new(big.Int).SetBytes(common.Hex2Bytes("ca8db229299a4f937eeb0a36c451751cd59df978aceaaf190c28783c321cf267")),
},
D: new(big.Int).SetBytes(common.Hex2Bytes("e521e757356c1f197f704502dfa10333993e3705ca3d304d6a349461ed67ae71")),
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This statement can be replaced by crypto.HexToECDSA("e521e757356c1f197f704502dfa10333993e3705ca3d304d6a349461ed67ae71")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, thanks for the tip 👍

@fjl fjl removed the status:triage label Feb 25, 2025
@qdm12
Copy link
Contributor Author

qdm12 commented Feb 27, 2025

This seems like a very very complex solution to the problem. I would like to discuss this on triage

Any update or idea on how to make this test simpler? 🤔

@fjl
Copy link
Contributor

fjl commented May 20, 2025

Closing because we decided to include the simpler alternative #31836

@fjl fjl closed this May 20, 2025
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.

4 participants