saito_core/core/util/test/
node_tester.rs

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                    // sender_global: (),
262                    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}