فهرست منبع

validator/verification: Allow fee call at any place in the transaction

parazyd 2 سال پیش
والد
کامیت
511b072c25
1فایلهای تغییر یافته به همراه21 افزوده شده و 24 حذف شده
  1. 21 24
      src/validator/verification.rs

+ 21 - 24
src/validator/verification.rs

@@ -341,7 +341,7 @@ pub async fn verify_transaction(
     time_keeper: &TimeKeeper,
     tx: &Transaction,
     verifying_keys: &mut HashMap<[u8; 32], HashMap<String, VerifyingKey>>,
-    verify_fee: bool, // FIXME: Remove this bool
+    verify_fee: bool,
 ) -> Result<u64> {
     let tx_hash = tx.hash()?;
     debug!(target: "validator::verification::verify_transaction", "Validating transaction {}", tx_hash);
@@ -366,30 +366,19 @@ pub async fn verify_transaction(
     let mut sig_table = vec![];
 
     if verify_fee {
-        // Verify that the first call is the transaction fee and that it has no parents or children.
-        let Some(fee_call_parent_index) = tx.calls[0].parent_index else {
-            error!(
-                target: "validator::verification::verify_transaction",
-                "[VALIDATOR] Fee call does not have parent index",
-            );
-            return Err(TxVerifyFailed::InvalidFee.into())
-        };
-
-        if fee_call_parent_index != tx.calls.len() - 1 ||
-            tx.calls[0].data.contract_id != *MONEY_CONTRACT_ID ||
-            tx.calls[0].data.data[0] != 0x00
-        {
-            error!(
-                target: "validator::verification::verify_transaction",
-                "[VALIDATOR] First tx call is not Money::Fee",
-            );
-            return Err(TxVerifyFailed::MissingFee.into())
+        let mut found_fee = false;
+        // Verify that there is a Money::FeeV1 (0x00) call in the transaction
+        for call in tx.calls.iter() {
+            if call.data.contract_id == *MONEY_CONTRACT_ID && call.data.data[0] == 0x00 {
+                found_fee = true;
+                break
+            }
         }
 
-        if !tx.calls[0].children_indexes.is_empty() {
+        if !found_fee {
             error!(
-                target: "validator::verification::verify_transaction",
-                "[VALIDATOR] Fee call invalid (has children)",
+                target: "validator::verification::verify_transcation",
+                "[VALIDATOR] Transaction {} does not contain fee payment call", tx_hash,
             );
             return Err(TxVerifyFailed::InvalidFee.into())
         }
@@ -428,7 +417,15 @@ pub async fn verify_transaction(
         let zkp_pub: Vec<(String, Vec<pallas::Base>)> =
             AsyncDecodable::decode_async(&mut decoder).await?;
         let sig_pub: Vec<PublicKey> = AsyncDecodable::decode_async(&mut decoder).await?;
-        // TODO: Make sure we've read all the bytes above.
+
+        if decoder.position() != metadata.len() as u64 {
+            error!(
+                target: "validator::verification::verify_transaction",
+                "[VALIDATOR] Failed decoding entire metadata buffer for {}:{}", tx_hash, idx,
+            );
+            return Err(TxVerifyFailed::ErroneousTxs(vec![tx.clone()]).into())
+        }
+
         debug!(target: "validator::verification::verify_transaction", "Successfully executed \"metadata\" call");
 
         // Here we'll look up verifying keys and insert them into the per-contract map.
@@ -537,7 +534,7 @@ pub async fn verify_transaction(
         if gas_used > fee {
             error!(
                 target: "validator::verification::verify_transaction",
-                "[VALIDATOR] tx {} has insufficient fee. Required: {}, Paid: {}",
+                "[VALIDATOR] Transaction {} has insufficient fee. Required: {}, Paid: {}",
                 tx_hash, gas_used, fee,
             );
             return Err(TxVerifyFailed::InsufficientFee.into())