diff --git a/dlc-messages/src/channel.rs b/dlc-messages/src/channel.rs index 2798f63b..4a664dc4 100644 --- a/dlc-messages/src/channel.rs +++ b/dlc-messages/src/channel.rs @@ -124,7 +124,7 @@ impl OfferChannel { && self.cet_nsequence >= min_cet_nsequence && self.cet_nsequence <= max_cet_nsequence; if !valid_dates { - return Err(Error::InvalidArgument); + return Err(Error::InvalidArgument("Invalid dates".to_string())); } match &self.contract_info { diff --git a/dlc-messages/src/lib.rs b/dlc-messages/src/lib.rs index f6b76826..3ca8d7a0 100644 --- a/dlc-messages/src/lib.rs +++ b/dlc-messages/src/lib.rs @@ -383,7 +383,7 @@ impl OfferDlc { ContractInfo::SingleContractInfo(s) => s.contract_info.oracle_info.validate(secp)?, ContractInfo::DisjointContractInfo(d) => { if d.contract_infos.len() < 2 { - return Err(Error::InvalidArgument); + return Err(Error::InvalidArgument("Contract infos length smaller than 2".to_string())); } for c in &d.contract_infos { @@ -397,7 +397,7 @@ impl OfferDlc { && closest_maturity_date + min_timeout_interval <= self.refund_locktime && self.refund_locktime <= closest_maturity_date + max_timeout_interval; if !valid_dates { - return Err(Error::InvalidArgument); + return Err(Error::InvalidArgument("Invalid dates".to_string())); } Ok(()) diff --git a/dlc-messages/src/oracle_msgs.rs b/dlc-messages/src/oracle_msgs.rs index aa779a58..7a844b07 100644 --- a/dlc-messages/src/oracle_msgs.rs +++ b/dlc-messages/src/oracle_msgs.rs @@ -224,7 +224,7 @@ impl OracleEvent { if expected_nb_nonces == self.oracle_nonces.len() { Ok(()) } else { - Err(Error::InvalidArgument) + Err(Error::InvalidArgument("Expected nb nonces is not equal to oracle nonecs length".to_string())) } } } diff --git a/dlc-trie/src/multi_oracle_trie.rs b/dlc-trie/src/multi_oracle_trie.rs index 20f979a2..c2b397d4 100644 --- a/dlc-trie/src/multi_oracle_trie.rs +++ b/dlc-trie/src/multi_oracle_trie.rs @@ -168,7 +168,7 @@ impl MultiOracleTrie { /// Creates a new MultiOracleTrie pub fn new(oracle_numeric_infos: &OracleNumericInfo, threshold: usize) -> Result { if oracle_numeric_infos.nb_digits.is_empty() { - return Err(Error::InvalidArgument); + return Err(Error::InvalidArgument("Oracle numeric infos nb digits is empty".to_string())); } let digit_trie = DigitTrie::new(oracle_numeric_infos.base); let extra_cover_trie = if oracle_numeric_infos.has_diff_nb_digits() { diff --git a/dlc-trie/src/multi_oracle_trie_with_diff.rs b/dlc-trie/src/multi_oracle_trie_with_diff.rs index 67c87c76..505b13d7 100644 --- a/dlc-trie/src/multi_oracle_trie_with_diff.rs +++ b/dlc-trie/src/multi_oracle_trie_with_diff.rs @@ -33,7 +33,7 @@ impl MultiOracleTrieWithDiff { let is_valid = nb_oracles >= 1 && threshold <= nb_oracles && min_support_exp < max_error_exp; if !is_valid { - return Err(Error::InvalidArgument); + return Err(Error::InvalidArgument("Invalid nb oracles".to_string())); } let multi_trie = MultiTrie::new( oracle_numeric_infos, diff --git a/dlc-trie/src/utils.rs b/dlc-trie/src/utils.rs index e559fcff..559ed655 100644 --- a/dlc-trie/src/utils.rs +++ b/dlc-trie/src/utils.rs @@ -18,7 +18,7 @@ pub(crate) fn get_adaptor_point_for_indexed_paths( debug_assert!(indexes.len() == paths.len()); debug_assert!(precomputed_points.len() >= indexes.len()); if indexes.is_empty() { - return Err(super::Error::InvalidArgument); + return Err(super::Error::InvalidArgument("Indexes is empty".to_string())); } let mut keys = Vec::new(); diff --git a/dlc/src/channel/mod.rs b/dlc/src/channel/mod.rs index d97d2580..124df045 100644 --- a/dlc/src/channel/mod.rs +++ b/dlc/src/channel/mod.rs @@ -302,7 +302,7 @@ pub fn create_renewal_channel_transactions( }; if fund_output.value <= extra_fee + super::DUST_LIMIT { - return Err(Error::InvalidArgument); + return Err(Error::InvalidArgument(format!("Fund output: {} smaller or equal to extra fee: {} + dust limit: {}", fund_output.value, extra_fee, super::DUST_LIMIT))); } let outpoint = OutPoint { @@ -392,7 +392,7 @@ pub fn sign_cet( descriptor .satisfy(&mut cet.input[0], sigs) - .map_err(|_| Error::InvalidArgument)?; + .map_err(|e| Error::InvalidArgument(format!("{e:#}")))?; Ok(()) } @@ -422,7 +422,7 @@ pub fn satisfy_buffer_descriptor( descriptor .satisfy(&mut tx.input[0], sigs) - .map_err(|_| Error::InvalidArgument)?; + .map_err(|e| Error::InvalidArgument(format!("{e:#}")))?; Ok(()) } @@ -498,7 +498,7 @@ pub fn create_and_sign_punish_buffer_transaction( descriptor .satisfy(&mut tx.input[0], sigs) - .map_err(|_| Error::InvalidArgument)?; + .map_err(|e| Error::InvalidArgument(format!("{e:#}")))?; Ok(tx) } @@ -578,7 +578,7 @@ pub fn create_and_sign_punish_settle_transaction( descriptor .satisfy(&mut tx.input[0], sigs) - .map_err(|_| Error::InvalidArgument)?; + .map_err(|e| Error::InvalidArgument(format!("{e:#}")))?; Ok(tx) } diff --git a/dlc/src/channel/sub_channel.rs b/dlc/src/channel/sub_channel.rs index bb0d59ab..330338b2 100644 --- a/dlc/src/channel/sub_channel.rs +++ b/dlc/src/channel/sub_channel.rs @@ -87,14 +87,14 @@ pub fn create_split_tx( let dlc_output_value = dlc_collateral .checked_add(dlc_fee) - .ok_or(Error::InvalidArgument)?; + .ok_or(Error::InvalidArgument("Failed to checked add dlc fee to dlc collateral".to_string()))?; if dlc_output_value > channel_value .checked_add(crate::DUST_LIMIT) - .ok_or(Error::InvalidArgument)? + .ok_or(Error::InvalidArgument("Failed to checked add dust limit to channel value".to_string()))? { - return Err(Error::InvalidArgument); + return Err(Error::InvalidArgument(format!("Dlc output value greater than channel value: {} + dust limit: {}", channel_value, crate::DUST_LIMIT))); } let ln_output_value = channel_value @@ -238,7 +238,7 @@ pub fn create_and_sign_punish_split_transaction( descriptor .satisfy(&mut tx.input[i], sigs.clone()) - .map_err(|_| Error::InvalidArgument)?; + .map_err(|e| Error::InvalidArgument(format!("{e:#}")))?; } Ok(tx) diff --git a/dlc/src/lib.rs b/dlc/src/lib.rs index f9e0fd3a..3c7800d0 100644 --- a/dlc/src/lib.rs +++ b/dlc/src/lib.rs @@ -69,7 +69,7 @@ pub const P2WPKH_WITNESS_SIZE: usize = 107; macro_rules! checked_add { ($a: expr, $b: expr) => { - $a.checked_add($b).ok_or(Error::InvalidArgument) + $a.checked_add($b).ok_or(Error::InvalidArgument("Failed to checked add".to_string())) }; ($a: expr, $b: expr, $c: expr) => { checked_add!(checked_add!($a, $b)?, $c) @@ -182,7 +182,7 @@ pub enum Error { /// An error while computing a signature hash Sighash(bitcoin::util::sighash::Error), /// An invalid argument was provided - InvalidArgument, + InvalidArgument(String), /// An error occurred in miniscript Miniscript(miniscript::Error), } @@ -213,9 +213,9 @@ impl From for Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { + match self { Error::Secp256k1(_) => write!(f, "Secp256k1 error"), - Error::InvalidArgument => write!(f, "Invalid argument"), + Error::InvalidArgument(message) => write!(f, "Invalid argument {message}"), Error::Sighash(_) => write!(f, "Error while computing sighash"), Error::Miniscript(_) => write!(f, "Error within miniscript"), } @@ -227,7 +227,7 @@ impl std::error::Error for Error { match self { Error::Secp256k1(e) => Some(e), Error::Sighash(e) => Some(e), - Error::InvalidArgument => None, + Error::InvalidArgument(_) => None, Error::Miniscript(e) => Some(e), } } @@ -278,7 +278,7 @@ impl PartyParams { let script_weight = util::redeem_script_to_script_sig(&w.redeem_script) .len() .checked_mul(4) - .ok_or(Error::InvalidArgument)?; + .ok_or(Error::InvalidArgument("Failed to multiple 4 to script weight".to_string()))?; inputs_weight = checked_add!( inputs_weight, TX_INPUT_BASE_WEIGHT, @@ -290,7 +290,7 @@ impl PartyParams { // Value size + script length var_int + ouput script pubkey size let change_size = self.change_script_pubkey.len(); // Change size is scaled by 4 from vBytes to weight units - let change_weight = change_size.checked_mul(4).ok_or(Error::InvalidArgument)?; + let change_weight = change_size.checked_mul(4).ok_or(Error::InvalidArgument("failed to multiply 4 to change size".to_string()))?; // Base weight (nLocktime, nVersion, ...) is distributed among parties // independently of inputs contributed @@ -313,13 +313,13 @@ impl PartyParams { .payout_script_pubkey .len() .checked_mul(4) - .ok_or(Error::InvalidArgument)?; + .ok_or(Error::InvalidArgument("failed to multiply 4 to payout script pubkey length".to_string()))?; let total_cet_weight = checked_add!(this_party_cet_base_weight, output_spk_weight)?; let cet_or_refund_fee = util::weight_to_fee(total_cet_weight, fee_rate_per_vb)?; let required_input_funds = checked_add!(self.collateral, fund_fee, cet_or_refund_fee, extra_fee)?; if self.input_amount < required_input_funds { - return Err(Error::InvalidArgument); + return Err(Error::InvalidArgument(format!("input amount: {} smaller than required input funds: {} (collateral: {}, fund_fee: {}, cet_or_refund_fee: {}, extra_fee: {})", self.input_amount, required_input_funds, self.collateral, fund_fee, cet_or_refund_fee, extra_fee))); } let change_output = TxOut { @@ -476,8 +476,13 @@ pub(crate) fn create_cets_and_refund_tx( } }); + let total_in_offer = payouts.iter().map(|p| checked_add!(p.offer, p.accept).unwrap_or(0)).collect::>().iter().sum::(); + dbg!(total_in_offer); + if !has_proper_outcomes { - return Err(Error::InvalidArgument); + dbg!(has_proper_outcomes); + dbg!(total_collateral); + return Err(Error::InvalidArgument("payouts doe not have proper outcomes".to_string())); } let cet_input = TxIn { @@ -667,7 +672,7 @@ fn get_oracle_sig_point( msgs: &[Message], ) -> Result { if oracle_info.nonces.len() < msgs.len() { - return Err(Error::InvalidArgument); + return Err(Error::InvalidArgument("length of oracle info nonces is smaller than msgs length".to_string())); } let sig_points: Vec = oracle_info @@ -690,7 +695,7 @@ pub fn get_adaptor_point_from_oracle_info( msgs: &[Vec], ) -> Result { if oracle_infos.is_empty() || msgs.is_empty() { - return Err(Error::InvalidArgument); + return Err(Error::InvalidArgument("empty oracle infos or msgs".to_string())); } let mut oracle_sigpoints = Vec::with_capacity(msgs[0].len()); @@ -776,7 +781,7 @@ pub fn create_cet_adaptor_sigs_from_oracle_info( msgs: &[Vec>], ) -> Result, Error> { if msgs.len() != cets.len() { - return Err(Error::InvalidArgument); + return Err(Error::InvalidArgument("length of msgs is not equal to length of cets".to_string())); } cets.iter() diff --git a/dlc/src/util.rs b/dlc/src/util.rs index 68948f05..bb5d0354 100644 --- a/dlc/src/util.rs +++ b/dlc/src/util.rs @@ -102,7 +102,7 @@ pub fn weight_to_fee(weight: usize, fee_rate: u64) -> Result { Ok(u64::max( (f64::ceil((weight as f64) / 4.0) as u64) .checked_mul(fee_rate) - .ok_or(Error::InvalidArgument)?, + .ok_or(Error::InvalidArgument(format!("Failed to multiply fee rate: {} to weight", fee_rate )))?, MIN_FEE, )) } @@ -254,7 +254,7 @@ pub(crate) fn compute_var_int_prefix_size(len: usize) -> usize { /// Validate that the fee rate is not too high pub fn validate_fee_rate(fee_rate_per_vb: u64) -> Result<(), Error> { if fee_rate_per_vb > 25 * 250 { - return Err(Error::InvalidArgument); + return Err(Error::InvalidArgument(format!("Fee rate: {} greater than 25 * 250", fee_rate_per_vb))); } Ok(())