library_blockchain/
lib.rs

1// #![recursion_limit="5000000"]
2
3#![no_main] 
4pub mod block;
5pub mod blockchain_executive;
6pub use crate::block::Block;
7pub mod hashable;
8pub use crate::{blockchain::Blockchain, hashable::Hashable};
9pub mod blockchain;
10pub mod transaction;
11pub mod factory;
12type Hash = Vec<u8>;
13type Address = String;
14
15use std::fmt::{self, Formatter};
16use std::os::unix::prelude::MetadataExt;
17// Credit: https://stackoverflow.com/a/44378174/2773837
18use std::time::{SystemTime, UNIX_EPOCH};
19
20
21
22
23pub fn lib_block_now() -> u128 {
24    let duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
25
26    duration.as_secs() as u128 * 1000 + duration.subsec_millis() as u128
27}
28
29pub fn lib_block_u32_bytes(u: &u32) -> [u8; 4] {
30    [
31        (u >> 8 * 0x0) as u8,
32        (u >> 8 * 0x1) as u8,
33        (u >> 8 * 0x2) as u8,
34        (u >> 8 * 0x3) as u8,
35    ]
36}
37
38pub fn lib_block_u64_bytes(u: &u64) -> [u8; 8] {
39    [
40        (u >> 8 * 0x0) as u8,
41        (u >> 8 * 0x1) as u8,
42        (u >> 8 * 0x2) as u8,
43        (u >> 8 * 0x3) as u8,
44        (u >> 8 * 0x4) as u8,
45        (u >> 8 * 0x5) as u8,
46        (u >> 8 * 0x6) as u8,
47        (u >> 8 * 0x7) as u8,
48    ]
49}
50
51pub fn lib_block_u128_bytes(u: &u128) -> [u8; 16] {
52    [
53        (u >> 8 * 0x0) as u8,
54        (u >> 8 * 0x1) as u8,
55        (u >> 8 * 0x2) as u8,
56        (u >> 8 * 0x3) as u8,
57        (u >> 8 * 0x4) as u8,
58        (u >> 8 * 0x5) as u8,
59        (u >> 8 * 0x6) as u8,
60        (u >> 8 * 0x7) as u8,
61        (u >> 8 * 0x8) as u8,
62        (u >> 8 * 0x9) as u8,
63        (u >> 8 * 0xa) as u8,
64        (u >> 8 * 0xb) as u8,
65        (u >> 8 * 0xc) as u8,
66        (u >> 8 * 0xd) as u8,
67        (u >> 8 * 0xe) as u8,
68        (u >> 8 * 0xf) as u8,
69    ]
70}
71
72pub fn lib_block_difficulty_bytes_as_u128(v: &Vec<u8>) -> u128 {
73    ((v[31] as u128) << 0xf * 8)
74        | ((v[30] as u128) << 0xe * 8)
75        | ((v[29] as u128) << 0xd * 8)
76        | ((v[28] as u128) << 0xc * 8)
77        | ((v[27] as u128) << 0xb * 8)
78        | ((v[26] as u128) << 0xa * 8)
79        | ((v[25] as u128) << 0x9 * 8)
80        | ((v[24] as u128) << 0x8 * 8)
81        | ((v[23] as u128) << 0x7 * 8)
82        | ((v[22] as u128) << 0x6 * 8)
83        | ((v[21] as u128) << 0x5 * 8)
84        | ((v[20] as u128) << 0x4 * 8)
85        | ((v[19] as u128) << 0x3 * 8)
86        | ((v[18] as u128) << 0x2 * 8)
87        | ((v[17] as u128) << 0x1 * 8)
88        | ((v[16] as u128) << 0x0 * 8)
89}
90
91/// In the stable version rust that we used is concat macro.
92/// </br>
93/// 🔬 For a nightly-only experimental API. (slice_concat_trait #27747)
94/// https://doc.rust-lang.org/std/slice/trait.Concat.html#
95/// Another Solution </br>
96/// #[macro_use(concat_string)]</br>
97/// ```
98/// extern crate concat_string;
99/// pub fn blockchain_concat_two_str(str:String,num:String)-> String {    
100///     let output=concat_string!(str,num);    
101///     output
102/// }
103/// ```
104pub fn lib_block_concat_two_string(str1:String,str2:String) -> String{
105    let str =&mut str1.to_string().to_owned();
106    str.push_str(&str2);
107    let output:String =str.chars().filter(|c| !c.is_whitespace()).collect();
108    output
109}
110
111#[derive(Debug)]
112pub enum StringError {
113    StringParse(std::string::ParseError),
114    InvalidOption(String),
115    Other,
116}
117#[derive(Debug)]
118pub enum BlockainFactoryError {
119    ZeroBlock,
120    ZeroBlockchain,
121    IsNullTransaction,
122    Other,
123}
124#[derive(Debug)]
125pub enum BlockValidationError {
126    MismatchedIndex,
127    InvalidHash,
128    AchronologicalTimestamp,
129    MismatchedPreviousHash,
130    InvalidGenesisBlockFormat,
131    InvalidInput,
132    InsufficientInputValue,
133    InvalidCoinbaseTransaction,
134    InvalidCoinbaseTransactionFee,
135    NonceAttemptFailed
136}
137/// Allow the use of "{:?}" format specifier
138#[derive(Debug)]
139pub enum CustomError {
140    String(StringError),
141    SerdeJson(serde_json::Error),
142    IO(std::io::Error),
143    BlockchainFactory(BlockainFactoryError),
144    BlockValidation(BlockValidationError),    
145    InvalidOption(String),
146    Other,
147}
148
149impl fmt::Display for crate::BlockainFactoryError {
150    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
151        match *self {
152                BlockainFactoryError::IsNullTransaction => write!(f, "BlockainFactory:IsNullTransaction Error"),
153                BlockainFactoryError::ZeroBlock => write!(f, "BlockainFactory:ZeroBlock Error"),
154                BlockainFactoryError::ZeroBlockchain => write!(f, "BlockainFactory:ZeroBlockchain Error"),
155                BlockainFactoryError::Other => write!(f, "BlockainFactory:Unknown Error"),                
156            }
157        }
158}
159
160impl fmt::Display for crate::BlockValidationError {
161    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
162        match *self {
163                BlockValidationError::AchronologicalTimestamp => write!(f, "BlockValidation:AchronologicalTimestamp Error"),
164                BlockValidationError::InsufficientInputValue => write!(f, "BlockValidation:InsufficientInputValue Error"),
165                BlockValidationError::InvalidCoinbaseTransaction => write!(f, "BlockValidation:InvalidCoinbaseTransaction Error"),
166                BlockValidationError::InvalidCoinbaseTransactionFee => write!(f, "BlockValidation:InvalidCoinbaseTransactionFee Error"),
167                BlockValidationError::InvalidGenesisBlockFormat => write!(f, "BlockValidation:InvalidGenesisBlockFormat Error"),
168                BlockValidationError::InvalidHash => write!(f, "BlockValidation:InvalidHash Error"),
169                BlockValidationError::InvalidInput=> write!(f, "BlockValidation:InvalidInput Error"),
170                BlockValidationError::MismatchedIndex=> write!(f, "BlockValidation:MismatchedIndex Error"),
171                BlockValidationError::MismatchedPreviousHash=> write!(f, "BlockValidation:MismatchedPreviousHash Error"),
172                BlockValidationError::NonceAttemptFailed=> write!(f, "BlockValidation:NonceAttemptFailed Error"),                
173            }
174        }
175}
176// Allow the use of "{}" format specifier
177impl fmt::Display for CustomError {
178    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
179        match *self {
180            CustomError::String(_) => write!(f, "\nString Error"),
181            CustomError::SerdeJson(ref cause) => write!(f, "\nSerdeJson Error: {}", cause),
182            CustomError::IO(ref cause) => write!(f, "\nIO Error: {}", cause),
183            CustomError::BlockchainFactory(ref cause) => write!(f, "\nBlockchainFactory Error: {}", cause),
184            CustomError::BlockValidation(ref cause) => write!(f, "\nBlockValidation Error: {}", cause),
185            CustomError::Other => write!(f, "\nUnknown error!"),
186            CustomError::InvalidOption(_) => write!(f, "\nInvalid Option!"),
187        }
188    }
189}
190
191// impl From<json::de::Error> for Error {
192//     fn from(err: toml::de::Error) -> Self {
193//         Error::Toml(err)
194//     }
195// }
196
197impl std::error::Error for CustomError {
198    fn cause(&self) -> Option<&dyn std::error::Error> {
199        match *self {
200            CustomError::String(_) => None,
201            CustomError::SerdeJson(ref cause) => Some(cause),
202            CustomError::IO(ref cause) => Some(cause),
203            CustomError::BlockchainFactory(_) => None,
204            CustomError::BlockValidation(_) => None,
205            CustomError::Other => None,
206            CustomError::InvalidOption(_) => None,
207        }
208    }
209}
210
211impl From<std::string::ParseError> for StringError {
212    fn from(cause: std::string::ParseError) -> StringError {
213        StringError::InvalidOption(cause.to_string())
214    }
215}
216
217impl From<serde_json::Error> for CustomError {
218    fn from(cause: serde_json::Error) -> CustomError {
219        CustomError::SerdeJson(cause)
220    }
221}
222impl From<std::io::Error> for CustomError {
223    fn from(cause: std::io::Error) -> CustomError {
224        CustomError::IO(cause)
225    }
226}
227impl From<BlockValidationError> for CustomError {
228    fn from(cause: BlockValidationError) -> CustomError {
229        CustomError::BlockValidation(cause)
230    }
231}
232impl From<BlockainFactoryError> for CustomError {
233    fn from(cause: BlockainFactoryError) -> CustomError {
234        CustomError::BlockchainFactory(cause)
235    }
236}