Переглянути джерело

feat: move input limit check to verify_inputs (#1649)

tsk 3 днів тому
батько
коміт
48845ed3d8

+ 8 - 31
crates/cdk/src/mint/melt/melt_saga/mod.rs

@@ -6,7 +6,10 @@ use cdk_common::database::DynMintDatabase;
 use cdk_common::mint::{MeltSagaState, Operation, Saga, SagaStateEnum};
 use cdk_common::nut00::KnownMethod;
 use cdk_common::nuts::MeltQuoteState;
-use cdk_common::{Amount, CurrencyUnit, Error, ProofsMethods, PublicKey, QuoteId, State};
+use cdk_common::{
+    Amount, CurrencyUnit, Error, ProofsMethods, PublicKey, QuoteId, SpendingConditionVerification,
+    State,
+};
 #[cfg(feature = "prometheus")]
 use cdk_prometheus::METRICS;
 use tokio::sync::Mutex;
@@ -194,41 +197,15 @@ impl MeltSaga<Initial> {
         input_verification: Verification,
         payment_method: cdk_common::PaymentMethod,
     ) -> Result<MeltSaga<SetupComplete>, Error> {
+        // Verify spending conditions (NUT-10/NUT-11/NUT-14), i.e. P2PK
+        // and HTLC (including SIGALL)
+        melt_request.verify_spending_conditions()?;
+
         let Verification {
             amount: input_amount,
         } = input_verification;
         let input_unit = Some(input_amount.unit().clone());
 
-        // Check max inputs limit
-        let inputs_count = melt_request.inputs().len();
-        if inputs_count > self.mint.max_inputs {
-            tracing::warn!(
-                "Melt request exceeds max inputs limit: {} > {}",
-                inputs_count,
-                self.mint.max_inputs
-            );
-            return Err(Error::MaxInputsExceeded {
-                actual: inputs_count,
-                max: self.mint.max_inputs,
-            });
-        }
-
-        // Check max outputs limit (if change outputs are provided)
-        if let Some(outputs) = melt_request.outputs() {
-            let outputs_count = outputs.len();
-            if outputs_count > self.mint.max_outputs {
-                tracing::warn!(
-                    "Melt request exceeds max outputs limit: {} > {}",
-                    outputs_count,
-                    self.mint.max_outputs
-                );
-                return Err(Error::MaxOutputsExceeded {
-                    actual: outputs_count,
-                    max: self.mint.max_outputs,
-                });
-            }
-        }
-
         let mut tx = self.db.begin_transaction().await?;
 
         let mut quote =

+ 32 - 10
crates/cdk/src/mint/melt/mod.rs

@@ -9,9 +9,7 @@ use cdk_common::payment::{
     OutgoingPaymentOptions,
 };
 use cdk_common::quote_id::QuoteId;
-use cdk_common::{
-    MeltOptions, MeltQuoteBolt12Request, MeltQuoteCustomRequest, SpendingConditionVerification,
-};
+use cdk_common::{MeltOptions, MeltQuoteBolt12Request, MeltQuoteCustomRequest};
 #[cfg(feature = "prometheus")]
 use cdk_prometheus::METRICS;
 use lightning::offers::offer::Offer;
@@ -540,13 +538,21 @@ impl Mint {
         &self,
         melt_request: &MeltRequest<QuoteId>,
     ) -> Result<MeltQuoteBolt11Response<QuoteId>, Error> {
-        // Verify spending conditions (NUT-10/NUT-11/NUT-14), i.e. P2PK
-        // and HTLC (including SIGALL)
-        melt_request.verify_spending_conditions()?;
-
-        // We don't need to check P2PK or HTLC again. It has all been checked above
-        // and the code doesn't reach here unless such verifications were satisfactory
-
+        // Check max outputs limit (if change outputs are provided)
+        if let Some(outputs) = melt_request.outputs() {
+            let outputs_count = outputs.len();
+            if outputs_count > self.max_outputs {
+                tracing::warn!(
+                    "Melt request exceeds max outputs limit: {} > {}",
+                    outputs_count,
+                    self.max_outputs
+                );
+                return Err(Error::MaxOutputsExceeded {
+                    actual: outputs_count,
+                    max: self.max_outputs,
+                });
+            }
+        }
         let verification = self.verify_inputs(melt_request.inputs()).await?;
 
         // Fetch the quote to get payment_method for operation tracking
@@ -587,6 +593,22 @@ impl Mint {
         &self,
         melt_request: &MeltRequest<QuoteId>,
     ) -> Result<MeltQuoteBolt11Response<QuoteId>, Error> {
+        // Check max outputs limit (if change outputs are provided)
+        if let Some(outputs) = melt_request.outputs() {
+            let outputs_count = outputs.len();
+            if outputs_count > self.max_outputs {
+                tracing::warn!(
+                    "Melt request exceeds max outputs limit: {} > {}",
+                    outputs_count,
+                    self.max_outputs
+                );
+                return Err(Error::MaxOutputsExceeded {
+                    actual: outputs_count,
+                    max: self.max_outputs,
+                });
+            }
+        }
+
         let verification = self.verify_inputs(melt_request.inputs()).await?;
 
         // Get the quote first for payment_method and to return with PENDING state

+ 4 - 18
crates/cdk/src/mint/swap/mod.rs

@@ -25,10 +25,6 @@ impl Mint {
         swap_request.input_amount()?;
         swap_request.output_amount()?;
 
-        // Verify spending conditions (NUT-10/NUT-11/NUT-14), i.e. P2PK
-        // and HTLC (including SIGALL)
-        swap_request.verify_spending_conditions()?;
-
         let input_proofs = swap_request.inputs();
 
         if input_proofs.is_empty() {
@@ -39,20 +35,6 @@ impl Mint {
             ));
         }
 
-        // Check max inputs limit
-        let inputs_count = input_proofs.len();
-        if inputs_count > self.max_inputs {
-            tracing::warn!(
-                "Swap request exceeds max inputs limit: {} > {}",
-                inputs_count,
-                self.max_inputs
-            );
-            return Err(Error::MaxInputsExceeded {
-                actual: inputs_count,
-                max: self.max_inputs,
-            });
-        }
-
         // Check max outputs limit
         let outputs_count = swap_request.outputs().len();
         if outputs_count > self.max_outputs {
@@ -79,6 +61,10 @@ impl Mint {
             err
         })?;
 
+        // Verify spending conditions (NUT-10/NUT-11/NUT-14), i.e. P2PK
+        // and HTLC (including SIGALL)
+        swap_request.verify_spending_conditions()?;
+
         // Step 1: Initialize the swap saga
         let init_saga = SwapSaga::new(self, self.localstore.clone(), self.pubsub_manager.clone());
 

+ 14 - 0
crates/cdk/src/mint/verification.rs

@@ -192,6 +192,20 @@ impl Mint {
     /// **NOTE: This does not check if inputs have been spent
     #[instrument(skip_all)]
     pub async fn verify_inputs(&self, inputs: &Proofs) -> Result<Verification, Error> {
+        // Check max inputs limit
+        let inputs_count = inputs.len();
+        if inputs_count > self.max_inputs {
+            tracing::warn!(
+                "Melt request exceeds max inputs limit: {} > {}",
+                inputs_count,
+                self.max_inputs
+            );
+            return Err(Error::MaxInputsExceeded {
+                actual: inputs_count,
+                max: self.max_inputs,
+            });
+        }
+
         Mint::check_inputs_unique(inputs)?;
         let unit = self.verify_inputs_keyset(inputs).await?;