Skip to content
Closed
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 56 additions & 1 deletion src/l1block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ const L1_SCALAR_SLOT: U256 = U256::from_limbs([3u64, 0, 0, 0]);
const L1_BLOB_BASE_FEE_SLOT: U256 = U256::from_limbs([5u64, 0, 0, 0]);

/// The L1 commit scalar storage slot.
///
/// Post-FEYNMAN this represents the exec_scalar.
const L1_COMMIT_SCALAR_SLOT: U256 = U256::from_limbs([6u64, 0, 0, 0]);

/// The L1 blob scalar storage slot.
Expand Down Expand Up @@ -136,12 +138,65 @@ impl L1BlockInfo {
self.calldata_gas.unwrap().saturating_add(blob_gas).wrapping_div(TX_L1_FEE_PRECISION)
}

fn calculate_tx_l1_cost_feynman(&self, input: &[u8], spec_id: ScrollSpecId) -> U256 {
// rollup_fee(tx) = compression_ratio(tx) * size(tx) * (component_exec + component_blob)
//
// - compression_ratio(tx): estimated compression ratio of RLP-encoded signed tx data,
// derived by plugging in this tx into the previous finalised batch. This gives us an idea
// as to how compressible is the zstd-encoding of the data in this tx.
//
// - size(tx): denotes the size of the RLP-encoded signed tx data.
//
// - component_exec: The component that accounts towards commiting this tx as part of a L2
// batch as well as gas costs for the eventual on-chain proof verification.
// => (compression_scalar + commit_scalar + verification_scalar) * l1_base_fee
// => (new_commit_scalar) * l1_base_fee
//
// - component_blob: The component that accounts the costs associated with data
// availability, i.e. the costs of posting this tx's data in the EIP-4844 blob.
// => (compression_scalar + blob_scalar) * l1_blob_base_fee
// => (new_blob_scalar) * l1_blob_base_fee
//
// Note that the same slots for L1_COMMIT_SCALAR_SLOT and L1_BLOB_SCALAR_SLOT are
// re-used/updated for the new values post-FEYNMAN.
let component_exec = {
let exec_scalar = self
.l1_commit_scalar
.unwrap_or_else(|| panic!("exec scalar in spec_id={:?}", spec_id));
exec_scalar.saturating_mul(self.l1_base_fee)
};
let component_blob = {
let blob_scalar = self
.l1_blob_scalar
.unwrap_or_else(|| panic!("l1 blob scalar in spec_id={:?}", spec_id));
let blob_base_fee = self
.l1_blob_base_fee
.unwrap_or_else(|| panic!("l1 blob base fee in spec_id={:?}", spec_id));
blob_scalar.saturating_mul(blob_base_fee)
};

// Assume compression_ratio = 1 until we have specification for estimating compression
// ratio based on previous finalised batches.
let compression_ratio = |_input: &[u8]| -> U256 { U256::ONE };

// size(tx) is just the length of the RLP-encoded signed tx data.
let tx_size = |input: &[u8]| -> U256 { U256::from(input.len()) };

compression_ratio(input)
.saturating_mul(tx_size(input))
.saturating_mul(component_exec.saturating_add(component_blob))
.wrapping_div(TX_L1_FEE_PRECISION)
.wrapping_div(TX_L1_FEE_PRECISION)
}

/// Calculate the gas cost of a transaction based on L1 block data posted on L2.
pub fn calculate_tx_l1_cost(&self, input: &[u8], spec_id: ScrollSpecId) -> U256 {
if !spec_id.is_enabled_in(ScrollSpecId::CURIE) {
self.calculate_tx_l1_cost_shanghai(input, spec_id)
} else {
} else if !spec_id.is_enabled_in(ScrollSpecId::FEYNMAN) {
self.calculate_tx_l1_cost_curie(input, spec_id)
} else {
self.calculate_tx_l1_cost_feynman(input, spec_id)
}
}
}
Loading