Просмотр исходного кода

drk: added sub command to list scanned blocks

skoupidi 1 год назад
Родитель
Сommit
7d2811f136
3 измененных файлов с 93 добавлено и 26 удалено
  1. 8 2
      bin/drk/src/cli_util.rs
  2. 56 0
      bin/drk/src/main.rs
  3. 29 24
      bin/drk/src/scanned_blocks.rs

+ 8 - 2
bin/drk/src/cli_util.rs

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

+ 56 - 0
bin/drk/src/main.rs

@@ -410,6 +410,12 @@ enum ExplorerSubcmd {
         /// Encode specific history record transaction to base58
         /// Encode specific history record transaction to base58
         encode: bool,
         encode: bool,
     },
     },
+
+    /// Fetch scanned blocks records
+    ScannedBlocks {
+        /// Fetch specific height record (optional)
+        height: Option<u32>,
+    },
 }
 }
 
 
 #[derive(Clone, Debug, Deserialize, StructOpt)]
 #[derive(Clone, Debug, Deserialize, StructOpt)]
@@ -1960,6 +1966,56 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
 
 
                 Ok(())
                 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 {
         Subcmd::Alias { command } => match command {

+ 29 - 24
bin/drk/src/scanned_blocks.rs

@@ -49,14 +49,8 @@ impl Drk {
         self.wallet.exec_sql(&query, rusqlite::params![height, hash, rollback_query])
         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 {
         let Value::Integer(height) = row[0] else {
             return Err(WalletDbError::ParseColumnValueError);
             return Err(WalletDbError::ParseColumnValueError);
         };
         };
@@ -75,15 +69,35 @@ impl Drk {
         Ok((height, hash.clone(), rollback_query.clone()))
         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.
     /// Get the last scanned block height and hash from the wallet.
     /// If database is empty default (0, '-') is returned.
     /// If database is empty default (0, '-') is returned.
     pub fn get_last_scanned_block(&self) -> WalletDbResult<(u32, String)> {
     pub fn get_last_scanned_block(&self) -> WalletDbResult<(u32, String)> {
         let query = format!(
         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, &[])?;
         let ret = self.wallet.query_custom(&query, &[])?;
 
 
@@ -91,18 +105,9 @@ impl Drk {
             return Ok((0, String::from("-")))
             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 Value::Text(ref hash) = ret[0][1] else {
-            return Err(WalletDbError::ParseColumnValueError);
-        };
+        let (height, hash, _) = self.parse_scanned_block_record(&ret[0])?;
 
 
-        Ok((height, hash.clone()))
+        Ok((height, hash))
     }
     }
 
 
     /// Reset the scanned blocks information records in the wallet.
     /// Reset the scanned blocks information records in the wallet.