diff --git a/crates/fuel-gas-price-algorithm/gas-price-analysis/src/charts.rs b/crates/fuel-gas-price-algorithm/gas-price-analysis/src/charts.rs index 6e5ac008f05..32194a716a2 100644 --- a/crates/fuel-gas-price-algorithm/gas-price-analysis/src/charts.rs +++ b/crates/fuel-gas-price-algorithm/gas-price-analysis/src/charts.rs @@ -10,6 +10,7 @@ pub fn draw_chart( results: SimulationResults, p_comp: i64, d_comp: i64, + da_finalization_period: usize, file_path: &str, ) -> anyhow::Result<()> { let SimulationResults { @@ -53,9 +54,10 @@ pub fn draw_chart( &projected_profit, &pessimistic_costs, &format!( - "Profit p_comp: {}, d_comp: {}", + "Profit p_comp: {}, d_comp: {}, da_finalization_period: {}", prettify_number(p_comp), - prettify_number(d_comp) + prettify_number(d_comp), + prettify_number(da_finalization_period) ), )?; draw_gas_prices( diff --git a/crates/fuel-gas-price-algorithm/gas-price-analysis/src/main.rs b/crates/fuel-gas-price-algorithm/gas-price-analysis/src/main.rs index 7b60eed78c7..ae15233f37f 100644 --- a/crates/fuel-gas-price-algorithm/gas-price-analysis/src/main.rs +++ b/crates/fuel-gas-price-algorithm/gas-price-analysis/src/main.rs @@ -37,6 +37,9 @@ struct Arg { /// File path to save the chart to. Will not generate chart if left blank #[arg(short, long)] file_path: Option, + #[arg(short, long)] + /// DA finalization period in L2 blocks + da_finalization_period: usize, } #[derive(Subcommand)] @@ -80,19 +83,23 @@ async fn main() -> anyhow::Result<()> { const UPDATE_PERIOD: usize = 12; + let da_finalization_period = args.da_finalization_period; + let (results, (p_comp, d_comp)) = match args.mode { Mode::WithValues { p, d, source } => { let da_cost_per_byte = get_da_cost_per_byte_from_source(source, UPDATE_PERIOD); let size = da_cost_per_byte.len(); println!( - "Running simulation with P: {}, D: {}, and {} blocks", + "Running simulation with P: {}, D: {}, {} blocks and {} da_finalization_period", prettify_number(p), prettify_number(d), - prettify_number(size) + prettify_number(size), + prettify_number(da_finalization_period) ); let simulator = Simulator::new(da_cost_per_byte); - let result = simulator.run_simulation(p, d, UPDATE_PERIOD); + let result = + simulator.run_simulation(p, d, UPDATE_PERIOD, da_finalization_period); (result, (p, d)) } Mode::Optimization { iterations, source } => { @@ -103,12 +110,18 @@ async fn main() -> anyhow::Result<()> { "Running optimization with {iterations} iterations and {size} blocks" ); let simulator = Simulator::new(da_cost_per_byte); - let (results, (p, d)) = - naive_optimisation(&simulator, iterations as usize, UPDATE_PERIOD).await; + let (results, (p, d)) = naive_optimisation( + &simulator, + iterations as usize, + UPDATE_PERIOD, + da_finalization_period, + ) + .await; println!( - "Optimization results: P: {}, D: {}", + "Optimization results: P: {}, D: {}, da_finalization_period: {}", prettify_number(p), - prettify_number(d) + prettify_number(d), + prettify_number(da_finalization_period) ); (results, (p, d)) } @@ -117,7 +130,7 @@ async fn main() -> anyhow::Result<()> { print_info(&results); if let Some(file_path) = &args.file_path { - draw_chart(results, p_comp, d_comp, file_path)?; + draw_chart(results, p_comp, d_comp, da_finalization_period, file_path)?; } Ok(()) diff --git a/crates/fuel-gas-price-algorithm/gas-price-analysis/src/optimisation.rs b/crates/fuel-gas-price-algorithm/gas-price-analysis/src/optimisation.rs index 38df54365fd..4943091fb84 100644 --- a/crates/fuel-gas-price-algorithm/gas-price-analysis/src/optimisation.rs +++ b/crates/fuel-gas-price-algorithm/gas-price-analysis/src/optimisation.rs @@ -15,6 +15,7 @@ fn da_pid_factors(size: usize) -> Vec<(i64, i64)> { pub async fn naive_optimisation( simulator: &Simulator, iterations: usize, + update_period: usize, da_recording_rate: usize, ) -> (SimulationResults, (i64, i64)) { let tasks = da_pid_factors(iterations) @@ -23,7 +24,7 @@ pub async fn naive_optimisation( let new_simulator = simulator.clone(); let f = move || { ( - new_simulator.run_simulation(p, d, da_recording_rate), + new_simulator.run_simulation(p, d, update_period, da_recording_rate), (p, d), ) }; diff --git a/crates/fuel-gas-price-algorithm/gas-price-analysis/src/simulation.rs b/crates/fuel-gas-price-algorithm/gas-price-analysis/src/simulation.rs index 2cf4c97c4c1..6ad906cc41f 100644 --- a/crates/fuel-gas-price-algorithm/gas-price-analysis/src/simulation.rs +++ b/crates/fuel-gas-price-algorithm/gas-price-analysis/src/simulation.rs @@ -33,7 +33,8 @@ impl Simulator { &self, da_p_component: i64, da_d_component: i64, - da_recording_rate: usize, + update_period: usize, + da_finalization_rate: usize, ) -> SimulationResults { let capacity = 30_000_000; let gas_per_byte = 63; @@ -42,8 +43,11 @@ impl Simulator { let fullness_and_bytes = fullness_and_bytes_per_block(size, capacity); let l2_blocks = fullness_and_bytes.clone().into_iter(); - let da_blocks = - self.zip_l2_blocks_with_da_blocks(da_recording_rate, &fullness_and_bytes); + let da_blocks = self.calculate_da_blocks( + update_period, + da_finalization_rate, + &fullness_and_bytes, + ); let blocks = l2_blocks.zip(da_blocks.iter()).enumerate(); @@ -178,11 +182,14 @@ impl Simulator { } } - fn zip_l2_blocks_with_da_blocks( + fn calculate_da_blocks( &self, da_recording_rate: usize, + da_finalization_rate: usize, fullness_and_bytes: &Vec<(u64, u64)>, ) -> Vec>> { + let l2_blocks_with_no_da_blocks = + std::iter::repeat(None).take(da_finalization_rate); let (_, da_blocks) = fullness_and_bytes .iter() .zip(self.da_cost_per_byte.iter()) @@ -208,7 +215,7 @@ impl Simulator { } }, ); - da_blocks + l2_blocks_with_no_da_blocks.chain(da_blocks).collect() } } diff --git a/crates/fuel-gas-price-algorithm/src/v1.rs b/crates/fuel-gas-price-algorithm/src/v1.rs index 11c555a7faa..ca3b58f22f9 100644 --- a/crates/fuel-gas-price-algorithm/src/v1.rs +++ b/crates/fuel-gas-price-algorithm/src/v1.rs @@ -232,6 +232,12 @@ impl AlgorithmUpdaterV1 { // gas prices self.update_exec_gas_price(used, capacity); self.update_da_gas_price(); + + // metadata + self.unrecorded_blocks.push(BlockBytes { + height, + block_bytes, + }); Ok(()) } } diff --git a/crates/fuel-gas-price-algorithm/src/v1/tests/update_l2_block_data_tests.rs b/crates/fuel-gas-price-algorithm/src/v1/tests/update_l2_block_data_tests.rs index 0be90b5186b..1ad9a1aacad 100644 --- a/crates/fuel-gas-price-algorithm/src/v1/tests/update_l2_block_data_tests.rs +++ b/crates/fuel-gas-price-algorithm/src/v1/tests/update_l2_block_data_tests.rs @@ -1,5 +1,6 @@ use crate::v1::{ tests::UpdaterBuilder, + BlockBytes, Error, }; @@ -536,3 +537,71 @@ fn update_l2_block_data__negative_profit_increase_gas_price() { old_gas_price ); } + +#[test] +fn update_l2_block_data__adds_l2_block_to_unrecorded_blocks() { + // given + let starting_block = 0; + + let mut updater = UpdaterBuilder::new() + .with_l2_block_height(starting_block) + .build(); + + let height = 1; + let used = 50; + let capacity = 100.try_into().unwrap(); + let block_bytes = 1000; + let new_gas_price = 100; + + // when + updater + .update_l2_block_data(height, used, capacity, block_bytes, new_gas_price) + .unwrap(); + + // then + let block_bytes = BlockBytes { + height, + block_bytes, + }; + let contains_block_bytes = updater.unrecorded_blocks.contains(&block_bytes); + assert!(contains_block_bytes); +} + +#[test] +fn update_l2_block_data__retains_existing_blocks_and_adds_l2_block_to_unrecorded_blocks() +{ + // given + let starting_block = 0; + let preexisting_block = BlockBytes { + height: 0, + block_bytes: 1000, + }; + + let mut updater = UpdaterBuilder::new() + .with_l2_block_height(starting_block) + .with_unrecorded_blocks(vec![preexisting_block.clone()]) + .build(); + + let height = 1; + let used = 50; + let capacity = 100.try_into().unwrap(); + let block_bytes = 1000; + let new_gas_price = 100; + + // when + updater + .update_l2_block_data(height, used, capacity, block_bytes, new_gas_price) + .unwrap(); + + // then + let block_bytes = BlockBytes { + height, + block_bytes, + }; + let contains_block_bytes = updater.unrecorded_blocks.contains(&block_bytes); + assert!(contains_block_bytes); + + let contains_preexisting_block_bytes = + updater.unrecorded_blocks.contains(&preexisting_block); + assert!(contains_preexisting_block_bytes); +}