-
Notifications
You must be signed in to change notification settings - Fork 55
fix(l2): limit block to blob size #2292
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
Conversation
Lines of code reportTotal lines added: Detailed view
|
@@ -23,6 +23,26 @@ pub enum EvmState { | |||
Execution(Box<revm::db::CacheDB<ExecutionDB>>), | |||
} | |||
|
|||
impl Clone for EvmState { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was needed to restore the previous EVM state after executing a transaction whose resulting state diff doesn't fit in a blob.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That merits a code comment I believe. My first instinct in a few months after seeing this would be to try and convert it into a derive
, breaking the logic. Can't be the only one.
Also, where this differs from the derive(Clone)
should also be commented. I guess it's the cache clone at the end?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem was that revm::db::State
doesn't implement the Clone
trait. I added a comment here: dc9d5d8!
crates/blockchain/payload.rs
Outdated
@@ -540,6 +567,132 @@ impl Blockchain { | |||
context.account_updates = account_updates; | |||
Ok(()) | |||
} | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the idea is not to pollute l1 with a lot of l2 code, can't this go inside l2 crate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved tol2/sequencer/block_producer/payload_builder.rs
!
&mut accounts_info_cache, | ||
)? { | ||
debug!( | ||
"Skipping transaction: {}, doesn't feet in blob_size", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"doesn't feet" -> "doesn't fit"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in 621592b!
Let's add a similar "short circuit" if the current state diff size is too close to the limit for almost any meaningful transaction to get through, similar to this check for gas
we could use the state diff cost for a regular transfer transaction that touches new storage slots as a baseline. |
Added in 3169adb! |
Benchmark Results ComparisonPR ResultsBenchmark Results: Factorial
Benchmark Results: Factorial - Recursive
Benchmark Results: Fibonacci
Benchmark Results: ManyHashes
Benchmark Results: BubbleSort
Benchmark Results: ERC20 - Transfer
Benchmark Results: ERC20 - Mint
Benchmark Results: ERC20 - Approval
Main ResultsBenchmark Results: Factorial
Benchmark Results: Factorial - Recursive
Benchmark Results: Fibonacci
Benchmark Results: ManyHashes
Benchmark Results: BubbleSort
Benchmark Results: ERC20 - Transfer
Benchmark Results: ERC20 - Mint
Benchmark Results: ERC20 - Approval
|
if !blob_txs.is_empty() && context.blobs_bundle.blobs.len() >= max_blob_number_per_block { | ||
debug!("No more blob gas to run blob transactions"); | ||
blob_txs.clear(); | ||
} | ||
// Fetch the next transactions | ||
let (head_tx, is_blob) = match (plain_txs.peek(), blob_txs.peek()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we won't support blob txs in the L2, so maybe this is unnecessary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, we almost certainly won't support them, but I would tackle this in a separate PR where we remove all blob txs support on the L2
async fn check_state_diff_size( | ||
acc_withdrawals_size: &mut usize, | ||
acc_deposits_size: &mut usize, | ||
acc_state_diff_size: &mut usize, | ||
tx: Transaction, | ||
receipt: &Receipt, | ||
context: &mut PayloadBuildContext, | ||
accounts_info_cache: &mut HashMap<Address, Option<AccountInfo>>, | ||
) -> Result<bool, BlockProducerError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd add a doc comment saying what changes it'll do to the mut variables. Also maybe consider rename the function to something like update_state_diff_size
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in 0a1050a!
Motivation
With our current implementation, if a block state diff exceeds the blob size, we are unable to commit that block.
Description
This PR provides an initial solution by calculating the state diff size after including each transaction in the block. If the size exceeds the blob limit, the previous state is restored and transactions continue to be added from the remaining senders in the mempool.
Observations
blockchain::build_payload
was "replicated" inblock_producer/payload_builder.rs
with two key differences:blockchain::apply_system_operations
.fill_transactions
which adds the logic described above.blockchain
are now public to allow access frompayload_builder
.PayloadBuildContext
now contains am ownedBlock
instead of a mutable reference of it, as we need to be able to clone thePayloadBuildContext
to restore a previous state.PayloadBuildContext
is cloned before each transaction execution, which may impact performance.vm.get_state_transitions()
is called to compute the state diff size.REVM::vm.get_state_transitions()
mutates thePayloadBuildContext
, we need to clone it to avoid unintended changes.accounts_info_cache
is used to prevent callingget_account_info
on every tx execution.Warning
clone()
calls.LEVM::get_state_transitions
internally callsget_account_info
.These issues will be addressed in future PRs.