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}
164
165impl Default for CommonParams {
166 fn default() -> Self {
167 let mut base_block_rewards = BTreeMap::new();
168 base_block_rewards.insert(0, INITIAL_BASE_MINING_REWARD_IN_UCFX.into());
169 CommonParams {
170 maximum_extra_data_size: 0x20,
171 network_id: 0x1,
172 chain_id: ChainIdParamsInner::new_simple(AllChainID::new(1, 1)),
173 subprotocol_name: "cfx".into(),
174 min_gas_limit: 10_000_000.into(),
175 gas_limit_bound_divisor: 0x0400.into(),
176 max_transaction_size: 300 * 1024,
177 anticone_penalty_ratio: ANTICONE_PENALTY_RATIO,
178 base_block_rewards,
179 evm_transaction_block_ratio: EVM_TRANSACTION_BLOCK_RATIO,
180 evm_transaction_gas_ratio: EVM_TRANSACTION_GAS_RATIO,
181 params_dao_vote_period: DAO_PARAMETER_VOTE_PERIOD,
182 early_set_internal_contracts_states: false,
183 transition_numbers: Default::default(),
184 transition_heights: Default::default(),
185 min_base_price: SpaceMap::default(),
186 }
187 }
188}
189
190impl CommonParams {
191 pub fn spec(&self, number: BlockNumber, height: BlockHeight) -> Spec {
192 let mut spec = Spec::genesis_spec();
193 spec.cip43_contract = number >= self.transition_numbers.cip43a;
194 spec.cip43_init = number >= self.transition_numbers.cip43a
195 && number < self.transition_numbers.cip43b;
196 spec.cip62 = number >= self.transition_numbers.cip62;
197 spec.cip64 = number >= self.transition_numbers.cip64;
198 spec.cip71 = number >= self.transition_numbers.cip71;
199 spec.cip90 = number >= self.transition_numbers.cip90b;
200 spec.cip78a = number >= self.transition_numbers.cip78a;
201 spec.cip78b = number >= self.transition_numbers.cip78b;
202 spec.cip94 = number >= self.transition_numbers.cip94n;
203 spec.cip94_activation_block_number = self.transition_numbers.cip94n;
204 spec.cip97 = number >= self.transition_numbers.cip97;
205 spec.cip98 = number >= self.transition_numbers.cip98;
206 spec.cip105 = number >= self.transition_numbers.cip105;
207 spec.cip_sigma_fix = number >= self.transition_numbers.cip_sigma_fix;
208 spec.params_dao_vote_period = self.params_dao_vote_period;
209 spec.cip107 = number >= self.transition_numbers.cip107;
210 spec.cip118 = number >= self.transition_numbers.cip118;
211 spec.cip119 = number >= self.transition_numbers.cip119;
212 spec.cip131 = number >= self.transition_numbers.cip131;
213 spec.cip132 = number >= self.transition_numbers.cip132;
214 spec.cip133_b = self.transition_numbers.cip133b;
215 spec.cip133_e = self.transition_heights.cip133e;
216 spec.cip133_core = number >= self.transition_numbers.cip133b;
217 spec.cip137 = number >= self.transition_numbers.cip137;
218 spec.cip144 = number >= self.transition_numbers.cip144;
219 spec.cip145 = number >= self.transition_numbers.cip145;
220 spec.cip145_fix = height >= self.transition_heights.cip145_fix;
221 spec.cip1559 = height >= self.transition_heights.cip1559;
222 spec.cip150 = height >= self.transition_heights.cip150;
223 spec.cip151 = height >= self.transition_heights.cip151;
224 spec.cip152 = height >= self.transition_heights.cip152;
225 spec.cip154 = height >= self.transition_heights.cip154;
226 spec.cip7702 = height >= self.transition_heights.cip7702;
227 let cip645 = height >= self.transition_heights.cip645;
228 spec.cip645 = CIP645Spec::new(cip645);
229 spec.eip2935 = height >= self.transition_heights.eip2935;
230 spec.eip7623 = height >= self.transition_heights.eip7623;
231 spec.cip_c2_fix = height >= self.transition_heights.cip_c2_fix;
232 spec.cancun_opcodes = number >= self.transition_numbers.cancun_opcodes;
233 spec.align_evm = height >= self.transition_heights.align_evm && cip645;
234 spec.eip7939 = height >= self.transition_heights.cip166;
235
236 spec.overwrite_gas_plan_by_cip();
237
238 spec
239 }
240
241 pub fn consensus_spec(&self, height: BlockHeight) -> ConsensusGasSpec {
242 let mut spec = ConsensusGasSpec::genesis_spec();
243 spec.cip1559 = height >= self.transition_heights.cip1559;
244 let cip645 = height >= self.transition_heights.cip645;
245 spec.cip645 = CIP645Spec::new(cip645);
246
247 spec.align_evm = height >= self.transition_heights.align_evm && cip645;
248
249 spec.overwrite_gas_plan_by_cip();
250
251 spec
252 }
253
254 #[cfg(test)]
255 pub fn spec_for_test(&self, number: u64) -> Spec {
256 self.spec(number, number)
257 }
258
259 pub fn base_reward_in_ucfx(
262 &self, _past_block_count: u64, height: BlockHeight,
263 ) -> U512 {
264 let (_, start_base_ward) = self.base_block_rewards.iter()
265 .rev()
266 .find(|&(block, _)| *block <= height)
267 .expect("Current block's reward is not found; this indicates a chain config error");
268 U512::from(start_base_ward) * U512::from(ONE_UCFX_IN_DRIP)
270 }
271
272 pub fn custom_prefix(&self, height: BlockHeight) -> Option<Vec<Bytes>> {
273 if height >= self.transition_heights.cip40
274 && height < self.transition_heights.cip94h
275 {
276 Some(vec![TANZANITE_HEADER_CUSTOM_FIRST_ELEMENT.to_vec()])
277 } else if height >= self.transition_heights.cip94h
278 && height < self.transition_heights.cip112
279 {
280 Some(vec![DAO_VOTE_HEADER_CUSTOM_FIRST_ELEMENT.to_vec()])
281 } else if height >= self.transition_heights.cip112
282 && height < self.transition_heights.cip1559
283 {
284 Some(vec![CIP112_HEADER_CUSTOM_FIRST_ELEMENT.to_vec()])
285 } else if height >= self.transition_heights.cip1559 {
286 Some(vec![NEXT_HARDFORK_HEADER_CUSTOM_FIRST_ELEMENT.to_vec()])
287 } else {
288 None
289 }
290 }
291
292 pub fn can_pack_evm_transaction(&self, height: BlockHeight) -> bool {
293 height % self.evm_transaction_block_ratio == 0
294 }
295
296 pub fn chain_id(&self, epoch_height: u64, space: Space) -> u32 {
297 self.chain_id
298 .read()
299 .get_chain_id(epoch_height)
300 .in_space(space)
301 }
302
303 pub fn chain_id_map(&self, epoch_height: u64) -> BTreeMap<Space, u32> {
304 BTreeMap::from([
305 (Space::Native, self.chain_id(epoch_height, Space::Native)),
306 (
307 Space::Ethereum,
308 self.chain_id(epoch_height, Space::Ethereum),
309 ),
310 ])
311 }
312
313 pub fn init_base_price(&self) -> SpaceMap<U256> { self.min_base_price }
314
315 pub fn min_base_price(&self) -> SpaceMap<U256> { self.min_base_price }
316}