Browse Source

drk: add freeze block height reference to tokens

skoupidi 1 năm trước cách đây
mục cha
commit
34982f1555
5 tập tin đã thay đổi với 68 bổ sung21 xóa
  1. 2 1
      bin/drk/money.sql
  2. 10 4
      bin/drk/src/main.rs
  3. 12 4
      bin/drk/src/money.rs
  4. 8 2
      bin/drk/src/rpc.rs
  5. 36 10
      bin/drk/src/token.rs

+ 2 - 1
bin/drk/money.sql

@@ -31,7 +31,8 @@ CREATE TABLE IF NOT EXISTS BZHKGQ26bzmBithTQYTJtjo2QdCqpkR9tjSBopT4yf4o_money_to
 	token_id BLOB PRIMARY KEY NOT NULL,
 	mint_authority BLOB NOT NULL,
 	token_blind BLOB NOT NULL,
-	is_frozen INTEGER NOT NULL
+	is_frozen INTEGER NOT NULL,
+	freeze_height INTEGER
 );
 
 -- The token aliases in our wallet

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

@@ -2406,16 +2406,22 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
                     "Aliases",
                     "Mint Authority",
                     "Token Blind",
-                    "Frozen"
+                    "Frozen",
+                    "Freeze Height"
                 ]);
 
