diff --git a/subprojects/gdk_rust/Cargo.toml b/subprojects/gdk_rust/Cargo.toml index c50bf5046..21fb3e542 100644 --- a/subprojects/gdk_rust/Cargo.toml +++ b/subprojects/gdk_rust/Cargo.toml @@ -30,7 +30,7 @@ ureq = { version = "1.0.0", features = ["json"] } [dev-dependencies] tempdir = "0.3.7" bitcoincore-rpc = { git="https://github.com/romanz/rust-bitcoincore-rpc", rev="637e895a0b73ffc21c8f62fa2c65b6fd1247785a" } -electrum-client = "0.3.0-beta.1" +electrum-client = "0.4.0-beta.1" elements = { version = "0.13", features = ["serde-feature"] } [profile.release] @@ -42,4 +42,3 @@ incremental = false [patch.crates-io] bitcoin = { git = "https://github.com/shesek/rust-bitcoin", branch = "0.25.2-uint-serde", features = [ "use-serde" ] } -electrum-client = { git = "https://github.com/shesek/rust-electrum-client", branch = "202011-custom-ssl-stream" } diff --git a/subprojects/gdk_rust/gdk_electrum/Cargo.toml b/subprojects/gdk_rust/gdk_electrum/Cargo.toml index 8f2dc3991..e3245c366 100644 --- a/subprojects/gdk_rust/gdk_electrum/Cargo.toml +++ b/subprojects/gdk_rust/gdk_electrum/Cargo.toml @@ -19,7 +19,7 @@ aes-gcm-siv = "0.5.0" gdk-common = { path = "../gdk_common" } libc = "0.2" android_logger = { version = "0.8.6", optional = true } -electrum-client = "0.3.0-beta.1" +electrum-client = "0.4.0-beta.1" chrono = "0.4.11" ureq = { version = "1.0.0", features = ["json"] } block-modes = "0.3.3" @@ -34,4 +34,3 @@ elements = { version = "0.13", features = ["serde-feature"] } [patch.crates-io] bitcoin = { git = "https://github.com/shesek/rust-bitcoin", branch = "0.25.2-uint-serde", features = [ "use-serde" ] } -electrum-client = { git = "https://github.com/shesek/rust-electrum-client", branch = "202011-custom-ssl-stream" } diff --git a/subprojects/gdk_rust/gdk_electrum/src/interface.rs b/subprojects/gdk_rust/gdk_electrum/src/interface.rs index 11aa48e05..8af1d7973 100644 --- a/subprojects/gdk_rust/gdk_electrum/src/interface.rs +++ b/subprojects/gdk_rust/gdk_electrum/src/interface.rs @@ -22,16 +22,13 @@ use crate::error::*; use crate::store::*; use bitcoin::util::bip143::SigHashCache; -use electrum_client::raw_client::RawClient; -use electrum_client::Client; +use electrum_client::{Client, ConfigBuilder}; use elements::confidential::{Asset, Nonce, Value}; use gdk_common::be::{self, *}; use std::cmp::Ordering; use std::collections::{HashMap, HashSet}; use std::convert::TryInto; -use std::net::{TcpStream, ToSocketAddrs}; use std::str::FromStr; -use std::time::Duration; pub struct WalletCtx { pub secp: Secp256k1, @@ -52,41 +49,19 @@ pub enum ElectrumUrl { impl ElectrumUrl { pub fn build_client(&self) -> Result { - match self { - ElectrumUrl::Tls(url, validate) => { - let client = RawClient::new_ssl(url.as_str(), *validate)?; - Ok(Client::SSL(client)) - } - ElectrumUrl::Plaintext(url) => { - let client = RawClient::new(&url)?; - Ok(Client::TCP(client)) - } - } + self.build_config(ConfigBuilder::new()) } - pub fn build_client_timeout(&self, timeouts: Timeouts) -> Result { - let (connect_timeout, read_timeout, write_timeout) = timeouts; - - let make_stream = |url: &str| -> Result { - let mut addrs = url.to_socket_addrs()?; - // connect_timeout only works with a single socket address - let addr = addrs.next().ok_or_else(|| Error::AddrParse(url.into()))?; - - let stream = TcpStream::connect_timeout(&addr, connect_timeout)?; - stream.set_read_timeout(Some(read_timeout))?; - stream.set_write_timeout(Some(write_timeout))?; - Ok(stream) - }; - - match self { + pub fn build_config(&self, config: ConfigBuilder) -> Result { + let (url, config) = match self { ElectrumUrl::Tls(url, validate) => { - let stream = make_stream(&url)?; - let client = RawClient::new_ssl_from_stream(url.as_str(), *validate, stream)?; - Ok(Client::SSL(client)) + (format!("tls://{}", url), config.validate_domain(*validate)) } - ElectrumUrl::Plaintext(url) => Ok(Client::TCP(make_stream(url)?.into())), - } + ElectrumUrl::Plaintext(url) => (format!("tcp://{}", url), config), + }; + Ok(Client::from_config(&url, config.build())?) } + pub fn url(&self) -> &str { match self { ElectrumUrl::Tls(url, _) => url, @@ -95,9 +70,6 @@ impl ElectrumUrl { } } -/// Timeouts for connect, read and write -pub type Timeouts = (Duration, Duration, Duration); - // Parse the standard :: string format, // with an optional non-standard `:noverify` suffix to skip tls validation impl FromStr for ElectrumUrl { diff --git a/subprojects/gdk_rust/gdk_electrum/src/spv.rs b/subprojects/gdk_rust/gdk_electrum/src/spv.rs index f71233e93..1dfeb317e 100644 --- a/subprojects/gdk_rust/gdk_electrum/src/spv.rs +++ b/subprojects/gdk_rust/gdk_electrum/src/spv.rs @@ -2,29 +2,24 @@ use log::warn; use rand::seq::SliceRandom; use serde::{Deserialize, Serialize}; use std::str::FromStr; -use std::time::Duration; use bitcoin::blockdata::constants::{max_target, DIFFCHANGE_INTERVAL, DIFFCHANGE_TIMESPAN}; use bitcoin::BlockHash; use bitcoin::{util::uint::Uint256, util::BitArray, BlockHeader}; -use electrum_client::{Client as ElectrumClient, ElectrumApi}; +use electrum_client::{Client as ElectrumClient, ConfigBuilder, ElectrumApi}; use gdk_common::network::Network; use crate::error::Error; use crate::headers::bitcoin::HeadersChain; -use crate::interface::{ElectrumUrl, Timeouts}; +use crate::interface::ElectrumUrl; const INIT_CHUNK_SIZE: u32 = 5; const MAX_CHUNK_SIZE: u32 = 200; const MAX_FORK_DEPTH: u32 = DIFFCHANGE_INTERVAL * 3; const SERVERS_PER_ROUND: usize = 3; -const TIMEOUTS: Timeouts = ( - Duration::from_secs(2), // connect timeout - Duration::from_secs(4), // read timeout - Duration::from_secs(2), // write timeout -); +const TIMEOUT: u8 = 3; // connect, read and write timeout #[derive(Debug)] pub struct SpvCrossValidator { @@ -145,7 +140,7 @@ pub fn spv_cross_validate( local_tip_hash: &BlockHash, server_url: &ElectrumUrl, ) -> Result { - let client = server_url.build_client_timeout(TIMEOUTS)?; + let client = server_url.build_config(ConfigBuilder::new().timeout(TIMEOUT)?)?; let remote_tip = client.block_headers_subscribe()?; let remote_tip_hash = remote_tip.header.block_hash(); let remote_tip_height = remote_tip.height as u32; diff --git a/subprojects/gdk_rust/tests/test_session.rs b/subprojects/gdk_rust/tests/test_session.rs index 8094668c9..2c7129101 100644 --- a/subprojects/gdk_rust/tests/test_session.rs +++ b/subprojects/gdk_rust/tests/test_session.rs @@ -183,7 +183,7 @@ pub fn setup( let electrs_header = loop { assert!(i > 0, "1 minute without updates"); i -= 1; - match RawClient::new(&electrs_url) { + match RawClient::new(&electrs_url, None) { Ok(c) => { let header = c.block_headers_subscribe_raw().unwrap(); if header.height == 101 { @@ -196,7 +196,7 @@ pub fn setup( } thread::sleep(Duration::from_millis(500)); }; - let electrs = RawClient::new(&electrs_url).unwrap(); + let electrs = RawClient::new(&electrs_url, None).unwrap(); info!("done creating electrs client"); let mut network = Network::default();