diff --git a/silentpayments/src/receive/error.rs b/silentpayments/src/receive/error.rs index 738011b..3c09dc9 100644 --- a/silentpayments/src/receive/error.rs +++ b/silentpayments/src/receive/error.rs @@ -8,6 +8,8 @@ pub enum SpReceiveError { SliceError(bitcoin::key::FromSliceError), /// Cannot derive silent payment output without input prevout outpoints NoOutpoints(crate::LexMinError), + /// The number of matched tweaks exceeded the BIP-352 per-group recipient limit + ScanLimitExceeded(u32), } impl From for SpReceiveError { @@ -41,6 +43,9 @@ impl std::fmt::Display for SpReceiveError { SpReceiveError::Secp256k1Error(e) => write!(f, "Silent payment receive error: {e}"), SpReceiveError::SliceError(e) => write!(f, "Silent payment receive error: {e}"), Self::NoOutpoints(e) => write!(f, "Silent payment sending error: {e}"), + SpReceiveError::ScanLimitExceeded(k) => { + write!(f, "Silent payment receive error: Scan limit exceeded ({k})") + } } } } diff --git a/silentpayments/src/receive/mod.rs b/silentpayments/src/receive/mod.rs index eb03d89..59bd51f 100644 --- a/silentpayments/src/receive/mod.rs +++ b/silentpayments/src/receive/mod.rs @@ -93,6 +93,9 @@ pub fn extract_pubkey(txin: TxIn, script_pubkey: &ScriptBuf) -> Option<(SpInputs }) } +/// BIP-352 per-group recipient limit. +pub const K_MAX: u32 = 2323; + pub fn scan_txouts( spend_pk: PublicKey, label_lookup: &BTreeMap, @@ -123,6 +126,9 @@ pub fn scan_txouts( ) { spouts_found.push(spout); matched_tweaks += 1; + if matched_tweaks > K_MAX { + return Err(SpReceiveError::ScanLimitExceeded(K_MAX)); + } } Ok(spouts_found) diff --git a/silentpayments/tests/functional_tests/bip352_vectors/receive.rs b/silentpayments/tests/functional_tests/bip352_vectors/receive.rs index d819473..f66d4c2 100644 --- a/silentpayments/tests/functional_tests/bip352_vectors/receive.rs +++ b/silentpayments/tests/functional_tests/bip352_vectors/receive.rs @@ -274,7 +274,6 @@ fn input_keys_intermediate_sum_is_zero_but_final_sum_is_non_zero() { } #[test] -#[ignore = "limit k-max not implemented"] fn maximum_per_group_recipient_limit_k_max_is_exceeded() { check_cases(27); }