drk: added sub command to list scanned blocks

This commit is contained in:
skoupidi
2024-12-10 19:30:51 +02:00
parent ed9979efc9
commit 7d2811f136
3 changed files with 93 additions and 26 deletions

View File

@@ -382,7 +382,7 @@ pub fn generate_completions(shell: &str) -> Result<()> {
let simulate_tx =
SubCommand::with_name("simulate-tx").about("Read a transaction from stdin and simulate it");
let tx_hash = Arg::with_name("tx-hash").help("Transaction hash");
let tx_hash = Arg::with_name("tx-hash").help("Fetch specific history record (optional)");
let encode = Arg::with_name("encode")
.long("encode")
@@ -392,9 +392,15 @@ pub fn generate_completions(shell: &str) -> Result<()> {
.about("Fetch broadcasted transactions history")
.args(&vec![tx_hash, encode]);
let height = Arg::with_name("height").help("Fetch specific height record (optional)");
let scanned_blocks = SubCommand::with_name("scanned-blocks")
.about("Fetch scanned blocks records")
.args(&vec![height]);
let explorer = SubCommand::with_name("explorer")
.about("Explorer related subcommands")
.subcommands(vec![fetch_tx, simulate_tx, txs_history]);
.subcommands(vec![fetch_tx, simulate_tx, txs_history, scanned_blocks]);
// Alias
let alias = Arg::with_name("alias").help("Token alias");

View File

@@ -410,6 +410,12 @@ enum ExplorerSubcmd {
/// Encode specific history record transaction to base58
encode: bool,
},
/// Fetch scanned blocks records
ScannedBlocks {
/// Fetch specific height record (optional)
height: Option<u32>,
},
}
#[derive(Clone, Debug, Deserialize, StructOpt)]
@@ -1960,6 +1966,56 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
Ok(())
}
ExplorerSubcmd::ScannedBlocks { height } => {
let drk = new_wallet(
blockchain_config.wallet_path,
blockchain_config.wallet_pass,
None,
ex,
args.fun,
)
.await;
if let Some(h) = height {
let (height, hash, _) = match drk.get_scanned_block_record(h) {
Ok(ret) => ret,
Err(e) => {
eprintln!("Failed to retrieve scanned block record: {e:?}");
exit(2);
}
};
println!("Height: {height}");
println!("Hash: {hash}");
return Ok(())
}
let map = match drk.get_scanned_block_records() {
Ok(m) => m,
Err(e) => {
eprintln!("Failed to retrieve scanned blocks records: {e:?}");
exit(2);
}
};
// Create a prettytable with the new data:
let mut table = Table::new();
table.set_format(*format::consts::FORMAT_NO_BORDER_LINE_SEPARATOR);
table.set_titles(row!["Height", "Hash"]);
for (height, hash, _) in map.iter() {
table.add_row(row![height, hash]);
}
if table.is_empty() {
println!("No scanned blocks records found");
} else {
println!("{table}");
}
Ok(())
}
},
Subcmd::Alias { command } => match command {

View File

@@ -49,14 +49,8 @@ impl Drk {
self.wallet.exec_sql(&query, rusqlite::params![height, hash, rollback_query])
}
/// Get a scanned block information record.
pub fn get_scanned_block_record(&self, height: u32) -> WalletDbResult<(u32, String, String)> {
let row = self.wallet.query_single(
WALLET_SCANNED_BLOCKS_TABLE,
&[],
convert_named_params! {(WALLET_SCANNED_BLOCKS_COL_HEIGH, height)},
)?;
/// Auxiliary function to parse a `WALLET_SCANNED_BLOCKS_TABLE` records.
fn parse_scanned_block_record(&self, row: &[Value]) -> WalletDbResult<(u32, String, String)> {
let Value::Integer(height) = row[0] else {
return Err(WalletDbError::ParseColumnValueError);
};
@@ -75,15 +69,35 @@ impl Drk {
Ok((height, hash.clone(), rollback_query.clone()))
}
/// Get a scanned block information record.
pub fn get_scanned_block_record(&self, height: u32) -> WalletDbResult<(u32, String, String)> {
let row = self.wallet.query_single(
WALLET_SCANNED_BLOCKS_TABLE,
&[],
convert_named_params! {(WALLET_SCANNED_BLOCKS_COL_HEIGH, height)},
)?;
self.parse_scanned_block_record(&row)
}
/// Fetch all scanned block information record.
pub fn get_scanned_block_records(&self) -> WalletDbResult<Vec<(u32, String, String)>> {
let rows = self.wallet.query_multiple(WALLET_SCANNED_BLOCKS_TABLE, &[], &[])?;
let mut ret = Vec::with_capacity(rows.len());
for row in rows {
ret.push(self.parse_scanned_block_record(&row)?);
}
Ok(ret)
}
/// Get the last scanned block height and hash from the wallet.
/// If database is empty default (0, '-') is returned.
pub fn get_last_scanned_block(&self) -> WalletDbResult<(u32, String)> {
let query = format!(
"SELECT {}, {} FROM {} ORDER BY {} DESC LIMIT 1;",
WALLET_SCANNED_BLOCKS_COL_HEIGH,
WALLET_SCANNED_BLOCKS_COL_HASH,
WALLET_SCANNED_BLOCKS_TABLE,
WALLET_SCANNED_BLOCKS_COL_HEIGH,
"SELECT * FROM {} ORDER BY {} DESC LIMIT 1;",
WALLET_SCANNED_BLOCKS_TABLE, WALLET_SCANNED_BLOCKS_COL_HEIGH,
);
let ret = self.wallet.query_custom(&query, &[])?;
@@ -91,18 +105,9 @@ impl Drk {
return Ok((0, String::from("-")))
}
let Value::Integer(height) = ret[0][0] else {
return Err(WalletDbError::ParseColumnValueError);
};
let Ok(height) = u32::try_from(height) else {
return Err(WalletDbError::ParseColumnValueError);
};
let (height, hash, _) = self.parse_scanned_block_record(&ret[0])?;
let Value::Text(ref hash) = ret[0][1] else {
return Err(WalletDbError::ParseColumnValueError);
};
Ok((height, hash.clone()))
Ok((height, hash))
}
/// Reset the scanned blocks information records in the wallet.