1use std::{
2 collections::HashMap, path::Path, str::FromStr, sync::Arc, time::Duration,
3};
4
5use parking_lot::Mutex;
6use rand_08::{prelude::StdRng, SeedableRng};
7use threadpool::ThreadPool;
8
9use cfx_internal_common::ChainIdParamsInner;
10use cfx_parameters::{
11 block::{MAX_BLOCK_SIZE_IN_BYTES, REFEREE_DEFAULT_BOUND},
12 consensus::{GENESIS_GAS_LIMIT, TRANSACTION_DEFAULT_EPOCH_BOUND},
13 tx_pool::TXPOOL_DEFAULT_NONCE_BITS,
14 WORKER_COMPUTATION_PARALLELISM,
15};
16use cfx_storage::{StorageConfiguration, StorageManager};
17use cfx_types::{
18 address_util::AddressUtil, Address, AddressSpaceUtil, AllChainID, H256,
19 U256,
20};
21use diem_config::keys::ConfigKey;
22use diem_crypto::Uniform;
23use diem_types::validator_config::{
24 ConsensusPrivateKey, ConsensusVRFPrivateKey,
25};
26use primitives::{Block, BlockHeaderBuilder};
27
28use crate::{
29 block_data_manager::{BlockDataManager, DataManagerConfiguration, DbType},
30 cache_config::CacheConfig,
31 consensus::{
32 consensus_inner::consensus_executor::ConsensusExecutionConfiguration,
33 pos_handler::{PosConfiguration, PosVerifier},
34 ConsensusConfig, ConsensusInnerConfig,
35 },
36 db::NUM_COLUMNS,
37 genesis_block::{genesis_block, GenesisPosState},
38 pow::{self, PowComputer, ProofOfWorkConfig},
39 statistics::Statistics,
40 sync::{SyncGraphConfig, SynchronizationGraph},
41 transaction_pool::TxPoolConfig,
42 verification::VerificationConfig,
43 ConsensusGraph, NodeType, Notifications, TransactionPool,
44};
45use cfx_executor::{
46 machine::{Machine, VmFactory},
47 spec::CommonParams,
48};
49
50pub fn create_simple_block_impl(
51 parent_hash: H256, ref_hashes: Vec<H256>, height: u64, nonce: U256,
52 diff: U256, block_weight: u32, adaptive: bool,
53) -> (H256, Block) {
54 let mut b = BlockHeaderBuilder::new();
55 let mut author = Address::zero();
56 author.set_user_account_type_bits();
57 let mut header = b
58 .with_parent_hash(parent_hash)
59 .with_height(height)
60 .with_referee_hashes(ref_hashes)
61 .with_gas_limit(GENESIS_GAS_LIMIT.into())
62 .with_nonce(nonce)
63 .with_difficulty(diff)
64 .with_adaptive(adaptive)
65 .with_author(author)
66 .build();
67 header.compute_hash();
68 let pow_quality = if block_weight > 1 {
69 diff * block_weight
70 } else {
71 diff
72 };
73 header.pow_hash =
76 Some(pow::pow_quality_to_hash(&pow_quality, &header.nonce()));
77 let block = Block::new(header, vec![]);
81 (block.hash(), block)
82}
83
84pub fn create_simple_block(
85 sync: Arc<SynchronizationGraph>, parent_hash: H256, ref_hashes: Vec<H256>,
86 height: u64, block_weight: u32, adaptive: bool,
87) -> (H256, Block) {
88 let exp_diff = U256::from(10);
98 let nonce = U256::from(sync.block_count() as u64 + 1);
99 create_simple_block_impl(
100 parent_hash,
101 ref_hashes,
102 height,
103 nonce,
104 exp_diff,
105 block_weight,
106 adaptive,
107 )
108}
109
110pub fn initialize_data_manager(
111 db_dir: &str, dbtype: DbType, pow: Arc<PowComputer>, vm: VmFactory,
112) -> (Arc<BlockDataManager>, Arc<Block>) {
113 let ledger_db = db::open_database(
114 db_dir,
115 &db::db_config(
116 Path::new(db_dir),
117 Some(128),
118 db::DatabaseCompactionProfile::default(),
119 NUM_COLUMNS,
120 false,
121 ),
122 )
123 .map_err(|e| format!("Failed to open database {:?}", e))
124 .unwrap();
125
126 let worker_thread_pool = Arc::new(Mutex::new(ThreadPool::with_name(
127 "Tx Recover".into(),
128 WORKER_COMPUTATION_PARALLELISM,
129 )));
130
131 let storage_manager = Arc::new(
132 StorageManager::new(StorageConfiguration::new_default(
133 db_dir,
134 cfx_parameters::consensus::SNAPSHOT_EPOCHS_CAPACITY,
135 cfx_parameters::consensus::ERA_DEFAULT_EPOCH_COUNT,
136 ))
137 .expect("Failed to initialize storage."),
138 );
139
140 let mut genesis_accounts = HashMap::new();
141 genesis_accounts.insert(
142 Address::from_str("1000000000000000000000000000000000000008")
143 .unwrap()
144 .with_native_space(),
145 U256::from(0),
146 );
147
148 let machine = Arc::new(Machine::new_with_builtin(Default::default(), vm));
149
150 let genesis_block = Arc::new(genesis_block(
151 &storage_manager,
152 genesis_accounts,
153 Address::from_str("1000000000000000000000000000000000000008").unwrap(),
154 U256::from(10),
155 machine.clone(),
156 false, None,
158 &Some(GenesisPosState {
159 initial_nodes: vec![],
160 initial_committee: vec![],
161 initial_seed: Default::default(),
162 }),
163 ));
164
165 let data_man = Arc::new(BlockDataManager::new(
166 CacheConfig::default(),
167 genesis_block.clone(),
168 ledger_db.clone(),
169 storage_manager,
170 worker_thread_pool,
171 DataManagerConfiguration::new(
172 false, false, Duration::from_millis(300_000), dbtype,
177 ),
178 pow,
179 ));
180 (data_man, genesis_block)
181}
182
183pub fn initialize_synchronization_graph_with_data_manager(
184 data_man: Arc<BlockDataManager>, beta: u64, h: u64, tcr: u64, tcb: u64,
185 era_epoch_count: u64, pow: Arc<PowComputer>, vm: VmFactory,
186) -> (Arc<SynchronizationGraph>, Arc<ConsensusGraph>) {
187 let mut params = CommonParams::default();
188 params.transition_heights.cip1559 = u64::MAX;
189 let machine = Arc::new(Machine::new_with_builtin(params.clone(), vm));
190 let mut rng = StdRng::from_seed([0u8; 32]);
191 let pos_verifier = Arc::new(PosVerifier::new(
192 None,
193 PosConfiguration {
195 bls_key: ConfigKey::new(ConsensusPrivateKey::generate(&mut rng)),
196 vrf_key: ConfigKey::new(ConsensusVRFPrivateKey::generate(&mut rng)),
197 diem_conf_path: Default::default(),
198 protocol_conf: Default::default(),
199 pos_initial_nodes_path: "".to_string(),
200 vrf_proposal_threshold: Default::default(),
201 pos_state_config: Default::default(),
202 },
203 u64::MAX,
204 ));
205
206 let verification_config = VerificationConfig::new(
207 true, REFEREE_DEFAULT_BOUND,
209 MAX_BLOCK_SIZE_IN_BYTES,
210 TRANSACTION_DEFAULT_EPOCH_BOUND,
211 TXPOOL_DEFAULT_NONCE_BITS,
212 pos_verifier.enable_height(),
213 machine.clone(),
214 );
215
216 let txpool = Arc::new(TransactionPool::new(
217 TxPoolConfig::default(),
218 verification_config.clone(),
219 data_man.clone(),
220 machine.clone(),
221 ));
222 let statistics = Arc::new(Statistics::new());
223
224 let pow_config = ProofOfWorkConfig::new(
225 true, false, "disable", Some(10),
229 String::from(""), 0, None, 1, 0, );
235 let sync_config = SyncGraphConfig {
236 future_block_buffer_capacity: 1,
237 enable_state_expose: false,
238 is_consortium: false,
239 };
240 let notifications = Notifications::init();
241 let consensus = Arc::new(ConsensusGraph::new(
242 ConsensusConfig {
243 chain_id: ChainIdParamsInner::new_simple(AllChainID::new(1, 1)),
244 inner_conf: ConsensusInnerConfig {
245 adaptive_weight_beta: beta,
246 heavy_block_difficulty_ratio: h,
247 timer_chain_block_difficulty_ratio: tcr,
248 timer_chain_beta: tcb,
249 era_epoch_count,
250 enable_optimistic_execution: false,
251 enable_state_expose: false,
252 pos_pivot_decision_defer_epoch_count: 50,
253 cip113_pivot_decision_defer_epoch_count: 50,
254 cip113_transition_height: u64::MAX,
255 debug_dump_dir_invalid_state_root: None,
256 debug_invalid_state_root_epoch: None,
257 force_recompute_height_during_construct_pivot: None,
258 recovery_latest_mpt_snapshot: false,
259 use_isolated_db_for_mpt_table: false,
260 },
261 bench_mode: true, transaction_epoch_bound: TRANSACTION_DEFAULT_EPOCH_BOUND,
264 referee_bound: REFEREE_DEFAULT_BOUND,
265 get_logs_epoch_batch_size: 32,
266 get_logs_filter_max_epoch_range: None,
267 get_logs_filter_max_block_number_range: None,
268 get_logs_filter_max_limit: None,
269 sync_state_starting_epoch: None,
270 sync_state_epoch_gap: None,
271 pivot_hint_conf: None,
272 },
273 txpool.clone(),
274 statistics.clone(),
275 data_man.clone(),
276 pow_config.clone(),
277 pow.clone(),
278 notifications.clone(),
279 ConsensusExecutionConfiguration {
280 executive_trace: false,
281 },
282 verification_config.clone(),
283 NodeType::Archive,
284 pos_verifier.clone(),
285 None,
286 params,
287 ));
288
289 let sync = Arc::new(SynchronizationGraph::new(
290 consensus.clone(),
291 data_man.clone(),
292 statistics.clone(),
293 verification_config,
294 pow_config,
295 pow.clone(),
296 sync_config,
297 notifications,
298 machine,
299 pos_verifier.clone(),
300 ));
301
302 (sync, consensus)
303}
304
305pub fn initialize_synchronization_graph(
307 db_dir: &str, beta: u64, h: u64, tcr: u64, tcb: u64, era_epoch_count: u64,
308 dbtype: DbType,
309) -> (
310 Arc<SynchronizationGraph>,
311 Arc<ConsensusGraph>,
312 Arc<BlockDataManager>,
313 Arc<Block>,
314) {
315 let vm = VmFactory::new(1024 * 32);
316 let pow = Arc::new(PowComputer::new(true));
317
318 let (data_man, genesis_block) =
319 initialize_data_manager(db_dir, dbtype, pow.clone(), vm.clone());
320
321 let (sync, consensus) = initialize_synchronization_graph_with_data_manager(
322 data_man.clone(),
323 beta,
324 h,
325 tcr,
326 tcb,
327 era_epoch_count,
328 pow,
329 vm,
330 );
331
332 (sync, consensus, data_man, genesis_block)
333}