parent
2a9278879f
commit
7b4e99e80c
@ -8,11 +8,12 @@ before_script:
|
||||
script:
|
||||
- cargo fmt -- --check --verbose
|
||||
- cargo test --verbose --all
|
||||
- cargo check --verbose --features=use-openssl
|
||||
- cargo check --verbose --no-default-features --features=proxy
|
||||
- cargo check --verbose --no-default-features --features=tls
|
||||
- cargo check --verbose --no-default-features --features=minimal
|
||||
- cargo check --verbose --no-default-features --features=minimal,debug-calls
|
||||
- cargo check --verbose --no-default-features --features=minimal,no-sync
|
||||
- cargo check --verbose --no-default-features --features=proxy,use-openssl
|
||||
- cargo check --verbose --no-default-features --features=proxy,use-rustls
|
||||
|
||||
before_cache:
|
||||
- rm -rf "$TRAVIS_HOME/.cargo/registry/src"
|
||||
|
||||
22
Cargo.toml
22
Cargo.toml
@ -1,5 +1,4 @@
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "electrum-client"
|
||||
version = "0.1.0-beta.6"
|
||||
authors = ["Alekos Filini <alekos.filini@gmail.com>"]
|
||||
@ -23,23 +22,20 @@ path = "src/lib.rs"
|
||||
[dependencies]
|
||||
log = "^0.4"
|
||||
bitcoin = { version = "0.23", features = ["use-serde"] }
|
||||
tokio = { version = "0.2", features = ["net", "io-util"] }
|
||||
futures = "0.3"
|
||||
serde = { version = "^1.0", features = ["derive"] }
|
||||
serde_json = { version = "^1.0" }
|
||||
|
||||
# Optional dependencies
|
||||
tokio-tls = { version = "0.3", optional = true }
|
||||
native-tls = { version = "0.2.4", optional = true }
|
||||
tokio-socks = { version = "0.2", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { version = "0.2", features = ["net", "io-util", "macros"] }
|
||||
socks = { version = "^0.3", optional = true }
|
||||
openssl = { version = "^0.10", optional = true }
|
||||
rustls = { version = "0.16.0", optional = true, features = ["dangerous_configuration"] }
|
||||
webpki = { version = "0.21.0", optional = true }
|
||||
webpki-roots = { version = "^0.19", optional = true }
|
||||
|
||||
[features]
|
||||
default = ["tokio-tls", "native-tls", "tokio-socks"]
|
||||
no-sync = []
|
||||
default = ["socks", "webpki", "webpki-roots", "rustls"]
|
||||
minimal = []
|
||||
debug-calls = []
|
||||
proxy = ["tokio-socks"]
|
||||
tls = ["tokio-tls", "native-tls"]
|
||||
proxy = ["socks"]
|
||||
use-rustls = ["webpki", "webpki-roots", "rustls"]
|
||||
use-openssl = ["openssl"]
|
||||
|
||||
@ -2,9 +2,8 @@ extern crate electrum_client;
|
||||
|
||||
use electrum_client::Client;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let mut client = Client::new("kirsche.emzy.de:50001").await.unwrap();
|
||||
let res = client.server_features().await;
|
||||
fn main() {
|
||||
let mut client = Client::new("kirsche.emzy.de:50001").unwrap();
|
||||
let res = client.server_features();
|
||||
println!("{:#?}", res);
|
||||
}
|
||||
|
||||
9
examples/ssl.rs
Normal file
9
examples/ssl.rs
Normal file
@ -0,0 +1,9 @@
|
||||
extern crate electrum_client;
|
||||
|
||||
use electrum_client::Client;
|
||||
|
||||
fn main() {
|
||||
let mut client = Client::new_ssl("electrum2.hodlister.co:50002", true).unwrap();
|
||||
let res = client.server_features();
|
||||
println!("{:#?}", res);
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
extern crate electrum_client;
|
||||
|
||||
use electrum_client::Client;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let mut client = Client::new_tls("electrum2.hodlister.co:50002", true)
|
||||
.await
|
||||
.unwrap();
|
||||
let res = client.server_features().await;
|
||||
println!("{:#?}", res);
|
||||
}
|
||||
@ -2,15 +2,12 @@ extern crate electrum_client;
|
||||
|
||||
use electrum_client::Client;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
fn main() {
|
||||
// NOTE: This assumes Tor is running localy, with an unauthenticated Socks5 listening at
|
||||
// localhost:9050
|
||||
|
||||
let mut client = Client::new_proxy("ozahtqwp25chjdjd.onion:50001", "127.0.0.1:9050")
|
||||
.await
|
||||
.unwrap();
|
||||
let res = client.server_features().await;
|
||||
let mut client = Client::new_proxy("ozahtqwp25chjdjd.onion:50001", "127.0.0.1:9050").unwrap();
|
||||
let res = client.server_features();
|
||||
println!("{:#?}", res);
|
||||
|
||||
// works both with onion v2/v3 (if your Tor supports them)
|
||||
@ -18,8 +15,7 @@ async fn main() {
|
||||
"v7gtzf7nua6hdmb2wtqaqioqmesdb4xrlly4zwr7bvayxv2bpg665pqd.onion:50001",
|
||||
"127.0.0.1:9050",
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let res = client.server_features().await;
|
||||
let res = client.server_features();
|
||||
println!("{:#?}", res);
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
use bitcoin::hashes::hex::ToHex;
|
||||
use bitcoin::{Script, Txid};
|
||||
|
||||
use crate::types::{Param, ToElectrumScriptHash};
|
||||
use types::{Param, ToElectrumScriptHash};
|
||||
|
||||
/// Helper structure that caches all the requests before they are actually sent to the server.
|
||||
///
|
||||
|
||||
585
src/client.rs
585
src/client.rs
File diff suppressed because it is too large
Load Diff
30
src/lib.rs
30
src/lib.rs
@ -12,22 +12,34 @@
|
||||
//! # Example
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use electrum_client::{Client, Error};
|
||||
//! use electrum_client::Client;
|
||||
//!
|
||||
//! #[tokio::main]
|
||||
//! async fn main() -> Result<(), Error> {
|
||||
//! let mut client = Client::new("kirsche.emzy.de:50001").await?;
|
||||
//! let response = client.server_features().await?;
|
||||
//!
|
||||
//! Ok(())
|
||||
//! }
|
||||
//! let mut client = Client::new("kirsche.emzy.de:50001")?;
|
||||
//! let response = client.server_features()?;
|
||||
//! # Ok::<(), electrum_client::Error>(())
|
||||
//! ```
|
||||
|
||||
pub extern crate bitcoin;
|
||||
pub extern crate tokio;
|
||||
extern crate log;
|
||||
#[cfg(feature = "use-openssl")]
|
||||
extern crate openssl;
|
||||
#[cfg(all(
|
||||
any(feature = "default", feature = "use-rustls"),
|
||||
not(feature = "use-openssl")
|
||||
))]
|
||||
extern crate rustls;
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
#[cfg(any(feature = "default", feature = "proxy"))]
|
||||
extern crate socks;
|
||||
#[cfg(any(feature = "use-rustls", feature = "default"))]
|
||||
extern crate webpki;
|
||||
#[cfg(any(feature = "use-rustls", feature = "default"))]
|
||||
extern crate webpki_roots;
|
||||
|
||||
pub mod batch;
|
||||
pub mod client;
|
||||
mod stream;
|
||||
#[cfg(test)]
|
||||
mod test_stream;
|
||||
pub mod types;
|
||||
|
||||
@ -31,3 +31,10 @@ impl<T: Read + Write> Clone for ClonableStream<T> {
|
||||
ClonableStream(Arc::clone(&self.0))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
impl<T: Read + Write> ClonableStream<T> {
|
||||
pub fn stream(&self) -> Arc<Mutex<T>> {
|
||||
Arc::clone(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,7 @@
|
||||
use std::io::{Read, Write};
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
use std::io::{Read, Result, Write};
|
||||
|
||||
use std::fs::File;
|
||||
|
||||
use tokio::io::{AsyncRead, AsyncWrite, Result};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TestStream {
|
||||
pub file: File,
|
||||
pub buffer: Vec<u8>,
|
||||
@ -21,26 +16,18 @@ impl TestStream {
|
||||
}
|
||||
}
|
||||
|
||||
impl AsyncRead for TestStream {
|
||||
fn poll_read(
|
||||
mut self: Pin<&mut Self>,
|
||||
_cx: &mut Context,
|
||||
buf: &mut [u8],
|
||||
) -> Poll<Result<usize>> {
|
||||
Poll::Ready(self.as_mut().file.read(buf))
|
||||
impl Read for TestStream {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
||||
self.file.read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsyncWrite for TestStream {
|
||||
fn poll_write(mut self: Pin<&mut Self>, _cx: &mut Context, buf: &[u8]) -> Poll<Result<usize>> {
|
||||
Poll::Ready(self.as_mut().buffer.write(buf))
|
||||
impl Write for TestStream {
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||
self.buffer.write(buf)
|
||||
}
|
||||
|
||||
fn poll_flush(mut self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Result<()>> {
|
||||
Poll::Ready(self.as_mut().buffer.flush())
|
||||
}
|
||||
|
||||
fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Result<()>> {
|
||||
Poll::Ready(Ok(()))
|
||||
fn flush(&mut self) -> Result<()> {
|
||||
self.buffer.flush()
|
||||
}
|
||||
}
|
||||
|
||||
21
src/types.rs
21
src/types.rs
@ -242,16 +242,13 @@ pub enum Error {
|
||||
InvalidDNSNameError(String),
|
||||
/// Missing domain while it was explicitly asked to validate it
|
||||
MissingDomain,
|
||||
/// EOF while trying to read from the underlying stream
|
||||
EOF,
|
||||
|
||||
#[cfg(any(feature = "default", feature = "tls"))]
|
||||
/// TLS Error
|
||||
TLS(native_tls::Error),
|
||||
|
||||
#[cfg(any(feature = "default", feature = "proxy"))]
|
||||
/// Proxy Error
|
||||
Proxy(tokio_socks::Error),
|
||||
#[cfg(feature = "use-openssl")]
|
||||
/// Invalid OpenSSL method used
|
||||
InvalidSslMethod(openssl::error::ErrorStack),
|
||||
#[cfg(feature = "use-openssl")]
|
||||
/// SSL Handshake failed with the server
|
||||
SslHandshakeError(openssl::ssl::HandshakeError<std::net::TcpStream>),
|
||||
}
|
||||
|
||||
macro_rules! impl_error {
|
||||
@ -268,9 +265,3 @@ impl_error!(std::io::Error, IOError);
|
||||
impl_error!(serde_json::Error, JSON);
|
||||
impl_error!(bitcoin::hashes::hex::Error, Hex);
|
||||
impl_error!(bitcoin::consensus::encode::Error, Bitcoin);
|
||||
|
||||
#[cfg(any(feature = "default", feature = "tls"))]
|
||||
impl_error!(native_tls::Error, TLS);
|
||||
|
||||
#[cfg(any(feature = "default", feature = "proxy"))]
|
||||
impl_error!(tokio_socks::Error, Proxy);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user