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(fjord): Fjord Parameter Updates #284

Merged
merged 1 commit into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
455 changes: 152 additions & 303 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion crates/derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ extern crate alloc;
mod params;
pub use params::{
ChannelID, CHANNEL_ID_LENGTH, CONFIG_UPDATE_EVENT_VERSION_0, CONFIG_UPDATE_TOPIC,
DERIVATION_VERSION_0, FRAME_OVERHEAD, MAX_CHANNEL_BANK_SIZE, MAX_FRAME_LEN,
DERIVATION_VERSION_0, FJORD_MAX_CHANNEL_BANK_SIZE, FJORD_MAX_RLP_BYTES_PER_CHANNEL,
FJORD_MAX_SPAN_BATCH_BYTES, FRAME_OVERHEAD, MAX_CHANNEL_BANK_SIZE, MAX_FRAME_LEN,
MAX_RLP_BYTES_PER_CHANNEL, MAX_SPAN_BATCH_BYTES, SEQUENCER_FEE_VAULT_ADDRESS,
};

Expand Down
13 changes: 13 additions & 0 deletions crates/derive/src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,26 @@ pub const DERIVATION_VERSION_0: u8 = 0;
/// MaxRLPBytesPerChannel because single batch cannot be larger than channel size.
pub const MAX_SPAN_BATCH_BYTES: u64 = MAX_RLP_BYTES_PER_CHANNEL;

/// [FJORD_MAX_SPAN_BATCH_BYTES] is the maximum amount of bytes that will be needed
/// to decode every span batch field after the Fjord Hardfork.
/// This value cannot be larger than MaxRLPBytesPerChannel because single batch
/// cannot be larger than channel size.
pub const FJORD_MAX_SPAN_BATCH_BYTES: u64 = FJORD_MAX_RLP_BYTES_PER_CHANNEL;

/// [MAX_RLP_BYTES_PER_CHANNEL] is the maximum amount of bytes that will be read from
/// a channel. This limit is set when decoding the RLP.
pub const MAX_RLP_BYTES_PER_CHANNEL: u64 = 10_000_000;

/// [FJORD_MAX_RLP_BYTES_PER_CHANNEL] is the maximum amount of bytes that will be read from
/// a channel when the Fjord Hardfork is activated. This limit is set when decoding the RLP.
pub const FJORD_MAX_RLP_BYTES_PER_CHANNEL: u64 = 100_000_000;

/// The maximum size of a channel bank.
pub const MAX_CHANNEL_BANK_SIZE: usize = 100_000_000;

/// The maximum size of a channel bank after the Fjord Hardfork.
pub const FJORD_MAX_CHANNEL_BANK_SIZE: usize = 1_000_000_000;

/// [CHANNEL_ID_LENGTH] is the length of the channel ID.
pub const CHANNEL_ID_LENGTH: usize = 16;

Expand Down
4 changes: 2 additions & 2 deletions crates/derive/src/types/batch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub use span_batch::{
RawSpanBatch, SpanBatch, SpanBatchBits, SpanBatchEip1559TransactionData,
SpanBatchEip2930TransactionData, SpanBatchElement, SpanBatchError,
SpanBatchLegacyTransactionData, SpanBatchPayload, SpanBatchPrefix, SpanBatchTransactionData,
SpanBatchTransactions, SpanDecodingError, MAX_SPAN_BATCH_SIZE,
SpanBatchTransactions, SpanDecodingError,
};

