Test against mainnet servers
This commit is contained in:
parent
f37bcd59e0
commit
db4554f9e2
@ -2,6 +2,9 @@ language: rust
|
||||
rust:
|
||||
- stable
|
||||
# - 1.31.0 TODO: support the first 2018-edition toolchain
|
||||
env:
|
||||
- TEST_ELECTRUM_SERVER=electrum.blockstream.info:50001
|
||||
- TEST_ELECTRUM_SERVER=bitcoin.aranguren.org:50001
|
||||
before_script:
|
||||
- rustup component add rustfmt
|
||||
# Run tests and check a few combinations of features
|
||||
|
||||
@ -9,9 +9,6 @@ documentation = "https://docs.rs/electrum-client/"
|
||||
description = "Bitcoin Electrum client library. Supports plaintext, TLS and Onion servers."
|
||||
keywords = ["bitcoin", "electrum"]
|
||||
readme = "README.md"
|
||||
exclude = [
|
||||
"test_data/*",
|
||||
]
|
||||
|
||||
# loosely based on https://github.com/evgeniy-scherbina/rust-electrumx-client
|
||||
|
||||
|
||||
@ -1,39 +1,9 @@
|
||||
extern crate electrum_client;
|
||||
extern crate env_logger;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
|
||||
use electrum_client::Client;
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let client = Arc::new(Client::new("electrum.blockstream.info:50001").unwrap());
|
||||
|
||||
let mut handles = Vec::new();
|
||||
|
||||
/*let _client = Arc::clone(&client);
|
||||
let handle = thread::spawn(move || {
|
||||
_client.reader_thread().unwrap();
|
||||
println!("reader thread exited");
|
||||
});
|
||||
|
||||
handles.push(handle);*/
|
||||
|
||||
thread::sleep(std::time::Duration::from_secs(1));
|
||||
|
||||
for _ in 0..4 {
|
||||
let client = Arc::clone(&client);
|
||||
let handle = thread::spawn(move || {
|
||||
let res = client.batch_estimate_fee(vec![1, 3, 6, 12]);
|
||||
println!("{:?}", res);
|
||||
});
|
||||
|
||||
handles.push(handle);
|
||||
}
|
||||
|
||||
for h in handles {
|
||||
h.join().unwrap();
|
||||
}
|
||||
let client = Client::new("kirsche.emzy.de:50001").unwrap();
|
||||
let res = client.server_features();
|
||||
println!("{:#?}", res);
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ extern crate electrum_client;
|
||||
use electrum_client::Client;
|
||||
|
||||
fn main() {
|
||||
let mut client = Client::new_ssl("electrum2.hodlister.co:50002", true).unwrap();
|
||||
let client = Client::new_ssl("electrum2.hodlister.co:50002", true).unwrap();
|
||||
let res = client.server_features();
|
||||
println!("{:#?}", res);
|
||||
}
|
||||
|
||||
@ -6,12 +6,12 @@ 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").unwrap();
|
||||
let 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)
|
||||
let mut client = Client::new_proxy(
|
||||
let client = Client::new_proxy(
|
||||
"v7gtzf7nua6hdmb2wtqaqioqmesdb4xrlly4zwr7bvayxv2bpg665pqd.onion:50001",
|
||||
"127.0.0.1:9050",
|
||||
)
|
||||
|
||||
235
src/client.rs
235
src/client.rs
@ -2,11 +2,11 @@
|
||||
//!
|
||||
//! This module contains definitions of all the complex data structures that are returned by calls
|
||||
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
use std::io::{BufRead, BufReader, Read, Write};
|
||||
use std::mem::drop;
|
||||
use std::net::{TcpStream, ToSocketAddrs};
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||
use std::sync::{Mutex, TryLockError};
|
||||
|
||||
@ -102,7 +102,7 @@ where
|
||||
script_notifications: Mutex<HashMap<ScriptHash, VecDeque<ScriptStatus>>>,
|
||||
|
||||
#[cfg(feature = "debug-calls")]
|
||||
calls: usize,
|
||||
calls: AtomicUsize,
|
||||
}
|
||||
|
||||
impl<S> From<S> for Client<S>
|
||||
@ -123,7 +123,7 @@ where
|
||||
script_notifications: Mutex::new(HashMap::new()),
|
||||
|
||||
#[cfg(feature = "debug-calls")]
|
||||
calls: 0,
|
||||
calls: AtomicUsize::new(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -723,8 +723,14 @@ impl<S: Read + Write> Client<S> {
|
||||
params,
|
||||
);
|
||||
let result = self.call(req)?;
|
||||
let mut result: Vec<ListUnspentRes> = serde_json::from_value(result)?;
|
||||
|
||||
Ok(serde_json::from_value(result)?)
|
||||
// This should not be necessary, since the protocol documentation says that the txs should
|
||||
// be "in blockchain order" (https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-scripthash-listunspent).
|
||||
// However, elects seems to be ignoring this at the moment, so we'll sort again here just
|
||||
// to make sure the result is consistent.
|
||||
result.sort_unstable_by_key(|k| (k.height, k.tx_pos));
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Batch version of [`script_list_unspent`](#method.script_list_unspent).
|
||||
@ -879,13 +885,13 @@ impl<S: Read + Write> Client<S> {
|
||||
#[cfg(feature = "debug-calls")]
|
||||
/// Returns the number of network calls made since the creation of the client.
|
||||
pub fn calls_made(&self) -> usize {
|
||||
self.calls
|
||||
self.calls.load(Ordering::SeqCst)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(feature = "debug-calls")]
|
||||
fn increment_calls(&mut self) {
|
||||
self.calls += 1;
|
||||
fn increment_calls(&self) {
|
||||
self.calls.fetch_add(1, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -895,127 +901,76 @@ impl<S: Read + Write> Client<S> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use test_stream::TestStream;
|
||||
|
||||
use client::Client;
|
||||
|
||||
impl Client<TestStream> {
|
||||
pub fn new_test(file: File) -> Self {
|
||||
TestStream::new(file).into()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_test_prelude {
|
||||
( $testcase:expr ) => {{
|
||||
let data_in = File::open(format!("./test_data/{}.in", $testcase)).unwrap();
|
||||
Client::new_test(data_in)
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! impl_test_conclusion {
|
||||
( $testcase:expr, $stream:expr ) => {
|
||||
let mut data_out = File::open(format!("./test_data/{}.out", $testcase)).unwrap();
|
||||
let mut buffer = Vec::new();
|
||||
data_out.read_to_end(&mut buffer).unwrap();
|
||||
let stream_buffer = $stream.stream().lock().unwrap().buffer.clone();
|
||||
|
||||
assert_eq!(
|
||||
stream_buffer,
|
||||
buffer,
|
||||
"Expecting `{}`, got `{}`",
|
||||
String::from_utf8_lossy(&buffer.to_vec()),
|
||||
String::from_utf8_lossy(&stream_buffer)
|
||||
);
|
||||
};
|
||||
fn get_test_server() -> String {
|
||||
std::env::var("TEST_ELECTRUM_SERVER").unwrap_or("electrum.blockstream.info:50001".into())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_server_features_simple() {
|
||||
let test_case = "server_features_simple";
|
||||
let mut client = impl_test_prelude!(test_case);
|
||||
let client = Client::new(get_test_server()).unwrap();
|
||||
|
||||
let resp = client.server_features().unwrap();
|
||||
assert_eq!(resp.server_version, "ElectrumX 1.0.17");
|
||||
assert_eq!(
|
||||
resp.genesis_hash,
|
||||
[
|
||||
0x00, 0x00, 0x00, 0x00, 0x09, 0x33, 0xEA, 0x01, 0xAD, 0x0E, 0xE9, 0x84, 0x20, 0x97,
|
||||
0x79, 0xBA, 0xAE, 0xC3, 0xCE, 0xD9, 0x0F, 0xA3, 0xF4, 0x08, 0x71, 0x95, 0x26, 0xF8,
|
||||
0xD7, 0x7F, 0x49, 0x43
|
||||
]
|
||||
0, 0, 0, 0, 0, 25, 214, 104, 156, 8, 90, 225, 101, 131, 30, 147, 79, 247, 99, 174,
|
||||
70, 162, 166, 193, 114, 179, 241, 182, 10, 140, 226, 111
|
||||
],
|
||||
);
|
||||
assert_eq!(resp.protocol_min, "1.0");
|
||||
assert_eq!(resp.protocol_max, "1.0");
|
||||
assert_eq!(resp.hash_function, Some("sha256".into()));
|
||||
assert_eq!(resp.pruning, None);
|
||||
|
||||
impl_test_conclusion!(test_case, client.stream);
|
||||
}
|
||||
#[test]
|
||||
fn test_relay_fee() {
|
||||
let test_case = "relay_fee";
|
||||
let mut client = impl_test_prelude!(test_case);
|
||||
let client = Client::new(get_test_server()).unwrap();
|
||||
|
||||
let resp = client.relay_fee().unwrap();
|
||||
assert_eq!(resp, 123.4);
|
||||
|
||||
impl_test_conclusion!(test_case, client.stream);
|
||||
assert_eq!(resp, 0.00001);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_estimate_fee() {
|
||||
let test_case = "estimate_fee";
|
||||
let mut client = impl_test_prelude!(test_case);
|
||||
let client = Client::new(get_test_server()).unwrap();
|
||||
|
||||
let resp = client.estimate_fee(10).unwrap();
|
||||
assert_eq!(resp, 10.0);
|
||||
|
||||
impl_test_conclusion!(test_case, client.stream);
|
||||
assert!(resp > 0.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_block_header() {
|
||||
let test_case = "block_header";
|
||||
let mut client = impl_test_prelude!(test_case);
|
||||
let client = Client::new(get_test_server()).unwrap();
|
||||
|
||||
let resp = client.block_header(500).unwrap();
|
||||
assert_eq!(resp.version, 536870912);
|
||||
assert_eq!(resp.time, 1578166214);
|
||||
assert_eq!(resp.nonce, 0);
|
||||
|
||||
impl_test_conclusion!(test_case, client.stream);
|
||||
let resp = client.block_header(0).unwrap();
|
||||
assert_eq!(resp.version, 0x01);
|
||||
assert_eq!(resp.time, 1231006505);
|
||||
assert_eq!(resp.nonce, 0x7c2bac1d);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_block_headers() {
|
||||
let test_case = "block_headers";
|
||||
let mut client = impl_test_prelude!(test_case);
|
||||
let client = Client::new(get_test_server()).unwrap();
|
||||
|
||||
let resp = client.block_headers(100, 4).unwrap();
|
||||
let resp = client.block_headers(0, 4).unwrap();
|
||||
assert_eq!(resp.count, 4);
|
||||
assert_eq!(resp.max, 2016);
|
||||
assert_eq!(resp.headers.len(), 4);
|
||||
|
||||
assert_eq!(resp.headers[0].time, 1563694949);
|
||||
|
||||
impl_test_conclusion!(test_case, client.stream);
|
||||
assert_eq!(resp.headers[0].time, 1231006505);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_script_get_balance() {
|
||||
use std::str::FromStr;
|
||||
|
||||
let test_case = "script_get_balance";
|
||||
let mut client = impl_test_prelude!(test_case);
|
||||
let client = Client::new(get_test_server()).unwrap();
|
||||
|
||||
let addr = bitcoin::Address::from_str("2N1xJCxBUXTDs6y8Sydz3axhAiXrrQwcosi").unwrap();
|
||||
// Realistically nobody will ever spend from this address, so we can expect the balance to
|
||||
// increase over time
|
||||
let addr = bitcoin::Address::from_str("1CounterpartyXXXXXXXXXXXXXXXUWLpVr").unwrap();
|
||||
let resp = client.script_get_balance(&addr.script_pubkey()).unwrap();
|
||||
assert_eq!(resp.confirmed, 0);
|
||||
assert_eq!(resp.unconfirmed, 130000000);
|
||||
|
||||
impl_test_conclusion!(test_case, client.stream);
|
||||
assert!(resp.confirmed >= 213091301265);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -1025,80 +980,67 @@ mod test {
|
||||
use bitcoin::hashes::hex::FromHex;
|
||||
use bitcoin::Txid;
|
||||
|
||||
let test_case = "script_get_history";
|
||||
let mut client = impl_test_prelude!(test_case);
|
||||
let client = Client::new(get_test_server()).unwrap();
|
||||
|
||||
let addr = bitcoin::Address::from_str("2N1xJCxBUXTDs6y8Sydz3axhAiXrrQwcosi").unwrap();
|
||||
// Mt.Gox hack address
|
||||
let addr = bitcoin::Address::from_str("1FeexV6bAHb8ybZjqQMjJrcCrHGW9sb6uF").unwrap();
|
||||
let resp = client.script_get_history(&addr.script_pubkey()).unwrap();
|
||||
assert_eq!(resp.len(), 2);
|
||||
|
||||
assert!(resp.len() >= 328);
|
||||
assert_eq!(
|
||||
resp[0].tx_hash,
|
||||
Txid::from_hex("a1aa2b52fb79641f918d44a27f51781c3c0c49f7ee0e4b14dbb37c722853f046")
|
||||
Txid::from_hex("e67a0550848b7932d7796aeea16ab0e48a5cfe81c4e8cca2c5b03e0416850114")
|
||||
.unwrap()
|
||||
);
|
||||
|
||||
impl_test_conclusion!(test_case, client.stream);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_script_list_unspent() {
|
||||
use std::str::FromStr;
|
||||
|
||||
use bitcoin::hashes::hex::FromHex;
|
||||
use bitcoin::Txid;
|
||||
use std::str::FromStr;
|
||||
|
||||
let test_case = "script_list_unspent";
|
||||
let mut client = impl_test_prelude!(test_case);
|
||||
let client = Client::new(get_test_server()).unwrap();
|
||||
|
||||
let addr = bitcoin::Address::from_str("2N1xJCxBUXTDs6y8Sydz3axhAiXrrQwcosi").unwrap();
|
||||
// Mt.Gox hack address
|
||||
let addr = bitcoin::Address::from_str("1FeexV6bAHb8ybZjqQMjJrcCrHGW9sb6uF").unwrap();
|
||||
let resp = client.script_list_unspent(&addr.script_pubkey()).unwrap();
|
||||
assert_eq!(resp.len(), 2);
|
||||
assert_eq!(resp[0].value, 30000000);
|
||||
assert_eq!(resp[0].height, 0);
|
||||
assert_eq!(resp[0].tx_pos, 1);
|
||||
|
||||
assert!(resp.len() >= 329);
|
||||
assert_eq!(resp[0].value, 7995600000000);
|
||||
assert_eq!(resp[0].height, 111194);
|
||||
assert_eq!(resp[0].tx_pos, 0);
|
||||
assert_eq!(
|
||||
resp[0].tx_hash,
|
||||
Txid::from_hex("a1aa2b52fb79641f918d44a27f51781c3c0c49f7ee0e4b14dbb37c722853f046")
|
||||
Txid::from_hex("e67a0550848b7932d7796aeea16ab0e48a5cfe81c4e8cca2c5b03e0416850114")
|
||||
.unwrap()
|
||||
);
|
||||
|
||||
impl_test_conclusion!(test_case, client.stream);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_batch_script_list_unspent() {
|
||||
use std::str::FromStr;
|
||||
|
||||
let test_case = "batch_script_list_unspent";
|
||||
let mut client = impl_test_prelude!(test_case);
|
||||
let client = Client::new(get_test_server()).unwrap();
|
||||
|
||||
let script_1 = bitcoin::Address::from_str("2N1xJCxBUXTDs6y8Sydz3axhAiXrrQwcosi")
|
||||
.unwrap()
|
||||
.script_pubkey();
|
||||
let script_2 = bitcoin::Address::from_str("2MyEi7dbTfQxo1M4hJaAzA2tgEJFQhYv5Au")
|
||||
// Mt.Gox hack address
|
||||
let script_1 = bitcoin::Address::from_str("1FeexV6bAHb8ybZjqQMjJrcCrHGW9sb6uF")
|
||||
.unwrap()
|
||||
.script_pubkey();
|
||||
|
||||
let resp = client
|
||||
.batch_script_list_unspent(vec![&script_1, &script_2])
|
||||
.unwrap();
|
||||
assert_eq!(resp.len(), 2);
|
||||
assert_eq!(resp[0].len(), 2);
|
||||
assert_eq!(resp[1].len(), 1);
|
||||
|
||||
impl_test_conclusion!(test_case, client.stream);
|
||||
let resp = client.batch_script_list_unspent(vec![&script_1]).unwrap();
|
||||
assert_eq!(resp.len(), 1);
|
||||
assert!(resp[0].len() >= 329);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_batch_estimate_fee() {
|
||||
let test_case = "batch_estimate_fee";
|
||||
let mut client = impl_test_prelude!(test_case);
|
||||
let client = Client::new(get_test_server()).unwrap();
|
||||
|
||||
let resp = client.batch_estimate_fee(vec![10, 20]).unwrap();
|
||||
assert_eq!(resp[0], 10.0);
|
||||
assert_eq!(resp[1], 20.0);
|
||||
|
||||
impl_test_conclusion!(test_case, client.stream);
|
||||
assert_eq!(resp.len(), 2);
|
||||
assert!(resp[0] > 0.0);
|
||||
assert!(resp[1] > 0.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -1106,41 +1048,16 @@ mod test {
|
||||
use bitcoin::hashes::hex::FromHex;
|
||||
use bitcoin::Txid;
|
||||
|
||||
let test_case = "transaction_get";
|
||||
let mut client = impl_test_prelude!(test_case);
|
||||
let client = Client::new(get_test_server()).unwrap();
|
||||
|
||||
let resp = client
|
||||
.transaction_get(
|
||||
&Txid::from_hex("a1aa2b52fb79641f918d44a27f51781c3c0c49f7ee0e4b14dbb37c722853f046")
|
||||
&Txid::from_hex("cc2ca076fd04c2aeed6d02151c447ced3d09be6fb4d4ef36cb5ed4e7a3260566")
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(resp.version, 2);
|
||||
assert_eq!(resp.lock_time, 1376);
|
||||
|
||||
impl_test_conclusion!(test_case, client.stream);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transaction_broadcast() {
|
||||
use bitcoin::consensus::deserialize;
|
||||
use bitcoin::hashes::hex::FromHex;
|
||||
use bitcoin::Txid;
|
||||
|
||||
let test_case = "transaction_broadcast";
|
||||
let mut client = impl_test_prelude!(test_case);
|
||||
|
||||
let buf = Vec::<u8>::from_hex("02000000000101f6cd5873d669cc2de550453623d9d10ed5b5ba906d81160ee3ab853ebcfffa0c0100000000feffffff02e22f82000000000017a914e229870f3af1b1a3aefc3452a4d2939b443e6eba8780c3c9010000000017a9145f859501ff79211aeb972633b782743dd3b31dab8702473044022046ff3b0618107e08bd25fb753e31542b8c23575d7e9faf43dd17f59727cfb9c902200a4f3837105808d810de01fcd63fb18e66a69026090dc72b66840d41e55c6bf3012103e531113bbca998f8d164235e3395db336d3ba03552d1bfaa83fd7cffe6e5c6c960050000").unwrap();
|
||||
let tx: bitcoin::Transaction = deserialize(&buf).unwrap();
|
||||
|
||||
let resp = client.transaction_broadcast(&tx).unwrap();
|
||||
assert_eq!(
|
||||
resp,
|
||||
Txid::from_hex("a1aa2b52fb79641f918d44a27f51781c3c0c49f7ee0e4b14dbb37c722853f046")
|
||||
.unwrap()
|
||||
);
|
||||
|
||||
impl_test_conclusion!(test_case, client.stream);
|
||||
assert_eq!(resp.version, 1);
|
||||
assert_eq!(resp.lock_time, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -1148,28 +1065,24 @@ mod test {
|
||||
use bitcoin::hashes::hex::FromHex;
|
||||
use bitcoin::Txid;
|
||||
|
||||
let test_case = "transaction_get_merkle";
|
||||
let mut client = impl_test_prelude!(test_case);
|
||||
let client = Client::new(get_test_server()).unwrap();
|
||||
|
||||
let resp = client
|
||||
.transaction_get_merkle(
|
||||
&Txid::from_hex("2d64851151550e8c4d337f335ee28874401d55b358a66f1bafab2c3e9f48773d")
|
||||
&Txid::from_hex("cc2ca076fd04c2aeed6d02151c447ced3d09be6fb4d4ef36cb5ed4e7a3260566")
|
||||
.unwrap(),
|
||||
1234,
|
||||
630000,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(resp.block_height, 450538);
|
||||
assert_eq!(resp.pos, 710);
|
||||
assert_eq!(resp.merkle.len(), 11);
|
||||
assert_eq!(resp.block_height, 630000);
|
||||
assert_eq!(resp.pos, 0);
|
||||
assert_eq!(resp.merkle.len(), 12);
|
||||
assert_eq!(
|
||||
resp.merkle[0],
|
||||
[
|
||||
0x71, 0x3D, 0x6C, 0x7E, 0x6C, 0xE7, 0xBB, 0xEA, 0x70, 0x8D, 0x61, 0x16, 0x22, 0x31,
|
||||
0xEA, 0xA8, 0xEC, 0xB3, 0x1C, 0x4C, 0x5D, 0xD8, 0x4F, 0x81, 0xC2, 0x04, 0x09, 0xA9,
|
||||
0x00, 0x69, 0xCB, 0x24
|
||||
30, 10, 161, 245, 132, 125, 136, 198, 186, 138, 107, 216, 92, 22, 145, 81, 130,
|
||||
126, 200, 65, 121, 158, 105, 111, 38, 151, 38, 147, 144, 224, 5, 218
|
||||
]
|
||||
);
|
||||
|
||||
impl_test_conclusion!(test_case, client.stream);
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,8 +41,6 @@ extern crate webpki_roots;
|
||||
pub mod batch;
|
||||
pub mod client;
|
||||
mod stream;
|
||||
#[cfg(test)]
|
||||
mod test_stream;
|
||||
pub mod types;
|
||||
|
||||
pub use batch::Batch;
|
||||
|
||||
@ -31,10 +31,3 @@ 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,33 +0,0 @@
|
||||
use std::io::{Read, Result, Write};
|
||||
|
||||
use std::fs::File;
|
||||
|
||||
pub struct TestStream {
|
||||
pub file: File,
|
||||
pub buffer: Vec<u8>,
|
||||
}
|
||||
|
||||
impl TestStream {
|
||||
pub fn new(file: File) -> Self {
|
||||
TestStream {
|
||||
file,
|
||||
buffer: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Read for TestStream {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
||||
self.file.read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for TestStream {
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||
self.buffer.write(buf)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> Result<()> {
|
||||
self.buffer.flush()
|
||||
}
|
||||
}
|
||||
@ -1,2 +0,0 @@
|
||||
{"id":0,"jsonrpc":"2.0","result":10.0}
|
||||
{"id":0,"jsonrpc":"2.0","result":20.0}
|
||||
@ -1,2 +0,0 @@
|
||||
{"jsonrpc":"2.0","id":0,"method":"blockchain.estimatefee","params":[10]}
|
||||
{"jsonrpc":"2.0","id":1,"method":"blockchain.estimatefee","params":[20]}
|
||||
@ -1,2 +0,0 @@
|
||||
{"id":1,"jsonrpc":"2.0","result":[{"height":0,"tx_hash":"83f5de2e6d7dfd5b582a5b2a3de4a5adb32c9cdca91473cf1fbcba76d56e4486","tx_pos":1,"value":100000000}]}
|
||||
{"id":0,"jsonrpc":"2.0","result":[{"height":0,"tx_hash":"eb07e5d67565bad5231fd5aeeb16d0c2c53371265690642b943aa24c83ecae1d","tx_pos":0,"value":300000000},{"height":0,"tx_hash":"824f9a426d4b6a9b23c52901754a01017f3113ffdf3ed20c02747db85b161a40","tx_pos":0,"value":100000000}]}
|
||||
@ -1,2 +0,0 @@
|
||||
{"jsonrpc":"2.0","id":0,"method":"blockchain.scripthash.listunspent","params":["c60b02f19c2053efedddb804024edd3f05f181ac2f828384dff40d072d25d962"]}
|
||||
{"jsonrpc":"2.0","id":1,"method":"blockchain.scripthash.listunspent","params":["97897cdd5b98fab0b99aa5f861cee45c597a1ab2fe90ea1a7cf234b029eb5883"]}
|
||||
@ -1 +0,0 @@
|
||||
{"id":0,"jsonrpc":"2.0","result":"000000207a8eb5cf562c0b013f03bf4be90318770510bcc57b918491b07f29f15a6433416fe34a556424483dad983f24f906a77638b4583688a0308c75d5bb9f31561e20c6e7105effff7f2000000000"}
|
||||
@ -1 +0,0 @@
|
||||
{"jsonrpc":"2.0","id":0,"method":"blockchain.block.header","params":[500]}
|
||||
@ -1 +0,0 @@
|
||||
{"id":0,"jsonrpc":"2.0","result":{"count":4,"hex":"00000020a6b63c802e0bdeccfd6f4e132dfbad5822c563ef705b57267b1c05c07fb4bb066a95320ef101fba9911c3f4870cc8c3f8900cfa57384379635cba0466fb42bf36517345dffff7f200000000000000020cfa3201d443e007ec5edebbb2600c11ba04f07bd88056ad1ac402573ffe63473937fa56356c956cc4320cd8d98a3db17b845cffaf07158b5abcc7f914c85dcc66517345dffff7f200100000000000020a20ed7c06c55db6ec785d5578c32fb57c3db0bf1d3ef6c90a7af647d88add90df34090f37280af8b2e31f7857350947b1698a1a1742117eb1eff7d87c7fa9b986517345dffff7f2001000000000000207d475add1706bb3fceb22a45a9816ce156a8292a515bf4eeecf60e5aa9dc3007edf508bf9eb08dfa3d73d758e05e9f6730552277c5a249e6ba89ad7b50b4c93d6517345dffff7f2000000000","max":2016}}
|
||||
@ -1 +0,0 @@
|
||||
{"jsonrpc":"2.0","id":0,"method":"blockchain.block.headers","params":[100,4]}
|
||||
@ -1 +0,0 @@
|
||||
{"id":0,"jsonrpc":"2.0","result":10.0}
|
||||
@ -1 +0,0 @@
|
||||
{"jsonrpc":"2.0","id":0,"method":"blockchain.estimatefee","params":[10]}
|
||||
@ -1 +0,0 @@
|
||||
{"id":0,"jsonrpc":"2.0","result":123.4}
|
||||
@ -1 +0,0 @@
|
||||
{"jsonrpc":"2.0","id":0,"method":"blockchain.relayfee","params":[]}
|
||||
@ -1 +0,0 @@
|
||||
{"id":0,"jsonrpc":"2.0","result":{"confirmed":0,"unconfirmed":130000000}}
|
||||
@ -1 +0,0 @@
|
||||
{"jsonrpc":"2.0","id":0,"method":"blockchain.scripthash.get_balance","params":["c60b02f19c2053efedddb804024edd3f05f181ac2f828384dff40d072d25d962"]}
|
||||
@ -1 +0,0 @@
|
||||
{"id":0,"jsonrpc":"2.0","result":[{"height":0,"tx_hash":"a1aa2b52fb79641f918d44a27f51781c3c0c49f7ee0e4b14dbb37c722853f046"},{"height":0,"tx_hash":"f9b4649764b9e9b53641d8bad750b1e40329937f79ae192f9e84e4a7978267bc"}]}
|
||||
@ -1 +0,0 @@
|
||||
{"jsonrpc":"2.0","id":0,"method":"blockchain.scripthash.get_history","params":["c60b02f19c2053efedddb804024edd3f05f181ac2f828384dff40d072d25d962"]}
|
||||
@ -1 +0,0 @@
|
||||
{"id":0,"jsonrpc":"2.0","result":[{"height":0,"tx_hash":"a1aa2b52fb79641f918d44a27f51781c3c0c49f7ee0e4b14dbb37c722853f046","tx_pos":1,"value":30000000},{"height":0,"tx_hash":"f9b4649764b9e9b53641d8bad750b1e40329937f79ae192f9e84e4a7978267bc","tx_pos":1,"value":100000000}]}
|
||||
@ -1 +0,0 @@
|
||||
{"jsonrpc":"2.0","id":0,"method":"blockchain.scripthash.listunspent","params":["c60b02f19c2053efedddb804024edd3f05f181ac2f828384dff40d072d25d962"]}
|
||||
@ -1 +0,0 @@
|
||||
{"id": 0, "method":"server.features", "result": {"genesis_hash": "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943","hosts": {"14.3.140.101": {"tcp_port": 51001, "ssl_port": 51002}},"protocol_max": "1.0","protocol_min": "1.0","pruning": null,"server_version": "ElectrumX 1.0.17","hash_function": "sha256"}}
|
||||
@ -1 +0,0 @@
|
||||
{"jsonrpc":"2.0","id":0,"method":"server.features","params":[]}
|
||||
@ -1 +0,0 @@
|
||||
{"id":0,"jsonrpc":"2.0","result":"a1aa2b52fb79641f918d44a27f51781c3c0c49f7ee0e4b14dbb37c722853f046"}
|
||||
@ -1 +0,0 @@
|
||||
{"jsonrpc":"2.0","id":0,"method":"blockchain.transaction.broadcast","params":["02000000000101f6cd5873d669cc2de550453623d9d10ed5b5ba906d81160ee3ab853ebcfffa0c0100000000feffffff02e22f82000000000017a914e229870f3af1b1a3aefc3452a4d2939b443e6eba8780c3c9010000000017a9145f859501ff79211aeb972633b782743dd3b31dab8702473044022046ff3b0618107e08bd25fb753e31542b8c23575d7e9faf43dd17f59727cfb9c902200a4f3837105808d810de01fcd63fb18e66a69026090dc72b66840d41e55c6bf3012103e531113bbca998f8d164235e3395db336d3ba03552d1bfaa83fd7cffe6e5c6c960050000"]}
|
||||
@ -1 +0,0 @@
|
||||
{"id":0,"jsonrpc":"2.0","result":"02000000000101f6cd5873d669cc2de550453623d9d10ed5b5ba906d81160ee3ab853ebcfffa0c0100000000feffffff02e22f82000000000017a914e229870f3af1b1a3aefc3452a4d2939b443e6eba8780c3c9010000000017a9145f859501ff79211aeb972633b782743dd3b31dab8702473044022046ff3b0618107e08bd25fb753e31542b8c23575d7e9faf43dd17f59727cfb9c902200a4f3837105808d810de01fcd63fb18e66a69026090dc72b66840d41e55c6bf3012103e531113bbca998f8d164235e3395db336d3ba03552d1bfaa83fd7cffe6e5c6c960050000"}
|
||||
@ -1 +0,0 @@
|
||||
{"jsonrpc":"2.0","id":0,"method":"blockchain.transaction.get","params":["a1aa2b52fb79641f918d44a27f51781c3c0c49f7ee0e4b14dbb37c722853f046"]}
|
||||
@ -1 +0,0 @@
|
||||
{"id": 0, "method": "blockchain.transaction.get_merkle", "result": {"merkle": ["713d6c7e6ce7bbea708d61162231eaa8ecb31c4c5dd84f81c20409a90069cb24", "03dbaec78d4a52fbaf3c7aa5d3fccd9d8654f323940716ddf5ee2e4bda458fde", "e670224b23f156c27993ac3071940c0ff865b812e21e0a162fe7a005d6e57851", "369a1619a67c3108a8850118602e3669455c70cdcdb89248b64cc6325575b885", "4756688678644dcb27d62931f04013254a62aeee5dec139d1aac9f7b1f318112", "7b97e73abc043836fd890555bfce54757d387943a6860e5450525e8e9ab46be5", "61505055e8b639b7c64fd58bce6fc5c2378b92e025a02583303f69930091b1c3", "27a654ff1895385ac14a574a0415d3bbba9ec23a8774f22ec20d53dd0b5386ff", "5312ed87933075e60a9511857d23d460a085f3b6e9e5e565ad2443d223cfccdc", "94f60b14a9f106440a197054936e6fb92abbd69d6059b38fdf79b33fc864fca0", "2d64851151550e8c4d337f335ee28874401d55b358a66f1bafab2c3e9f48773d"], "block_height": 450538, "pos": 710}}
|
||||
@ -1 +0,0 @@
|
||||
{"jsonrpc":"2.0","id":0,"method":"blockchain.transaction.get_merkle","params":["2d64851151550e8c4d337f335ee28874401d55b358a66f1bafab2c3e9f48773d",1234]}
|
||||
Loading…
Reference in New Issue
Block a user