1use cfx_bytes::Bytes;
6use cfx_internal_common::{ChainIdParams, ChainIdParamsInner};
7use cfx_parameters::{
8 block::{EVM_TRANSACTION_BLOCK_RATIO, EVM_TRANSACTION_GAS_RATIO},
9 consensus::{
10 CIP112_HEADER_CUSTOM_FIRST_ELEMENT,
11 DAO_VOTE_HEADER_CUSTOM_FIRST_ELEMENT,
12 NEXT_HARDFORK_HEADER_CUSTOM_FIRST_ELEMENT, ONE_UCFX_IN_DRIP,
13 TANZANITE_HEADER_CUSTOM_FIRST_ELEMENT,
14 },
15 consensus_internal::{
16 ANTICONE_PENALTY_RATIO, DAO_PARAMETER_VOTE_PERIOD,
17 INITIAL_BASE_MINING_REWARD_IN_UCFX,
18 },
19};
20use cfx_types::{AllChainID, Space, SpaceMap, U256, U512};
21use cfx_vm_types::{CIP645Spec, ConsensusGasSpec, Spec};
22use primitives::{block::BlockHeight, BlockNumber};
23use std::collections::BTreeMap;
24
25#[derive(Debug, Clone)]
30pub struct CommonParams {
31 pub maximum_extra_data_size: usize,
33 pub network_id: u64,
35 pub chain_id: ChainIdParams,
37 pub subprotocol_name: String,
39 pub min_gas_limit: U256,
41 pub gas_limit_bound_divisor: U256,
43 pub max_transaction_size: usize,
46 pub anticone_penalty_ratio: u64,
49 pub base_block_rewards: BTreeMap<BlockHeight, U256>,
51 pub evm_transaction_block_ratio: u64,
53 pub evm_transaction_gas_ratio: u64,
56 pub params_dao_vote_period: u64,
57 pub min_base_price: SpaceMap<U256>,
58
59 pub early_set_internal_contracts_states: bool,
62 pub transition_numbers: TransitionsBlockNumber,
64 pub transition_heights: TransitionsEpochHeight,
66}
67
68#[derive(Default, Debug, Clone)]
69pub struct TransitionsBlockNumber {
70 pub cip43a: BlockNumber,
72 pub cip43b: BlockNumber,
73 pub cip62: BlockNumber,
75 pub cip64: BlockNumber,
77 pub cip71: BlockNumber,
79 pub cip78a: BlockNumber,
81 pub cip78b: BlockNumber,
82 pub cip90b: BlockNumber,
84 pub cip92: BlockNumber,
86 pub cip94n: BlockNumber,
88 pub cip97: BlockNumber,
90 pub cip98: BlockNumber,
92 pub cip105: BlockNumber,
94 pub cip107: BlockNumber,
96 pub cip_sigma_fix: BlockNumber,
98 pub cip118: BlockNumber,
100 pub cip119: BlockNumber,
102 pub cip131: BlockNumber,
104 pub cip132: BlockNumber,
106 pub cip133b: BlockNumber,
108 pub cip137: BlockNumber,
110 pub cancun_opcodes: BlockNumber,
114 pub cip144: BlockNumber,
116 pub cip145: BlockNumber,
118}
119
120#[derive(Default, Debug, Clone)]
121pub struct TransitionsEpochHeight {
122 pub cip40: BlockHeight,
124 pub cip76: BlockHeight,
126 pub cip86: BlockHeight,
128 pub cip90a: BlockHeight,
130 pub cip94h: BlockHeight,
132 pub cip112: BlockHeight,
134 pub cip130: BlockHeight,
136 pub cip133e: BlockHeight,
138 pub cip1559: BlockHeight,
140 pub cip150: BlockHeight,
142 pub cip151: BlockHeight,
144 pub cip152: BlockHeight,
146 pub cip154: BlockHeight,
148 pub cip7702: BlockHeight,
150 pub cip645: BlockHeight,
152 pub align_evm: BlockHeight,
153 pub eip2935: BlockHeight,
155 pub eip2537: BlockHeight,
157 pub eip7623: BlockHeight,
159 pub cip_c2_fix: BlockHeight,
160 pub cip145_fix: BlockHeight,
161 pub cip166: BlockHeight,
163 pub cip167: BlockHeight,
165}
166
167impl Default for CommonParams {
168 fn default() -> Self {
169 let mut base_block_rewards = BTreeMap::new();
170 base_block_rewards.insert(0, INITIAL_BASE_MINING_REWARD_IN_UCFX.into());
171 CommonParams {
172 maximum_extra_data_size: 0x20,
173 network_id: 0x1,
174 chain_id: ChainIdParamsInner::new_simple(AllChainID::new(1, 1)),
175 subprotocol_name: "cfx".into(),
176 min_gas_limit: 10_000_000.into(),
177 gas_limit_bound_divisor: 0x0400.into(),
178 max_transaction_size: 300 * 1024,
179 anticone_penalty_ratio: ANTICONE_PENALTY_RATIO,
180 base_block_rewards,
181 evm_transaction_block_ratio: EVM_TRANSACTION_BLOCK_RATIO,
182 evm_transaction_gas_ratio: EVM_TRANSACTION_GAS_RATIO,
183 params_dao_vote_period: DAO_PARAMETER_VOTE_PERIOD,
184 early_set_internal_contracts_states: false,
185 transition_numbers: Default::default(),
186 transition_heights: Default::default(),
187 min_base_price: SpaceMap::default(),
188 }
189 }
190}
191
192impl CommonParams {
193 pub fn spec(&self, number: BlockNumber, height: BlockHeight) -> Spec {
194 let mut spec = Spec::genesis_spec();
195 spec.cip43_contract = number >= self.transition_numbers.cip43a;
196 spec.cip43_init = number >= self.transition_numbers.cip43a
197 && number < self.transition_numbers.cip43b;
198 spec.cip62 = number >= self.transition_numbers.cip62;
199 spec.cip64 = number >= self.transition_numbers.cip64;
200 spec.cip71 = number >= self.transition_numbers.cip71;
201 spec.cip90 = number >= self.transition_numbers.cip90b;
202 spec.cip78a = number >= self.transition_numbers.cip78a;
203 spec.cip78b = number >= self.transition_numbers.cip78b;
204 spec.cip94 = number >= self.transition_numbers.cip94n;
205 spec.cip94_activation_block_number = self.transition_numbers.cip94n;
206 spec.cip97 = number >= self.transition_numbers.cip97;
207 spec.cip98 = number >= self.transition_numbers.cip98;
208 spec.cip105 = number >= self.transition_numbers.cip105;
209 spec.cip_sigma_fix = number >= self.transition_numbers.cip_sigma_fix;
210 spec.params_dao_vote_period = self.params_dao_vote_period;
211 spec.cip107 = number >= self.transition_numbers.cip107;
212 spec.cip118 = number >= self.transition_numbers.cip118;
213 spec.cip119 = number >= self.transition_numbers.cip119;
214 spec.cip131 = number >= self.transition_numbers.cip131;
215 spec.cip132 = number >= self.transition_numbers.cip132;
216 spec.cip133_b = self.transition_numbers.cip133b;
217 spec.cip133_e = self.transition_heights.cip133e;
218 spec.cip133_core = number >= self.transition_numbers.cip133b;
219 spec.cip137 = number >= self.transition_numbers.cip137;
220 spec.cip144 = number >= self.transition_numbers.cip144;
221 spec.cip145 = number >= self.transition_numbers.cip145;
222 spec.cip145_fix = height >= self.transition_heights.cip145_fix;
223 spec.cip1559 = height >= self.transition_heights.cip1559;
224 spec.cip150 = height >= self.transition_heights.cip150;
225 spec.cip151 = height >= self.transition_heights.cip151;
226 spec.cip152 = height >= self.transition_heights.cip152;
227 spec.cip154 = height >= self.transition_heights.cip154;
228 spec.cip7702 = height >= self.transition_heights.cip7702;
229 let cip645 = height >= self.transition_heights.cip645;
230 spec.cip645 = CIP645Spec::new(cip645);
231 spec.eip2935 = height >= self.transition_heights.eip2935;
232 spec.eip7623 = height >= self.transition_heights.eip7623;
233 spec.cip_c2_fix = height >= self.transition_heights.cip_c2_fix;
234 spec.cancun_opcodes = number >= self.transition_numbers.cancun_opcodes;
235 spec.align_evm = height >= self.transition_heights.align_evm && cip645;
236 spec.eip7939 = height >= self.transition_heights.cip166;
237
238 spec.overwrite_gas_plan_by_cip();
239
240 spec
241 }
242
243 pub fn consensus_spec(&self, height: BlockHeight) -> ConsensusGasSpec {
244 let mut spec = ConsensusGasSpec::genesis_spec();
245 spec.cip1559 = height >= self.transition_heights.cip1559;
246 let cip645 = height >= self.transition_heights.cip645;
247 spec.cip645 = CIP645Spec::new(cip645);
248
249 spec.align_evm = height >= self.transition_heights.align_evm && cip645;
250
251 spec.overwrite_gas_plan_by_cip();
252
253 spec
254 }
255
256 #[cfg(test)]
257 pub fn spec_for_test(&self, number: u64) -> Spec {
258 self.spec(number, number)
259 }
260
261 pub fn base_reward_in_ucfx(
264 &self, _past_block_count: u64, height: BlockHeight,
265 ) -> U512 {
266 let (_, start_base_ward) = self.base_block_rewards.iter()
267 .rev()
268 .find(|&(block, _)| *block <= height)
269 .expect("Current block's reward is not found; this indicates a chain config error");
270 U512::from(start_base_ward) * U512::from(ONE_UCFX_IN_DRIP)
272 }
273
274 pub fn custom_prefix(&self, height: BlockHeight) -> Option<Vec<Bytes>> {
275 if height >= self.transition_heights.cip40
276 && height < self.transition_heights.cip94h
277 {
278 Some(vec![TANZANITE_HEADER_CUSTOM_FIRST_ELEMENT.to_vec()])
279 } else if height >= self.transition_heights.cip94h
280 && height < self.transition_heights.cip112
281 {
282 Some(vec![DAO_VOTE_HEADER_CUSTOM_FIRST_ELEMENT.to_vec()])
283 } else if height >= self.transition_heights.cip112
284 && height < self.transition_heights.cip1559
285 {
286 Some(vec![CIP112_HEADER_CUSTOM_FIRST_ELEMENT.to_vec()])
287 } else if height >= self.transition_heights.cip1559 {
288 Some(vec![NEXT_HARDFORK_HEADER_CUSTOM_FIRST_ELEMENT.to_vec()])
289 } else {
290 None
291 }
292 }
293
294 pub fn can_pack_evm_transaction(&self, height: BlockHeight) -> bool {
295 height % self.evm_transaction_block_ratio == 0
296 }
297
298 pub fn chain_id(&self, epoch_height: u64, space: Space) -> u32 {
299 self.chain_id
300 .read()
301 .get_chain_id(epoch_height)
302 .in_space(space)
303 }
304
305 pub fn chain_id_map(&self, epoch_height: u64) -> BTreeMap<Space, u32> {
306 BTreeMap::from([
307 (Space::Native, self.chain_id(epoch_height, Space::Native)),
308 (
309 Space::Ethereum,
310 self.chain_id(epoch_height, Space::Ethereum),
311 ),
312 ])
313 }
314
315 pub fn init_base_price(&self) -> SpaceMap<U256> { self.min_base_price }
316
317 pub fn min_base_price(&self) -> SpaceMap<U256> { self.min_base_price }
318}