Skip to main content

snap_coin/core/
blockchain_ext.rs

1use crate::{
2    blockchain_data_provider::BlockchainDataProvider,
3    core::{
4        block::Block, blockchain::{Blockchain, BlockchainError}, transaction::{TransactionId, TransactionOutput}
5    },
6    crypto::Hash,
7    economics::get_block_reward,
8};
9
10#[async_trait::async_trait]
11impl BlockchainDataProvider for Blockchain {
12    async fn get_height(
13        &self,
14    ) -> Result<usize, crate::blockchain_data_provider::BlockchainDataProviderError> {
15        Ok(self.block_store().get_height())
16    }
17
18    async fn get_reward(
19        &self,
20    ) -> Result<u64, crate::blockchain_data_provider::BlockchainDataProviderError> {
21        Ok(get_block_reward(self.block_store().get_height()))
22    }
23
24    async fn get_block_by_height(
25        &self,
26        height: usize,
27    ) -> Result<Option<Block>, crate::blockchain_data_provider::BlockchainDataProviderError> {
28        Ok(self.block_store().get_block_by_height(height))
29    }
30
31    async fn get_block_by_hash(
32        &self,
33        hash: Hash,
34    ) -> Result<Option<Block>, crate::blockchain_data_provider::BlockchainDataProviderError> {
35        Ok(self.block_store().get_block_by_hash(hash))
36    }
37
38    async fn get_height_by_hash(
39        &self,
40        hash: Hash,
41    ) -> Result<Option<usize>, crate::blockchain_data_provider::BlockchainDataProviderError> {
42        Ok(self.block_store().get_block_height_by_hash(hash))
43    }
44
45    async fn get_block_hash_by_height(
46        &self,
47        height: usize,
48    ) -> Result<Option<Hash>, crate::blockchain_data_provider::BlockchainDataProviderError> {
49        Ok(self.block_store().get_block_hash_by_height(height))
50    }
51
52    async fn get_transaction_difficulty(
53        &self,
54    ) -> Result<[u8; 32], crate::blockchain_data_provider::BlockchainDataProviderError> {
55        Ok(self.get_transaction_difficulty())
56    }
57
58    async fn get_block_difficulty(
59        &self,
60    ) -> Result<[u8; 32], crate::blockchain_data_provider::BlockchainDataProviderError> {
61        Ok(self.get_block_difficulty())
62    }
63
64    async fn get_available_transaction_outputs(
65        &self,
66        address: crate::crypto::keys::Public,
67    ) -> Result<
68        Vec<(TransactionId, TransactionOutput, usize)>,
69        crate::blockchain_data_provider::BlockchainDataProviderError,
70    > {
71        let mut available_outputs = vec![];
72
73        for item in self.get_utxos().db.iter() {
74            let (txid_bytes, value) = item.map_err(|e| BlockchainError::UTXOs(e.to_string()))?;
75            let txid_str = String::from_utf8(txid_bytes.to_vec())
76                .map_err(|e| BlockchainError::UTXOs(e.to_string()))?;
77            let txid = TransactionId::new_from_base36(&txid_str)
78                .ok_or(BlockchainError::UTXOs("Invalid TransactionId".to_string()))?;
79
80            // Decode the outputs
81            let outputs: Vec<Option<TransactionOutput>> =
82                bincode::decode_from_slice::<Vec<Option<TransactionOutput>>, _>(
83                    &value,
84                    bincode::config::standard(),
85                )
86                .map_err(|e| BlockchainError::UTXOs(e.to_string()))?
87                .0;
88
89            for (index, output_opt) in outputs.into_iter().enumerate() {
90                if let Some(output) = output_opt {
91                    if output.receiver == address {
92                        available_outputs.push((txid, output, index));
93                    }
94                }
95            }
96        }
97
98        Ok(available_outputs)
99    }
100}