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

Use bytes from unrecorded_blocks rather from the block from DA #2252

Merged
merged 22 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
ffa4fdb
Fix DA tests to expect unrecorded blocks to exist and to take the byt…
MitchTurner Sep 25, 2024
e82170c
Merge branch 'master' into fix/use-bytes-from-l2-blocks-not-da
MitchTurner Sep 25, 2024
fc3cf91
Remove regression for unimportant failure mode
MitchTurner Sep 25, 2024
8cd972f
Move struct that is only used in tests
MitchTurner Sep 25, 2024
8fd6616
Remove unused struct
MitchTurner Sep 26, 2024
49e521e
Change interface of `update_da_record_data`
MitchTurner Sep 26, 2024
cc28922
Move `RecordedBlock` into tests
MitchTurner Sep 26, 2024
e00319c
Merge branch 'master' into fix/use-bytes-from-l2-blocks-not-da
MitchTurner Sep 26, 2024
93a6e98
Use BTreeMap instead of HashMap
MitchTurner Sep 26, 2024
41c26f0
Use `pop_first` instead of `remove`
MitchTurner Sep 26, 2024
364ce4a
Fix compilation errors
MitchTurner Sep 26, 2024
e40a857
Kinda fix the analyzer I think
MitchTurner Sep 26, 2024
ea5469f
Cleanup prints
MitchTurner Sep 26, 2024
6a845ba
Merge branch 'master' into fix/use-bytes-from-l2-blocks-not-da
MitchTurner Sep 27, 2024
bfafd03
Fix test compilation
MitchTurner Sep 27, 2024
97fcc32
Fix profit chart length
MitchTurner Sep 27, 2024
a51a32c
Remove normalization function to fix simulation
MitchTurner Sep 27, 2024
dd8a252
Remove comment, add todo
MitchTurner Sep 30, 2024
7880500
Merge branch 'master' into fix/use-bytes-from-l2-blocks-not-da
MitchTurner Oct 1, 2024
76b904a
Merge remote-tracking branch 'origin' into fix/use-bytes-from-l2-bloc…
MitchTurner Oct 2, 2024
5848462
clean up function signature
MitchTurner Oct 2, 2024
8ec9c18
revert file inclusion from botched merge
MitchTurner Oct 2, 2024
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
6 changes: 0 additions & 6 deletions crates/fuel-gas-price-algorithm/src/v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,6 @@ pub struct AlgorithmUpdaterV0 {
pub l2_block_fullness_threshold_percent: u64,
}

#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq)]
pub struct BlockBytes {
pub height: u32,
pub block_bytes: u64,
}

