1#[cfg(test)]
2pub mod test {
3 use crate::core::consensus::block::{Block, BlockType};
4 use crate::core::consensus::blockchain::Blockchain;
5 use crate::core::consensus::blockchain_sync_state::BlockchainSyncState;
6 use crate::core::consensus::context::Context;
7 use crate::core::consensus::mempool::Mempool;
8 use crate::core::consensus::peers::peer_collection::PeerCollection;
9
10 use crate::core::consensus::slip::Slip;
11 use crate::core::consensus::transaction::Transaction;
12 use crate::core::consensus::wallet::Wallet;
13 use crate::core::consensus_thread::{ConsensusEvent, ConsensusStats, ConsensusThread};
14 use crate::core::defs::{
15 BlockId, Currency, ForkId, PrintForLog, SaitoHash, SaitoPrivateKey, StatVariable,
16 STAT_BIN_COUNT,
17 };
18 use crate::core::defs::{SaitoPublicKey, Timestamp};
19 use crate::core::io::network::Network;
20 use crate::core::io::network_event::NetworkEvent;
21 use crate::core::io::storage::Storage;
22 use crate::core::mining_thread::{MiningEvent, MiningThread};
23 use crate::core::process::keep_time::KeepTime;
24 use crate::core::process::keep_time::Timer;
25 use crate::core::process::process_event::ProcessEvent;
26 use crate::core::routing_thread::{RoutingEvent, RoutingStats, RoutingThread};
27 use crate::core::stat_thread::StatThread;
28 use crate::core::util::configuration::{
29 get_default_issuance_writing_block_interval, BlockchainConfig, Configuration,
30 ConsensusConfig, Endpoint, PeerConfig, Server,
31 };
32 use crate::core::util::crypto::{generate_keypair_from_private_key, generate_keys};
33 use crate::core::util::test::test_io_handler::test::TestIOHandler;
34 use crate::core::verification_thread::{VerificationThread, VerifyRequest};
35 use log::{info, warn};
36 use serde::Deserialize;
37 use std::io::{Error, ErrorKind};
38 use std::ops::DerefMut;
39 use std::sync::Arc;
40 use std::time::{Duration, SystemTime, UNIX_EPOCH};
41 use tokio::sync::mpsc::Receiver;
42 use tokio::sync::RwLock;
43
44 #[derive(Clone)]
45 pub struct TestTimeKeeper {}
46
47 impl KeepTime for TestTimeKeeper {
48 fn get_timestamp_in_ms(&self) -> Timestamp {
49 SystemTime::now()
50 .duration_since(UNIX_EPOCH)
51 .unwrap()
52 .as_millis() as Timestamp
53 }
54 }
55 fn get_default_consensus() -> Option<ConsensusConfig> {
56 Some(ConsensusConfig::default())
57 }
58 #[derive(Deserialize, Debug)]
59 pub struct TestConfiguration {
60 server: Option<Server>,
61 peers: Vec<PeerConfig>,
62 blockchain: BlockchainConfig,
63 spv_mode: bool,
64 browser_mode: bool,
65 #[serde(default = "get_default_consensus")]
66 consensus: Option<ConsensusConfig>,
67 }
68 impl Configuration for TestConfiguration {
69 fn get_server_configs(&self) -> Option<&Server> {
70 self.server.as_ref()
71 }
72
73 fn get_peer_configs(&self) -> &Vec<PeerConfig> {
74 &self.peers
75 }
76
77 fn get_blockchain_configs(&self) -> &BlockchainConfig {
78 &self.blockchain
79 }
80
81 fn get_block_fetch_url(&self) -> String {
82 "".to_string()
83 }
84
85 fn is_spv_mode(&self) -> bool {
86 self.spv_mode
87 }
88
89 fn is_browser(&self) -> bool {
90 self.browser_mode
91 }
92
93 fn replace(&mut self, config: &dyn Configuration) {
94 todo!()
95 }
96
97 fn get_consensus_config(&self) -> Option<&ConsensusConfig> {
98 self.consensus.as_ref()
99 }
100 }
101 impl Default for TestConfiguration {
102 fn default() -> Self {
103 TestConfiguration {
104 server: Some(Server {
105 host: "localhost".to_string(),
106 port: 12100,
107 protocol: "http".to_string(),
108 endpoint: Endpoint {
109 host: "localhost".to_string(),
110 port: 12101,
111 protocol: "http".to_string(),
112 },
113 verification_threads: 2,
114 channel_size: 1000,
115 stat_timer_in_ms: 10000,
116 reconnection_wait_time: 10000,
117 thread_sleep_time_in_ms: 10,
118 block_fetch_batch_size: 0,
119 }),
120 peers: vec![],
121 blockchain: BlockchainConfig {
122 last_block_hash:
123 "0000000000000000000000000000000000000000000000000000000000000000"
124 .to_string(),
125 last_block_id: 0,
126 last_timestamp: 0,
127 genesis_block_id: 0,
128 genesis_timestamp: 0,
129 lowest_acceptable_timestamp: 0,
130 lowest_acceptable_block_hash:
131 "0000000000000000000000000000000000000000000000000000000000000000"
132 .to_string(),
133 lowest_acceptable_block_id: 0,
134 fork_id: "0000000000000000000000000000000000000000000000000000000000000000"
135 .to_string(),
136 initial_loading_completed: false,
137 issuance_writing_block_interval: get_default_issuance_writing_block_interval(),
138 },
139 spv_mode: false,
140 browser_mode: false,
141 consensus: Some(ConsensusConfig {
142 genesis_period: 100,
143 heartbeat_interval: 5_000,
144 prune_after_blocks: 8,
145 max_staker_recursions: 3,
146 default_social_stake: 0,
147 default_social_stake_period: 60,
148 }),
149 }
150 }
151 }
152
153 pub struct NodeTester {
154 pub consensus_thread: ConsensusThread,
155 pub routing_thread: RoutingThread,
156 pub mining_thread: MiningThread,
157 pub verification_thread: VerificationThread,
158 pub stat_thread: StatThread,
159 pub timer: Timer,
160 receiver_for_router: Receiver<RoutingEvent>,
161 receiver_for_consensus: Receiver<ConsensusEvent>,
162 receiver_for_miner: Receiver<MiningEvent>,
163 receiver_for_verification: Receiver<VerifyRequest>,
164 receiver_for_stats: Receiver<String>,
165 pub timeout_in_ms: u64,
166 last_run_time: Timestamp,
167 pub initial_token_supply: Currency,
168 }
169
170 impl Default for NodeTester {
171 fn default() -> Self {
172 Self::new(100, None, None)
173 }
174 }
175 impl NodeTester {
176 pub fn new(
177 genesis_period: BlockId,
178 private_key: Option<SaitoPrivateKey>,
179 mut timer: Option<Timer>,
180 ) -> Self {
181 let (public_key, private_key) = if let Some(private_key) = &private_key {
182 generate_keypair_from_private_key(private_key)
183 } else {
184 generate_keys()
185 };
186 let wallet = Arc::new(RwLock::new(Wallet::new(private_key, public_key)));
187
188 info!("node tester public key : {:?}", public_key.to_base58());
189
190 let mut configuration = TestConfiguration::default();
191 configuration.consensus.as_mut().unwrap().genesis_period = genesis_period;
192 let configuration: Arc<RwLock<dyn Configuration + Send + Sync>> =
193 Arc::new(RwLock::new(configuration));
194
195 let channel_size = 1_000_000;
196
197 let peers = Arc::new(RwLock::new(PeerCollection::default()));
198 let context = Context {
199 blockchain_lock: Arc::new(RwLock::new(Blockchain::new(
200 wallet.clone(),
201 genesis_period,
202 0,
203 60,
204 ))),
205 mempool_lock: Arc::new(RwLock::new(Mempool::new(wallet.clone()))),
206 wallet_lock: wallet.clone(),
207 config_lock: configuration.clone(),
208 };
209
210 let (sender_to_consensus, receiver_in_mempool) =
211 tokio::sync::mpsc::channel(channel_size);
212 let (sender_to_blockchain, receiver_in_blockchain) =
213 tokio::sync::mpsc::channel(channel_size);
214 let (sender_to_miner, receiver_in_miner) = tokio::sync::mpsc::channel(channel_size);
215 let (sender_to_stat, receiver_in_stats) = tokio::sync::mpsc::channel(channel_size);
216 let (sender_to_verification, receiver_in_verification) =
217 tokio::sync::mpsc::channel(channel_size);
218
219 if timer.is_none() {
220 timer = Some(Timer {
221 time_reader: Arc::new(TestTimeKeeper {}),
222 hasten_multiplier: 10_000,
223 start_time: TestTimeKeeper {}.get_timestamp_in_ms(),
224 });
225 }
226
227 NodeTester {
228 routing_thread: RoutingThread {
229 blockchain_lock: context.blockchain_lock.clone(),
230 mempool_lock: context.mempool_lock.clone(),
231 sender_to_consensus: sender_to_consensus.clone(),
232 sender_to_miner: sender_to_miner.clone(),
233 config_lock: context.config_lock.clone(),
234 timer: timer.clone().unwrap(),
235 wallet_lock: wallet.clone(),
236 network: Network::new(
237 Box::new(TestIOHandler {}),
238 peers.clone(),
239 context.wallet_lock.clone(),
240 context.config_lock.clone(),
241 timer.clone().unwrap(),
242 ),
243 storage: Storage::new(Box::new(TestIOHandler {})),
244 reconnection_timer: 0,
245 peer_removal_timer: 0,
246 peer_file_write_timer: 0,
247 last_emitted_block_fetch_count: 0,
248 stats: RoutingStats::new(sender_to_stat.clone()),
249 senders_to_verification: vec![sender_to_verification.clone()],
250 last_verification_thread_index: 0,
251 stat_sender: sender_to_stat.clone(),
252 blockchain_sync_state: BlockchainSyncState::new(10),
253 },
254 consensus_thread: ConsensusThread {
255 mempool_lock: context.mempool_lock.clone(),
256 blockchain_lock: context.blockchain_lock.clone(),
257 wallet_lock: context.wallet_lock.clone(),
258 generate_genesis_block: false,
259 sender_to_router: sender_to_blockchain.clone(),
260 sender_to_miner: sender_to_miner.clone(),
261 block_producing_timer: 0,
263 timer: timer.clone().unwrap(),
264 network: Network::new(
265 Box::new(TestIOHandler {}),
266 peers.clone(),
267 context.wallet_lock.clone(),
268 configuration.clone(),
269 timer.clone().unwrap(),
270 ),
271 storage: Storage::new(Box::new(TestIOHandler {})),
272 stats: ConsensusStats::new(sender_to_stat.clone()),
273 txs_for_mempool: vec![],
274 stat_sender: sender_to_stat.clone(),
275 config_lock: configuration.clone(),
276 produce_blocks_by_timer: true,
277 delete_old_blocks: true,
278 },
279 mining_thread: MiningThread {
280 wallet_lock: context.wallet_lock.clone(),
281 sender_to_mempool: sender_to_consensus.clone(),
282 timer: timer.clone().unwrap(),
283 miner_active: false,
284 target: [0; 32],
285 target_id: 0,
286 difficulty: 0,
287 public_key: [0; 33],
288 mined_golden_tickets: 0,
289 stat_sender: sender_to_stat.clone(),
290 config_lock: configuration.clone(),
291 enabled: true,
292 mining_iterations: 1,
293 mining_start: 0,
294 },
295 verification_thread: VerificationThread {
296 sender_to_consensus: sender_to_consensus.clone(),
297 blockchain_lock: context.blockchain_lock.clone(),
298 peer_lock: peers.clone(),
299 wallet_lock: wallet.clone(),
300 processed_txs: StatVariable::new(
301 "verification::processed_txs".to_string(),
302 STAT_BIN_COUNT,
303 sender_to_stat.clone(),
304 ),
305 processed_blocks: StatVariable::new(
306 "verification::processed_blocks".to_string(),
307 STAT_BIN_COUNT,
308 sender_to_stat.clone(),
309 ),
310 processed_msgs: StatVariable::new(
311 "verification::processed_msgs".to_string(),
312 STAT_BIN_COUNT,
313 sender_to_stat.clone(),
314 ),
315 invalid_txs: StatVariable::new(
316 "verification::invalid_txs".to_string(),
317 STAT_BIN_COUNT,
318 sender_to_stat.clone(),
319 ),
320 stat_sender: sender_to_stat.clone(),
321 },
322 stat_thread: StatThread {
323 stat_queue: Default::default(),
324 io_interface: Box::new(TestIOHandler {}),
325 enabled: true,
326 },
327 timer: timer.clone().unwrap(),
328 receiver_for_router: receiver_in_blockchain,
329 receiver_for_consensus: receiver_in_mempool,
330 receiver_for_miner: receiver_in_miner,
331 receiver_for_verification: receiver_in_verification,
332 receiver_for_stats: receiver_in_stats,
333 timeout_in_ms: Duration::new(10, 0).as_millis() as u64,
334 last_run_time: 0,
335 initial_token_supply: 0,
336 }
337 }
338 pub async fn init(&mut self) -> Result<(), Error> {
339 self.consensus_thread.on_init().await;
340 self.routing_thread.on_init().await;
341 self.mining_thread.on_init().await;
342 self.verification_thread.on_init().await;
343 self.stat_thread.on_init().await;
344 self.initial_token_supply += self
345 .consensus_thread
346 .blockchain_lock
347 .read()
348 .await
349 .calculate_current_supply();
350
351 Ok(())
352 }
353
354 pub async fn init_with_staking(
355 &mut self,
356 staking_requirement: Currency,
357 staking_period: u64,
358 additional_funds: Currency,
359 ) -> Result<(), Error> {
360 let public_key = self.get_public_key().await;
361 self.set_staking_requirement(staking_requirement, staking_period)
362 .await;
363 let issuance = vec![
364 (public_key.to_base58(), staking_requirement * staking_period),
365 (public_key.to_base58(), additional_funds),
366 ];
367 self.set_issuance(issuance).await?;
368
369 self.init().await?;
370
371 self.wait_till_block_id(1).await
372 }
373 async fn run_event_loop_once(&mut self) {
374 if let Ok(event) = self.receiver_for_router.try_recv() {
375 self.routing_thread.process_event(event).await;
376 }
377 if let Ok(event) = self.receiver_for_miner.try_recv() {
378 self.mining_thread.process_event(event).await;
379 }
380 if let Ok(event) = self.receiver_for_stats.try_recv() {
381 self.stat_thread.process_event(event).await;
382 }
383 if let Ok(event) = self.receiver_for_consensus.try_recv() {
384 self.consensus_thread.process_event(event).await;
385 }
386 if let Ok(event) = self.receiver_for_verification.try_recv() {
387 self.verification_thread.process_event(event).await;
388 }
389 self.run_timer_loop_once().await;
390 }
391 async fn run_timer_loop_once(&mut self) {
392 let current_time = self.timer.get_timestamp_in_ms();
393 if current_time < self.last_run_time {
394 return;
395 }
396 let diff = current_time - self.last_run_time;
397 let duration = Duration::from_millis(diff);
398 self.routing_thread.process_timer_event(duration).await;
399 self.mining_thread.process_timer_event(duration).await;
400 self.stat_thread.process_timer_event(duration).await;
401 self.consensus_thread.process_timer_event(duration).await;
402 self.verification_thread.process_timer_event(duration).await;
403 self.last_run_time = self.timer.get_timestamp_in_ms();
404 }
405 pub async fn run_until(&mut self, timestamp: Timestamp) -> Result<(), Error> {
406 let time_keeper = TestTimeKeeper {};
407 loop {
408 if time_keeper.get_timestamp_in_ms() >= timestamp {
409 break;
410 }
411 self.run_event_loop_once().await;
412 }
413 Ok(())
414 }
415 pub async fn wait_till_block_id(&mut self, block_id: BlockId) -> Result<(), Error> {
416 let time_keeper = TestTimeKeeper {};
417 let timeout = time_keeper.get_timestamp_in_ms() + self.timeout_in_ms;
418 info!("waiting for block id : {}", block_id);
419 loop {
420 {
421 let blockchain = self.routing_thread.blockchain_lock.read().await;
422 if blockchain.get_latest_block_id() >= block_id {
423 break;
424 }
425 }
426
427 self.run_event_loop_once().await;
428
429 if time_keeper.get_timestamp_in_ms() > timeout {
430 panic!("request timed out");
431 }
432 }
433
434 Ok(())
435 }
436 pub async fn wait_till_block_id_with_hash(
437 &mut self,
438 block_id: BlockId,
439 block_hash: SaitoHash,
440 ) -> Result<(), Error> {
441 let time_keeper = TestTimeKeeper {};
442 let timeout = time_keeper.get_timestamp_in_ms() + self.timeout_in_ms;
443 info!("waiting for block id : {}", block_id);
444 loop {
445 {
446 let blockchain = self.routing_thread.blockchain_lock.read().await;
447 if blockchain.contains_block_hash_at_block_id(block_id, block_hash) {
448 break;
449 }
450 }
451
452 self.run_event_loop_once().await;
453
454 if time_keeper.get_timestamp_in_ms() > timeout {
455 panic!("request timed out");
456 }
457 }
458
459 Ok(())
460 }
461 pub async fn wait_till_block_id_with_txs(
462 &mut self,
463 wait_till_block_id: BlockId,
464 tx_value: Currency,
465 tx_fee: Currency,
466 ) -> Result<(), Error> {
467 let public_key = self.get_public_key().await;
468 let mut current_block_id = self.get_latest_block_id().await;
469
470 let time_keeper = TestTimeKeeper {};
471 let timeout_time = time_keeper.get_timestamp_in_ms() + self.timeout_in_ms;
472
473 loop {
474 let tx = self
475 .create_transaction(tx_value, tx_fee, public_key)
476 .await?;
477 self.add_transaction(tx).await;
478 self.wait_till_block_id(current_block_id + 1).await?;
479 current_block_id = self.get_latest_block_id().await;
480
481 if current_block_id >= wait_till_block_id {
482 break;
483 }
484 let current_time = time_keeper.get_timestamp_in_ms();
485 if current_time > timeout_time {
486 panic!("request timed out");
487 }
488 }
489 self.wait_till_block_id(wait_till_block_id).await
490 }
491 pub async fn get_latest_block_id(&self) -> BlockId {
492 self.routing_thread
493 .blockchain_lock
494 .read()
495 .await
496 .get_latest_block_id()
497 }
498 pub async fn wait_till_mempool_tx_count(&mut self, tx_count: u64) -> Result<(), Error> {
499 let timeout = self.timer.get_timestamp_in_ms() + self.timeout_in_ms;
500 let time_keeper = TestTimeKeeper {};
501 loop {
502 {
503 let mempool = self.routing_thread.mempool_lock.read().await;
504 if mempool.transactions.len() >= tx_count as usize {
505 break;
506 }
507 }
508 self.run_event_loop_once().await;
509
510 if time_keeper.get_timestamp_in_ms() > timeout {
511 panic!("request timed out");
512 }
513 }
514
515 Ok(())
516 }
517 pub async fn wait_till_wallet_balance(&mut self, balance: Currency) -> Result<(), Error> {
518 let timeout = self.timer.get_timestamp_in_ms() + self.timeout_in_ms;
519 let time_keeper = TestTimeKeeper {};
520 loop {
521 {
522 let wallet = self.routing_thread.wallet_lock.read().await;
523 if wallet.get_available_balance() >= balance {
524 break;
525 }
526 }
527 self.run_event_loop_once().await;
528
529 if time_keeper.get_timestamp_in_ms() > timeout {
530 panic!("request timed out");
531 }
532 }
533
534 Ok(())
535 }
536 pub async fn get_public_key(&self) -> SaitoPublicKey {
537 self.routing_thread.wallet_lock.read().await.public_key
538 }
539 pub async fn get_private_key(&self) -> SaitoPrivateKey {
540 self.routing_thread.wallet_lock.read().await.private_key
541 }
542 pub async fn get_fork_id(&self, block_id: BlockId) -> ForkId {
543 self.routing_thread
544 .blockchain_lock
545 .read()
546 .await
547 .generate_fork_id(block_id)
548 .unwrap()
549 }
550 pub async fn add_transaction(&mut self, transaction: Transaction) {
551 self.consensus_thread
552 .process_event(ConsensusEvent::NewTransaction { transaction })
553 .await
554 .unwrap()
555 }
556 pub async fn add_block(&mut self, block: Block) {
557 self.routing_thread
558 .process_network_event(NetworkEvent::BlockFetched {
559 block_hash: block.hash,
560 block_id: block.id,
561 peer_index: block.routed_from_peer.unwrap_or(0),
562 buffer: block.serialize_for_net(BlockType::Full),
563 })
564 .await;
565 }
566 pub async fn set_staking_enabled(&mut self, enable: bool) {
567 self.routing_thread
568 .blockchain_lock
569 .write()
570 .await
571 .social_stake_requirement = if enable { 60 } else { 0 };
572 }
573 pub async fn set_staking_requirement(&self, amount: Currency, period: u64) {
574 let mut blockchain = self.routing_thread.blockchain_lock.write().await;
575 blockchain.social_stake_requirement = amount;
576 blockchain.social_stake_period = period;
577 }
578
579 pub async fn delete_blocks() -> Result<(), Error> {
580 tokio::fs::create_dir_all("./data/blocks").await?;
581 tokio::fs::remove_dir_all("./data/blocks/").await?;
582 Ok(())
583 }
584 pub async fn delete_checkpoints() -> Result<(), Error> {
585 tokio::fs::create_dir_all("./data/checkpoints").await?;
586 tokio::fs::remove_dir_all("./data/checkpoints/").await?;
587 Ok(())
588 }
589 pub async fn delete_data() -> Result<(), Error> {
590 tokio::fs::create_dir_all("./data").await?;
591 tokio::fs::remove_dir_all("./data/").await?;
592 Ok(())
593 }
594 pub async fn create_block(
595 &self,
596 parent_hash: SaitoHash,
597 tx_count: u32,
598 fee_amount: Currency,
599 with_gt: bool,
600 ) -> Result<Block, Error> {
601 todo!()
602 }
603 pub async fn create_transaction(
604 &self,
605 with_payment: Currency,
606 with_fee: Currency,
607 to_key: SaitoPublicKey,
608 ) -> Result<Transaction, Error> {
609 let configs = self.consensus_thread.config_lock.read().await;
610 let blockchain = self.consensus_thread.blockchain_lock.read().await;
611 let mut wallet = self.routing_thread.wallet_lock.write().await;
612
613 let latest_block_id = blockchain.get_latest_block_id();
614 let genesis_period = configs.get_consensus_config().unwrap().genesis_period;
615
616 let mut tx = Transaction::create(
617 wallet.deref_mut(),
618 to_key,
619 with_payment,
620 with_fee,
621 false,
622 None,
623 latest_block_id,
624 genesis_period,
625 )?;
626 tx.generate(&wallet.public_key, 0, 0);
627 tx.sign(&wallet.private_key);
628 Ok(tx)
629 }
630 pub async fn set_issuance(
631 &mut self,
632 entries: Vec<(String, Currency)>,
633 ) -> Result<(), Error> {
634 let mut content = String::new();
635
636 for (key, amount) in entries {
637 self.initial_token_supply += amount;
638 content += (amount.to_string() + "\t" + key.as_str() + "\t" + "Normal\n").as_str();
639 }
640
641 tokio::fs::create_dir_all("./data/issuance/").await?;
642 tokio::fs::write("./data/issuance/issuance", content.as_bytes()).await
643 }
644 pub async fn check_total_supply(&self) -> Result<(), Error> {
645 let mut current_supply = 0;
646 let blockchain = self.consensus_thread.blockchain_lock.read().await;
647 let amount_in_utxo = blockchain
648 .utxoset
649 .iter()
650 .filter(|(_, value)| **value)
651 .map(|(key, value)| {
652 let slip = Slip::parse_slip_from_utxokey(key).unwrap();
653 info!(
654 "Utxo : {:?} : {} : {:?}, block : {}-{}-{}, valid : {}",
655 slip.public_key.to_base58(),
656 slip.amount,
657 slip.slip_type,
658 slip.block_id,
659 slip.tx_ordinal,
660 slip.slip_index,
661 value
662 );
663 slip.amount
664 })
665 .sum::<Currency>();
666
667 current_supply += amount_in_utxo;
668
669 let latest_block = blockchain
670 .get_latest_block()
671 .expect("There should be a latest block in blockchain");
672 current_supply += latest_block.graveyard;
673 current_supply += latest_block.treasury;
674 current_supply += latest_block.previous_block_unpaid;
675 current_supply += latest_block.total_fees;
676
677 warn!(
678 "diff : {}",
679 self.initial_token_supply as i64 - current_supply as i64
680 );
681 warn!("Current supply is {}", current_supply);
682 warn!("Initial token supply is {}", self.initial_token_supply);
683 warn!(
684 "Social Stake Requirement is {}",
685 blockchain.social_stake_requirement
686 );
687 warn!("Graveyard is {}", latest_block.graveyard);
688 warn!("Treasury is {}", latest_block.treasury);
689 warn!("Unpaid fees is {}", latest_block.previous_block_unpaid);
690 warn!("Total Fees ATR is {}", latest_block.total_fees_atr);
691 warn!("Total Fees New is {}", latest_block.total_fees_new);
692 warn!("Total Fee is {}", latest_block.total_fees);
693 warn!("Amount in utxo {}", amount_in_utxo);
694
695 if current_supply != self.initial_token_supply {
696 warn!(
697 "current supply : {:?} doesn't equal to initial supply : {:?}",
698 current_supply, self.initial_token_supply
699 );
700 let block = blockchain.get_latest_block().unwrap();
701 info!("block : {}", block);
702 return Err(Error::from(ErrorKind::InvalidData));
703 }
704 if latest_block.total_fees != latest_block.total_fees_new + latest_block.total_fees_atr
705 {
706 warn!(
707 "total fees : {:?} doesn't equal to new fees : {:?} + atr fees {:?}",
708 latest_block.total_fees,
709 latest_block.total_fees_new,
710 latest_block.total_fees_atr
711 );
712 return Err(Error::from(ErrorKind::InvalidData));
713 }
714
715 Ok(())
716 }
717 }
718}