Skip to content

Commit

Permalink
Merge pull request #4 from zoedberg/v0.11_fixes
Browse files Browse the repository at this point in the history
v0.11 fixes
  • Loading branch information
dr-orlovsky authored Feb 19, 2025
2 parents a660268 + 45a82ea commit 5241130
Show file tree
Hide file tree
Showing 12 changed files with 60 additions and 81 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ path = "src/lib.rs"
amplify = "4.7.0"
sha2 = "0.10.8"
log = "^0.4"
bp-std = { version = "0.11.0-beta.9.1", features = ["serde"] }
bp-std = { version = "0.11.1-alpha.1", features = ["serde"] }
serde = { version = "^1.0", features = ["derive"] }
serde_json = { version = "^1.0" }

Expand Down
4 changes: 4 additions & 0 deletions _typos.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[default]
extend-ignore-identifiers-re = [
"Clonable*",
]
2 changes: 1 addition & 1 deletion examples/tor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ extern crate electrum;
use electrum::{Client, ConfigBuilder, ElectrumApi, Socks5Config};

fn main() {
// NOTE: This assumes Tor is running localy, with an unauthenticated Socks5 listening at
// NOTE: This assumes Tor is running locally, with an unauthenticated Socks5 listening at
// localhost:9050
let proxy = Socks5Config::new("127.0.0.1:9050");
let config = ConfigBuilder::new().socks5(Some(proxy)).build();
Expand Down
6 changes: 4 additions & 2 deletions src/api.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Electrum APIs
use bpstd::{BlockHeader, ConsensusDecode, ConsensusEncode, ScriptPubkey, Tx, Txid};
use std::borrow::Borrow;
use std::convert::TryInto;
use bpstd::{BlockHeader, ConsensusDecode, ConsensusEncode, ScriptPubkey, Tx, Txid};

use crate::batch::Batch;
use crate::types::*;
Expand All @@ -11,7 +11,9 @@ use crate::types::*;
pub trait ElectrumApi {
/// Gets the block header for height `height`.
fn block_header(&self, height: usize) -> Result<BlockHeader, Error> {
Ok(BlockHeader::consensus_deserialize(&self.block_header_raw(height)?)?)
Ok(BlockHeader::consensus_deserialize(
&self.block_header_raw(height)?,
)?)
}

/// Subscribes to notifications for new block headers, by sending a `blockchain.headers.subscribe` call.
Expand Down
18 changes: 6 additions & 12 deletions src/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
//!
//! This module contains definitions and helper functions used when making batch calls.

use bpstd::{ScriptPubkey, Txid};
use crate::types::{Call, Param, ToElectrumScriptHash};
use bpstd::{ScriptPubkey, Txid};

/// Helper structure that caches all the requests before they are actually sent to the server.
///
Expand All @@ -16,6 +15,7 @@ use crate::types::{Call, Param, ToElectrumScriptHash};
/// [`Client`](../client/struct.Client.html), like
/// [`batch_script_get_balance`](../client/struct.Client.html#method.batch_script_get_balance) to ask the
/// server for the balance of multiple scripts with a single request.
#[derive(Default)]
pub struct Batch {
calls: Vec<Call>,
}
Expand All @@ -28,28 +28,28 @@ impl Batch {

/// Add one `blockchain.scripthash.listunspent` request to the batch queue
pub fn script_list_unspent(&mut self, script: &ScriptPubkey) {
let params = vec![Param::String(script.to_electrum_scripthash().to_hex())];
let params = vec![Param::String(script.to_electrum_scripthash().as_hex())];
self.calls
.push((String::from("blockchain.scripthash.listunspent"), params));
}

/// Add one `blockchain.scripthash.get_history` request to the batch queue
pub fn script_get_history(&mut self, script: &ScriptPubkey) {
let params = vec![Param::String(script.to_electrum_scripthash().to_hex())];
let params = vec![Param::String(script.to_electrum_scripthash().as_hex())];
self.calls
.push((String::from("blockchain.scripthash.get_history"), params));
}

/// Add one `blockchain.scripthash.get_balance` request to the batch queue
pub fn script_get_balance(&mut self, script: &ScriptPubkey) {
let params = vec![Param::String(script.to_electrum_scripthash().to_hex())];
let params = vec![Param::String(script.to_electrum_scripthash().as_hex())];
self.calls
.push((String::from("blockchain.scripthash.get_balance"), params));
}

/// Add one `blockchain.scripthash.listunspent` request to the batch queue
pub fn script_subscribe(&mut self, script: &ScriptPubkey) {
let params = vec![Param::String(script.to_electrum_scripthash().to_hex())];
let params = vec![Param::String(script.to_electrum_scripthash().as_hex())];
self.calls
.push((String::from("blockchain.scripthash.subscribe"), params));
}
Expand Down Expand Up @@ -107,9 +107,3 @@ impl<'a> Iterator for BatchIter<'a> {
val
}
}

impl Default for Batch {
fn default() -> Self {
Batch { calls: Vec::new() }
}
}
16 changes: 8 additions & 8 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ use crate::api::ElectrumApi;
use crate::batch::Batch;
use crate::config::Config;
use crate::raw_client::*;
use std::convert::TryFrom;
use bpstd::{ScriptPubkey, Txid};
use crate::types::*;
use bpstd::{ScriptPubkey, Txid};
use std::convert::TryFrom;

/// Generalized Electrum client that supports multiple backends. This wraps
/// [`RawClient`](client/struct.RawClient.html) and provides a more user-friendly
Expand Down Expand Up @@ -71,7 +71,7 @@ macro_rules! impl_inner_call {
std::thread::sleep(std::time::Duration::from_secs((1 << errors.len()).min(30) as u64));
match ClientType::from_config(&$self.url, &$self.config) {
Ok(new_client) => {
info!("Succesfully created new client");
info!("Successfully created new client");
*write_client = new_client;
break;
},
Expand Down Expand Up @@ -352,7 +352,7 @@ mod tests {
fn more_failed_attempts_than_retries_means_exhausted() {
let exhausted = retries_exhausted(10, 5);

assert_eq!(exhausted, true)
assert!(exhausted)
}

#[test]
Expand All @@ -361,21 +361,21 @@ mod tests {

let exhausted = retries_exhausted(failed_attempts, u8::MAX);

assert_eq!(exhausted, true)
assert!(exhausted)
}

#[test]
fn less_failed_attempts_means_not_exhausted() {
let exhausted = retries_exhausted(2, 5);

assert_eq!(exhausted, false)
assert!(!exhausted)
}

#[test]
fn attempts_equals_retries_means_not_exhausted_yet() {
let exhausted = retries_exhausted(2, 2);

assert_eq!(exhausted, false)
assert!(!exhausted)
}

#[test]
Expand Down Expand Up @@ -407,7 +407,7 @@ mod tests {
sender.send(()).unwrap();

for _stream in listener.incoming() {
loop {}
std::thread::sleep(std::time::Duration::from_secs(60));
}
});

Expand Down
34 changes: 15 additions & 19 deletions src/raw_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@ use openssl::ssl::{SslConnector, SslMethod, SslStream, SslVerifyMode};
any(feature = "default", feature = "use-rustls"),
not(feature = "use-openssl")
))]
use rustls::{
pki_types::ServerName,
ClientConfig, ClientConnection, RootCertStore, StreamOwned,
};
use rustls::{pki_types::ServerName, ClientConfig, ClientConnection, RootCertStore, StreamOwned};

#[cfg(any(feature = "default", feature = "proxy"))]
use crate::socks::{Socks5Stream, TargetAddr, ToTargetAddr};
Expand Down Expand Up @@ -76,7 +73,7 @@ pub trait ToSocketAddrsDomain: ToSocketAddrs {

impl ToSocketAddrsDomain for &str {
fn domain(&self) -> Option<&str> {
self.splitn(2, ':').next()
self.split(':').next()
}
}

Expand Down Expand Up @@ -112,15 +109,15 @@ impl_to_socket_addrs_domain!((std::net::Ipv6Addr, u16));
/// Instance of an Electrum client
///
/// A `Client` maintains a constant connection with an Electrum server and exposes methods to
/// interact with it. It can also subscribe and receive notifictations from the server about new
/// interact with it. It can also subscribe and receive notifications from the server about new
/// blocks or activity on a specific *scriptPubKey*.
///
/// The `Client` is modeled in such a way that allows the external caller to have full control over
/// its functionality: no threads or tasks are spawned internally to monitor the state of the
/// connection.
///
/// More transport methods can be used by manually creating an instance of this struct with an
/// arbitray `S` type.
/// arbitrary `S` type.
#[derive(Debug)]
pub struct RawClient<S>
where
Expand Down Expand Up @@ -551,9 +548,8 @@ impl<S: Read + Write> RawClient<S> {
if let Some(err) = map.values().find_map(|sender| {
sender
.send(ChannelMessage::WakeUp)
.map_err(|err| {
.inspect_err(|_| {
warn!("Unable to wake up a thread, trying some other");
err
})
.err()
}) {
Expand All @@ -578,7 +574,7 @@ impl<S: Read + Write> RawClient<S> {
// No id, that's probably a notification.
let mut resp = resp;

if let Some(ref method) = resp["method"].take().as_str() {
if let Some(method) = resp["method"].take().as_str() {
self.handle_notification(method, resp["params"].take())?;
} else {
warn!("Unexpected response: {:?}", resp);
Expand Down Expand Up @@ -639,7 +635,7 @@ impl<S: Read + Write> RawClient<S> {
) -> Result<serde_json::Value, Error> {
loop {
// Try to take the lock on the reader. If we manage to do so, we'll become the reader
// thread until we get our reponse
// thread until we get our response
match self._reader_thread(Some(req_id)) {
Ok(response) => break Ok(response),
Err(Error::CouldntLockReader) => {
Expand Down Expand Up @@ -695,7 +691,7 @@ impl<S: Read + Write> RawClient<S> {
) -> Result<serde_json::Value, Error> {
let req = Request::new_id(
self.last_id.fetch_add(1, Ordering::SeqCst),
&method_name,
method_name,
params,
);
let result = self.call(req)?;
Expand Down Expand Up @@ -736,7 +732,7 @@ impl<T: Read + Write> ElectrumApi for RawClient<T> {
for (method, params) in batch.iter() {
let req = Request::new_id(
self.last_id.fetch_add(1, Ordering::SeqCst),
&method,
method,
params.to_vec(),
);
missing_responses.insert(req.id);
Expand Down Expand Up @@ -777,7 +773,7 @@ impl<T: Read + Write> ElectrumApi for RawClient<T> {
};
}

Ok(answers.into_iter().map(|(_, r)| r).collect())
Ok(answers.into_values().collect())
}

fn block_headers_subscribe_raw(&self) -> Result<RawHeaderNotification, Error> {
Expand Down Expand Up @@ -872,7 +868,7 @@ impl<T: Read + Write> ElectrumApi for RawClient<T> {
let req = Request::new_id(
self.last_id.fetch_add(1, Ordering::SeqCst),
"blockchain.scripthash.subscribe",
vec![Param::String(script_hash.to_hex())],
vec![Param::String(script_hash.as_hex())],
);
let value = self.call(req)?;

Expand Down Expand Up @@ -909,7 +905,7 @@ impl<T: Read + Write> ElectrumApi for RawClient<T> {
let req = Request::new_id(
self.last_id.fetch_add(1, Ordering::SeqCst),
"blockchain.scripthash.unsubscribe",
vec![Param::String(script_hash.to_hex())],
vec![Param::String(script_hash.as_hex())],
);
let value = self.call(req)?;
let answer = serde_json::from_value(value)?;
Expand All @@ -929,7 +925,7 @@ impl<T: Read + Write> ElectrumApi for RawClient<T> {
}

fn script_get_balance(&self, script: &ScriptPubkey) -> Result<GetBalanceRes, Error> {
let params = vec![Param::String(script.to_electrum_scripthash().to_hex())];
let params = vec![Param::String(script.to_electrum_scripthash().as_hex())];
let req = Request::new_id(
self.last_id.fetch_add(1, Ordering::SeqCst),
"blockchain.scripthash.get_balance",
Expand All @@ -948,7 +944,7 @@ impl<T: Read + Write> ElectrumApi for RawClient<T> {
}

fn script_get_history(&self, script: &ScriptPubkey) -> Result<Vec<GetHistoryRes>, Error> {
let params = vec![Param::String(script.to_electrum_scripthash().to_hex())];
let params = vec![Param::String(script.to_electrum_scripthash().as_hex())];
let req = Request::new_id(
self.last_id.fetch_add(1, Ordering::SeqCst),
"blockchain.scripthash.get_history",
Expand All @@ -967,7 +963,7 @@ impl<T: Read + Write> ElectrumApi for RawClient<T> {
}

fn script_list_unspent(&self, script: &ScriptPubkey) -> Result<Vec<ListUnspentRes>, Error> {
let params = vec![Param::String(script.to_electrum_scripthash().to_hex())];
let params = vec![Param::String(script.to_electrum_scripthash().as_hex())];
let req = Request::new_id(
self.last_id.fetch_add(1, Ordering::SeqCst),
"blockchain.scripthash.listunspent",
Expand Down
4 changes: 2 additions & 2 deletions src/socks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ impl ToTargetAddr for (Ipv6Addr, u16) {
}
}

impl<'a> ToTargetAddr for (&'a str, u16) {
impl ToTargetAddr for (&str, u16) {
fn to_target_addr(&self) -> io::Result<TargetAddr> {
// try to parse as an IP first
if let Ok(addr) = self.0.parse::<Ipv4Addr>() {
Expand All @@ -114,7 +114,7 @@ impl<'a> ToTargetAddr for (&'a str, u16) {
}
}

impl<'a> ToTargetAddr for &'a str {
impl ToTargetAddr for &str {
fn to_target_addr(&self) -> io::Result<TargetAddr> {
// try to parse as an IP first
if let Ok(addr) = self.parse::<SocketAddrV4>() {
Expand Down
11 changes: 4 additions & 7 deletions src/socks/v4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,18 +109,15 @@ impl Socks4Stream {
let _ = packet.write_u32::<BigEndian>(Ipv4Addr::new(0, 0, 0, 1).into());
let _ = packet.write_all(userid.as_bytes());
let _ = packet.write_u8(0);
let _ = packet.extend(host.as_bytes());
packet.extend(host.as_bytes());
let _ = packet.write_u8(0);
}
}

socket.write_all(&packet)?;
let proxy_addr = read_response(&mut socket)?;

Ok(Socks4Stream {
socket: socket,
proxy_addr: proxy_addr,
})
Ok(Socks4Stream { socket, proxy_addr })
}

/// Returns the proxy-side address of the connection between the proxy and
Expand Down Expand Up @@ -151,7 +148,7 @@ impl Read for Socks4Stream {
}
}

impl<'a> Read for &'a Socks4Stream {
impl Read for &Socks4Stream {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
(&self.socket).read(buf)
}
Expand All @@ -167,7 +164,7 @@ impl Write for Socks4Stream {
}
}

impl<'a> Write for &'a Socks4Stream {
impl Write for &Socks4Stream {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
(&self.socket).write(buf)
}
Expand Down
Loading

0 comments on commit 5241130

Please sign in to comment.