Skip to content

Commit

Permalink
feat(fjord): fjord parameter changes (#284)
Browse files Browse the repository at this point in the history
  • Loading branch information
refcell authored Jun 20, 2024
1 parent 4b8e9ee commit 1b95755
Show file tree
Hide file tree
Showing 13 changed files with 453 additions and 383 deletions.
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

0 comments on commit 1b95755

Please sign in to comment.