From 4d73fe10969238b5a4f48a9af13cfaa81aa1aebf Mon Sep 17 00:00:00 2001 From: vatsalkeshav Date: Sun, 12 Apr 2026 00:34:59 +0530 Subject: [PATCH 1/5] refactor(electrum): remove unwrap and expect remove all .unwrap() and non-infallible .expect() calls in non-test code of /floresta-electrum/s/electrum_protocol.rs contribute to issue #463 --- .../src/electrum_protocol.rs | 155 ++++++++++++------ 1 file changed, 104 insertions(+), 51 deletions(-) diff --git a/crates/floresta-electrum/src/electrum_protocol.rs b/crates/floresta-electrum/src/electrum_protocol.rs index caad13721..755fd5e9f 100644 --- a/crates/floresta-electrum/src/electrum_protocol.rs +++ b/crates/floresta-electrum/src/electrum_protocol.rs @@ -92,22 +92,28 @@ impl TcpActor { result = lines.next_line() => { match result { Ok(Some(line)) => { - self.message_transmitter - .send(Message::Message((self.client_id, line))) - .expect("Main loop is broken"); + match self.message_transmitter.send(Message::Message((self.client_id, line))) { + Ok(_) => {} + Err(e) => { + error!("main loop receiver dropped: {e:?}"); + break; + } + } } Ok(None) => { info!("Client closed connection: {}", self.client_id); - self.message_transmitter - .send(Message::Disconnect(self.client_id)) - .expect("Main loop is broken"); + match self.message_transmitter.send(Message::Disconnect(self.client_id)) { + Ok(_) => {} + Err(e) => error!("main loop receiver dropped: {e:?}"), + } break; } Err(e) => { error!("Error reading from client: {e:?}"); - self.message_transmitter - .send(Message::Disconnect(self.client_id)) - .expect("Main loop is broken"); + match self.message_transmitter.send(Message::Disconnect(self.client_id)) { + Ok(_) => {} + Err(e) => error!("main loop receiver dropped: {e:?}"), + } break; } } @@ -336,15 +342,13 @@ impl ElectrumServer { "blockchain.scripthash.get_mempool" => json_rpc_res!(request, []), "blockchain.scripthash.listunspent" => { let hash = get_arg!(request, sha256::Hash, 0); - let utxos = self.address_cache.get_address_utxos(&hash); - if utxos.is_none() { + let Some(utxos) = self.address_cache.get_address_utxos(&hash) else { return json_rpc_res!(request, []); - } + }; let mut final_utxos = Vec::new(); - for (utxo, prevout) in utxos.unwrap().into_iter() { - let height = self.address_cache.get_height(&prevout.txid).unwrap(); - - let position = self.address_cache.get_position(&prevout.txid).unwrap(); + for (utxo, prevout) in utxos.into_iter() { + let height = self.address_cache.get_height(&prevout.txid).unwrap_or(0); + let position = self.address_cache.get_position(&prevout.txid).unwrap_or(0); final_utxos.push(json!({ "height": height, @@ -514,7 +518,7 @@ impl ElectrumServer { let genesis_hash = self .chain .get_block_hash(0) - .expect("Genesis block should be present"); + .expect("genesis block is always in the chain store"); let res = json!( { "genesis_hash": genesis_hash, @@ -540,7 +544,13 @@ impl ElectrumServer { } pub async fn rebroadcast_mempool_transactions(&self) { - let unconfirmed = self.address_cache.find_unconfirmed().unwrap(); + let unconfirmed = match self.address_cache.find_unconfirmed() { + Ok(txs) => txs, + Err(e) => { + error!("Could not fetch unconfirmed transactions for rebroadcast: {e}"); + return; + } + }; for tx in unconfirmed { let txid = tx.compute_txid(); if let Ok(Err(e)) = self.node_interface.broadcast_transaction(tx.clone()).await { @@ -644,6 +654,7 @@ impl ElectrumServer { let Ok(blocks) = cfilters.match_any(_addresses, start_height, stop_height, self.chain.clone()) else { + info!("Could not match block filters"); self.addresses_to_scan.extend(addresses); // push them back to get a retry return Ok(()); }; @@ -654,16 +665,16 @@ impl ElectrumServer { for block in blocks { let block = self.node_interface.get_block(block).await; let Ok(Some(block)) = block else { + info!("Could not get block from node"); self.addresses_to_scan.extend(addresses); // push them back to get a retry return Ok(()); }; - let height = self - .chain - .get_block_height(&block.block_hash()) - .ok() - .flatten() - .unwrap(); + let Ok(Some(height)) = self.chain.get_block_height(&block.block_hash()) else { + info!("Could not get block height: {}", block.block_hash()); + self.addresses_to_scan.extend(addresses); // push them back to get a retry + return Ok(()); + }; self.handle_block(block, height); } @@ -708,13 +719,24 @@ impl ElectrumServer { self.address_cache.bump_height(height); } - if self.chain.get_height().unwrap() == height { - for client in &mut self.clients.values() { - let res = client.write(serde_json::to_string(&result).unwrap().as_bytes()); - if res.is_err() { - info!("Could not write to client {client:?}"); + match self.chain.get_height() { + Ok(chain_height) => { + if chain_height == height { + for client in &mut self.clients.values() { + let res = client.write( + serde_json::to_string(&result) + .expect("serde_json::Value is always serializable") + .as_bytes(), + ); + if res.is_err() { + info!("Could not write to client {client:?}"); + } + } } } + Err(e) => { + error!("Could not get chain height: {e:?}"); + } } let transactions = self.address_cache.block_process(&block, height); @@ -732,17 +754,19 @@ impl ElectrumServer { Message::Message((client, msg)) => { trace!("Message: {msg}"); if let Ok(req) = serde_json::from_str::(msg.as_str()) { - let client = self.clients.get(&client); - if client.is_none() { + let Some(client) = self.clients.get(&client).cloned() else { error!("Client sent a message but is not listed as client"); return Ok(()); - } - let client = client.unwrap().to_owned(); + }; let id = req.id.to_owned(); let res = self.handle_client_request(client.clone(), req).await; if let Ok(res) = res { - client.write(serde_json::to_string(&res).unwrap().as_bytes())?; + client.write( + serde_json::to_string(&res) + .expect("serde_json::Value is always serializable") + .as_bytes(), + )?; } else { let res = json!({ "jsonrpc": "2.0", @@ -753,17 +777,19 @@ impl ElectrumServer { }, "id": id }); - client.write(serde_json::to_string(&res).unwrap().as_bytes())?; + client.write( + serde_json::to_string(&res) + .expect("serde_json::Value is always serializable") + .as_bytes(), + )?; } } else if let Ok(requests) = serde_json::from_str::>(&msg) { let mut results = Vec::new(); for req in requests { - let client = self.clients.get(&client); - if client.is_none() { + let Some(client) = self.clients.get(&client).cloned() else { error!("Client sent a message but is not listed as client"); return Ok(()); - } - let client = client.unwrap().to_owned(); + }; let id = req.id.to_owned(); let res = self.handle_client_request(client.clone(), req).await; @@ -783,7 +809,11 @@ impl ElectrumServer { } } if let Some(client) = self.clients.get(&client) { - client.write(serde_json::to_string(&results).unwrap().as_bytes())?; + client.write( + serde_json::to_string(&results) + .expect("serde_json::Value is always serializable") + .as_bytes(), + )?; } } else { let res = json!({ @@ -796,7 +826,11 @@ impl ElectrumServer { "id": null }); if let Some(client) = self.clients.get(&client) { - client.write(serde_json::to_string(&res).unwrap().as_bytes())?; + client.write( + serde_json::to_string(&res) + .expect("serde_json::Value is always serializable") + .as_bytes(), + )?; } } } @@ -813,15 +847,22 @@ impl ElectrumServer { for (_, out) in transactions { let hash = get_spk_hash(&out.script_pubkey); if let Some(client) = self.client_addresses.get(&hash) { - let history = self.address_cache.get_address_history(&hash); + let Some(history) = self.address_cache.get_address_history(&hash) else { + info!("Could not get address history for {hash}"); + continue; + }; - let status_hash = get_status(history.unwrap()); + let status_hash = get_status(history); let notify = json!({ "jsonrpc": "2.0", "method": "blockchain.scripthash.subscribe", "params": [hash, status_hash] }); - if let Err(err) = client.write(serde_json::to_string(¬ify).unwrap().as_bytes()) { + if let Err(err) = client.write( + serde_json::to_string(¬ify) + .expect("serde_json::Value is always serializable") + .as_bytes(), + ) { error!("{err}"); } } @@ -848,10 +889,17 @@ pub async fn client_accept_loop( tls_stream, message_transmitter.clone(), )); - message_transmitter + match message_transmitter .send(Message::NewClient((client.client_id, client))) - .expect("Main loop is broken"); - id_count += 1; + { + Ok(_) => { + id_count += 1; + } + Err(e) => { + error!("main loop receiver dropped: {e:?}"); + break; + } + } } Err(e) => { error!("TLS accept error: {e:?}"); @@ -859,10 +907,15 @@ pub async fn client_accept_loop( } } else { let client = Arc::new(Client::new(id_count, stream, message_transmitter.clone())); - message_transmitter - .send(Message::NewClient((client.client_id, client))) - .expect("Main loop is broken"); - id_count += 1; + match message_transmitter.send(Message::NewClient((client.client_id, client))) { + Ok(_) => { + id_count += 1; + } + Err(e) => { + error!("main loop receiver dropped: {e:?}"); + break; + } + } } } } From 390cb746c2dfc1003795b9feceff6a16192631f3 Mon Sep 17 00:00:00 2001 From: vatsalkeshav Date: Wed, 15 Apr 2026 13:00:28 +0530 Subject: [PATCH 2/5] refactor(electrum): fixes from review - propogate errors, remove unwrap_or(), flatten nesting --- .../src/electrum_protocol.rs | 124 ++++++++---------- crates/floresta-electrum/src/error.rs | 3 + crates/floresta-electrum/src/lib.rs | 1 + 3 files changed, 60 insertions(+), 68 deletions(-) diff --git a/crates/floresta-electrum/src/electrum_protocol.rs b/crates/floresta-electrum/src/electrum_protocol.rs index 755fd5e9f..af281ae39 100644 --- a/crates/floresta-electrum/src/electrum_protocol.rs +++ b/crates/floresta-electrum/src/electrum_protocol.rs @@ -347,8 +347,12 @@ impl ElectrumServer { }; let mut final_utxos = Vec::new(); for (utxo, prevout) in utxos.into_iter() { - let height = self.address_cache.get_height(&prevout.txid).unwrap_or(0); - let position = self.address_cache.get_position(&prevout.txid).unwrap_or(0); + let Some(height) = self.address_cache.get_height(&prevout.txid) else { + return json_rpc_res!(request, []); + }; + let Some(position) = self.address_cache.get_position(&prevout.txid) else { + return json_rpc_res!(request, []); + }; final_utxos.push(json!({ "height": height, @@ -493,18 +497,18 @@ impl ElectrumServer { } "blockchain.transaction.get_merkle" => { let tx_id = get_arg!(request, Txid, 0); - let proof = self.address_cache.get_merkle_proof(&tx_id); - let height = self.address_cache.get_height(&tx_id); - if let Some(proof) = proof { - let result = json!({ - "merkle": proof.hashes, - "block_height": height.unwrap_or(0), - "pos": proof.pos - }); - return json_rpc_res!(request, result); - } - - Err(super::error::Error::InvalidParams) + let Some(proof) = self.address_cache.get_merkle_proof(&tx_id) else { + return Err(super::error::Error::InvalidParams); + }; + let Some(height) = self.address_cache.get_height(&tx_id) else { + return Err(super::error::Error::InvalidParams); + }; + let result = json!({ + "merkle": proof.hashes, + "block_height": height, + "pos": proof.pos + }); + json_rpc_res!(request, result) } //blockchain.transaction.id_from_pos // TODO: Create an actual histogram @@ -518,7 +522,7 @@ impl ElectrumServer { let genesis_hash = self .chain .get_block_hash(0) - .expect("genesis block is always in the chain store"); + .expect("Genesis block is always in the chain store"); let res = json!( { "genesis_hash": genesis_hash, @@ -543,14 +547,11 @@ impl ElectrumServer { } } - pub async fn rebroadcast_mempool_transactions(&self) { - let unconfirmed = match self.address_cache.find_unconfirmed() { - Ok(txs) => txs, - Err(e) => { - error!("Could not fetch unconfirmed transactions for rebroadcast: {e}"); - return; - } - }; + pub async fn rebroadcast_mempool_transactions(&self) -> Result<(), super::error::Error> { + let unconfirmed = self + .address_cache + .find_unconfirmed() + .map_err(|e| super::error::Error::WatchOnly(Box::new(e)))?; for tx in unconfirmed { let txid = tx.compute_txid(); if let Ok(Err(e)) = self.node_interface.broadcast_transaction(tx.clone()).await { @@ -559,6 +560,7 @@ impl ElectrumServer { debug!("Rebroadcasted transaction {txid}"); } } + Ok(()) } pub async fn main_loop(mut self) -> Result<(), crate::error::Error> { @@ -594,7 +596,7 @@ impl ElectrumServer { .unwrap_or(true); if should_rebroadcast { - self.rebroadcast_mempool_transactions().await; + self.rebroadcast_mempool_transactions().await?; self.last_rebroadcast = Some(Instant::now()); } @@ -654,7 +656,7 @@ impl ElectrumServer { let Ok(blocks) = cfilters.match_any(_addresses, start_height, stop_height, self.chain.clone()) else { - info!("Could not match block filters"); + error!("Could not match block filters"); self.addresses_to_scan.extend(addresses); // push them back to get a retry return Ok(()); }; @@ -665,13 +667,13 @@ impl ElectrumServer { for block in blocks { let block = self.node_interface.get_block(block).await; let Ok(Some(block)) = block else { - info!("Could not get block from node"); + error!("Could not get block from node"); self.addresses_to_scan.extend(addresses); // push them back to get a retry return Ok(()); }; let Ok(Some(height)) = self.chain.get_block_height(&block.block_hash()) else { - info!("Could not get block height: {}", block.block_hash()); + error!("Could not get block height: {}", block.block_hash()); self.addresses_to_scan.extend(addresses); // push them back to get a retry return Ok(()); }; @@ -719,24 +721,20 @@ impl ElectrumServer { self.address_cache.bump_height(height); } - match self.chain.get_height() { - Ok(chain_height) => { - if chain_height == height { - for client in &mut self.clients.values() { - let res = client.write( - serde_json::to_string(&result) - .expect("serde_json::Value is always serializable") - .as_bytes(), - ); - if res.is_err() { - info!("Could not write to client {client:?}"); - } - } + let height_matches = self + .chain + .get_height() + .inspect_err(|e| error!("Could not get chain height: {e:?}")) + .is_ok_and(|h| h == height); + + if height_matches { + let serialized = serde_json::to_string(&result) + .expect("serde_json::Value is always serializable"); + for client in self.clients.values() { + if client.write(serialized.as_bytes()).is_err() { + info!("Could not write to client {client:?}"); } } - Err(e) => { - error!("Could not get chain height: {e:?}"); - } } let transactions = self.address_cache.block_process(&block, height); @@ -762,11 +760,9 @@ impl ElectrumServer { let res = self.handle_client_request(client.clone(), req).await; if let Ok(res) = res { - client.write( - serde_json::to_string(&res) - .expect("serde_json::Value is always serializable") - .as_bytes(), - )?; + let res = serde_json::to_string(&res) + .expect("serde_json::Value is always serializable"); + client.write(res.as_bytes())?; } else { let res = json!({ "jsonrpc": "2.0", @@ -777,11 +773,9 @@ impl ElectrumServer { }, "id": id }); - client.write( - serde_json::to_string(&res) - .expect("serde_json::Value is always serializable") - .as_bytes(), - )?; + let res = serde_json::to_string(&res) + .expect("serde_json::Value is always serializable"); + client.write(res.as_bytes())?; } } else if let Ok(requests) = serde_json::from_str::>(&msg) { let mut results = Vec::new(); @@ -809,11 +803,9 @@ impl ElectrumServer { } } if let Some(client) = self.clients.get(&client) { - client.write( - serde_json::to_string(&results) - .expect("serde_json::Value is always serializable") - .as_bytes(), - )?; + let results = serde_json::to_string(&results) + .expect("serde_json::Value is always serializable"); + client.write(results.as_bytes())?; } } else { let res = json!({ @@ -826,11 +818,9 @@ impl ElectrumServer { "id": null }); if let Some(client) = self.clients.get(&client) { - client.write( - serde_json::to_string(&res) - .expect("serde_json::Value is always serializable") - .as_bytes(), - )?; + let res = serde_json::to_string(&res) + .expect("serde_json::Value is always serializable"); + client.write(res.as_bytes())?; } } } @@ -858,11 +848,9 @@ impl ElectrumServer { "method": "blockchain.scripthash.subscribe", "params": [hash, status_hash] }); - if let Err(err) = client.write( - serde_json::to_string(¬ify) - .expect("serde_json::Value is always serializable") - .as_bytes(), - ) { + let notify = serde_json::to_string(¬ify) + .expect("serde_json::Value is always serializable"); + if let Err(err) = client.write(notify.as_bytes()) { error!("{err}"); } } diff --git a/crates/floresta-electrum/src/error.rs b/crates/floresta-electrum/src/error.rs index 8b3276edb..c04f00107 100644 --- a/crates/floresta-electrum/src/error.rs +++ b/crates/floresta-electrum/src/error.rs @@ -20,6 +20,9 @@ pub enum Error { #[error("Mempool accept error")] Mempool(Box), + #[error("Watch-only cache error")] + WatchOnly(Box), + #[error("Node isn't working")] NodeInterface(#[from] oneshot::error::RecvError), } diff --git a/crates/floresta-electrum/src/lib.rs b/crates/floresta-electrum/src/lib.rs index 108012201..eea2c5323 100644 --- a/crates/floresta-electrum/src/lib.rs +++ b/crates/floresta-electrum/src/lib.rs @@ -7,6 +7,7 @@ html_favicon_url = "https://raw.githubusercontent.com/getfloresta/floresta-media/master/logo_png/Icon-Green(main).png" )] #![allow(clippy::manual_is_multiple_of)] +#![cfg_attr(not(test), deny(clippy::unwrap_used))] use serde::Deserialize; use serde::Serialize; From 8c8e54d2a288011aef3432786c0bd092b17acd32 Mon Sep 17 00:00:00 2001 From: vatsalkeshav Date: Wed, 15 Apr 2026 17:39:44 +0530 Subject: [PATCH 3/5] refactor(electrum): run cargo fmt --- crates/floresta-electrum/src/electrum_protocol.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/floresta-electrum/src/electrum_protocol.rs b/crates/floresta-electrum/src/electrum_protocol.rs index af281ae39..b3200f351 100644 --- a/crates/floresta-electrum/src/electrum_protocol.rs +++ b/crates/floresta-electrum/src/electrum_protocol.rs @@ -728,8 +728,8 @@ impl ElectrumServer { .is_ok_and(|h| h == height); if height_matches { - let serialized = serde_json::to_string(&result) - .expect("serde_json::Value is always serializable"); + let serialized = + serde_json::to_string(&result).expect("serde_json::Value is always serializable"); for client in self.clients.values() { if client.write(serialized.as_bytes()).is_err() { info!("Could not write to client {client:?}"); From ab159b6a05a4a81ef23de51b17df22cb7fe66060 Mon Sep 17 00:00:00 2001 From: vatsalkeshav Date: Wed, 15 Apr 2026 18:13:58 +0530 Subject: [PATCH 4/5] refactor(electrum): run cargo fmt; fixes from review - use if-let-err instead of pattern matching, shorter erro path --- .../src/electrum_protocol.rs | 95 ++++++++----------- 1 file changed, 40 insertions(+), 55 deletions(-) diff --git a/crates/floresta-electrum/src/electrum_protocol.rs b/crates/floresta-electrum/src/electrum_protocol.rs index b3200f351..735f2d899 100644 --- a/crates/floresta-electrum/src/electrum_protocol.rs +++ b/crates/floresta-electrum/src/electrum_protocol.rs @@ -42,6 +42,7 @@ use tracing::error; use tracing::info; use tracing::trace; +use crate::error::Error; use crate::get_arg; use crate::json_rpc_res; use crate::request::Request; @@ -92,27 +93,22 @@ impl TcpActor { result = lines.next_line() => { match result { Ok(Some(line)) => { - match self.message_transmitter.send(Message::Message((self.client_id, line))) { - Ok(_) => {} - Err(e) => { - error!("main loop receiver dropped: {e:?}"); - break; - } + if let Err(e) = self.message_transmitter.send(Message::Message((self.client_id, line))) { + error!("main loop receiver dropped: {e:?}"); + break; } } Ok(None) => { info!("Client closed connection: {}", self.client_id); - match self.message_transmitter.send(Message::Disconnect(self.client_id)) { - Ok(_) => {} - Err(e) => error!("main loop receiver dropped: {e:?}"), + if let Err(e) = self.message_transmitter.send(Message::Disconnect(self.client_id)) { + error!("main loop receiver dropped: {e:?}"); } break; } Err(e) => { error!("Error reading from client: {e:?}"); - match self.message_transmitter.send(Message::Disconnect(self.client_id)) { - Ok(_) => {} - Err(e) => error!("main loop receiver dropped: {e:?}"), + if let Err(e) = self.message_transmitter.send(Message::Disconnect(self.client_id)) { + error!("main loop receiver dropped: {e:?}"); } break; } @@ -256,7 +252,7 @@ impl ElectrumServer { &mut self, client: Arc, request: Request, - ) -> Result { + ) -> Result { // Methods are in alphabetical order match request.method.as_str() { "blockchain.block.header" => { @@ -264,11 +260,11 @@ impl ElectrumServer { let hash = self .chain .get_block_hash(height as u32) - .map_err(|_| super::error::Error::InvalidParams)?; + .map_err(|_| Error::InvalidParams)?; let header = self .chain .get_block_header(&hash) - .map_err(|e| super::error::Error::Blockchain(Box::new(e)))?; + .map_err(|e| Error::Blockchain(Box::new(e)))?; let header = serialize_hex(&header); json_rpc_res!(request, header) } @@ -281,12 +277,12 @@ impl ElectrumServer { let hash = self .chain .get_block_hash(height as u32) - .map_err(|_| super::error::Error::InvalidParams)?; + .map_err(|_| Error::InvalidParams)?; let header = self .chain .get_block_header(&hash) - .map_err(|e| super::error::Error::Blockchain(Box::new(e)))?; + .map_err(|e| Error::Blockchain(Box::new(e)))?; let header = serialize_hex(&header); headers.push_str(&header); } @@ -301,11 +297,11 @@ impl ElectrumServer { let (height, hash) = self .chain .get_best_block() - .map_err(|e| super::error::Error::Blockchain(Box::new(e)))?; + .map_err(|e| Error::Blockchain(Box::new(e)))?; let header = self .chain .get_block_header(&hash) - .map_err(|e| super::error::Error::Blockchain(Box::new(e)))?; + .map_err(|e| Error::Blockchain(Box::new(e)))?; let result = json!({ "height": height, "hex": serialize_hex(&header) @@ -461,10 +457,8 @@ impl ElectrumServer { // end of experimental endpoints "blockchain.transaction.broadcast" => { let tx = get_arg!(request, String, 0); - let hex: Vec<_> = - Vec::from_hex(&tx).map_err(|_| super::error::Error::InvalidParams)?; - let tx: Transaction = - deserialize(&hex).map_err(|_| super::error::Error::InvalidParams)?; + let hex: Vec<_> = Vec::from_hex(&tx).map_err(|_| Error::InvalidParams)?; + let tx: Transaction = deserialize(&hex).map_err(|_| Error::InvalidParams)?; let txid = tx.compute_txid(); if let Err(e) = self @@ -473,7 +467,7 @@ impl ElectrumServer { .await? { error!("Could not broadcast transaction {txid} due to {e}"); - return Err(super::error::Error::Mempool(Box::new(e))); + return Err(Error::Mempool(Box::new(e))); }; let updated = self @@ -493,15 +487,15 @@ impl ElectrumServer { return json_rpc_res!(request, tx); } - Err(super::error::Error::InvalidParams) + Err(Error::InvalidParams) } "blockchain.transaction.get_merkle" => { let tx_id = get_arg!(request, Txid, 0); let Some(proof) = self.address_cache.get_merkle_proof(&tx_id) else { - return Err(super::error::Error::InvalidParams); + return Err(Error::InvalidParams); }; let Some(height) = self.address_cache.get_height(&tx_id) else { - return Err(super::error::Error::InvalidParams); + return Err(Error::InvalidParams); }; let result = json!({ "merkle": proof.hashes, @@ -543,15 +537,15 @@ impl ElectrumServer { [format!("Floresta {}", env!("CARGO_PKG_VERSION")), "1.4"] ), - _ => Err(super::error::Error::InvalidParams), + _ => Err(Error::InvalidParams), } } - pub async fn rebroadcast_mempool_transactions(&self) -> Result<(), super::error::Error> { + pub async fn rebroadcast_mempool_transactions(&self) -> Result<(), Error> { let unconfirmed = self .address_cache .find_unconfirmed() - .map_err(|e| super::error::Error::WatchOnly(Box::new(e)))?; + .map_err(|e| Error::WatchOnly(Box::new(e)))?; for tx in unconfirmed { let txid = tx.compute_txid(); if let Ok(Err(e)) = self.node_interface.broadcast_transaction(tx.clone()).await { @@ -623,10 +617,7 @@ impl ElectrumServer { /// Usually, we'll rely on compact block filters to speed things up. If /// we don't have compact block filters, we may rescan using the older, /// more bandwidth-intensive method of actually downloading blocks. - async fn rescan_for_addresses( - &mut self, - addresses: Vec, - ) -> Result<(), super::error::Error> { + async fn rescan_for_addresses(&mut self, addresses: Vec) -> Result<(), Error> { // If compact block filters are enabled, use them. Otherwise, fallback // to the "old-school" rescaning. if let Some(cfilters) = &self.block_filters { @@ -646,7 +637,7 @@ impl ElectrumServer { start_height: Option, stop_height: Option, addresses: Vec, - ) -> Result<(), super::error::Error> { + ) -> Result<(), Error> { // By default, we look from 1..tip let mut _addresses = addresses .iter() @@ -656,7 +647,7 @@ impl ElectrumServer { let Ok(blocks) = cfilters.match_any(_addresses, start_height, stop_height, self.chain.clone()) else { - error!("Could not match block filters"); + error!("Could not find matching block filters"); self.addresses_to_scan.extend(addresses); // push them back to get a retry return Ok(()); }; @@ -877,17 +868,13 @@ pub async fn client_accept_loop( tls_stream, message_transmitter.clone(), )); - match message_transmitter - .send(Message::NewClient((client.client_id, client))) + if let Err(e) = + message_transmitter.send(Message::NewClient((client.client_id, client))) { - Ok(_) => { - id_count += 1; - } - Err(e) => { - error!("main loop receiver dropped: {e:?}"); - break; - } + error!("main loop receiver dropped: {e:?}"); + break; } + id_count += 1; } Err(e) => { error!("TLS accept error: {e:?}"); @@ -895,15 +882,13 @@ pub async fn client_accept_loop( } } else { let client = Arc::new(Client::new(id_count, stream, message_transmitter.clone())); - match message_transmitter.send(Message::NewClient((client.client_id, client))) { - Ok(_) => { - id_count += 1; - } - Err(e) => { - error!("main loop receiver dropped: {e:?}"); - break; - } + if let Err(e) = + message_transmitter.send(Message::NewClient((client.client_id, client))) + { + error!("main loop receiver dropped: {e:?}"); + break; } + id_count += 1; } } } @@ -963,13 +948,13 @@ macro_rules! json_rpc_res { } #[macro_export] -/// Returns and parses a value from the request json or fails with [super::error::Error::InvalidParams]. +/// Returns and parses a value from the request json or fails with [Error::InvalidParams]. macro_rules! get_arg { ($request:ident, $arg_type:ty, $idx:literal) => { if let Some(arg) = $request.params.get($idx) { serde_json::from_value::<$arg_type>(arg.clone())? } else { - return Err(super::error::Error::InvalidParams); + return Err(Error::InvalidParams); } }; } From 6db1b2a1606b382e0debac714d95c00636063372 Mon Sep 17 00:00:00 2001 From: vatsalkeshav Date: Wed, 15 Apr 2026 22:50:12 +0530 Subject: [PATCH 5/5] refactor(electrum): remove unnecessary type hint --- crates/floresta-electrum/src/electrum_protocol.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/floresta-electrum/src/electrum_protocol.rs b/crates/floresta-electrum/src/electrum_protocol.rs index 735f2d899..44109f42b 100644 --- a/crates/floresta-electrum/src/electrum_protocol.rs +++ b/crates/floresta-electrum/src/electrum_protocol.rs @@ -457,7 +457,7 @@ impl ElectrumServer { // end of experimental endpoints "blockchain.transaction.broadcast" => { let tx = get_arg!(request, String, 0); - let hex: Vec<_> = Vec::from_hex(&tx).map_err(|_| Error::InvalidParams)?; + let hex = Vec::from_hex(&tx).map_err(|_| Error::InvalidParams)?; let tx: Transaction = deserialize(&hex).map_err(|_| Error::InvalidParams)?; let txid = tx.compute_txid();