Bläddra i källkod

drk: add block height reference to txs history

skoupidi 1 år sedan
förälder
incheckning
37bee3e638
4 ändrade filer med 69 tillägg och 16 borttagningar
  1. 12 4
      bin/drk/src/main.rs
  2. 4 2
      bin/drk/src/rpc.rs
  3. 52 10
      bin/drk/src/txs_history.rs
  4. 1 0
      bin/drk/wallet.sql

+ 12 - 4
bin/drk/src/main.rs

@@ -2120,7 +2120,7 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
                 .await;
 
                 if let Some(c) = tx_hash {
-                    let (tx_hash, status, tx) = drk.get_tx_history_record(&c).await?;
+                    let (tx_hash, status, block_height, tx) = drk.get_tx_history_record(&c).await?;
 
                     if encode {
                         println!("{}", base64::encode(&serialize_async(&tx).await));
@@ -2129,6 +2129,10 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
 
                     println!("Transaction ID: {tx_hash}");
                     println!("Status: {status}");
+                    match block_height {
+                        Some(block_height) => println!("Block height: {block_height}"),
+                        None => println!("Block height: -"),
+                    }
                     println!("{tx:?}");
 
                     return Ok(())
@@ -2145,9 +2149,13 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
                 // 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!["Transaction Hash", "Status"]);
-                for (txs_hash, status) in map.iter() {
-                    table.add_row(row![txs_hash, status]);
+                table.set_titles(row!["Transaction Hash", "Status", "Block Height"]);
+                for (txs_hash, status, block_height) in map.iter() {
+                    let block_height = match block_height {
+                        Some(block_height) => block_height.to_string(),
+                        None => String::from("-"),
+                    };
+                    table.add_row(row![txs_hash, status, block_height]);
                 }
 
                 if table.is_empty() {

+ 4 - 2
bin/drk/src/rpc.rs

@@ -414,7 +414,9 @@ impl Drk {
             .apply_diff(&scan_cache.money_smt.store.overlay.0.diff(&[])?)?;
 
         // Update wallet transactions records
-        if let Err(e) = self.put_tx_history_records(&wallet_txs, "Confirmed").await {
+        if let Err(e) =
+            self.put_tx_history_records(&wallet_txs, "Confirmed", Some(block.header.height)).await
+        {
             return Err(Error::DatabaseError(format!(
                 "[scan_block] Inserting transaction history records failed: {e:?}"
             )))
@@ -565,7 +567,7 @@ impl Drk {
         let txid = rep.get::<String>().unwrap().clone();
 
         // Store transactions history record
-        if let Err(e) = self.put_tx_history_record(tx, "Broadcasted").await {
+        if let Err(e) = self.put_tx_history_record(tx, "Broadcasted", None).await {
             return Err(Error::DatabaseError(format!(
                 "[broadcast_tx] Inserting transaction history record failed: {e:?}"
             )))

+ 52 - 10
bin/drk/src/txs_history.rs

@@ -32,6 +32,7 @@ use crate::{
 const WALLET_TXS_HISTORY_TABLE: &str = "transactions_history";
 const WALLET_TXS_HISTORY_COL_TX_HASH: &str = "transaction_hash";
 const WALLET_TXS_HISTORY_COL_STATUS: &str = "status";
+const WALLET_TXS_HISTORY_BLOCK_HEIGHT: &str = "block_height";
 const WALLET_TXS_HISTORY_COL_TX: &str = "tx";
 
 impl Drk {
@@ -41,16 +42,24 @@ impl Drk {
         &self,
         tx: &Transaction,
         status: &str,
+        block_height: Option<u32>,
     ) -> WalletDbResult<String> {
         // Create an SQL `INSERT OR REPLACE` query
         let query = format!(
-            "INSERT OR REPLACE INTO {WALLET_TXS_HISTORY_TABLE} ({WALLET_TXS_HISTORY_COL_TX_HASH}, {WALLET_TXS_HISTORY_COL_STATUS}, {WALLET_TXS_HISTORY_COL_TX}) VALUES (?1, ?2, ?3);"
+            "INSERT OR REPLACE INTO {} ({}, {}, {}, {}) VALUES (?1, ?2, ?3, ?4);",
+            WALLET_TXS_HISTORY_TABLE,
+            WALLET_TXS_HISTORY_COL_TX_HASH,
+            WALLET_TXS_HISTORY_COL_STATUS,
+            WALLET_TXS_HISTORY_BLOCK_HEIGHT,
+            WALLET_TXS_HISTORY_COL_TX,
         );
 
         // Execute the query
         let tx_hash = tx.hash().to_string();
-        self.wallet
-            .exec_sql(&query, rusqlite::params![tx_hash, status, &serialize_async(tx).await,])?;
+        self.wallet.exec_sql(
+            &query,
+            rusqlite::params![tx_hash, status, block_height, &serialize_async(tx).await],
+        )?;
 
         Ok(tx_hash)
     }
@@ -61,10 +70,11 @@ impl Drk {
         &self,
         txs: &[&Transaction],
         status: &str,
+        block_height: Option<u32>,
     ) -> WalletDbResult<Vec<String>> {
         let mut ret = Vec::with_capacity(txs.len());
         for tx in txs {
-            ret.push(self.put_tx_history_record(tx, status).await?);
+            ret.push(self.put_tx_history_record(tx, status, block_height).await?);
         }
         Ok(ret)
     }
@@ -73,7 +83,7 @@ impl Drk {
     pub async fn get_tx_history_record(
         &self,
         tx_hash: &str,
-    ) -> Result<(String, String, Transaction)> {
+    ) -> Result<(String, String, Option<u32>, Transaction)> {
         let row = match self.wallet.query_single(
             WALLET_TXS_HISTORY_TABLE,
             &[],
@@ -97,21 +107,42 @@ impl Drk {
             return Err(Error::ParseFailed("[get_tx_history_record] Status parsing failed"))
         };
 
-        let Value::Blob(ref bytes) = row[2] else {
+        let block_height = match row[2] {
+            Value::Integer(block_height) => {
+                let Ok(block_height) = u32::try_from(block_height) else {
+                    return Err(Error::ParseFailed(
+                        "[get_tx_history_record] Block height parsing failed",
+                    ))
+                };
+                Some(block_height)
+            }
+            Value::Null => None,
+            _ => {
+                return Err(Error::ParseFailed(
+                    "[get_tx_history_record] Block height parsing failed",
+                ))
+            }
+        };
+
+        let Value::Blob(ref bytes) = row[3] else {
             return Err(Error::ParseFailed(
                 "[get_tx_history_record] Transaction bytes parsing failed",
             ))
         };
         let tx: Transaction = deserialize_async(bytes).await?;
 
-        Ok((tx_hash.clone(), status.clone(), tx))
+        Ok((tx_hash.clone(), status.clone(), block_height, tx))
     }
 
     /// Fetch all transactions history records, excluding bytes column.
-    pub fn get_txs_history(&self) -> WalletDbResult<Vec<(String, String)>> {
+    pub fn get_txs_history(&self) -> WalletDbResult<Vec<(String, String, Option<u32>)>> {
         let rows = self.wallet.query_multiple(
             WALLET_TXS_HISTORY_TABLE,
-            &[WALLET_TXS_HISTORY_COL_TX_HASH, WALLET_TXS_HISTORY_COL_STATUS],
+            &[
+                WALLET_TXS_HISTORY_COL_TX_HASH,
+                WALLET_TXS_HISTORY_COL_STATUS,
+                WALLET_TXS_HISTORY_BLOCK_HEIGHT,
+            ],
             &[],
         )?;
 
@@ -125,7 +156,18 @@ impl Drk {
                 return Err(WalletDbError::ParseColumnValueError)
             };
 
-            ret.push((tx_hash.clone(), status.clone()));
+            let block_height = match row[2] {
+                Value::Integer(block_height) => {
+                    let Ok(block_height) = u32::try_from(block_height) else {
+                        return Err(WalletDbError::ParseColumnValueError)
+                    };
+                    Some(block_height)
+                }
+                Value::Null => None,
+                _ => return Err(WalletDbError::ParseColumnValueError),
+            };
+
+            ret.push((tx_hash.clone(), status.clone(), block_height));
         }
 
         Ok(ret)

+ 1 - 0
bin/drk/wallet.sql

@@ -7,5 +7,6 @@ PRAGMA foreign_keys = ON;
 CREATE TABLE IF NOT EXISTS transactions_history (
     transaction_hash TEXT PRIMARY KEY NOT NULL,
     status TEXT NOT NULL,
+    block_height INTEGER,
 	tx BLOB NOT NULL
 );