anvil_zksync_core/node/
fee_model.rs1use crate::node::fork::ForkDetails;
2use anvil_zksync_config::constants::{
3 DEFAULT_ESTIMATE_GAS_PRICE_SCALE_FACTOR, DEFAULT_ESTIMATE_GAS_SCALE_FACTOR,
4 DEFAULT_FAIR_PUBDATA_PRICE, DEFAULT_L1_GAS_PRICE, DEFAULT_L2_GAS_PRICE,
5};
6use anvil_zksync_config::BaseTokenConfig;
7use zksync_multivm::utils::derive_base_fee_and_gas_per_pubdata;
8use zksync_multivm::VmVersion;
9use zksync_types::fee_model::{
10 BaseTokenConversionRatio, BatchFeeInput, FeeModelConfigV2, FeeParams, FeeParamsV2,
11};
12
13#[derive(Debug, Clone)]
14pub struct TestNodeFeeInputProvider {
15 pub estimate_gas_price_scale_factor: f64,
17 pub estimate_gas_scale_factor: f32,
19
20 fee_params: FeeParamsV2,
21 forced_base_fee: Option<u64>,
22}
23
24impl PartialEq for TestNodeFeeInputProvider {
26 fn eq(&self, other: &Self) -> bool {
27 fn eq_config(a: FeeModelConfigV2, b: FeeModelConfigV2) -> bool {
28 a.minimal_l2_gas_price == b.minimal_l2_gas_price
29 && a.compute_overhead_part == b.compute_overhead_part
30 && a.pubdata_overhead_part == b.pubdata_overhead_part
31 && a.batch_overhead_l1_gas == b.batch_overhead_l1_gas
32 && a.max_gas_per_batch == b.max_gas_per_batch
33 && a.max_pubdata_per_batch == b.max_pubdata_per_batch
34 }
35
36 self.estimate_gas_price_scale_factor == other.estimate_gas_price_scale_factor
37 && self.estimate_gas_scale_factor == other.estimate_gas_scale_factor
38 && self.fee_params.l1_gas_price() == other.fee_params.l1_gas_price()
39 && self.fee_params.l1_pubdata_price() == other.fee_params.l1_pubdata_price()
40 && eq_config(self.fee_params.config(), other.fee_params.config())
41 }
42}
43
44impl TestNodeFeeInputProvider {
45 pub fn from_fork(fork: Option<&ForkDetails>, base_token_config: &BaseTokenConfig) -> Self {
46 if let Some(fork) = fork {
47 TestNodeFeeInputProvider::from_fee_params_and_estimate_scale_factors(
48 fork.fee_params,
49 fork.estimate_gas_price_scale_factor,
50 fork.estimate_gas_scale_factor,
51 )
52 } else {
53 let ratio = base_token_config.ratio;
54 let l1_gas_price = ((DEFAULT_L1_GAS_PRICE as u128)
55 * u128::from(ratio.denominator.get())
56 / u128::from(ratio.numerator.get()))
57 .try_into()
58 .expect("L1 gas price exceeded 2^64; base token ratio is too large");
59 let fair_pubdata_price = ((DEFAULT_FAIR_PUBDATA_PRICE as u128)
60 * u128::from(ratio.denominator.get())
61 / u128::from(ratio.numerator.get()))
62 .try_into()
63 .expect("pubdata gas price exceeded 2^64; base token ratio is too large");
64 Self {
65 estimate_gas_price_scale_factor: DEFAULT_ESTIMATE_GAS_PRICE_SCALE_FACTOR,
66 estimate_gas_scale_factor: DEFAULT_ESTIMATE_GAS_SCALE_FACTOR,
67 fee_params: FeeParamsV2::new(
68 FeeModelConfigV2 {
69 minimal_l2_gas_price: DEFAULT_L2_GAS_PRICE,
70 compute_overhead_part: 0.0,
71 pubdata_overhead_part: 1.0,
72 batch_overhead_l1_gas: 800000,
73 max_gas_per_batch: 200000000,
74 max_pubdata_per_batch: 500000,
75 },
76 l1_gas_price,
77 fair_pubdata_price,
78 ratio,
79 ),
80 forced_base_fee: None,
81 }
82 }
83 }
84
85 pub fn from_fee_params_and_estimate_scale_factors(
86 fee_params: FeeParams,
87 estimate_gas_price_scale_factor: f64,
88 estimate_gas_scale_factor: f32,
89 ) -> Self {
90 match fee_params {
91 FeeParams::V1(_) => todo!(),
92 FeeParams::V2(fee_params) => Self {
93 estimate_gas_price_scale_factor,
94 estimate_gas_scale_factor,
95 fee_params,
96 forced_base_fee: None,
97 },
98 }
99 }
100
101 pub fn from_estimate_scale_factors(
102 estimate_gas_price_scale_factor: f64,
103 estimate_gas_scale_factor: f32,
104 ) -> Self {
105 Self {
106 estimate_gas_price_scale_factor,
107 estimate_gas_scale_factor,
108 ..Default::default()
109 }
110 }
111
112 pub fn get_fee_model_config(&self) -> FeeModelConfigV2 {
113 self.fee_params.config()
114 }
115
116 fn get_params(&self) -> FeeParams {
117 FeeParams::V2(self.fee_params)
119 }
120
121 fn enforce_base_fee(&self, mut fee_input: BatchFeeInput) -> BatchFeeInput {
122 if let Some(base_fee) = self.forced_base_fee {
123 let mut pubdata_fee_input = fee_input.into_pubdata_independent();
124 pubdata_fee_input.fair_l2_gas_price = base_fee;
125 fee_input = BatchFeeInput::PubdataIndependent(pubdata_fee_input);
126 }
127 fee_input
128 }
129
130 pub(crate) fn get_batch_fee_input(&self) -> BatchFeeInput {
131 let fee_input = self.get_params().scale(1.0, 1.0);
132 self.enforce_base_fee(fee_input)
133 }
134
135 pub(crate) fn get_batch_fee_input_scaled(&self) -> BatchFeeInput {
136 let scale_factor = self.estimate_gas_price_scale_factor;
137 let fee_input = self.get_params().scale(scale_factor, scale_factor);
138 self.enforce_base_fee(fee_input)
139 }
140
141 pub fn gas_price(&self) -> u64 {
142 let (base_fee, _) = derive_base_fee_and_gas_per_pubdata(
143 self.get_batch_fee_input_scaled(),
144 VmVersion::latest(),
145 );
146 base_fee
147 }
148
149 pub fn fair_pubdata_price(&self) -> u64 {
150 self.get_batch_fee_input_scaled().fair_pubdata_price()
151 }
152
153 pub fn set_base_fee(&mut self, base_fee: u64) {
154 self.forced_base_fee = Some(base_fee);
155 }
156}
157
158impl Default for TestNodeFeeInputProvider {
159 fn default() -> Self {
160 Self {
161 estimate_gas_price_scale_factor: DEFAULT_ESTIMATE_GAS_PRICE_SCALE_FACTOR,
162 estimate_gas_scale_factor: DEFAULT_ESTIMATE_GAS_SCALE_FACTOR,
163 fee_params: FeeParamsV2::new(
164 FeeModelConfigV2 {
165 minimal_l2_gas_price: DEFAULT_L2_GAS_PRICE,
166 compute_overhead_part: 0.0,
167 pubdata_overhead_part: 1.0,
168 batch_overhead_l1_gas: 800000,
169 max_gas_per_batch: 200000000,
170 max_pubdata_per_batch: 500000,
171 },
172 DEFAULT_L1_GAS_PRICE,
173 DEFAULT_FAIR_PUBDATA_PRICE,
174 BaseTokenConversionRatio::default(),
175 ),
176 forced_base_fee: None,
177 }
178 }
179}