diff --git a/.github/workflows/cont_integration.yml b/.github/workflows/cont_integration.yml index 729ab07c..e8c7f8d4 100644 --- a/.github/workflows/cont_integration.yml +++ b/.github/workflows/cont_integration.yml @@ -24,10 +24,11 @@ jobs: include: - rust: stable features: default - clippy: false + clippy: true test: true - rust: 1.45.0 features: default + clippy: true test: true - rust: nightly features: test-md-docs @@ -55,6 +56,7 @@ jobs: profile: minimal toolchain: ${{ matrix.rust }} override: true + components: clippy - name: build uses: actions-rs/cargo@v1 with: diff --git a/src/blockchain/mod.rs b/src/blockchain/mod.rs index 2577864e..5119e514 100644 --- a/src/blockchain/mod.rs +++ b/src/blockchain/mod.rs @@ -221,7 +221,11 @@ pub fn log_progress() -> LogProgress { impl Progress for LogProgress { fn update(&self, progress: f32, message: Option) -> Result<(), Error> { - log::info!("Sync {:.3}%: `{}`", progress, message.unwrap_or("".into())); + log::info!( + "Sync {:.3}%: `{}`", + progress, + message.unwrap_or_else(|| "".into()) + ); Ok(()) } diff --git a/src/database/keyvalue.rs b/src/database/keyvalue.rs index 2e24fa1d..e61ff06e 100644 --- a/src/database/keyvalue.rs +++ b/src/database/keyvalue.rs @@ -314,7 +314,7 @@ impl Database for Tree { let is_internal = serde_json::from_value(val["i"].take())?; Ok(UTXO { - outpoint: outpoint.clone(), + outpoint: *outpoint, txout, is_internal, }) diff --git a/src/database/memory.rs b/src/database/memory.rs index 004ab585..eeacd131 100644 --- a/src/database/memory.rs +++ b/src/database/memory.rs @@ -77,7 +77,7 @@ impl MapKey<'_> { fn serialize_content(&self) -> Vec { match self { - MapKey::Path((_, Some(child))) => u32::from(*child).to_be_bytes().to_vec(), + MapKey::Path((_, Some(child))) => child.to_be_bytes().to_vec(), MapKey::Script(Some(s)) => serialize(*s), MapKey::UTXO(Some(s)) => serialize(*s), MapKey::RawTx(Some(s)) => serialize(*s), @@ -94,8 +94,8 @@ impl MapKey<'_> { } } -fn after(key: &Vec) -> Vec { - let mut key = key.clone(); +fn after(key: &[u8]) -> Vec { + let mut key = key.to_owned(); let mut idx = key.len(); while idx > 0 { if key[idx - 1] == 0xFF { @@ -233,7 +233,7 @@ impl BatchOperations for MemoryDatabase { Some(b) => { let (txout, is_internal) = b.downcast_ref().cloned().unwrap(); Ok(Some(UTXO { - outpoint: outpoint.clone(), + outpoint: *outpoint, txout, is_internal, })) @@ -387,7 +387,7 @@ impl Database for MemoryDatabase { Ok(self.map.get(&key).map(|b| { let (txout, is_internal) = b.downcast_ref().cloned().unwrap(); UTXO { - outpoint: outpoint.clone(), + outpoint: *outpoint, txout, is_internal, } @@ -424,9 +424,9 @@ impl Database for MemoryDatabase { let key = MapKey::LastIndex(script_type).as_map_key(); let value = self .map - .entry(key.clone()) + .entry(key) .and_modify(|x| *x.downcast_mut::().unwrap() += 1) - .or_insert(Box::::new(0)) + .or_insert_with(|| Box::::new(0)) .downcast_mut() .unwrap(); @@ -445,8 +445,8 @@ impl BatchDatabase for MemoryDatabase { for key in batch.deleted_keys { self.map.remove(&key); } - - Ok(self.map.append(&mut batch.map)) + self.map.append(&mut batch.map); + Ok(()) } } diff --git a/src/database/mod.rs b/src/database/mod.rs index 090e1ae4..3e77a07f 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -191,7 +191,7 @@ pub(crate) trait DatabaseUtils: Database { self.get_raw_tx(&outpoint.txid)? .map(|previous_tx| { if outpoint.vout as usize >= previous_tx.output.len() { - Err(Error::InvalidOutpoint(outpoint.clone())) + Err(Error::InvalidOutpoint(*outpoint)) } else { Ok(previous_tx.output[outpoint.vout as usize].clone()) } diff --git a/src/descriptor/error.rs b/src/descriptor/error.rs index 2bd0629f..5730fc97 100644 --- a/src/descriptor/error.rs +++ b/src/descriptor/error.rs @@ -57,7 +57,7 @@ impl From for Error { match key_error { crate::keys::KeyError::Miniscript(inner) => Error::Miniscript(inner), crate::keys::KeyError::BIP32(inner) => Error::BIP32(inner), - e @ _ => Error::Key(e), + e => Error::Key(e), } } } diff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs index ba4c3410..8632419d 100644 --- a/src/descriptor/mod.rs +++ b/src/descriptor/mod.rs @@ -78,8 +78,8 @@ impl ToWalletDescriptor for &str { self, network: Network, ) -> Result<(ExtendedDescriptor, KeyMap), KeyError> { - let descriptor = if self.contains("#") { - let parts: Vec<&str> = self.splitn(2, "#").collect(); + let descriptor = if self.contains('#') { + let parts: Vec<&str> = self.splitn(2, '#').collect(); if !get_checksum(parts[0]) .ok() .map(|computed| computed == parts[1]) @@ -171,7 +171,7 @@ impl ToWalletDescriptor for (ExtendedDescriptor, KeyMap, ValidNetworks) { DescriptorPublicKey::XPub(xpub) } - other @ _ => other.clone(), + other => other.clone(), }; Ok(pk) @@ -201,19 +201,19 @@ pub(crate) trait XKeyUtils { impl XKeyUtils for DescriptorXKey { fn full_path(&self, append: &[ChildNumber]) -> DerivationPath { - let full_path = match &self.source { - &Some((_, ref path)) => path + let full_path = match self.source { + Some((_, ref path)) => path .into_iter() .chain(self.derivation_path.into_iter()) .cloned() .collect(), - &None => self.derivation_path.clone(), + None => self.derivation_path.clone(), }; if self.is_wildcard { full_path .into_iter() - .chain(append.into_iter()) + .chain(append.iter()) .cloned() .collect() } else { @@ -222,9 +222,9 @@ impl XKeyUtils for DescriptorXKey { } fn root_fingerprint(&self) -> Fingerprint { - match &self.source { - &Some((fingerprint, _)) => fingerprint.clone(), - &None => self.xkey.xkey_fingerprint(), + match self.source { + Some((fingerprint, _)) => fingerprint, + None => self.xkey.xkey_fingerprint(), } } } diff --git a/src/descriptor/policy.rs b/src/descriptor/policy.rs index ec123221..4df6248a 100644 --- a/src/descriptor/policy.rs +++ b/src/descriptor/policy.rs @@ -43,7 +43,7 @@ //! # Ok::<(), bdk::Error>(()) //! ``` -use std::cmp::max; +use std::cmp::{max, Ordering}; use std::collections::{BTreeMap, HashSet, VecDeque}; use std::fmt; use std::sync::Arc; @@ -155,7 +155,7 @@ impl SatisfiableItem { } } -fn combinations(vec: &Vec, size: usize) -> Vec> { +fn combinations(vec: &[usize], size: usize) -> Vec> { assert!(vec.len() >= size); let mut answer = Vec::new(); @@ -344,8 +344,8 @@ impl Satisfaction { .map(|i| { conditions .get(i) - .and_then(|set| Some(set.clone().into_iter().collect())) - .unwrap_or(vec![]) + .map(|set| set.clone().into_iter().collect()) + .unwrap_or_default() }) .collect()) .into_iter() @@ -525,7 +525,7 @@ impl Policy { } fn make_multisig( - keys: &Vec, + keys: &[DescriptorPublicKey], signers: Arc>, threshold: usize, ) -> Result, PolicyError> { @@ -542,7 +542,7 @@ impl Policy { conditions: Default::default(), }; for (index, key) in keys.iter().enumerate() { - if let Some(_) = signers.find(signer_id(key)) { + if signers.find(signer_id(key)).is_some() { contribution.add( &Satisfaction::Complete { condition: Default::default(), @@ -582,7 +582,7 @@ impl Policy { // if items.len() == threshold, selected can be omitted and we take all of them by default let default = match &self.item { SatisfiableItem::Thresh { items, threshold } if items.len() == *threshold => { - (0..*threshold).into_iter().collect() + (0..*threshold).collect() } _ => vec![], }; @@ -608,10 +608,14 @@ impl Policy { // if we have something, make sure we have enough items. note that the user can set // an empty value for this step in case of n-of-n, because `selected` is set to all // the elements above - if selected.len() < *threshold { - return Err(PolicyError::NotEnoughItemsSelected(self.id.clone())); - } else if selected.len() > *threshold { - return Err(PolicyError::TooManyItemsSelected(self.id.clone())); + match selected.len().cmp(threshold) { + Ordering::Less => { + return Err(PolicyError::NotEnoughItemsSelected(self.id.clone())) + } + Ordering::Greater => { + return Err(PolicyError::TooManyItemsSelected(self.id.clone())) + } + Ordering::Equal => (), } // check the selected items, see if there are conflicting requirements @@ -676,7 +680,7 @@ fn signature_key( ) -> Policy { let mut policy: Policy = SatisfiableItem::Signature(PKOrF::from_key_hash(*key_hash)).into(); - if let Some(_) = signers.find(SignerId::PkHash(*key_hash)) { + if signers.find(SignerId::PkHash(*key_hash)).is_some() { policy.contribution = Satisfaction::Complete { condition: Default::default(), } diff --git a/src/error.rs b/src/error.rs index 40f5820b..6628cc0d 100644 --- a/src/error.rs +++ b/src/error.rs @@ -122,7 +122,7 @@ impl From for Error { crate::keys::KeyError::Miniscript(inner) => Error::Miniscript(inner), crate::keys::KeyError::BIP32(inner) => Error::BIP32(inner), crate::keys::KeyError::InvalidChecksum => Error::ChecksumMismatch, - e @ _ => Error::Key(e), + e => Error::Key(e), } } } diff --git a/src/keys/mod.rs b/src/keys/mod.rs index 70e14829..9aa17d33 100644 --- a/src/keys/mod.rs +++ b/src/keys/mod.rs @@ -562,12 +562,12 @@ pub mod test { use super::*; - const test_entropy: [u8; 32] = [0xAA; 32]; + const TEST_ENTROPY: [u8; 32] = [0xAA; 32]; #[test] fn test_keys_generate_xprv() { let generated_xprv: GeneratedKey<_, miniscript::Segwitv0> = - bip32::ExtendedPrivKey::generate_with_entropy((), test_entropy).unwrap(); + bip32::ExtendedPrivKey::generate_with_entropy((), TEST_ENTROPY).unwrap(); assert_eq!(generated_xprv.valid_networks, any_network()); assert_eq!(generated_xprv.to_string(), "xprv9s21ZrQH143K4Xr1cJyqTvuL2FWR8eicgY9boWqMBv8MDVUZ65AXHnzBrK1nyomu6wdcabRgmGTaAKawvhAno1V5FowGpTLVx3jxzE5uk3Q"); diff --git a/src/lib.rs b/src/lib.rs index 8df950dc..73ebb40a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,7 +42,7 @@ extern crate async_trait; #[macro_use] extern crate bdk_macros; -#[cfg(any(test, feature = "compact_filters"))] +#[cfg(feature = "compact_filters")] #[macro_use] extern crate lazy_static; diff --git a/src/types.rs b/src/types.rs index 14a5b8de..e4e33d10 100644 --- a/src/types.rs +++ b/src/types.rs @@ -39,8 +39,8 @@ pub enum ScriptType { impl ScriptType { pub fn as_byte(&self) -> u8 { match self { - ScriptType::External => 'e' as u8, - ScriptType::Internal => 'i' as u8, + ScriptType::External => b'e', + ScriptType::Internal => b'i', } } diff --git a/src/wallet/mod.rs b/src/wallet/mod.rs index 9991faba..67a8570a 100644 --- a/src/wallet/mod.rs +++ b/src/wallet/mod.rs @@ -605,9 +605,7 @@ where available_utxos, use_all_utxos, new_feerate, - fee_difference - .checked_sub(removed_change_output.value) - .unwrap_or(0), + fee_difference.saturating_sub(removed_change_output.value), input_witness_weight, 0.0, )?; @@ -620,7 +618,7 @@ where // copy the n_sequence from the inputs that were already in the transaction txin.iter_mut() .for_each(|i| i.sequence = tx.input[0].sequence); - tx.input.extend_from_slice(&mut txin); + tx.input.extend_from_slice(&txin); details.sent += selected_amount; selected_amount @@ -666,7 +664,7 @@ where .iter() .map(|txin| { Ok(( - txin.previous_output.clone(), + txin.previous_output, self.database .borrow() .get_previous_output(&txin.previous_output)?, @@ -765,7 +763,7 @@ where .database .borrow() .get_tx(&input.previous_output.txid, false)? - .and_then(|tx| Some(tx.height.unwrap_or(std::u32::MAX))); + .map(|tx| tx.height.unwrap_or(std::u32::MAX)); let current_height = assume_height.or(self.current_height); debug!( @@ -833,15 +831,13 @@ where &self, script_type: ScriptType, ) -> (&ExtendedDescriptor, ScriptType) { - let desc = match script_type { + match script_type { ScriptType::Internal if self.change_descriptor.is_some() => ( self.change_descriptor.as_ref().unwrap(), ScriptType::Internal, ), _ => (&self.descriptor, ScriptType::External), - }; - - desc + } } fn get_descriptor_for_txout(&self, txout: &TxOut) -> Result, Error> { @@ -941,7 +937,7 @@ where ) -> Result<(Vec, bool), Error> { let unspendable_set = match unspendable { None => HashSet::new(), - Some(vec) => vec.into_iter().collect(), + Some(vec) => vec.iter().collect(), }; match utxo { @@ -1131,10 +1127,7 @@ where if self .database .borrow() - .get_script_pubkey_from_path( - ScriptType::Internal, - max_address.checked_sub(1).unwrap_or(0), - )? + .get_script_pubkey_from_path(ScriptType::Internal, max_address.saturating_sub(1))? .is_none() { run_setup = true; diff --git a/src/wallet/signer.rs b/src/wallet/signer.rs index 0618d763..989d4d9d 100644 --- a/src/wallet/signer.rs +++ b/src/wallet/signer.rs @@ -205,7 +205,7 @@ impl Signer for DescriptorXKey { .hd_keypaths .iter() .filter_map(|(pk, &(fingerprint, ref path))| { - if self.matches(fingerprint.clone(), &path).is_some() { + if self.matches(fingerprint, &path).is_some() { Some((pk, path)) } else { None @@ -284,7 +284,7 @@ impl Signer for PrivateKey { } fn descriptor_secret_key(&self) -> Option { - Some(DescriptorSecretKey::PrivKey(self.clone())) + Some(DescriptorSecretKey::PrivKey(*self)) } } @@ -407,7 +407,7 @@ impl SignersContainer { Included(&(id, SignerOrdering(usize::MAX)).into()), )) .map(|(_, v)| v) - .nth(0) + .next() } } @@ -431,9 +431,9 @@ impl ComputeSighash for Legacy { let tx_input = &psbt.global.unsigned_tx.input[input_index]; let sighash = psbt_input.sighash_type.ok_or(SignerError::MissingSighash)?; - let script = match &psbt_input.redeem_script { - &Some(ref redeem_script) => redeem_script.clone(), - &None => { + let script = match psbt_input.redeem_script { + Some(ref redeem_script) => redeem_script.clone(), + None => { let non_witness_utxo = psbt_input .non_witness_utxo .as_ref() @@ -485,9 +485,9 @@ impl ComputeSighash for Segwitv0 { .ok_or(SignerError::MissingNonWitnessUtxo)?; let value = witness_utxo.value; - let script = match &psbt_input.witness_script { - &Some(ref witness_script) => witness_script.clone(), - &None => { + let script = match psbt_input.witness_script { + Some(ref witness_script) => witness_script.clone(), + None => { if witness_utxo.script_pubkey.is_v0_p2wpkh() { p2wpkh_script_code(&witness_utxo.script_pubkey) } else if psbt_input diff --git a/testutils/src/lib.rs b/testutils/src/lib.rs index d467a0b0..496f1b84 100644 --- a/testutils/src/lib.rs +++ b/testutils/src/lib.rs @@ -24,8 +24,6 @@ #[macro_use] extern crate serde_json; -#[macro_use] -extern crate serial_test; pub use serial_test::serial;