mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 14:48:08 -05:00
script/research/blockchain-explorer: updated to latest darkfi structures
This commit is contained in:
@@ -12,9 +12,11 @@ edition = "2021"
|
||||
[dependencies]
|
||||
blake3 = "1.5.0"
|
||||
clap = {version = "4.5.2", features = ["derive"]}
|
||||
darkfi = {path = "../../../", features = ["blockchain", "wallet", "rpc"]}
|
||||
darkfi = {path = "../../../", features = ["blockchain"]}
|
||||
darkfi-sdk = {path = "../../../src/sdk"}
|
||||
num-bigint = "0.4.4"
|
||||
sled = "0.34.7"
|
||||
|
||||
[patch.crates-io]
|
||||
halo2_proofs = {git="https://github.com/parazyd/halo2", branch="v3"}
|
||||
halo2_proofs = {git="https://github.com/parazyd/halo2", branch="v4"}
|
||||
halo2_gadgets = {git="https://github.com/parazyd/halo2", branch="v4"}
|
||||
|
||||
@@ -21,19 +21,24 @@ use std::{fs::File, io::Write};
|
||||
use clap::Parser;
|
||||
use darkfi::{
|
||||
blockchain::{
|
||||
block_store::{Block, BlockOrderStore, BlockProducer, BlockStore},
|
||||
block_store::{
|
||||
Block, BlockDifficulty, BlockDifficultyStore, BlockOrderStore, BlockRanks, BlockStore,
|
||||
},
|
||||
contract_store::{ContractStateStore, WasmStore},
|
||||
header_store::{Header, HeaderStore},
|
||||
slot_store::SlotStore,
|
||||
tx_store::TxStore,
|
||||
tx_store::{PendingTxOrderStore, PendingTxStore, TxStore},
|
||||
Blockchain,
|
||||
},
|
||||
cli_desc,
|
||||
consensus::constants::EPOCH_LENGTH,
|
||||
tx::Transaction,
|
||||
util::{path::expand_path, time::Timestamp},
|
||||
Result,
|
||||
};
|
||||
use darkfi_sdk::crypto::MerkleNode;
|
||||
use darkfi_sdk::{
|
||||
blockchain::block_epoch,
|
||||
crypto::{ContractId, MerkleTree},
|
||||
};
|
||||
use num_bigint::BigUint;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(about = cli_desc!())]
|
||||
@@ -42,11 +47,11 @@ struct Args {
|
||||
/// Path containing the node folders
|
||||
path: String,
|
||||
|
||||
#[arg(short, long, default_values = ["darkfid0", "faucetd"])]
|
||||
#[arg(short, long, default_values = ["darkfid"])]
|
||||
/// Node folder name (supports multiple values)
|
||||
node: Vec<String>,
|
||||
|
||||
#[arg(short, long, default_value = "/blockchain/testnet")]
|
||||
#[arg(short, long, default_value = "")]
|
||||
/// Node blockchain folder
|
||||
blockchain: String,
|
||||
|
||||
@@ -55,40 +60,28 @@ struct Args {
|
||||
export: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct BlockProducerInfo {
|
||||
_signature: String,
|
||||
_proposal: Transaction,
|
||||
}
|
||||
|
||||
impl BlockProducerInfo {
|
||||
pub fn new(producer: &BlockProducer) -> BlockProducerInfo {
|
||||
let _signature = format!("{:?}", producer.signature);
|
||||
let _proposal = producer.proposal.clone();
|
||||
BlockProducerInfo { _signature, _proposal }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct HeaderInfo {
|
||||
_hash: blake3::Hash,
|
||||
_version: u8,
|
||||
_previous: blake3::Hash,
|
||||
_epoch: u64,
|
||||
_slot: u64,
|
||||
_height: u64,
|
||||
_timestamp: Timestamp,
|
||||
_root: MerkleNode,
|
||||
_nonce: u64,
|
||||
_tree: MerkleTree,
|
||||
}
|
||||
|
||||
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 }
|
||||
HeaderInfo {
|
||||
_hash,
|
||||
_version: header.version,
|
||||
_previous: header.previous,
|
||||
_height: header.height,
|
||||
_timestamp: header.timestamp,
|
||||
_nonce: header.nonce,
|
||||
_tree: header.tree.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +97,7 @@ impl HeaderStoreInfo {
|
||||
match result {
|
||||
Ok(iter) => {
|
||||
for (hash, header) in iter.iter() {
|
||||
_headers.push(HeaderInfo::new(hash.clone(), &header));
|
||||
_headers.push(HeaderInfo::new(*hash, header));
|
||||
}
|
||||
}
|
||||
Err(e) => println!("Error: {:?}", e),
|
||||
@@ -116,21 +109,19 @@ impl HeaderStoreInfo {
|
||||
#[derive(Debug)]
|
||||
struct BlockInfo {
|
||||
_hash: blake3::Hash,
|
||||
_magic: [u8; 4],
|
||||
_header: blake3::Hash,
|
||||
_txs: Vec<blake3::Hash>,
|
||||
_producer: BlockProducerInfo,
|
||||
_slots: Vec<u64>,
|
||||
_signature: String,
|
||||
}
|
||||
|
||||
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 _producer = BlockProducerInfo::new(&block.producer);
|
||||
let _slots = block.slots.clone();
|
||||
BlockInfo { _hash, _magic, _header, _txs, _producer, _slots }
|
||||
BlockInfo {
|
||||
_hash,
|
||||
_header: block.header,
|
||||
_txs: block.txs.clone(),
|
||||
_signature: format!("{:?}", block.signature),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +137,7 @@ impl BlockInfoChain {
|
||||
match result {
|
||||
Ok(iter) => {
|
||||
for (hash, block) in iter.iter() {
|
||||
_blocks.push(BlockInfo::new(hash.clone(), &block));
|
||||
_blocks.push(BlockInfo::new(*hash, block));
|
||||
}
|
||||
}
|
||||
Err(e) => println!("Error: {:?}", e),
|
||||
@@ -157,13 +148,13 @@ impl BlockInfoChain {
|
||||
|
||||
#[derive(Debug)]
|
||||
struct OrderInfo {
|
||||
_slot: u64,
|
||||
_height: u64,
|
||||
_hash: blake3::Hash,
|
||||
}
|
||||
|
||||
impl OrderInfo {
|
||||
pub fn new(_slot: u64, _hash: blake3::Hash) -> OrderInfo {
|
||||
OrderInfo { _slot, _hash }
|
||||
pub fn new(_height: u64, _hash: blake3::Hash) -> OrderInfo {
|
||||
OrderInfo { _height, _hash }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,8 +169,8 @@ impl BlockOrderStoreInfo {
|
||||
let result = orderstore.get_all();
|
||||
match result {
|
||||
Ok(iter) => {
|
||||
for (slot, hash) in iter.iter() {
|
||||
_order.push(OrderInfo::new(slot.clone(), hash.clone()));
|
||||
for (height, hash) in iter.iter() {
|
||||
_order.push(OrderInfo::new(*height, *hash));
|
||||
}
|
||||
}
|
||||
Err(e) => println!("Error: {:?}", e),
|
||||
@@ -189,42 +180,63 @@ impl BlockOrderStoreInfo {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct SlotInfo {
|
||||
_id: u64,
|
||||
_eta: String,
|
||||
_sigma1: String,
|
||||
_sigma2: String,
|
||||
struct BlockRanksInfo {
|
||||
_target_rank: BigUint,
|
||||
_targets_rank: BigUint,
|
||||
_hash_rank: BigUint,
|
||||
_hashes_rank: BigUint,
|
||||
}
|
||||
|
||||
impl SlotInfo {
|
||||
pub fn new(_id: u64, _eta: String, _sigma1: String, _sigma2: String) -> SlotInfo {
|
||||
SlotInfo { _id, _eta, _sigma1, _sigma2 }
|
||||
impl BlockRanksInfo {
|
||||
pub fn new(ranks: &BlockRanks) -> BlockRanksInfo {
|
||||
BlockRanksInfo {
|
||||
_target_rank: ranks.target_rank.clone(),
|
||||
_targets_rank: ranks.targets_rank.clone(),
|
||||
_hash_rank: ranks.hash_rank.clone(),
|
||||
_hashes_rank: ranks.hashes_rank.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct SlotStoreInfo {
|
||||
_slots: Vec<SlotInfo>,
|
||||
struct BlockDifficultyInfo {
|
||||
_height: u64,
|
||||
_timestamp: Timestamp,
|
||||
_difficulty: BigUint,
|
||||
_cummulative_difficulty: BigUint,
|
||||
_ranks: BlockRanksInfo,
|
||||
}
|
||||
|
||||
impl SlotStoreInfo {
|
||||
pub fn new(slot_store: &SlotStore) -> SlotStoreInfo {
|
||||
let mut _slots = Vec::new();
|
||||
let result = slot_store.get_all();
|
||||
impl BlockDifficultyInfo {
|
||||
pub fn new(difficulty: &BlockDifficulty) -> BlockDifficultyInfo {
|
||||
BlockDifficultyInfo {
|
||||
_height: difficulty.height,
|
||||
_timestamp: difficulty.timestamp,
|
||||
_difficulty: difficulty.difficulty.clone(),
|
||||
_cummulative_difficulty: difficulty.cummulative_difficulty.clone(),
|
||||
_ranks: BlockRanksInfo::new(&difficulty.ranks),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct BlockDifficultyStoreInfo {
|
||||
_difficulties: Vec<BlockDifficultyInfo>,
|
||||
}
|
||||
|
||||
impl BlockDifficultyStoreInfo {
|
||||
pub fn new(difficultiesstore: &BlockDifficultyStore) -> BlockDifficultyStoreInfo {
|
||||
let mut _difficulties = Vec::new();
|
||||
let result = difficultiesstore.get_all();
|
||||
match result {
|
||||
Ok(iter) => {
|
||||
for slot in iter.iter() {
|
||||
_slots.push(SlotInfo::new(
|
||||
slot.id,
|
||||
format!("{:?}", slot.previous_eta),
|
||||
format!("{:?}", slot.sigma1),
|
||||
format!("{:?}", slot.sigma2),
|
||||
));
|
||||
for (_, difficulty) in iter.iter() {
|
||||
_difficulties.push(BlockDifficultyInfo::new(difficulty));
|
||||
}
|
||||
}
|
||||
Err(e) => println!("Error: {:?}", e),
|
||||
}
|
||||
SlotStoreInfo { _slots }
|
||||
BlockDifficultyStoreInfo { _difficulties }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,8 +248,7 @@ struct TxInfo {
|
||||
|
||||
impl TxInfo {
|
||||
pub fn new(_hash: blake3::Hash, tx: &Transaction) -> TxInfo {
|
||||
let _payload = tx.clone();
|
||||
TxInfo { _hash, _payload }
|
||||
TxInfo { _hash, _payload: tx.clone() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,7 +264,7 @@ impl TxStoreInfo {
|
||||
match result {
|
||||
Ok(iter) => {
|
||||
for (hash, tx) in iter.iter() {
|
||||
_transactions.push(TxInfo::new(hash.clone(), &tx));
|
||||
_transactions.push(TxInfo::new(*hash, tx));
|
||||
}
|
||||
}
|
||||
Err(e) => println!("Error: {:?}", e),
|
||||
@@ -262,23 +273,141 @@ impl TxStoreInfo {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct PendingTxStoreInfo {
|
||||
_transactions: Vec<TxInfo>,
|
||||
}
|
||||
|
||||
impl PendingTxStoreInfo {
|
||||
pub fn new(pendingtxstore: &PendingTxStore) -> PendingTxStoreInfo {
|
||||
let mut _transactions = Vec::new();
|
||||
let result = pendingtxstore.get_all();
|
||||
match result {
|
||||
Ok(iter) => {
|
||||
for (hash, tx) in iter.iter() {
|
||||
_transactions.push(TxInfo::new(*hash, tx));
|
||||
}
|
||||
}
|
||||
Err(e) => println!("Error: {:?}", e),
|
||||
}
|
||||
PendingTxStoreInfo { _transactions }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct PendingTxOrderStoreInfo {
|
||||
_order: Vec<OrderInfo>,
|
||||
}
|
||||
|
||||
impl PendingTxOrderStoreInfo {
|
||||
pub fn new(orderstore: &PendingTxOrderStore) -> PendingTxOrderStoreInfo {
|
||||
let mut _order = Vec::new();
|
||||
let result = orderstore.get_all();
|
||||
match result {
|
||||
Ok(iter) => {
|
||||
for (height, hash) in iter.iter() {
|
||||
_order.push(OrderInfo::new(*height, *hash));
|
||||
}
|
||||
}
|
||||
Err(e) => println!("Error: {:?}", e),
|
||||
}
|
||||
PendingTxOrderStoreInfo { _order }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ContractStateInfo {
|
||||
_id: ContractId,
|
||||
_state_hashes: Vec<blake3::Hash>,
|
||||
}
|
||||
|
||||
impl ContractStateInfo {
|
||||
pub fn new(_id: ContractId, state_hashes: &[blake3::Hash]) -> ContractStateInfo {
|
||||
ContractStateInfo { _id, _state_hashes: state_hashes.to_vec() }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ContractStateStoreInfo {
|
||||
_contracts: Vec<ContractStateInfo>,
|
||||
}
|
||||
|
||||
impl ContractStateStoreInfo {
|
||||
pub fn new(contractsstore: &ContractStateStore) -> ContractStateStoreInfo {
|
||||
let mut _contracts = Vec::new();
|
||||
let result = contractsstore.get_all();
|
||||
match result {
|
||||
Ok(iter) => {
|
||||
for (id, state_hash) in iter.iter() {
|
||||
_contracts.push(ContractStateInfo::new(*id, state_hash));
|
||||
}
|
||||
}
|
||||
Err(e) => println!("Error: {:?}", e),
|
||||
}
|
||||
ContractStateStoreInfo { _contracts }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct WasmInfo {
|
||||
_id: ContractId,
|
||||
_bincode_hash: blake3::Hash,
|
||||
}
|
||||
|
||||
impl WasmInfo {
|
||||
pub fn new(_id: ContractId, bincode: &[u8]) -> WasmInfo {
|
||||
let _bincode_hash = blake3::hash(bincode);
|
||||
WasmInfo { _id, _bincode_hash }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct WasmStoreInfo {
|
||||
_wasm_bincodes: Vec<WasmInfo>,
|
||||
}
|
||||
|
||||
impl WasmStoreInfo {
|
||||
pub fn new(wasmstore: &WasmStore) -> WasmStoreInfo {
|
||||
let mut _wasm_bincodes = Vec::new();
|
||||
let result = wasmstore.get_all();
|
||||
match result {
|
||||
Ok(iter) => {
|
||||
for (id, bincode) in iter.iter() {
|
||||
_wasm_bincodes.push(WasmInfo::new(*id, bincode));
|
||||
}
|
||||
}
|
||||
Err(e) => println!("Error: {:?}", e),
|
||||
}
|
||||
WasmStoreInfo { _wasm_bincodes }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct BlockchainInfo {
|
||||
_headers: HeaderStoreInfo,
|
||||
_blocks: BlockInfoChain,
|
||||
_order: BlockOrderStoreInfo,
|
||||
_slots: SlotStoreInfo,
|
||||
_difficulties: BlockDifficultyStoreInfo,
|
||||
_transactions: TxStoreInfo,
|
||||
_pending_txs: PendingTxStoreInfo,
|
||||
_pending_txs_order: PendingTxOrderStoreInfo,
|
||||
_contracts: ContractStateStoreInfo,
|
||||
_wasm_bincode: WasmStoreInfo,
|
||||
}
|
||||
|
||||
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 _slots = SlotStoreInfo::new(&blockchain.slots);
|
||||
let _transactions = TxStoreInfo::new(&blockchain.transactions);
|
||||
BlockchainInfo { _headers, _blocks, _order, _slots, _transactions }
|
||||
BlockchainInfo {
|
||||
_headers: HeaderStoreInfo::new(&blockchain.headers),
|
||||
_blocks: BlockInfoChain::new(&blockchain.blocks),
|
||||
_order: BlockOrderStoreInfo::new(&blockchain.order),
|
||||
_difficulties: BlockDifficultyStoreInfo::new(&blockchain.difficulties),
|
||||
_transactions: TxStoreInfo::new(&blockchain.transactions),
|
||||
_pending_txs: PendingTxStoreInfo::new(&blockchain.pending_txs),
|
||||
_pending_txs_order: PendingTxOrderStoreInfo::new(&blockchain.pending_txs_order),
|
||||
_contracts: ContractStateStoreInfo::new(&blockchain.contracts),
|
||||
_wasm_bincode: WasmStoreInfo::new(&blockchain.wasm_bincode),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,19 +420,18 @@ fn statistics(folder: &str, node: &str, blockchain: &str) -> Result<()> {
|
||||
// Initialize or load sled database
|
||||
let path = folder.to_owned() + blockchain;
|
||||
let db_path = expand_path(&path).unwrap();
|
||||
let sled_db = sled::open(&db_path)?;
|
||||
let sled_db = sled::open(db_path)?;
|
||||
|
||||
// Retrieve statistics
|
||||
let blockchain = Blockchain::new(&sled_db)?;
|
||||
let slot = blockchain.last_slot()?.id;
|
||||
let epoch = slot / EPOCH_LENGTH as u64;
|
||||
let (_, block) = blockchain.last()?;
|
||||
let (height, block) = blockchain.last()?;
|
||||
let epoch = block_epoch(height);
|
||||
let blocks = blockchain.len();
|
||||
let txs = blockchain.txs_len();
|
||||
drop(sled_db);
|
||||
|
||||
// Print statistics
|
||||
println!("Latest slot: {slot}");
|
||||
println!("Latest height: {height}");
|
||||
println!("Epoch: {epoch}");
|
||||
println!("Latest block: {block}");
|
||||
println!("Total blocks: {blocks}");
|
||||
@@ -321,7 +449,7 @@ fn export(folder: &str, node: &str, blockchain: &str) -> Result<()> {
|
||||
// Initialize or load sled database
|
||||
let path = folder.to_owned() + blockchain;
|
||||
let db_path = expand_path(&path).unwrap();
|
||||
let sled_db = sled::open(&db_path)?;
|
||||
let sled_db = sled::open(db_path)?;
|
||||
|
||||
// Data export
|
||||
let blockchain = Blockchain::new(&sled_db)?;
|
||||
@@ -329,7 +457,7 @@ fn export(folder: &str, node: &str, blockchain: &str) -> Result<()> {
|
||||
let info_string = format!("{:#?}", info);
|
||||
let file_name = node.to_owned() + "_db";
|
||||
let mut file = File::create(file_name.clone())?;
|
||||
file.write(info_string.as_bytes())?;
|
||||
file.write_all(info_string.as_bytes())?;
|
||||
drop(sled_db);
|
||||
println!("Data exported to file: {file_name}");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user