diff --git a/clippy-config b/clippy-config index 543c3cec..691c35f2 100644 --- a/clippy-config +++ b/clippy-config @@ -29,7 +29,6 @@ -D clippy::deref_by_slicing -D clippy::empty_structs_with_brackets -D clippy::get_unwrap --D clippy::if_then_some_else_none -D clippy::rest_pat_in_fully_bound_structs -D clippy::semicolon_inside_block -D clippy::tests_outside_test_module diff --git a/coins/monero/src/ringct/clsag/mod.rs b/coins/monero/src/ringct/clsag/mod.rs index 746cb76c..ef31cbe4 100644 --- a/coins/monero/src/ringct/clsag/mod.rs +++ b/coins/monero/src/ringct/clsag/mod.rs @@ -249,7 +249,7 @@ impl Clsag { let mask = random_scalar(rng); sum_pseudo_outs += mask; mask - } + }; let mut nonce = Zeroizing::new(random_scalar(rng)); let (mut clsag, pseudo_out, p, c) = Self::sign_core( diff --git a/coins/monero/src/rpc/mod.rs b/coins/monero/src/rpc/mod.rs index c2c4e43f..69bc8645 100644 --- a/coins/monero/src/rpc/mod.rs +++ b/coins/monero/src/rpc/mod.rs @@ -102,7 +102,7 @@ fn read_epee_vi(reader: &mut R) -> io::Result { } #[async_trait] -pub trait RpcConnection: Clone + Debug { +pub trait RpcConnection: Send + Sync + Clone + Debug { /// Perform a POST request to the specified route with the specified body. /// /// The implementor is left to handle anything such as authentication. @@ -117,7 +117,7 @@ impl Rpc { /// /// This is NOT a JSON-RPC call. They use a route of "json_rpc" and are available via /// `json_rpc_call`. - pub async fn rpc_call( + pub async fn rpc_call( &self, route: &str, params: Option, diff --git a/coins/monero/src/transaction.rs b/coins/monero/src/transaction.rs index a60a40ba..0273bb8f 100644 --- a/coins/monero/src/transaction.rs +++ b/coins/monero/src/transaction.rs @@ -345,14 +345,15 @@ impl Transaction { hashes.extend(hash(&buf)); buf.clear(); - match self.rct_signatures.prunable { - RctPrunable::Null => buf.resize(32, 0), - _ => { + hashes.extend(&match self.rct_signatures.prunable { + RctPrunable::Null => [0; 32], + RctPrunable::MlsagBorromean { .. } | + RctPrunable::MlsagBulletproofs { .. } | + RctPrunable::Clsag { .. } => { self.rct_signatures.prunable.write(&mut buf, self.rct_signatures.rct_type()).unwrap(); - buf = hash(&buf).to_vec(); + hash(&buf) } - } - hashes.extend(&buf); + }); hash(&hashes) } diff --git a/coins/monero/src/wallet/decoys.rs b/coins/monero/src/wallet/decoys.rs index 1f276115..91c541ae 100644 --- a/coins/monero/src/wallet/decoys.rs +++ b/coins/monero/src/wallet/decoys.rs @@ -35,8 +35,8 @@ fn DISTRIBUTION() -> &'static Mutex> { DISTRIBUTION_CELL.get_or_init(|| Mutex::new(Vec::with_capacity(3_000_000))) } -#[allow(clippy::too_many_arguments)] -async fn select_n<'a, R: RngCore + CryptoRng, RPC: RpcConnection>( +#[allow(clippy::too_many_arguments, clippy::as_conversions)] +async fn select_n<'a, R: Send + RngCore + CryptoRng, RPC: RpcConnection>( rng: &mut R, rpc: &Rpc, distribution: &[u64], @@ -75,11 +75,9 @@ async fn select_n<'a, R: RngCore + CryptoRng, RPC: RpcConnection>( age -= TIP_APPLICATION; } else { // f64 does not have try_from available, which is why these are written with `as` - #[allow(clippy::as_conversions)] age = (rng.next_u64() % u64::try_from(RECENT_WINDOW * BLOCK_TIME).unwrap()) as f64; } - #[allow(clippy::as_conversions)] let o = (age * per_second) as u64; if o < high { let i = distribution.partition_point(|s| *s < (high - 1 - o)); @@ -149,7 +147,8 @@ impl Decoys { } /// Select decoys using the same distribution as Monero. - pub async fn select( + #[allow(clippy::as_conversions)] + pub async fn select( rng: &mut R, rpc: &Rpc, ring_len: usize, @@ -183,7 +182,6 @@ impl Decoys { let per_second = { let blocks = distribution.len().min(BLOCKS_PER_YEAR); let outputs = high - distribution[distribution.len().saturating_sub(blocks + 1)]; - #[allow(clippy::as_conversions)] (outputs as f64) / ((blocks * BLOCK_TIME) as f64) }; @@ -234,6 +232,7 @@ impl Decoys { let target_median = high * 3 / 5; while ring[ring_len / 2].0 < target_median { // If it's not, update the bottom half with new values to ensure the median only moves up + #[allow(clippy::needless_collect)] // Needed for ownership reasons for removed in ring.drain(0 .. (ring_len / 2)).collect::>() { // If we removed the real spend, add it back if removed.0 == o.0 { diff --git a/coins/monero/src/wallet/extra.rs b/coins/monero/src/wallet/extra.rs index 8df8de34..e0704ece 100644 --- a/coins/monero/src/wallet/extra.rs +++ b/coins/monero/src/wallet/extra.rs @@ -133,7 +133,7 @@ impl Extra { ExtraField::PublicKeys(these_additional) => { additional = additional.or(Some(these_additional)); } - _ => (), + ExtraField::Nonce(_) | ExtraField::MergeMining(..) => (), } } // Don't return any keys if this was non-standard and didn't include the primary key diff --git a/coins/monero/src/wallet/scan.rs b/coins/monero/src/wallet/scan.rs index 62782fee..7409f5db 100644 --- a/coins/monero/src/wallet/scan.rs +++ b/coins/monero/src/wallet/scan.rs @@ -115,6 +115,7 @@ impl Metadata { } pub fn read(r: &mut R) -> io::Result { + #[allow(clippy::if_then_some_else_none)] // The Result usage makes this invalid let subaddress = if read_byte(r)? == 1 { Some( SubaddressIndex::new(read_u32(r)?, read_u32(r)?) @@ -323,7 +324,7 @@ impl Scanner { for key in [Some(Some(&tx_key)), additional.as_ref().map(|additional| additional.get(o))] { let Some(Some(key)) = key else { - if let Some(None) = key { + if key == Some(None) { // This is non-standard. There were additional keys, yet not one for this output // https://github.com/monero-project/monero/ // blob/04a1e2875d6e35e27bb21497988a6c822d319c28/ @@ -451,7 +452,7 @@ impl Scanner { }; let mut res = vec![]; - for tx in txs.drain(..) { + for tx in txs { if let Some(timelock) = map(self.scan_transaction(&tx), index) { res.push(timelock); } diff --git a/coins/monero/src/wallet/send/mod.rs b/coins/monero/src/wallet/send/mod.rs index ea476fa8..9bdb13e2 100644 --- a/coins/monero/src/wallet/send/mod.rs +++ b/coins/monero/src/wallet/send/mod.rs @@ -153,7 +153,7 @@ pub enum TransactionError { FrostError(FrostError), } -async fn prepare_inputs( +async fn prepare_inputs( rng: &mut R, rpc: &Rpc, ring_len: usize, @@ -665,7 +665,7 @@ impl SignableTransaction { } /// Sign this transaction. - pub async fn sign( + pub async fn sign( mut self, rng: &mut R, rpc: &Rpc, diff --git a/coins/monero/src/wallet/send/multisig.rs b/coins/monero/src/wallet/send/multisig.rs index d5ed4ad7..d7638053 100644 --- a/coins/monero/src/wallet/send/multisig.rs +++ b/coins/monero/src/wallet/send/multisig.rs @@ -367,12 +367,13 @@ impl SignMachine for TransactionSignMachine { while !sorted.is_empty() { let value = sorted.remove(0); - let mut mask = random_scalar(&mut rng); - if sorted.is_empty() { - mask = output_masks - sum_pseudo_outs; + let mask = if sorted.is_empty() { + output_masks - sum_pseudo_outs } else { + let mask = random_scalar(&mut rng); sum_pseudo_outs += mask; - } + mask + }; tx.prefix.inputs.push(Input::ToKey { amount: None, @@ -432,7 +433,9 @@ impl SignatureMachine for TransactionSignatureMachine { pseudo_outs.push(pseudo_out); } } - _ => unreachable!("attempted to sign a multisig TX which wasn't CLSAG"), + RctPrunable::MlsagBorromean { .. } | RctPrunable::MlsagBulletproofs { .. } => { + unreachable!("attempted to sign a multisig TX which wasn't CLSAG") + } } Ok(tx) } diff --git a/coins/monero/tests/add_data.rs b/coins/monero/tests/add_data.rs index 9f53b72d..ab45177b 100644 --- a/coins/monero/tests/add_data.rs +++ b/coins/monero/tests/add_data.rs @@ -12,8 +12,7 @@ test!( let arbitrary_data = vec![b'\0'; MAX_ARBITRARY_DATA_SIZE - 1]; // make sure we can add to tx - let result = builder.add_data(arbitrary_data.clone()); - assert!(result.is_ok()); + builder.add_data(arbitrary_data.clone()).unwrap(); builder.add_payment(addr, 5); (builder.build().unwrap(), (arbitrary_data,)) @@ -37,8 +36,7 @@ test!( // Add data multiple times for data in &data { - let result = builder.add_data(data.clone()); - assert!(result.is_ok()); + builder.add_data(data.clone()).unwrap(); } builder.add_payment(addr, 5); @@ -65,7 +63,7 @@ test!( // Reduce data size and retry. The data will now be 255 bytes long (including the added // marker), exactly data.pop(); - assert!(builder.add_data(data.clone()).is_ok()); + builder.add_data(data.clone()).unwrap(); builder.add_payment(addr, 5); (builder.build().unwrap(), data) diff --git a/coins/monero/tests/runner.rs b/coins/monero/tests/runner.rs index 8a480563..a5032678 100644 --- a/coins/monero/tests/runner.rs +++ b/coins/monero/tests/runner.rs @@ -102,6 +102,7 @@ pub static SEQUENTIAL: OnceLock> = OnceLock::new(); macro_rules! async_sequential { ($(async fn $name: ident() $body: block)*) => { $( + #[allow(clippy::tests_outside_test_module)] #[tokio::test] async fn $name() { let guard = runner::SEQUENTIAL.get_or_init(|| tokio::sync::Mutex::new(())).lock().await; diff --git a/coins/monero/tests/send.rs b/coins/monero/tests/send.rs index c210c59c..8acac581 100644 --- a/coins/monero/tests/send.rs +++ b/coins/monero/tests/send.rs @@ -37,8 +37,8 @@ test!( }, ), ( - |rpc, mut builder: Builder, addr, mut outputs: Vec| async move { - for output in outputs.drain(..) { + |rpc, mut builder: Builder, addr, outputs: Vec| async move { + for output in outputs { builder.add_input(SpendableOutput::from(&rpc, output).await.unwrap()); } builder.add_payment(addr, 6); diff --git a/coins/monero/tests/wallet2_compatibility.rs b/coins/monero/tests/wallet2_compatibility.rs index 57c73b16..9bd50161 100644 --- a/coins/monero/tests/wallet2_compatibility.rs +++ b/coins/monero/tests/wallet2_compatibility.rs @@ -70,7 +70,7 @@ async fn from_wallet_rpc_to_self(spec: AddressSpec) { // make an addr let (_, view_pair, _) = runner::random_address(); - let addr = Address::from_str(&view_pair.address(Network::Mainnet, spec).to_string()[..]).unwrap(); + let addr = Address::from_str(&view_pair.address(Network::Mainnet, spec).to_string()).unwrap(); // refresh & make a tx wallet_rpc.refresh(None).await.unwrap(); @@ -103,7 +103,9 @@ async fn from_wallet_rpc_to_self(spec: AddressSpec) { assert_eq!(output.metadata.payment_id, payment_id); assert_eq!(output.metadata.subaddress, None); } - _ => assert_eq!(output.metadata.subaddress, None), + AddressSpec::Standard | AddressSpec::Featured { .. } => { + assert_eq!(output.metadata.subaddress, None) + } } assert_eq!(output.commitment().amount, 1000000000000); } @@ -228,7 +230,7 @@ test!( for _ in 0 .. 2 { // Subtract 1 since we prefix data with 127 let data = vec![b'a'; MAX_TX_EXTRA_NONCE_SIZE - 1]; - assert!(builder.add_data(data).is_ok()); + builder.add_data(data).unwrap(); } (builder.build().unwrap(), (wallet_rpc,))