-                for (token_id, authority, blind, frozen) in tokens {
+                for (token_id, authority, blind, frozen, freeze_height) in tokens {
                     let aliases = match aliases_map.get(&token_id.to_string()) {
                         Some(a) => a,
                         None => "-",
                     };
 
-                    table.add_row(row![token_id, aliases, authority, blind, frozen]);
+                    let freeze_height = match freeze_height {
+                        Some(freeze_height) => freeze_height.to_string(),
+                        None => String::from("-"),
+                    };
+
+                    table.add_row(row![token_id, aliases, authority, blind, frozen, freeze_height]);
                 }
 
                 if table.is_empty() {
@@ -2571,7 +2577,7 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
 
                 let mut table = Table::new();
                 table.set_format(*format::consts::FORMAT_NO_BORDER_LINE_SEPARATOR);
-                table.set_titles(row!["Index", "Contract ID", "Frozen"]);
+                table.set_titles(row!["Index", "Contract ID", "Frozen", "Freeze Height"]);
 
                 for (idx, contract_id, frozen, freeze_height) in auths {
                     let freeze_height = match freeze_height {

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

@@ -108,6 +108,7 @@ pub const MONEY_TOKENS_COL_TOKEN_ID: &str = "token_id";
 pub const MONEY_TOKENS_COL_MINT_AUTHORITY: &str = "mint_authority";
 pub const MONEY_TOKENS_COL_TOKEN_BLIND: &str = "token_blind";
 pub const MONEY_TOKENS_COL_IS_FROZEN: &str = "is_frozen";
+pub const MONEY_TOKENS_COL_FREEZE_HEIGHT: &str = "freeze_height";
 
 // MONEY_ALIASES_TABLE
 pub const MONEY_ALIASES_COL_ALIAS: &str = "alias";
@@ -826,6 +827,7 @@ impl Drk {
         &self,
         own_tokens: &[TokenId],
         freezes: &[TokenId],
+        freeze_height: &u32,
     ) -> Result<bool> {
         // Check if we have any freezes to process
         if freezes.is_empty() {
@@ -847,8 +849,11 @@ impl Drk {
 
         // This is the SQL query we'll be executing to update frozen tokens into the wallet
         let query = format!(
-            "UPDATE {} SET {} = 1 WHERE {} = ?1;",
-            *MONEY_TOKENS_TABLE, MONEY_TOKENS_COL_IS_FROZEN, MONEY_TOKENS_COL_TOKEN_ID,
+            "UPDATE {} SET {} = 1, {} = ?1 WHERE {} = ?2;",
+            *MONEY_TOKENS_TABLE,
+            MONEY_TOKENS_COL_IS_FROZEN,
+            MONEY_TOKENS_COL_FREEZE_HEIGHT,
+            MONEY_TOKENS_COL_TOKEN_ID,
         );
 
         for token_id in own_freezes {
@@ -856,7 +861,9 @@ impl Drk {
             let key = serialize_async(token_id).await;
 
             // Execute the query
-            if let Err(e) = self.wallet.exec_sql(&query, rusqlite::params![key]) {
+            if let Err(e) =
+                self.wallet.exec_sql(&query, rusqlite::params![Some(freeze_height), key])
+            {
                 return Err(Error::DatabaseError(format!(
                     "[handle_money_call_freezes] Update Money token freeze failed: {e:?}"
                 )))
@@ -876,6 +883,7 @@ impl Drk {
         call_idx: &usize,
         calls: &[DarkLeaf<ContractCall>],
         tx_hash: &String,
+        block_height: &u32,
     ) -> Result<(bool, bool)> {
         // Parse the call
         let (nullifiers, coins, freezes) = self.parse_money_call(call_idx, calls).await?;
@@ -899,7 +907,7 @@ impl Drk {
 
         // Handle freezes
         let wallet_freezes =
-            self.handle_money_call_freezes(&scan_cache.own_tokens, &freezes).await?;
+            self.handle_money_call_freezes(&scan_cache.own_tokens, &freezes, block_height).await?;
 
         if self.fun && !owncoins.is_empty() {
             kaching().await;

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

@@ -92,7 +92,7 @@ impl Drk {
         }
         let mint_authorities = self.get_mint_authorities().await?;
         let mut own_tokens = Vec::with_capacity(mint_authorities.len());
-        for (token, _, _, _) in mint_authorities {
+        for (token, _, _, _, _) in mint_authorities {
             own_tokens.push(token);
         }
         let (dao_daos_tree, dao_proposals_tree) = self.get_dao_trees().await?;
@@ -318,7 +318,13 @@ impl Drk {
                 if call.data.contract_id == *MONEY_CONTRACT_ID {
                     println!("[scan_block] Found Money contract in call {i}");
                     let (update_tree, own_tx) = self
-                        .apply_tx_money_data(scan_cache, &i, &tx.calls, &tx_hash_string)
+                        .apply_tx_money_data(
+                            scan_cache,
+                            &i,
+                            &tx.calls,
+                            &tx_hash_string,
+                            &block.header.height,
+                        )
                         .await?;
                     if update_tree {
                         update_money_tree = true;

+ 36 - 10
bin/drk/src/token.rs

@@ -50,8 +50,9 @@ use crate::{
     convert_named_params,
     error::WalletDbResult,
     money::{
-        BALANCE_BASE10_DECIMALS, MONEY_TOKENS_COL_IS_FROZEN, MONEY_TOKENS_COL_MINT_AUTHORITY,
-        MONEY_TOKENS_COL_TOKEN_BLIND, MONEY_TOKENS_COL_TOKEN_ID, MONEY_TOKENS_TABLE,
+        BALANCE_BASE10_DECIMALS, MONEY_TOKENS_COL_FREEZE_HEIGHT, MONEY_TOKENS_COL_IS_FROZEN,
+        MONEY_TOKENS_COL_MINT_AUTHORITY, MONEY_TOKENS_COL_TOKEN_BLIND, MONEY_TOKENS_COL_TOKEN_ID,
+        MONEY_TOKENS_TABLE,
     },
     Drk,
 };
@@ -89,14 +90,16 @@ impl Drk {
     ) -> Result<TokenId> {
         let token_id = self.derive_token_attributes(mint_authority, token_blind).to_token_id();
         let is_frozen = 0;
+        let freeze_height: Option<u32> = None;
 
         let query = format!(
-            "INSERT INTO {} ({}, {}, {}, {}) VALUES (?1, ?2, ?3, ?4);",
+            "INSERT INTO {} ({}, {}, {}, {}, {}) VALUES (?1, ?2, ?3, ?4, ?5);",
             *MONEY_TOKENS_TABLE,
             MONEY_TOKENS_COL_TOKEN_ID,
             MONEY_TOKENS_COL_MINT_AUTHORITY,
             MONEY_TOKENS_COL_TOKEN_BLIND,
             MONEY_TOKENS_COL_IS_FROZEN,
+            MONEY_TOKENS_COL_FREEZE_HEIGHT,
         );
 
         if let Err(e) = self.wallet.exec_sql(
@@ -106,6 +109,7 @@ impl Drk {
                 serialize_async(&mint_authority).await,
                 serialize_async(&token_blind).await,
                 is_frozen,
+                freeze_height,
             ],
         ) {
             return Err(Error::DatabaseError(format!(
@@ -121,7 +125,7 @@ impl Drk {
     async fn parse_mint_authority_record(
         &self,
         row: &[Value],
-    ) -> Result<(TokenId, SecretKey, BaseBlind, bool)> {
+    ) -> Result<(TokenId, SecretKey, BaseBlind, bool, Option<u32>)> {
         let Value::Blob(ref token_bytes) = row[0] else {
             return Err(Error::ParseFailed(
                 "[parse_mint_authority_record] Token ID bytes parsing failed",
@@ -150,22 +154,44 @@ impl Drk {
             return Err(Error::ParseFailed("[parse_mint_authority_record] Is frozen parsing failed"))
         };
 
-        Ok((token_id, mint_authority, token_blind, frozen != 0))
+        let freeze_height = match row[4] {
+            Value::Integer(freeze_height) => {
+                let Ok(freeze_height) = u32::try_from(freeze_height) else {
+                    return Err(Error::ParseFailed(
+                        "[parse_mint_authority_record] Freeze height parsing failed",
+                    ))
+                };
+                Some(freeze_height)
+            }
+            Value::Null => None,
+            _ => {
+                return Err(Error::ParseFailed(
+                    "[parse_mint_authority_record] Freeze height parsing failed",
+                ))
+            }
+        };
+
+        Ok((token_id, mint_authority, token_blind, frozen != 0, freeze_height))
     }
 
     /// Reset all token mint authorities frozen status in the wallet.
     pub fn reset_mint_authorities(&self) -> WalletDbResult<()> {
         println!("Resetting mint authorities frozen status");
-        let query =
-            format!("UPDATE {} SET {} = 0", *MONEY_TOKENS_TABLE, MONEY_TOKENS_COL_IS_FROZEN,);
-        self.wallet.exec_sql(&query, &[])?;
+        let freeze_height: Option<u32> = None;
+        let query = format!(
+            "UPDATE {} SET {} = 0, {} = ?1",
+            *MONEY_TOKENS_TABLE, MONEY_TOKENS_COL_IS_FROZEN, MONEY_TOKENS_COL_FREEZE_HEIGHT
+        );
+        self.wallet.exec_sql(&query, rusqlite::params![freeze_height])?;
         println!("Successfully mint authorities frozen status");
 
         Ok(())
     }
 
     /// Fetch all token mint authorities from the wallet.
-    pub async fn get_mint_authorities(&self) -> Result<Vec<(TokenId, SecretKey, BaseBlind, bool)>> {
+    pub async fn get_mint_authorities(
+        &self,
+    ) -> Result<Vec<(TokenId, SecretKey, BaseBlind, bool, Option<u32>)>> {
         let rows = match self.wallet.query_multiple(&MONEY_TOKENS_TABLE, &[], &[]) {
             Ok(r) => r,
             Err(e) => {
@@ -187,7 +213,7 @@ impl Drk {
     async fn get_token_mint_authority(
         &self,
         token_id: &TokenId,
-    ) -> Result<(TokenId, SecretKey, BaseBlind, bool)> {
+    ) -> Result<(TokenId, SecretKey, BaseBlind, bool, Option<u32>)> {
         let row = match self.wallet.query_single(
             &MONEY_TOKENS_TABLE,
             &[],