Browse Source

tx: introduce predicate functions to identify PoW reward and single call transactions

This commit adds an `is_pow_reward` function to the transaction structure implementation, which indicates if a transaction is a Proof-of-Work (PoW) reward. A function `is_single_call` has also been added that checks if a transaction consists of a single call with non-empty data.

As usage example, updated all validator checks for transaction types to use new predicate functions.

This useful feature enhances our ability to differentiate PoW reward transactions and single call transactions from other transaction types.
kalm 1 year ago
parent
commit
49f5aaf475
2 changed files with 19 additions and 8 deletions
  1. 15 0
      src/tx/mod.rs
  2. 4 8
      src/validator/verification.rs

+ 15 - 0
src/tx/mod.rs

@@ -193,6 +193,21 @@ impl Transaction {
         self.encode(&mut hasher).expect("blake3 hasher");
         self.encode(&mut hasher).expect("blake3 hasher");
         TransactionHash(hasher.finalize().into())
         TransactionHash(hasher.finalize().into())
     }
     }
+
+    /// Returns true if transaction is a PoW reward one.
+    pub fn is_pow_reward(&self) -> bool {
+        // PoW rewards must be single contract calls
+        if !self.is_single_call() {
+            return false;
+        }
+
+        self.calls[0].data.is_money_pow_reward()
+    }
+
+    /// Returns true if the transaction consists of a single call with non-empty data.
+    pub fn is_single_call(&self) -> bool {
+        self.calls.len() == 1 && !self.calls[0].data.data.is_empty()
+    }
 }
 }
 
 
 // Avoid showing the proofs and sigs in the debug output since often they are very long.
 // Avoid showing the proofs and sigs in the debug output since often they are very long.

+ 4 - 8
src/validator/verification.rs

@@ -333,17 +333,13 @@ pub async fn verify_producer_transaction(
     let tx_hash = tx.hash();
     let tx_hash = tx.hash();
     debug!(target: "validator::verification::verify_producer_transaction", "Validating producer transaction {}", tx_hash);
     debug!(target: "validator::verification::verify_producer_transaction", "Validating producer transaction {}", tx_hash);
 
 
-    // Producer transactions must contain a single, non-empty call
-    if tx.calls.len() != 1 || tx.calls[0].data.data.is_empty() {
+    // Transaction must be a PoW reward one
+    if !tx.is_pow_reward() {
         return Err(TxVerifyFailed::ErroneousTxs(vec![tx.clone()]).into())
         return Err(TxVerifyFailed::ErroneousTxs(vec![tx.clone()]).into())
     }
     }
 
 
-    // Verify call based on version
+    // Retrieve first call from the transaction for further processing
     let call = &tx.calls[0];
     let call = &tx.calls[0];
-    // Call must be a PoW reward
-    if !call.data.is_money_pow_reward() {
-        return Err(TxVerifyFailed::ErroneousTxs(vec![tx.clone()]).into())
-    }
 
 
     // Map of ZK proof verifying keys for the current transaction
     // Map of ZK proof verifying keys for the current transaction
     let mut verifying_keys: HashMap<[u8; 32], HashMap<String, VerifyingKey>> = HashMap::new();
     let mut verifying_keys: HashMap<[u8; 32], HashMap<String, VerifyingKey>> = HashMap::new();
@@ -471,7 +467,7 @@ async fn apply_producer_transaction(
     debug!(target: "validator::verification::apply_producer_transaction", "Applying producer transaction {}", tx_hash);
     debug!(target: "validator::verification::apply_producer_transaction", "Applying producer transaction {}", tx_hash);
 
 
     // Producer transactions must contain a single, non-empty call
     // Producer transactions must contain a single, non-empty call
-    if tx.calls.len() != 1 || tx.calls[0].data.data.is_empty() {
+    if !tx.is_single_call() {
         return Err(TxVerifyFailed::ErroneousTxs(vec![tx.clone()]).into())
         return Err(TxVerifyFailed::ErroneousTxs(vec![tx.clone()]).into())
     }
     }