/* This file is part of DarkFi (https://dark.fi) * * Copyright (C) 2020-2023 Dyne.org foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ use std::{fs::File, io::Write}; use darkfi::{ blockchain::{ blockstore::{BlockOrderStore, BlockStore, HeaderStore}, slotcheckpointstore::SlotCheckpointStore, txstore::TxStore, Blockchain, }, consensus::{ block::{Block, Header}, constants::TESTNET_GENESIS_HASH_BYTES, lead_info::LeadInfo, validator::ValidatorState, }, tx::Transaction, util::{path::expand_path, time::Timestamp}, wallet::walletdb::init_wallet, Result, }; use darkfi_sdk::crypto::MerkleNode; #[derive(Debug)] struct LeadInfoInfo { _signature: String, _public_key: String, _public_inputs: Vec, _coin_slot: u64, _coin_eta: String, _proof: String, _offset: u64, _leaders: u64, } impl LeadInfoInfo { pub fn new(lead_info: &LeadInfo) -> LeadInfoInfo { let _signature = format!("{:?}", lead_info.signature); let _public_key = lead_info.public_key.to_string(); let mut _public_inputs = vec![]; for public_input in &lead_info.public_inputs { _public_inputs.push(format!("{:?}", public_input)); } let _coin_slot = lead_info.coin_slot; let _coin_eta = format!("{:?}", lead_info.coin_eta); let _proof = format!("{:?}", lead_info.proof); let _offset = lead_info.offset; let _leaders = lead_info.leaders; LeadInfoInfo { _signature, _public_key, _public_inputs, _coin_slot, _coin_eta, _proof, _offset, _leaders, } } } #[derive(Debug)] struct HeaderInfo { _hash: blake3::Hash, _version: u8, _previous: blake3::Hash, _epoch: u64, _slot: u64, _timestamp: Timestamp, _root: MerkleNode, } impl HeaderInfo { pub fn new(_hash: blake3::Hash, header: &Header) -> HeaderInfo { let _version = header.version; let _previous = header.previous; let _epoch = header.epoch; let _slot = header.slot; let _timestamp = header.timestamp; let _root = header.root; HeaderInfo { _hash, _version, _previous, _epoch, _slot, _timestamp, _root } } } #[derive(Debug)] struct HeaderStoreInfo { _headers: Vec, } impl HeaderStoreInfo { pub fn new(headerstore: &HeaderStore) -> HeaderStoreInfo { let mut _headers = Vec::new(); let result = headerstore.get_all(); match result { Ok(iter) => { for (hash, header) in iter.iter() { _headers.push(HeaderInfo::new(hash.clone(), &header)); } } Err(e) => println!("Error: {:?}", e), } HeaderStoreInfo { _headers } } } #[derive(Debug)] struct BlockInfo { _hash: blake3::Hash, _magic: [u8; 4], _header: blake3::Hash, _txs: Vec, _lead_info: LeadInfoInfo, } impl BlockInfo { pub fn new(_hash: blake3::Hash, block: &Block) -> BlockInfo { let _magic = block.magic; let _header = block.header; let _txs = block.txs.clone(); let _lead_info = LeadInfoInfo::new(&block.lead_info); BlockInfo { _hash, _magic, _header, _txs, _lead_info } } } #[derive(Debug)] struct BlockInfoChain { _blocks: Vec, } impl BlockInfoChain { pub fn new(blockstore: &BlockStore) -> BlockInfoChain { let mut _blocks = Vec::new(); let result = blockstore.get_all(); match result { Ok(iter) => { for (hash, block) in iter.iter() { _blocks.push(BlockInfo::new(hash.clone(), &block)); } } Err(e) => println!("Error: {:?}", e), } BlockInfoChain { _blocks } } } #[derive(Debug)] struct OrderInfo { _slot: u64, _hash: blake3::Hash, } impl OrderInfo { pub fn new(_slot: u64, _hash: blake3::Hash) -> OrderInfo { OrderInfo { _slot, _hash } } } #[derive(Debug)] struct BlockOrderStoreInfo { _order: Vec, } impl BlockOrderStoreInfo { pub fn new(orderstore: &BlockOrderStore) -> BlockOrderStoreInfo { let mut _order = Vec::new(); let result = orderstore.get_all(); match result { Ok(iter) => { for (slot, hash) in iter.iter() { _order.push(OrderInfo::new(slot.clone(), hash.clone())); } } Err(e) => println!("Error: {:?}", e), } BlockOrderStoreInfo { _order } } } #[derive(Debug)] struct SlotCheckpointInfo { _slot: u64, _eta: String, _sigma1: String, _sigma2: String, } impl SlotCheckpointInfo { pub fn new(_slot: u64, _eta: String, _sigma1: String, _sigma2: String) -> SlotCheckpointInfo { SlotCheckpointInfo { _slot, _eta, _sigma1, _sigma2 } } } #[derive(Debug)] struct SlotCheckpointStoreInfo { _slot_checkpoints: Vec, } impl SlotCheckpointStoreInfo { pub fn new(slotcheckpointstore: &SlotCheckpointStore) -> SlotCheckpointStoreInfo { let mut _slot_checkpoints = Vec::new(); let result = slotcheckpointstore.get_all(); match result { Ok(iter) => { for slot_checkpoint in iter.iter() { _slot_checkpoints.push(SlotCheckpointInfo::new( slot_checkpoint.slot, format!("{:?}", slot_checkpoint.eta), format!("{:?}", slot_checkpoint.sigma1), format!("{:?}", slot_checkpoint.sigma2), )); } } Err(e) => println!("Error: {:?}", e), } SlotCheckpointStoreInfo { _slot_checkpoints } } } #[derive(Debug)] struct TxInfo { _hash: blake3::Hash, _payload: Transaction, } impl TxInfo { pub fn new(_hash: blake3::Hash, tx: &Transaction) -> TxInfo { let _payload = tx.clone(); TxInfo { _hash, _payload } } } #[derive(Debug)] struct TxStoreInfo { _transactions: Vec, } impl TxStoreInfo { pub fn new(txstore: &TxStore) -> TxStoreInfo { let mut _transactions = Vec::new(); let result = txstore.get_all(); match result { Ok(iter) => { for (hash, tx) in iter.iter() { _transactions.push(TxInfo::new(hash.clone(), &tx)); } } Err(e) => println!("Error: {:?}", e), } TxStoreInfo { _transactions } } } #[derive(Debug)] struct BlockchainInfo { _headers: HeaderStoreInfo, _blocks: BlockInfoChain, _order: BlockOrderStoreInfo, _slot_checkpoints: SlotCheckpointStoreInfo, _transactions: TxStoreInfo, } impl BlockchainInfo { pub fn new(blockchain: &Blockchain) -> BlockchainInfo { let _headers = HeaderStoreInfo::new(&blockchain.headers); let _blocks = BlockInfoChain::new(&blockchain.blocks); let _order = BlockOrderStoreInfo::new(&blockchain.order); let _slot_checkpoints = SlotCheckpointStoreInfo::new(&blockchain.slot_checkpoints); let _transactions = TxStoreInfo::new(&blockchain.transactions); BlockchainInfo { _headers, _blocks, _order, _slot_checkpoints, _transactions } } } #[derive(Debug)] struct StateInfo { _blockchain: BlockchainInfo, } impl StateInfo { pub fn new(state: &ValidatorState) -> StateInfo { let _blockchain = BlockchainInfo::new(&state.blockchain); StateInfo { _blockchain } } } async fn generate(name: &str, folder: &str) -> Result<()> { let genesis_ts = Timestamp(1648383795); let genesis_data = *TESTNET_GENESIS_HASH_BYTES; let pass = "changeme"; // Initialize or load wallet let path = folder.to_owned() + "/wallet.db"; let wallet = init_wallet(&path, &pass).await?; // Initialize or load sled database let path = folder.to_owned() + "/blockchain/testnet"; let db_path = expand_path(&path).unwrap(); let sled_db = sled::open(&db_path)?; // Data export let state = ValidatorState::new(&sled_db, genesis_ts, genesis_data, wallet, vec![], false).await?; println!("Exporting data for {:?}", name); let info = StateInfo::new(&*state.read().await); let info_string = format!("{:#?}", info); let path = name.to_owned() + "_testnet_db"; let mut file = File::create(path)?; file.write(info_string.as_bytes())?; drop(sled_db); Ok(()) } #[async_std::main] async fn main() -> Result<()> { // darkfid0 generate("darkfid0", "../../../contrib/localnet/darkfid/darkfid0").await?; // darkfid1 generate("darkfid1", "../../../contrib/localnet/darkfid/darkfid1").await?; // darkfid2 generate("darkfid2", "../../../contrib/localnet/darkfid/darkfid2").await?; // faucetd generate("faucetd", "../../../contrib/localnet/darkfid/faucetd").await?; Ok(()) }