mod single_batch;
Expand Down Expand Up @@ -95,7 +95,7 @@ impl Batch {
}
BatchType::Span => {
let mut raw_span_batch =
RawSpanBatch::decode(r).map_err(DecodeError::SpanBatchError)?;
RawSpanBatch::decode(r, cfg).map_err(DecodeError::SpanBatchError)?;
let span_batch = raw_span_batch
.derive(cfg.block_time, cfg.genesis.l2_time, cfg.l2_chain_id)
.map_err(DecodeError::SpanBatchError)?;
Expand Down
5 changes: 3 additions & 2 deletions crates/derive/src/types/batch/single_batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,11 @@ impl SingleBatch {
}

// Check if we ran out of sequencer time drift
let max = if let Some(max) = batch_origin.timestamp.checked_add(cfg.max_sequencer_drift) {
let max_drift = cfg.max_sequencer_drift(batch_origin.timestamp);
let max = if let Some(max) = batch_origin.timestamp.checked_add(max_drift) {
max
} else {
warn!("dropped batch, timestamp exceeds configured max sequencer drift, origin timestamp: {}, max drift: {}", batch_origin.timestamp, cfg.max_sequencer_drift);
warn!("dropped batch, timestamp exceeds configured max sequencer drift, origin timestamp: {}, max drift: {}", batch_origin.timestamp, max_drift);
return BatchValidity::Drop;
};

Expand Down
6 changes: 4 additions & 2 deletions crates/derive/src/types/batch/span_batch/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,10 @@ impl SpanBatch {
);
return BatchValidity::Drop;
}

// Check if we ran out of sequencer time drift
if block_timestamp > l1_origin.timestamp + cfg.max_sequencer_drift {
let max_drift = cfg.max_sequencer_drift(l1_origin.timestamp);
if block_timestamp > l1_origin.timestamp + max_drift {
if batch.transactions.is_empty() {
// If the sequencer is co-operating by producing an empty batch,
// then allow the batch if it was the right thing to do to maintain the L2 time
Expand All @@ -248,7 +250,7 @@ impl SpanBatch {
// allowed to include anything past this point without moving to the next epoch.
warn!(
"batch exceeded sequencer time drift, sequencer must adopt new L1 origin to include transactions again, max_time: {}",
l1_origin.timestamp + cfg.max_sequencer_drift
l1_origin.timestamp + max_drift
);
return BatchValidity::Drop;
}
Expand Down
35 changes: 27 additions & 8 deletions crates/derive/src/types/batch/span_batch/bits.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
//! Module for working with span batch bits.

use crate::types::{SpanBatchError, MAX_SPAN_BATCH_SIZE};
use crate::{
params::{FJORD_MAX_SPAN_BATCH_BYTES, MAX_SPAN_BATCH_BYTES},
types::SpanBatchError,
};
use alloc::{vec, vec::Vec};
use alloy_rlp::Buf;
use anyhow::Result;
Expand Down Expand Up @@ -31,10 +34,19 @@ impl From<SpanBatchBits> for Vec<u8> {
impl SpanBatchBits {
/// Decodes a standard span-batch bitlist from a reader.
/// The bitlist is encoded as big-endian integer, left-padded with zeroes to a multiple of 8
/// bits. The encoded bitlist cannot be longer than [MAX_SPAN_BATCH_SIZE].
pub fn decode(b: &mut &[u8], bit_length: usize) -> Result<Self, SpanBatchError> {
/// bits. The encoded bitlist cannot be longer than [MAX_SPAN_BATCH_BYTES].
pub fn decode(
b: &mut &[u8],
bit_length: usize,
is_fjord_active: bool,
) -> Result<Self, SpanBatchError> {
let buffer_len = bit_length / 8 + if bit_length % 8 != 0 { 1 } else { 0 };
if buffer_len > MAX_SPAN_BATCH_SIZE {
let max_bytes = if is_fjord_active {
FJORD_MAX_SPAN_BATCH_BYTES as usize
} else {
MAX_SPAN_BATCH_BYTES as usize
};
if buffer_len > max_bytes {
return Err(SpanBatchError::TooBigSpanBatchSize);
}

Expand All @@ -59,11 +71,13 @@ impl SpanBatchBits {

/// Encodes a standard span-batch bitlist.
/// The bitlist is encoded as big-endian integer, left-padded with zeroes to a multiple of 8
/// bits. The encoded bitlist cannot be longer than [MAX_SPAN_BATCH_SIZE].
/// bits. The encoded bitlist cannot be longer than [MAX_SPAN_BATCH_BYTES] or
/// [FJORD_MAX_SPAN_BATCH_BYTES] if fjord is active.
pub fn encode(
w: &mut Vec<u8>,
bit_length: usize,
bits: &SpanBatchBits,
is_fjord_active: bool,
) -> Result<(), SpanBatchError> {
if bits.bit_len() > bit_length {
return Err(SpanBatchError::BitfieldTooLong);
Expand All @@ -72,7 +86,12 @@ impl SpanBatchBits {
// Round up, ensure enough bytes when number of bits is not a multiple of 8.
// Alternative of (L+7)/8 is not overflow-safe.
let buf_len = bit_length / 8 + if bit_length % 8 != 0 { 1 } else { 0 };
if buf_len > MAX_SPAN_BATCH_SIZE {
let max_bytes = if is_fjord_active {
FJORD_MAX_SPAN_BATCH_BYTES as usize
} else {
MAX_SPAN_BATCH_BYTES as usize
};
if buf_len > max_bytes {
return Err(SpanBatchError::TooBigSpanBatchSize);
}
let mut buf = vec![0; buf_len];
Expand Down Expand Up @@ -174,9 +193,9 @@ mod test {
#[test]
fn test_encode_decode_roundtrip_span_bitlist(vec in vec(any::<u8>(), 0..5096)) {
let bits = SpanBatchBits(vec);
assert_eq!(SpanBatchBits::decode(&mut bits.as_ref(), bits.0.len() * 8).unwrap(), bits);
assert_eq!(SpanBatchBits::decode(&mut bits.as_ref(), bits.0.len() * 8, false).unwrap(), bits);
let mut encoded = Vec::new();
SpanBatchBits::encode(&mut encoded, bits.0.len() * 8, &bits).unwrap();
SpanBatchBits::encode(&mut encoded, bits.0.len() * 8, &bits, false).unwrap();
assert_eq!(encoded, bits.0);
}

Expand Down
7 changes: 0 additions & 7 deletions crates/derive/src/types/batch/span_batch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,6 @@
//! txs = contract_creation_bits ++ y_parity_bits ++ tx_sigs ++ tx_tos ++ tx_datas ++ tx_nonces ++ tx_gases ++ protected_bits
//! ```

use crate::MAX_RLP_BYTES_PER_CHANNEL;

/// The maximum amount of bytes that will be needed to decode every span
/// batch field. This value cannot be larger than [MAX_RLP_BYTES_PER_CHANNEL]
/// because single batch cannot be larger than channel size.
pub const MAX_SPAN_BATCH_SIZE: usize = MAX_RLP_BYTES_PER_CHANNEL as usize;

mod batch;
pub use batch::SpanBatch;

Expand Down
Loading
Loading