Skip to content

code optimisations and clippies fixes #325

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -20,8 +20,6 @@ It assumes that the node has password authentication setup, the RPC interface is
is set up to accept RPC connections.

```rust
extern crate bitcoincore_rpc;

use bitcoincore_rpc::{Auth, Client, RpcApi};

fn main() {
81 changes: 40 additions & 41 deletions client/src/client.rs
Original file line number Diff line number Diff line change
@@ -17,11 +17,8 @@ use std::{fmt, result};

use crate::{bitcoin, deserialize_hex};
use bitcoin::hex::DisplayHex;
use jsonrpc;
use serde;
use serde_json;

use crate::bitcoin::address::{NetworkUnchecked, NetworkChecked};
use crate::bitcoin::address::{NetworkChecked, NetworkUnchecked};
use crate::bitcoin::hashes::hex::FromHex;
use crate::bitcoin::secp256k1::ecdsa::Signature;
use crate::bitcoin::{
@@ -54,11 +51,11 @@ impl From<OutPoint> for JsonOutPoint {
}
}

impl Into<OutPoint> for JsonOutPoint {
fn into(self) -> OutPoint {
impl From<JsonOutPoint> for OutPoint {
fn from(val: JsonOutPoint) -> Self {
OutPoint {
txid: self.txid,
vout: self.vout,
txid: val.txid,
vout: val.vout,
}
}
}
@@ -112,9 +109,9 @@ fn empty_obj() -> serde_json::Value {
///
/// Elements of `args` without corresponding `defaults` value, won't
/// be substituted, because they are required.
fn handle_defaults<'a, 'b>(
fn handle_defaults<'a>(
args: &'a mut [serde_json::Value],
defaults: &'b [serde_json::Value],
defaults: &[serde_json::Value],
) -> &'a [serde_json::Value] {
assert!(args.len() >= defaults.len());

@@ -230,7 +227,7 @@ pub trait RpcApi: Sized {
&self,
id: &<T as queryable::Queryable<Self>>::Id,
) -> Result<T> {
T::query(&self, &id)
T::query(self, id)
}

fn get_network_info(&self) -> Result<json::GetNetworkInfoResult> {
@@ -377,9 +374,9 @@ pub trait RpcApi: Sized {
self.call(
"getblocktemplate",
&[into_json(Argument {
mode: mode,
rules: rules,
capabilities: capabilities,
mode,
rules,
capabilities,
})?],
)
}
@@ -418,7 +415,7 @@ pub trait RpcApi: Sized {
type_: json::SoftforkType::Buried,
bip9: None,
height: None,
active: active,
active,
},
);
}
@@ -531,7 +528,7 @@ pub trait RpcApi: Sized {
}

fn get_balances(&self) -> Result<json::GetBalancesResult> {
Ok(self.call("getbalances", &[])?)
self.call("getbalances", &[])
}

fn get_received_by_address(&self, address: &Address, minconf: Option<u32>) -> Result<Amount> {
@@ -702,18 +699,14 @@ pub trait RpcApi: Sized {

/// To unlock, use [unlock_unspent].
fn lock_unspent(&self, outputs: &[OutPoint]) -> Result<bool> {
let outputs: Vec<_> = outputs
.into_iter()
.map(|o| serde_json::to_value(JsonOutPoint::from(*o)).unwrap())
.collect();
let outputs: Vec<_> =
outputs.iter().map(|o| serde_json::to_value(JsonOutPoint::from(*o)).unwrap()).collect();
self.call("lockunspent", &[false.into(), outputs.into()])
}

fn unlock_unspent(&self, outputs: &[OutPoint]) -> Result<bool> {
let outputs: Vec<_> = outputs
.into_iter()
.map(|o| serde_json::to_value(JsonOutPoint::from(*o)).unwrap())
.collect();
let outputs: Vec<_> =
outputs.iter().map(|o| serde_json::to_value(JsonOutPoint::from(*o)).unwrap()).collect();
self.call("lockunspent", &[true.into(), outputs.into()])
}

@@ -891,7 +884,10 @@ pub trait RpcApi: Sized {
}

/// Generate new address for receiving change
fn get_raw_change_address(&self, address_type: Option<json::AddressType>) -> Result<Address<NetworkUnchecked>> {
fn get_raw_change_address(
&self,
address_type: Option<json::AddressType>,
) -> Result<Address<NetworkUnchecked>> {
self.call("getrawchangeaddress", &[opt_into_json(address_type)?])
}

@@ -987,22 +983,22 @@ pub trait RpcApi: Sized {
/// Attempts to add a node to the addnode list.
/// Nodes added using addnode (or -connect) are protected from DoS disconnection and are not required to be full nodes/support SegWit as other outbound peers are (though such peers will not be synced from).
fn add_node(&self, addr: &str) -> Result<()> {
self.call("addnode", &[into_json(&addr)?, into_json("add")?])
self.call("addnode", &[into_json(addr)?, into_json("add")?])
}

/// Attempts to remove a node from the addnode list.
fn remove_node(&self, addr: &str) -> Result<()> {
self.call("addnode", &[into_json(&addr)?, into_json("remove")?])
self.call("addnode", &[into_json(addr)?, into_json("remove")?])
}

/// Attempts to connect to a node without permanently adding it to the addnode list.
fn onetry_node(&self, addr: &str) -> Result<()> {
self.call("addnode", &[into_json(&addr)?, into_json("onetry")?])
self.call("addnode", &[into_json(addr)?, into_json("onetry")?])
}

/// Immediately disconnects from the specified peer node.
fn disconnect_node(&self, addr: &str) -> Result<()> {
self.call("disconnectnode", &[into_json(&addr)?])
self.call("disconnectnode", &[into_json(addr)?])
}

fn disconnect_node_by_id(&self, node_id: u32) -> Result<()> {
@@ -1012,7 +1008,7 @@ pub trait RpcApi: Sized {
/// Returns information about the given added node, or all added nodes (note that onetry addnodes are not listed here)
fn get_added_node_info(&self, node: Option<&str>) -> Result<Vec<json::GetAddedNodeInfoResult>> {
if let Some(addr) = node {
self.call("getaddednodeinfo", &[into_json(&addr)?])
self.call("getaddednodeinfo", &[into_json(addr)?])
} else {
self.call("getaddednodeinfo", &[])
}
@@ -1024,7 +1020,7 @@ pub trait RpcApi: Sized {
count: Option<usize>,
) -> Result<Vec<json::GetNodeAddressesResult>> {
let cnt = count.unwrap_or(1);
self.call("getnodeaddresses", &[into_json(&cnt)?])
self.call("getnodeaddresses", &[into_json(cnt)?])
}

/// List all banned IPs/Subnets.
@@ -1041,18 +1037,18 @@ pub trait RpcApi: Sized {
fn add_ban(&self, subnet: &str, bantime: u64, absolute: bool) -> Result<()> {
self.call(
"setban",
&[into_json(&subnet)?, into_json("add")?, into_json(&bantime)?, into_json(&absolute)?],
&[into_json(subnet)?, into_json("add")?, into_json(bantime)?, into_json(absolute)?],
)
}

/// Attempts to remove an IP/Subnet from the banned list.
fn remove_ban(&self, subnet: &str) -> Result<()> {
self.call("setban", &[into_json(&subnet)?, into_json("remove")?])
self.call("setban", &[into_json(subnet)?, into_json("remove")?])
}

/// Disable/enable all p2p network activity.
fn set_network_active(&self, state: bool) -> Result<bool> {
self.call("setnetworkactive", &[into_json(&state)?])
self.call("setnetworkactive", &[into_json(state)?])
}

/// Returns data about each connected network node as an array of
@@ -1182,7 +1178,11 @@ pub trait RpcApi: Sized {
self.call("finalizepsbt", handle_defaults(&mut args, &[true.into()]))
}

fn derive_addresses(&self, descriptor: &str, range: Option<[u32; 2]>) -> Result<Vec<Address<NetworkUnchecked>>> {
fn derive_addresses(
&self,
descriptor: &str,
range: Option<[u32; 2]>,
) -> Result<Vec<Address<NetworkUnchecked>>> {
let mut args = [into_json(descriptor)?, opt_into_json(range)?];
self.call("deriveaddresses", handle_defaults(&mut args, &[null()]))
}
@@ -1248,10 +1248,10 @@ pub trait RpcApi: Sized {

/// Submit a block as a hex string
fn submit_block_hex(&self, block_hex: &str) -> Result<()> {
match self.call("submitblock", &[into_json(&block_hex)?]) {
match self.call("submitblock", &[into_json(block_hex)?]) {
Ok(serde_json::Value::Null) => Ok(()),
Ok(res) => Err(Error::ReturnedError(res.to_string())),
Err(err) => Err(err.into()),
Err(err) => Err(err),
}
}

@@ -1313,9 +1313,9 @@ impl RpcApi for Client {
let json_string = serde_json::to_string(a)?;
serde_json::value::RawValue::from_string(json_string) // we can't use to_raw_value here due to compat with Rust 1.29
})
.map(|a| a.map_err(|e| Error::Json(e)))
.map(|a| a.map_err(Error::Json))
.collect::<Result<Vec<_>>>()?;
let req = self.client.build_request(&cmd, &raw_args);
let req = self.client.build_request(cmd, &raw_args);
if log_enabled!(Debug) {
debug!(target: "bitcoincore_rpc", "JSON-RPC request: {} {}", cmd, serde_json::Value::from(args));
}
@@ -1357,12 +1357,11 @@ fn log_response(cmd: &str, resp: &Result<jsonrpc::Response>) {
mod tests {
use super::*;
use crate::bitcoin;
use serde_json;

#[test]
fn test_raw_tx() {
use crate::bitcoin::consensus::encode;
let client = Client::new("http://localhost/".into(), Auth::None).unwrap();
let client = Client::new("http://localhost/", Auth::None).unwrap();
let tx: bitcoin::Transaction = encode::deserialize(&Vec::<u8>::from_hex("0200000001586bd02815cf5faabfec986a4e50d25dbee089bd2758621e61c5fab06c334af0000000006b483045022100e85425f6d7c589972ee061413bcf08dc8c8e589ce37b217535a42af924f0e4d602205c9ba9cb14ef15513c9d946fa1c4b797883e748e8c32171bdf6166583946e35c012103dae30a4d7870cd87b45dd53e6012f71318fdd059c1c2623b8cc73f8af287bb2dfeffffff021dc4260c010000001976a914f602e88b2b5901d8aab15ebe4a97cf92ec6e03b388ac00e1f505000000001976a914687ffeffe8cf4e4c038da46a9b1d37db385a472d88acfd211500").unwrap()).unwrap();

assert!(client.send_raw_transaction(&tx).is_err());
2 changes: 0 additions & 2 deletions client/src/error.rs
Original file line number Diff line number Diff line change
@@ -13,8 +13,6 @@ use std::{error, fmt, io};
use crate::bitcoin;
use crate::bitcoin::hashes::hex;
use crate::bitcoin::secp256k1;
use jsonrpc;
use serde_json;

/// The error type for errors produced in this library.
#[derive(Debug)]
2 changes: 1 addition & 1 deletion client/src/lib.rs
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ pub use crate::error::Error;
pub use crate::queryable::*;

fn deserialize_hex<T: Decodable>(hex: &str) -> Result<T> {
let mut reader = HexToBytesIter::new(&hex)?;
let mut reader = HexToBytesIter::new(hex)?;
let object = Decodable::consensus_decode(&mut reader)?;
if reader.read_u8().is_ok() {
Err(Error::BitcoinSerialization(bitcoin::consensus::encode::Error::ParseFailed(
1 change: 0 additions & 1 deletion client/src/queryable.rs
Original file line number Diff line number Diff line change
@@ -9,7 +9,6 @@
//

use crate::bitcoin;
use serde_json;

use crate::client::Result;
use crate::client::RpcApi;
146 changes: 97 additions & 49 deletions integration_test/src/main.rs

Large diffs are not rendered by default.

31 changes: 17 additions & 14 deletions json/src/lib.rs
Original file line number Diff line number Diff line change
@@ -24,13 +24,15 @@ extern crate serde_json;

use std::collections::HashMap;


use bitcoin::address::NetworkUnchecked;
use bitcoin::block::Version;
use bitcoin::consensus::encode;
use bitcoin::hashes::hex::FromHex;
use bitcoin::hashes::sha256;
use bitcoin::{Address, Amount, PrivateKey, PublicKey, SignedAmount, Transaction, ScriptBuf, Script, bip158, bip32, Network};
use bitcoin::{
bip158, bip32, Address, Amount, Network, PrivateKey, PublicKey, Script, ScriptBuf,
SignedAmount, Transaction,
};
use serde::de::Error as SerdeError;
use serde::{Deserialize, Serialize};
use std::fmt;
@@ -51,7 +53,7 @@ pub mod serde_hex {

pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Vec<u8>, D::Error> {
let hex_str: String = ::serde::Deserialize::deserialize(d)?;
Ok(FromHex::from_hex(&hex_str).map_err(D::Error::custom)?)
FromHex::from_hex(&hex_str).map_err(D::Error::custom)
}

pub mod opt {
@@ -643,7 +645,7 @@ impl GetRawTransactionResult {
}

pub fn transaction(&self) -> Result<Transaction, encode::Error> {
Ok(encode::deserialize(&self.hex)?)
encode::deserialize(&self.hex)
}
}

@@ -712,7 +714,7 @@ pub struct GetTransactionResult {

impl GetTransactionResult {
pub fn transaction(&self) -> Result<Transaction, encode::Error> {
Ok(encode::deserialize(&self.hex)?)
encode::deserialize(&self.hex)
}
}

@@ -825,7 +827,7 @@ pub struct SignRawTransactionResult {

impl SignRawTransactionResult {
pub fn transaction(&self) -> Result<Transaction, encode::Error> {
Ok(encode::deserialize(&self.hex)?)
encode::deserialize(&self.hex)
}
}

@@ -1150,7 +1152,7 @@ impl<'a> serde::Serialize for ImportMultiRequestScriptPubkey<'a> {
S: serde::Serializer,
{
match *self {
ImportMultiRequestScriptPubkey::Address(ref addr) => {
ImportMultiRequestScriptPubkey::Address(addr) => {
#[derive(Serialize)]
struct Tmp<'a> {
pub address: &'a Address,
@@ -1877,10 +1879,7 @@ pub struct FundRawTransactionOptions {
pub include_watching: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lock_unspents: Option<bool>,
#[serde(
with = "bitcoin::amount::serde::as_btc::opt",
skip_serializing_if = "Option::is_none"
)]
#[serde(with = "bitcoin::amount::serde::as_btc::opt", skip_serializing_if = "Option::is_none")]
pub fee_rate: Option<Amount>,
#[serde(skip_serializing_if = "Option::is_none")]
pub subtract_fee_from_outputs: Option<Vec<u32>>,
@@ -2172,7 +2171,7 @@ where

/// deserialize_bip70_network deserializes a Bitcoin Core network according to BIP70
/// The accepted input variants are: {"main", "test", "signet", "regtest"}
fn deserialize_bip70_network<'de, D>(deserializer: D) -> Result<Network, D::Error>
fn deserialize_bip70_network<'de, D>(deserializer: D) -> Result<Network, D::Error>
where
D: serde::Deserializer<'de>,
{
@@ -2181,8 +2180,12 @@ where
type Value = Network;

fn visit_str<E: serde::de::Error>(self, s: &str) -> Result<Self::Value, E> {
Network::from_core_arg(s)
.map_err(|_| E::invalid_value(serde::de::Unexpected::Str(s), &"bitcoin network encoded as a string"))
Network::from_core_arg(s).map_err(|_| {
E::invalid_value(
serde::de::Unexpected::Str(s),
&"bitcoin network encoded as a string",
)
})
}

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {