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

Get DA costs from predefined data #2157

Merged
merged 15 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from 10 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
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
Cargo.lock
gas-price.png
gas-prices.png
/predefined_data
rymnc marked this conversation as resolved.
Show resolved Hide resolved
/charts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ publish = false

[dependencies]
clap = { version = "4.5.16", features = ["derive"] }
csv = "1.3.0"
fuel-gas-price-algorithm = { path = ".." }
plotters = "0.3.5"
rand = "0.8.5"
rand_distr = "0.4.3"
serde = { version = "1.0.209", features = ["derive"] }
Original file line number Diff line number Diff line change
@@ -1,4 +1,66 @@
use super::*;
use std::{
fs,
path::PathBuf,
};

pub fn draw_chart(results: SimulationResults, p_comp: i64, d_comp: i64, file_path: &str) {
let SimulationResults {
gas_prices,
exec_gas_prices,
da_gas_prices,
fullness,
bytes_and_costs,
actual_profit,
projected_profit,
pessimistic_costs,
} = results;

let plot_width = 640 * 2 * 2;
let plot_height = 480 * 3;

let path: PathBuf = file_path.into();

if path.is_dir() {
println!("Creating chart at: {}", file_path);
fs::create_dir_all(file_path).unwrap();
rymnc marked this conversation as resolved.
Show resolved Hide resolved
} else {
let new_path = path.parent().unwrap();
println!("Creating chart at: {}", new_path.display());
fs::create_dir_all(new_path).unwrap();
}
let root =
BitMapBackend::new(file_path, (plot_width, plot_height)).into_drawing_area();
root.fill(&WHITE).unwrap();
let (window_one, lower) = root.split_vertically(plot_height / 4);
let (window_two, new_lower) = lower.split_vertically(plot_height / 4);
let (window_three, window_four) = new_lower.split_vertically(plot_height / 4);

draw_fullness(&window_one, &fullness, "Fullness");

draw_bytes_and_cost_per_block(&window_two, &bytes_and_costs, "Bytes Per Block");

draw_profit(
&window_three,
&actual_profit,
&projected_profit,
&pessimistic_costs,
&format!(
"Profit p_comp: {}, d_comp: {}",
pretty(p_comp),
pretty(d_comp)
),
);
draw_gas_prices(
&window_four,
&gas_prices,
&exec_gas_prices,
&da_gas_prices,
"Gas Prices",
);

root.present().unwrap();
}

pub fn draw_gas_prices(
drawing_area: &DrawingArea<BitMapBackend, Shift>,
Expand Down Expand Up @@ -181,9 +243,9 @@ pub fn draw_bytes_and_cost_per_block(

pub fn draw_profit(
drawing_area: &DrawingArea<BitMapBackend, Shift>,
actual_profit: &[i64],
projected_profit: &[i64],
pessimistic_block_costs: &[u64],
actual_profit: &[i128],
rymnc marked this conversation as resolved.
Show resolved Hide resolved
projected_profit: &[i128],
pessimistic_block_costs: &[u128],
title: &str,
) {
const ACTUAL_PROFIT_COLOR: RGBColor = BLACK;
Expand Down
184 changes: 115 additions & 69 deletions crates/fuel-gas-price-algorithm/gas-price-analysis/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
use crate::{
charts::draw_chart,
simulation::da_cost_per_byte::get_da_cost_per_byte_from_source,
};
use plotters::prelude::*;
use rand::{
rngs::StdRng,
Expand All @@ -8,16 +12,10 @@ use rand::{
use plotters::coord::Shift;

use crate::{
charts::{
draw_bytes_and_cost_per_block,
draw_fullness,
draw_gas_prices,
draw_profit,
},
optimisation::naive_optimisation,
simulation::{
run_simulation,
SimulationResults,
Simulator,
},
};

Expand All @@ -26,20 +24,10 @@ mod simulation;

mod charts;

pub fn pretty<T: ToString>(input: T) -> String {
input
.to_string()
.as_bytes()
.rchunks(3)
.rev()
.map(std::str::from_utf8)
.collect::<Result<Vec<&str>, _>>()
.unwrap()
.join(",") // separator
}


use clap::{Parser, Subcommand};
use clap::{
Parser,
Subcommand,
};

#[derive(Parser)]
#[command(version, about, long_about = None)]
Expand Down Expand Up @@ -70,83 +58,141 @@ enum Mode {
source: Source,
/// Number of iterations to run the optimization for
iterations: u64,
}
},
}

#[derive(Subcommand)]
enum Source {
Generated { size: usize }
Generated {
size: usize,
},
Predefined {
file_path: String,
/// The number of L2 blocks to include from source
#[arg(short, long)]
sample_size: Option<usize>,
},
}

fn main() {
let args = Arg::parse();

const UPDATE_PERIOD: usize = 12;

let (results, (p_comp, d_comp)) = match args.mode {
Mode::WithValues { p, d, source } => {
let Source::Generated { size } = source;
println!("Running simulation with P: {}, D: {}, and {} blocks", pretty(p), pretty(d), pretty(size));
let result = run_simulation(p, d, size);
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",
pretty(p),
pretty(d),
pretty(size)
);
let simulator = Simulator::new(da_cost_per_byte);
let result = simulator.run_simulation(p, d, UPDATE_PERIOD);
(result, (p, d))
},
Mode::Optimization { iterations, source} => {
let Source::Generated { size } = source;
println!("Running optimization with {iterations} iterations and {size} blocks");
let (results, (p, d)) = naive_optimisation(iterations as usize, size);
}
Mode::Optimization { iterations, 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 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);
println!("Optimization results: P: {}, D: {}", pretty(p), pretty(d));
(results, (p, d))
}
};

print_info(&results);

if let Some(file_path) = &args.file_path {
draw_chart(results, p_comp, d_comp, file_path);

}
}

fn draw_chart(results: SimulationResults, p_comp: i64, d_comp: i64, file_path: &str) {
fn print_info(results: &SimulationResults) {
let SimulationResults {
gas_prices,
exec_gas_prices,
da_gas_prices,
fullness,
bytes_and_costs,
actual_profit,
projected_profit,
pessimistic_costs,
..
} = results;

let max_actual_profit = pretty(*actual_profit.iter().max().unwrap() as u64);
println!("max_actual: {max_actual_profit}");

let plot_width = 640 * 2 * 2;
let plot_height = 480 * 3;

let root =
BitMapBackend::new(file_path, (plot_width, plot_height)).into_drawing_area();
root.fill(&WHITE).unwrap();
let (window_one, lower) = root.split_vertically(plot_height / 4);
let (window_two, new_lower) = lower.split_vertically(plot_height / 4);
let (window_three, window_four) = new_lower.split_vertically(plot_height / 4);

draw_fullness(&window_one, &fullness, "Fullness");

draw_bytes_and_cost_per_block(&window_two, &bytes_and_costs, "Bytes Per Block");

draw_profit(
&window_three,
&actual_profit,
&projected_profit,
&pessimistic_costs,
&format!("Profit p_comp: {p_comp:?}, d_comp: {d_comp:?}"),
);
draw_gas_prices(
&window_four,
&gas_prices,
&exec_gas_prices,
&da_gas_prices,
"Gas Prices",
// Max actual profit
let (index, max_actual_profit) = actual_profit
.iter()
.enumerate()
.max_by(|(_, a), (_, b)| a.cmp(b))
.unwrap();
let eth = *max_actual_profit as f64 / (10_f64).powf(18.);
println!("max actual profit: {} ETH at {}", eth, index);

// Max projected profit
let (index, max_projected_profit) = projected_profit
.iter()
.enumerate()
.max_by(|(_, a), (_, b)| a.cmp(b))
.unwrap();
let eth = *max_projected_profit as f64 / (10_f64).powf(18.);
rymnc marked this conversation as resolved.
Show resolved Hide resolved
println!("max projected profit: {} ETH at {}", eth, index);

// Min actual profit
let (index, min_actual_profit) = actual_profit
.iter()
.enumerate()
.min_by(|(_, a), (_, b)| a.cmp(b))
.unwrap();
let eth = *min_actual_profit as f64 / (10_f64).powf(18.);
println!("min actual profit: {} ETH at {}", eth, index);

// Min projected profit
let (index, min_projected_profit) = projected_profit
.iter()
.enumerate()
.min_by(|(_, a), (_, b)| a.cmp(b))
.unwrap();
let eth = *min_projected_profit as f64 / (10_f64).powf(18.);
println!("min projected profit: {} ETH at {}", eth, index);

// Max DA Gas Price
let (index, max_da_gas_price) = da_gas_prices
.iter()
.enumerate()
.max_by(|(_, a), (_, b)| a.cmp(b))
.unwrap();
let eth = *max_da_gas_price as f64 / (10_f64).powf(18.);
println!(
"max DA gas price: {} Wei ({} ETH) at {}",
max_da_gas_price, eth, index
);

root.present().unwrap();
// Min Da Gas Price
let (index, min_da_gas_price) = da_gas_prices
.iter()
.enumerate()
.min_by(|(_, a), (_, b)| a.cmp(b))
.unwrap();
let eth = *min_da_gas_price as f64 / (10_f64).powf(18.);
println!(
"min DA gas price: {} Wei ({} ETH) at {}",
min_da_gas_price, eth, index
);
}

pub fn pretty<T: ToString>(input: T) -> String {
rymnc marked this conversation as resolved.
Show resolved Hide resolved
input
.to_string()
.as_bytes()
.rchunks(3)
.rev()
.map(std::str::from_utf8)
.collect::<Result<Vec<&str>, _>>()
.unwrap()
.join(",") // separator
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ fn da_pid_factors(size: usize) -> Vec<(i64, i64)> {
.collect()
}

pub fn naive_optimisation(iterations: usize, size: usize) -> (SimulationResults, (i64, i64)) {
pub fn naive_optimisation(simulator: Simulator, iterations: usize, da_recording_rate: usize) -> (SimulationResults, (i64, i64)) {
rymnc marked this conversation as resolved.
Show resolved Hide resolved
da_pid_factors(iterations)
.iter()
.map(|(p, d)| (run_simulation(*p, *d, size), (*p, *d)))
.map(|(p, d)| (simulator.run_simulation(*p, *d, da_recording_rate), (*p, *d)))
.min_by_key(|(results, _)| {
let SimulationResults { actual_profit, .. } = results;
let err = actual_profit.iter().map(|p| p.abs()).sum::<i64>();
let err = actual_profit.iter().map(|p| p.abs()).sum::<i128>();
err
})
.unwrap()
Expand Down
Loading
Loading