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(execution): binary search fee estimation #2566

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

sistemd
Copy link
Contributor

@sistemd sistemd commented Feb 3, 2025

Closes #2488.

@sistemd sistemd requested a review from a team as a code owner February 3, 2025 11:08
Comment on lines +63 to +64
/// The margin for the binary search for the minimal L2 gas limit.
const L2_GAS_SEARCH_MARGIN: GasAmount = GasAmount(100);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Question: is this OK? It seems to work well on sepolia at least, and doesn't take a very long time to converge. Making this value smaller gives precision in exchange for performance, whereas making it larger gives performance in exchange for precision.

Copy link
Contributor

Choose a reason for hiding this comment

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

We should ask Ariel if this is OK.

Comment on lines +101 to +102
// TODO: g = (1 + EPSILON) * g
// This step is missing. Check what EPSILON is, then implement it.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Question: what is this EPSILON value from the issue? Surely it's not f64::EPSILON, that doesn't really make sense.

Copy link
Contributor

Choose a reason for hiding this comment

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

Wasn't there some discussion about Starknet adapting the Ethereum algorithm? Specifically the Reth implementation? AFAIK there was some epsilon there, somewhere, but I can't find it now...

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is an "optimization" over the Ethereum algorithm. I think Ariel's idea was that in most cases refunds should be relatively small so he was expecting that most transactions run OK with a budget ~20% larger than the actual consumption after refunds. The ~20% margin was considered small enough so that it's not worth finding the exact value within that range.

Let us confirm the actual value of EPSILON with Ariel.

Comment on lines +375 to +376
// TODO: Is there a type-safe way to check for this error?
revert_error.to_string().contains("Out of gas")
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 think the answer to this is "no". At least I haven't been able to do this any better.

Copy link
Contributor

Choose a reason for hiding this comment

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

That's another good question. As far as I understand no, there's no better way since the actual error is converted to a string in the error stack so we're losing typed errors here.

return Err(error);
}
Err(TransactionSimulationError::OutOfGas) => {
unreachable!("Transaction should not run out of gas with MAX gas limit")
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if it's possible to construct a transaction so expensive it would run out even of GasAmount::MAX...

Copy link
Contributor

Choose a reason for hiding this comment

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

Plus, that seems to be a trivial DoS vector -- I'm sure there's a per-block gas limit, we should probably just use that.

fn midpoint(a: GasAmount, b: GasAmount) -> GasAmount {
let GasAmount(a) = a;
let GasAmount(b) = b;
GasAmount(a + (b - a) / 2)
Copy link
Contributor

Choose a reason for hiding this comment

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

This does not handle u64 overflows. I know it's rare, but still, we should be careful.

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 disagree:

  • a is a valid u64.
  • b is a valid u64.
  • (b - a) / 2 can't underflow due to how the surrounding code is written (i.e. b is always greater than a).
  • a + (b - a) / 2 is guaranteed to give a number between a and b hence can't overflow.

The code is written this way intentionally to avoid overflows. Let me know if I'm missing something.

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.

Implement binary search based fee estimation algorithm
3 participants