impl AlgorithmUpdaterV0 {
pub fn new(
new_exec_price: u64,
Expand Down
99 changes: 53 additions & 46 deletions crates/fuel-gas-price-algorithm/src/v1.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use crate::utils::cumulative_percentage_change;
use std::{
cmp::max,
collections::HashMap,
num::NonZeroU64,
ops::Div,
ops::{
Div,
Range,
},
};

use crate::utils::cumulative_percentage_change;

#[cfg(test)]
mod tests;

Expand All @@ -16,9 +19,11 @@ pub enum Error {
#[error("Skipped DA block update: expected {expected:?}, got {got:?}")]
SkippedDABlock { expected: u32, got: u32 },
#[error("Could not calculate cost per byte: {bytes:?} bytes, {cost:?} cost")]
CouldNotCalculateCostPerByte { bytes: u64, cost: u64 },
CouldNotCalculateCostPerByte { bytes: u128, cost: u128 },
#[error("Failed to include L2 block data: {0}")]
FailedTooIncludeL2BlockData(String),
#[error("L2 block expected but not found in unrecorded blocks: {0}")]
L2BlockExpectedNotFound(u32),
}

#[derive(Debug, Clone, PartialEq)]
Expand Down Expand Up @@ -94,6 +99,8 @@ impl AlgorithmV1 {
/// The DA portion also uses a moving average of the profits over the last `avg_window` blocks
/// instead of the actual profit. Setting the `avg_window` to 1 will effectively disable the
/// moving average.
type Height = u32;
type Bytes = u64;
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq)]
pub struct AlgorithmUpdaterV1 {
// Execution
Expand Down Expand Up @@ -144,8 +151,9 @@ pub struct AlgorithmUpdaterV1 {
pub second_to_last_profit: i128,
/// The latest known cost per byte for recording blocks on the DA chain
pub latest_da_cost_per_byte: u128,

/// The unrecorded blocks that are used to calculate the projected cost of recording blocks
pub unrecorded_blocks: Vec<BlockBytes>,
pub unrecorded_blocks: HashMap<Height, Bytes>,
}

/// A value that represents a value between 0 and 100. Higher values are clamped to 100
Expand Down Expand Up @@ -176,29 +184,17 @@ impl core::ops::Deref for ClampedPercentage {
}
}

#[derive(Debug, Clone)]
pub struct RecordedBlock {
pub height: u32,
pub block_bytes: u64,
pub block_cost: u64,
}

#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq)]
pub struct BlockBytes {
pub height: u32,
pub block_bytes: u64,
}

impl AlgorithmUpdaterV1 {
pub fn update_da_record_data(
&mut self,
blocks: &[RecordedBlock],
height_range: Range<u32>,
range_cost: u128,
) -> Result<(), Error> {
for block in blocks {
self.da_block_update(block.height, block.block_bytes, block.block_cost)?;
if height_range.len() != 0 {
self.da_block_update(height_range, range_cost)?;
self.recalculate_projected_cost();
self.normalize_rewards_and_costs();
}
self.recalculate_projected_cost();
self.normalize_rewards_and_costs();
Ok(())
}

Expand Down Expand Up @@ -234,10 +230,7 @@ impl AlgorithmUpdaterV1 {
self.update_da_gas_price();

// metadata
self.unrecorded_blocks.push(BlockBytes {
height,
block_bytes,
});
self.unrecorded_blocks.insert(height, block_bytes);
Ok(())
}
}
Expand Down Expand Up @@ -374,43 +367,57 @@ impl AlgorithmUpdaterV1 {

fn da_block_update(
&mut self,
height: u32,
block_bytes: u64,
block_cost: u64,
height_range: Range<u32>,
range_cost: u128,
) -> Result<(), Error> {
let expected = self.da_recorded_block_height.saturating_add(1);
if height != expected {
let first = height_range.start;
if first != expected {
Err(Error::SkippedDABlock {
expected: self.da_recorded_block_height.saturating_add(1),
got: height,
expected,
got: first,
})
} else {
let new_cost_per_byte: u128 = (block_cost as u128)
.checked_div(block_bytes as u128)
.ok_or(Error::CouldNotCalculateCostPerByte {
bytes: block_bytes,
cost: block_cost,
})?;
self.da_recorded_block_height = height;
let last = height_range.end - 1;
let range_bytes = self.drain_l2_block_bytes_for_range(height_range)?;
let new_cost_per_byte: u128 = range_cost.checked_div(range_bytes).ok_or(
Error::CouldNotCalculateCostPerByte {
bytes: range_bytes,
cost: range_cost,
},
)?;
self.da_recorded_block_height = last;
let new_block_cost = self
.latest_known_total_da_cost_excess
.saturating_add(block_cost as u128);
.saturating_add(range_cost);
self.latest_known_total_da_cost_excess = new_block_cost;
self.latest_da_cost_per_byte = new_cost_per_byte;
Ok(())
}
}

fn drain_l2_block_bytes_for_range(
Copy link
Member Author

@MitchTurner MitchTurner Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, we can consider improving performance here still.

Copy link
Member Author

@MitchTurner MitchTurner Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched to BTreeMap and pop_first.

&mut self,
height_range: Range<u32>,
) -> Result<u128, Error> {
let mut total: u128 = 0;
for height in height_range {
let bytes = self
.unrecorded_blocks
.remove(&height)
.ok_or(Error::L2BlockExpectedNotFound(height))?;
total = total.saturating_add(bytes as u128);
}
Ok(total)
}

fn recalculate_projected_cost(&mut self) {
// remove all blocks that have been recorded
self.unrecorded_blocks
.retain(|block| block.height > self.da_recorded_block_height);
// add the cost of the remaining blocks
let projection_portion: u128 = self
.unrecorded_blocks
.iter()
.map(|block| {
(block.block_bytes as u128).saturating_mul(self.latest_da_cost_per_byte)
.map(|(_, &bytes)| {
(bytes as u128).saturating_mul(self.latest_da_cost_per_byte)
})
.sum();
self.projected_total_da_cost = self
Expand Down
17 changes: 12 additions & 5 deletions crates/fuel-gas-price-algorithm/src/v1/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@
#![allow(clippy::arithmetic_side_effects)]
#![allow(clippy::cast_possible_truncation)]

use crate::v1::{
AlgorithmUpdaterV1,
BlockBytes,
};
use crate::v1::AlgorithmUpdaterV1;

#[cfg(test)]
mod algorithm_v1_tests;
Expand All @@ -14,6 +11,12 @@ mod update_da_record_data_tests;
#[cfg(test)]
mod update_l2_block_data_tests;

#[derive(Debug, Clone)]
pub struct BlockBytes {
rafal-ch marked this conversation as resolved.
Show resolved Hide resolved
pub height: u32,
pub block_bytes: u64,
}

pub struct UpdaterBuilder {
min_exec_gas_price: u64,
min_da_gas_price: u64,
Expand Down Expand Up @@ -175,7 +178,11 @@ impl UpdaterBuilder {
latest_da_cost_per_byte: self.da_cost_per_byte,
projected_total_da_cost: self.project_total_cost,
latest_known_total_da_cost_excess: self.latest_known_total_cost,
unrecorded_blocks: self.unrecorded_blocks,
unrecorded_blocks: self
.unrecorded_blocks
.iter()
.map(|b| (b.height, b.block_bytes))
.collect(),
last_profit: self.last_profit,
second_to_last_profit: self.second_to_last_profit,
min_da_gas_price: self.min_da_gas_price,
Expand Down
Loading
Loading