Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
QuentinI committed Nov 12, 2024
1 parent 23446f4 commit 30842fa
Show file tree
Hide file tree
Showing 9 changed files with 6,179 additions and 5,970 deletions.
54 changes: 54 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions crates/legacy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@ edition = { workspace = true }
marketplace-builder-shared = { path = "../shared" }

anyhow = { workspace = true }
atomic = "0.6"
bytemuck = { version = "1.19", features = ["derive"] }
coarsetime = "0.1.34"
async-broadcast = { workspace = true }
async-compatibility-layer = { workspace = true, features = ["logging-utils"] }
async-lock = { workspace = true }
async-std = { workspace = true, features = ["unstable", "attributes"] }
async-trait = { workspace = true }
bincode = { workspace = true }
committable = { workspace = true }
derive_more = { workspace = true, features = ["deref", "deref_mut", "debug"] }
futures = { workspace = true }
hotshot = { workspace = true }
hotshot-builder-api = { workspace = true }
Expand Down
136 changes: 136 additions & 0 deletions crates/legacy/src/block_size_limits.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
use atomic::Atomic;
use coarsetime::{Duration, Instant};
use std::sync::atomic::Ordering;

#[derive(Debug, Clone, Copy, bytemuck::NoUninit)]
#[repr(C)]
struct MutableState {
pub max_block_size: u64,
pub last_block_size_increment: u64,
}

/// Adjustable limits for block size ceiled by
/// maximum block size allowed by the protocol
#[derive(Debug, Clone)]
pub struct BlockSizeLimits {
// maximum block size allowed by the protocol
pub protocol_max_block_size: u64,
// estimated maximum block size we can build in time
mutable_state: Atomic<MutableState>,
pub increment_period: Duration,
}

impl BlockSizeLimits {
/// Never go lower than 10 kilobytes
pub const MAX_BLOCK_SIZE_FLOOR: u64 = 10_000;
/// When adjusting max block size, it will be decremented or incremented
/// by current value / `MAX_BLOCK_SIZE_CHANGE_DIVISOR`
pub const MAX_BLOCK_SIZE_CHANGE_DIVISOR: u64 = 10;

pub fn new(protocol_max_block_size: u64, increment_period: std::time::Duration) -> Self {
Self {
protocol_max_block_size,
mutable_state: Atomic::new(MutableState {
max_block_size: protocol_max_block_size,
last_block_size_increment: Instant::now().as_ticks(),
}),
increment_period,
}
}

pub fn max_block_size(&self) -> u64 {
self.mutable_state
.load(std::sync::atomic::Ordering::SeqCst)
.max_block_size
}

/// If increment period has elapsed or `force` flag is set,
/// increment [`Self::max_block_size`] by current value * [`Self::MAX_BLOCK_SIZE_CHANGE_DIVISOR`]
/// with [`Self::protocol_max_block_size`] as a ceiling
pub fn try_increment_block_size(&mut self, force: bool) {
if force
|| Instant::now().as_ticks()
- self
.mutable_state
.load(Ordering::SeqCst)
.last_block_size_increment
>= self.increment_period.as_ticks()
{
self.max_block_size = std::cmp::min(
self.max_block_size
+ self
.max_block_size
.div_ceil(Self::MAX_BLOCK_SIZE_CHANGE_DIVISOR),
self.protocol_max_block_size,
);
self.last_block_size_increment = Instant::now();
}
}

/// Decrement [`Self::max_block_size`] by current value * [`Self::MAX_BLOCK_SIZE_CHANGE_DIVISOR`]
/// with [`Self::MAX_BLOCK_SIZE_FLOOR`] as a floor
pub fn decrement_block_size(&mut self) {
self.max_block_size = std::cmp::max(
self.max_block_size
- self
.max_block_size
.div_ceil(Self::MAX_BLOCK_SIZE_CHANGE_DIVISOR),
Self::MAX_BLOCK_SIZE_FLOOR,
);
}
}

#[cfg(test)]
mod tests {
use marketplace_builder_shared::testing::constants::{
TEST_MAX_BLOCK_SIZE_INCREMENT_PERIOD, TEST_PROTOCOL_MAX_BLOCK_SIZE,
};

use super::*;

#[test]
fn test_increment_block_size() {
let mut block_size_limits =
BlockSizeLimits::new(TEST_PROTOCOL_MAX_BLOCK_SIZE, Duration::from_millis(25));
// Simulate decreased limits
block_size_limits.max_block_size = TEST_PROTOCOL_MAX_BLOCK_SIZE / 2;

// Shouldn't increment, increment period hasn't passed yet
block_size_limits.try_increment_block_size(false);
assert!(block_size_limits.max_block_size == TEST_PROTOCOL_MAX_BLOCK_SIZE / 2);

// Should increment, increment period hasn't passed yet, but force flag is set
block_size_limits.try_increment_block_size(true);
assert!(block_size_limits.max_block_size > TEST_PROTOCOL_MAX_BLOCK_SIZE / 2);
let new_size = block_size_limits.max_block_size;

std::thread::sleep(Duration::from_millis(30));

// Should increment, increment period has passed
block_size_limits.try_increment_block_size(false);
assert!(block_size_limits.max_block_size > new_size);
}

#[test]
fn test_decrement_block_size() {
let mut block_size_limits = BlockSizeLimits::new(
TEST_PROTOCOL_MAX_BLOCK_SIZE,
TEST_MAX_BLOCK_SIZE_INCREMENT_PERIOD,
);
block_size_limits.decrement_block_size();
assert!(block_size_limits.max_block_size < TEST_PROTOCOL_MAX_BLOCK_SIZE);
}

#[test]
fn test_max_block_size_floor() {
let mut block_size_limits = BlockSizeLimits::new(
BlockSizeLimits::MAX_BLOCK_SIZE_FLOOR + 1,
TEST_MAX_BLOCK_SIZE_INCREMENT_PERIOD,
);
block_size_limits.decrement_block_size();
assert_eq!(
block_size_limits.max_block_size,
BlockSizeLimits::MAX_BLOCK_SIZE_FLOOR
);
}
}
Loading

0 comments on commit 30842fa

Please sign in to comment.