main.rs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2023 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use std::{fs::File, io::Write};
  19. use clap::Parser;
  20. use darkfi::{
  21. blockchain::{
  22. block_store::{BlockOrderStore, BlockStore, HeaderStore},
  23. slot_checkpoint_store::SlotCheckpointStore,
  24. tx_store::{ErroneousTxStore, TxStore},
  25. Blockchain,
  26. },
  27. cli_desc,
  28. consensus::{
  29. block::{Block, Header},
  30. constants::{TESTNET_GENESIS_HASH_BYTES, TESTNET_GENESIS_TIMESTAMP},
  31. lead_info::LeadInfo,
  32. },
  33. tx::Transaction,
  34. util::{path::expand_path, time::Timestamp},
  35. Result,
  36. };
  37. use darkfi_sdk::crypto::MerkleNode;
  38. #[derive(Parser)]
  39. #[command(about = cli_desc!())]
  40. struct Args {
  41. #[arg(short, long, default_value = "../../../contrib/localnet/darkfid-single-node/")]
  42. /// Path containing the node folders
  43. path: String,
  44. #[arg(short, long, default_values = ["darkfid0", "faucetd"])]
  45. /// Node folder name (supports multiple values)
  46. node: Vec<String>,
  47. #[arg(short, long, default_value = "/blockchain/testnet")]
  48. /// Node blockchain folder
  49. blockchain: String,
  50. }
  51. #[derive(Debug)]
  52. struct LeadInfoInfo {
  53. _signature: String,
  54. _public_key: String,
  55. _public_inputs: Vec<String>,
  56. _coin_slot: u64,
  57. _coin_eta: String,
  58. _proof: String,
  59. _leaders: u64,
  60. }
  61. impl LeadInfoInfo {
  62. pub fn new(lead_info: &LeadInfo) -> LeadInfoInfo {
  63. let _signature = format!("{:?}", lead_info.signature);
  64. let _public_key = lead_info.public_key.to_string();
  65. let mut _public_inputs = vec![];
  66. for public_input in &lead_info.public_inputs {
  67. _public_inputs.push(format!("{:?}", public_input));
  68. }
  69. let _coin_slot = lead_info.coin_slot;
  70. let _coin_eta = format!("{:?}", lead_info.coin_eta);
  71. let _proof = format!("{:?}", lead_info.proof);
  72. let _leaders = lead_info.leaders;
  73. LeadInfoInfo {
  74. _signature,
  75. _public_key,
  76. _public_inputs,
  77. _coin_slot,
  78. _coin_eta,
  79. _proof,
  80. _leaders,
  81. }
  82. }
  83. }
  84. #[derive(Debug)]
  85. struct HeaderInfo {
  86. _hash: blake3::Hash,
  87. _version: u8,
  88. _previous: blake3::Hash,
  89. _epoch: u64,
  90. _slot: u64,
  91. _timestamp: Timestamp,
  92. _root: MerkleNode,
  93. }
  94. impl HeaderInfo {
  95. pub fn new(_hash: blake3::Hash, header: &Header) -> HeaderInfo {
  96. let _version = header.version;
  97. let _previous = header.previous;
  98. let _epoch = header.epoch;
  99. let _slot = header.slot;
  100. let _timestamp = header.timestamp;
  101. let _root = header.root;
  102. HeaderInfo { _hash, _version, _previous, _epoch, _slot, _timestamp, _root }
  103. }
  104. }
  105. #[derive(Debug)]
  106. struct HeaderStoreInfo {
  107. _headers: Vec<HeaderInfo>,
  108. }
  109. impl HeaderStoreInfo {
  110. pub fn new(headerstore: &HeaderStore) -> HeaderStoreInfo {
  111. let mut _headers = Vec::new();
  112. let result = headerstore.get_all();
  113. match result {
  114. Ok(iter) => {
  115. for (hash, header) in iter.iter() {
  116. _headers.push(HeaderInfo::new(hash.clone(), &header));
  117. }
  118. }
  119. Err(e) => println!("Error: {:?}", e),
  120. }
  121. HeaderStoreInfo { _headers }
  122. }
  123. }
  124. #[derive(Debug)]
  125. struct BlockInfo {
  126. _hash: blake3::Hash,
  127. _magic: [u8; 4],
  128. _header: blake3::Hash,
  129. _txs: Vec<blake3::Hash>,
  130. _lead_info: LeadInfoInfo,
  131. }
  132. impl BlockInfo {
  133. pub fn new(_hash: blake3::Hash, block: &Block) -> BlockInfo {
  134. let _magic = block.magic;
  135. let _header = block.header;
  136. let _txs = block.txs.clone();
  137. let _lead_info = LeadInfoInfo::new(&block.lead_info);
  138. BlockInfo { _hash, _magic, _header, _txs, _lead_info }
  139. }
  140. }
  141. #[derive(Debug)]
  142. struct BlockInfoChain {
  143. _blocks: Vec<BlockInfo>,
  144. }
  145. impl BlockInfoChain {
  146. pub fn new(blockstore: &BlockStore) -> BlockInfoChain {
  147. let mut _blocks = Vec::new();
  148. let result = blockstore.get_all();
  149. match result {
  150. Ok(iter) => {
  151. for (hash, block) in iter.iter() {
  152. _blocks.push(BlockInfo::new(hash.clone(), &block));
  153. }
  154. }
  155. Err(e) => println!("Error: {:?}", e),
  156. }
  157. BlockInfoChain { _blocks }
  158. }
  159. }
  160. #[derive(Debug)]
  161. struct OrderInfo {
  162. _slot: u64,
  163. _hash: blake3::Hash,
  164. }
  165. impl OrderInfo {
  166. pub fn new(_slot: u64, _hash: blake3::Hash) -> OrderInfo {
  167. OrderInfo { _slot, _hash }
  168. }
  169. }
  170. #[derive(Debug)]
  171. struct BlockOrderStoreInfo {
  172. _order: Vec<OrderInfo>,
  173. }
  174. impl BlockOrderStoreInfo {
  175. pub fn new(orderstore: &BlockOrderStore) -> BlockOrderStoreInfo {
  176. let mut _order = Vec::new();
  177. let result = orderstore.get_all();
  178. match result {
  179. Ok(iter) => {
  180. for (slot, hash) in iter.iter() {
  181. _order.push(OrderInfo::new(slot.clone(), hash.clone()));
  182. }
  183. }
  184. Err(e) => println!("Error: {:?}", e),
  185. }
  186. BlockOrderStoreInfo { _order }
  187. }
  188. }
  189. #[derive(Debug)]
  190. struct SlotCheckpointInfo {
  191. _slot: u64,
  192. _eta: String,
  193. _sigma1: String,
  194. _sigma2: String,
  195. }
  196. impl SlotCheckpointInfo {
  197. pub fn new(_slot: u64, _eta: String, _sigma1: String, _sigma2: String) -> SlotCheckpointInfo {
  198. SlotCheckpointInfo { _slot, _eta, _sigma1, _sigma2 }
  199. }
  200. }
  201. #[derive(Debug)]
  202. struct SlotCheckpointStoreInfo {
  203. _slot_checkpoints: Vec<SlotCheckpointInfo>,
  204. }
  205. impl SlotCheckpointStoreInfo {
  206. pub fn new(slotcheckpointstore: &SlotCheckpointStore) -> SlotCheckpointStoreInfo {
  207. let mut _slot_checkpoints = Vec::new();
  208. let result = slotcheckpointstore.get_all();
  209. match result {
  210. Ok(iter) => {
  211. for slot_checkpoint in iter.iter() {
  212. _slot_checkpoints.push(SlotCheckpointInfo::new(
  213. slot_checkpoint.slot,
  214. format!("{:?}", slot_checkpoint.eta),
  215. format!("{:?}", slot_checkpoint.sigma1),
  216. format!("{:?}", slot_checkpoint.sigma2),
  217. ));
  218. }
  219. }
  220. Err(e) => println!("Error: {:?}", e),
  221. }
  222. SlotCheckpointStoreInfo { _slot_checkpoints }
  223. }
  224. }
  225. #[derive(Debug)]
  226. struct TxInfo {
  227. _hash: blake3::Hash,
  228. _payload: Transaction,
  229. }
  230. impl TxInfo {
  231. pub fn new(_hash: blake3::Hash, tx: &Transaction) -> TxInfo {
  232. let _payload = tx.clone();
  233. TxInfo { _hash, _payload }
  234. }
  235. }
  236. #[derive(Debug)]
  237. struct TxStoreInfo {
  238. _transactions: Vec<TxInfo>,
  239. }
  240. impl TxStoreInfo {
  241. pub fn new(txstore: &TxStore) -> TxStoreInfo {
  242. let mut _transactions = Vec::new();
  243. let result = txstore.get_all();
  244. match result {
  245. Ok(iter) => {
  246. for (hash, tx) in iter.iter() {
  247. _transactions.push(TxInfo::new(hash.clone(), &tx));
  248. }
  249. }
  250. Err(e) => println!("Error: {:?}", e),
  251. }
  252. TxStoreInfo { _transactions }
  253. }
  254. }
  255. #[derive(Debug)]
  256. struct ErroneousTxStoreInfo {
  257. _transactions: Vec<blake3::Hash>,
  258. }
  259. impl ErroneousTxStoreInfo {
  260. pub fn new(erroneoustxstore: &ErroneousTxStore) -> ErroneousTxStoreInfo {
  261. let mut _transactions = Vec::new();
  262. let result = erroneoustxstore.get_all();
  263. match result {
  264. Ok(iter) => {
  265. for hash in iter.iter() {
  266. _transactions.push(hash.clone());
  267. }
  268. }
  269. Err(e) => println!("Error: {:?}", e),
  270. }
  271. ErroneousTxStoreInfo { _transactions }
  272. }
  273. }
  274. #[derive(Debug)]
  275. struct BlockchainInfo {
  276. _headers: HeaderStoreInfo,
  277. _blocks: BlockInfoChain,
  278. _order: BlockOrderStoreInfo,
  279. _slot_checkpoints: SlotCheckpointStoreInfo,
  280. _transactions: TxStoreInfo,
  281. _erroneous_txs: ErroneousTxStoreInfo,
  282. }
  283. impl BlockchainInfo {
  284. pub fn new(blockchain: &Blockchain) -> BlockchainInfo {
  285. let _headers = HeaderStoreInfo::new(&blockchain.headers);
  286. let _blocks = BlockInfoChain::new(&blockchain.blocks);
  287. let _order = BlockOrderStoreInfo::new(&blockchain.order);
  288. let _slot_checkpoints = SlotCheckpointStoreInfo::new(&blockchain.slot_checkpoints);
  289. let _transactions = TxStoreInfo::new(&blockchain.transactions);
  290. let _erroneous_txs = ErroneousTxStoreInfo::new(&blockchain.erroneous_txs);
  291. BlockchainInfo {
  292. _headers,
  293. _blocks,
  294. _order,
  295. _slot_checkpoints,
  296. _transactions,
  297. _erroneous_txs,
  298. }
  299. }
  300. }
  301. fn generate(folder: &str, node: &str, blockchain: &str) -> Result<()> {
  302. println!("Exporting data for {node}...");
  303. // Node folder
  304. let folder = folder.to_owned() + node;
  305. // Initialize or load sled database
  306. let path = folder.to_owned() + blockchain;
  307. let db_path = expand_path(&path).unwrap();
  308. let sled_db = sled::open(&db_path)?;
  309. // Data export
  310. let blockchain =
  311. Blockchain::new(&sled_db, *TESTNET_GENESIS_TIMESTAMP, *TESTNET_GENESIS_HASH_BYTES)?;
  312. let info = BlockchainInfo::new(&blockchain);
  313. let info_string = format!("{:#?}", info);
  314. let file_name = node.to_owned() + "_db";
  315. let mut file = File::create(file_name.clone())?;
  316. file.write(info_string.as_bytes())?;
  317. drop(sled_db);
  318. println!("Data exported to file: {file_name}");
  319. Ok(())
  320. }
  321. fn main() -> Result<()> {
  322. // Parse arguments
  323. let args = Args::parse();
  324. println!("Node folder path: {}", args.path);
  325. // Export data for each node
  326. for node in args.node {
  327. generate(&args.path, &node, &args.blockchain)?;
  328. }
  329. Ok(())
  330. }