Skip to content

WIP: Upgrade the bitcoin dependency #308

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

Closed
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
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -5,3 +5,6 @@ members = [
"client",
"integration_test",
]

[patch.crates-io.bitcoin]
path = "../rust-bitcoin/bitcoin"
14 changes: 7 additions & 7 deletions client/src/client.rs
Original file line number Diff line number Diff line change
@@ -14,14 +14,14 @@ use std::iter::FromIterator;
use std::path::PathBuf;
use std::{fmt, result};

use crate::{bitcoin, deserialize_hex};
use bitcoin_private::hex::exts::DisplayHex;
use crate::bitcoin::{self, consensus};
use bitcoin::hex::DisplayHex;
use jsonrpc;
use serde;
use serde_json;

use crate::bitcoin::address::{NetworkUnchecked, NetworkChecked};
use crate::bitcoin::hashes::hex::FromHex;
use crate::bitcoin::hex::FromHex;
use crate::bitcoin::secp256k1::ecdsa::Signature;
use crate::bitcoin::{
Address, Amount, Block, OutPoint, PrivateKey, PublicKey, Script, Transaction,
@@ -335,7 +335,7 @@ pub trait RpcApi: Sized {

fn get_block(&self, hash: &bitcoin::BlockHash) -> Result<Block> {
let hex: String = self.call("getblock", &[into_json(hash)?, 0.into()])?;
deserialize_hex(&hex)
Ok(consensus::deserialize_hex(&hex)?)
}

fn get_block_hex(&self, hash: &bitcoin::BlockHash) -> Result<String> {
@@ -349,7 +349,7 @@ pub trait RpcApi: Sized {

fn get_block_header(&self, hash: &bitcoin::BlockHash) -> Result<bitcoin::block::Header> {
let hex: String = self.call("getblockheader", &[into_json(hash)?, false.into()])?;
deserialize_hex(&hex)
Ok(consensus::deserialize_hex(&hex)?)
}

fn get_block_header_info(
@@ -493,7 +493,7 @@ pub trait RpcApi: Sized {
) -> Result<Transaction> {
let mut args = [into_json(txid)?, into_json(false)?, opt_into_json(block_hash)?];
let hex: String = self.call("getrawtransaction", handle_defaults(&mut args, &[null()]))?;
deserialize_hex(&hex)
Ok(consensus::deserialize_hex(&hex)?)
}

fn get_raw_transaction_hex(
@@ -790,7 +790,7 @@ pub trait RpcApi: Sized {
replaceable: Option<bool>,
) -> Result<Transaction> {
let hex: String = self.create_raw_transaction_hex(utxos, outs, locktime, replaceable)?;
deserialize_hex(&hex)
Ok(consensus::deserialize_hex(&hex)?)
}

fn decode_raw_transaction<R: RawTx>(
17 changes: 13 additions & 4 deletions client/src/error.rs
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@
use std::{error, fmt, io};

use crate::bitcoin;
use crate::bitcoin::hashes::hex;
use crate::bitcoin::hex;
use crate::bitcoin::secp256k1;
use jsonrpc;
use serde_json;
@@ -20,9 +20,10 @@ use serde_json;
#[derive(Debug)]
pub enum Error {
JsonRpc(jsonrpc::error::Error),
Hex(hex::Error),
Hex(hex::HexToBytesError),
Json(serde_json::error::Error),
BitcoinSerialization(bitcoin::consensus::encode::Error),
BitcoinDeserializeHex(bitcoin::consensus::FromHexError),
Secp256k1(secp256k1::Error),
Io(io::Error),
InvalidAmount(bitcoin::amount::ParseAmountError),
@@ -39,8 +40,8 @@ impl From<jsonrpc::error::Error> for Error {
}
}

impl From<hex::Error> for Error {
fn from(e: hex::Error) -> Error {
impl From<hex::HexToBytesError> for Error {
fn from(e: hex::HexToBytesError) -> Error {
Error::Hex(e)
}
}
@@ -57,6 +58,12 @@ impl From<bitcoin::consensus::encode::Error> for Error {
}
}

impl From<bitcoin::consensus::FromHexError> for Error {
fn from(e: bitcoin::consensus::FromHexError) -> Error {
Error::BitcoinDeserializeHex(e)
}
}

impl From<secp256k1::Error> for Error {
fn from(e: secp256k1::Error) -> Error {
Error::Secp256k1(e)
@@ -82,6 +89,7 @@ impl fmt::Display for Error {
Error::Hex(ref e) => write!(f, "hex decode error: {}", e),
Error::Json(ref e) => write!(f, "JSON error: {}", e),
Error::BitcoinSerialization(ref e) => write!(f, "Bitcoin serialization error: {}", e),
Error::BitcoinDeserializeHex(ref e) => write!(f, "Bitcoin deserialize hex error: {}", e),
Error::Secp256k1(ref e) => write!(f, "secp256k1 error: {}", e),
Error::Io(ref e) => write!(f, "I/O error: {}", e),
Error::InvalidAmount(ref e) => write!(f, "invalid amount: {}", e),
@@ -103,6 +111,7 @@ impl error::Error for Error {
Error::Hex(ref e) => Some(e),
Error::Json(ref e) => Some(e),
Error::BitcoinSerialization(ref e) => Some(e),
Error::BitcoinDeserializeHex(ref e) => Some(e),
Error::Secp256k1(ref e) => Some(e),
Error::Io(ref e) => Some(e),
_ => None,
14 changes: 0 additions & 14 deletions client/src/lib.rs
Original file line number Diff line number Diff line change
@@ -27,8 +27,6 @@ pub extern crate jsonrpc;
pub extern crate bitcoincore_rpc_json;
pub use crate::json::bitcoin;
pub use bitcoincore_rpc_json as json;
use json::bitcoin::consensus::{Decodable, ReadExt};
use json::bitcoin::hashes::hex::HexIterator;

mod client;
mod error;
@@ -37,15 +35,3 @@ mod queryable;
pub use crate::client::*;
pub use crate::error::Error;
pub use crate::queryable::*;

fn deserialize_hex<T: Decodable>(hex: &str) -> Result<T> {
let mut reader = HexIterator::new(&hex)?;
let object = Decodable::consensus_decode(&mut reader)?;
if reader.read_u8().is_ok() {
Err(Error::BitcoinSerialization(bitcoin::consensus::encode::Error::ParseFailed(
"data not consumed entirely when explicitly deserializing",
)))
} else {
Ok(object)
}
}
4 changes: 2 additions & 2 deletions client/src/queryable.rs
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@ impl<C: RpcApi> Queryable<C> for bitcoin::block::Block {
fn query(rpc: &C, id: &Self::Id) -> Result<Self> {
let rpc_name = "getblock";
let hex: String = rpc.call(rpc_name, &[serde_json::to_value(id)?, 0.into()])?;
let bytes: Vec<u8> = bitcoin::hashes::hex::FromHex::from_hex(&hex)?;
let bytes: Vec<u8> = bitcoin::hex::FromHex::from_hex(&hex)?;
Ok(bitcoin::consensus::encode::deserialize(&bytes)?)
}
}
@@ -39,7 +39,7 @@ impl<C: RpcApi> Queryable<C> for bitcoin::transaction::Transaction {
fn query(rpc: &C, id: &Self::Id) -> Result<Self> {
let rpc_name = "getrawtransaction";
let hex: String = rpc.call(rpc_name, &[serde_json::to_value(id)?])?;
let bytes: Vec<u8> = bitcoin::hashes::hex::FromHex::from_hex(&hex)?;
let bytes: Vec<u8> = bitcoin::hex::FromHex::from_hex(&hex)?;
Ok(bitcoin::consensus::encode::deserialize(&bytes)?)
}
}
15 changes: 8 additions & 7 deletions integration_test/src/main.rs
Original file line number Diff line number Diff line change
@@ -24,11 +24,12 @@ use bitcoincore_rpc::{Auth, Client, Error, RpcApi};

use crate::json::BlockStatsFields as BsFields;
use bitcoin::consensus::encode::{deserialize, serialize_hex};
use bitcoin::hashes::hex::FromHex;
use bitcoin::hex::FromHex;
use bitcoin::hashes::Hash;
use bitcoin::{secp256k1, ScriptBuf, sighash};
use bitcoin::address::{Address, NetworkUnchecked};
use bitcoin::{
Address, Amount, Network, OutPoint, PrivateKey,
Amount, Network, OutPoint, PrivateKey,
Sequence, SignedAmount, Transaction, TxIn, TxOut, Txid, Witness,
};
use bitcoincore_rpc::bitcoincore_rpc_json::{
@@ -596,7 +597,7 @@ fn test_sign_raw_transaction_with_send_raw_transaction(cl: &Client) {
witness: Witness::new(),
}],
output: vec![TxOut {
value: (unspent.amount - *FEE).to_sat(),
value: (unspent.amount - *FEE),
script_pubkey: addr.script_pubkey(),
}],
};
@@ -625,7 +626,7 @@ fn test_sign_raw_transaction_with_send_raw_transaction(cl: &Client) {
witness: Witness::new(),
}],
output: vec![TxOut {
value: (unspent.amount - *FEE - *FEE).to_sat(),
value: (unspent.amount - *FEE - *FEE),
script_pubkey: RANDOM_ADDRESS.script_pubkey(),
}],
};
@@ -1369,16 +1370,16 @@ fn test_add_multisig_address(cl: &Client) {

fn test_derive_addresses(cl: &Client) {
let descriptor = r"pkh(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c)#62k9sn4x";
assert_eq!(cl.derive_addresses(descriptor, None).unwrap(), vec!["mrkwtj5xpYQjHeJe5wsweNjVeTKkvR5fCr".parse().unwrap()]);
assert_eq!(cl.derive_addresses(descriptor, None).unwrap(), vec!["mrkwtj5xpYQjHeJe5wsweNjVeTKkvR5fCr".parse::<Address<NetworkUnchecked>>().unwrap()]);
assert!(cl.derive_addresses(descriptor, Some([0, 1])).is_err()); // Range should not be specified for an unranged descriptor

let descriptor = std::concat!(
r"wpkh([1004658e/84'/1'/0']tpubDCBEcmVKbfC9KfdydyLbJ2gfNL88grZu1XcWSW9ytTM6fi",
r"tvaRmVyr8Ddf7SjZ2ZfMx9RicjYAXhuh3fmLiVLPodPEqnQQURUfrBKiiVZc8/0/*)#g8l47ngv",
);
assert_eq!(cl.derive_addresses(descriptor, Some([0, 1])).unwrap(), vec![
"bcrt1q5n5tjkpva8v5s0uadu2y5f0g7pn4h5eqaq2ux2".parse().unwrap(),
"bcrt1qcgl303ht03ja2e0hudpwk7ypcxk5t478wspzlt".parse().unwrap(),
"bcrt1q5n5tjkpva8v5s0uadu2y5f0g7pn4h5eqaq2ux2".parse::<Address<NetworkUnchecked>>().unwrap(),
"bcrt1qcgl303ht03ja2e0hudpwk7ypcxk5t478wspzlt".parse::<Address<NetworkUnchecked>>().unwrap(),
]);
assert!(cl.derive_addresses(descriptor, None).is_err()); // Range must be specified for a ranged descriptor
}
8 changes: 3 additions & 5 deletions json/src/lib.rs
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@ use std::collections::HashMap;
use bitcoin::address::NetworkUnchecked;
use bitcoin::block::Version;
use bitcoin::consensus::encode;
use bitcoin::hashes::hex::FromHex;
use bitcoin::hex::FromHex;
use bitcoin::hashes::sha256;
use bitcoin::{Address, Amount, PrivateKey, PublicKey, SignedAmount, Transaction, ScriptBuf, Script, bip158, bip32, Network};
use serde::de::Error as SerdeError;
@@ -41,8 +41,7 @@ use std::fmt;
///
/// The module is compatible with the serde attribute.
pub mod serde_hex {
use bitcoin::hashes::hex::FromHex;
use bitcoin_private::hex::exts::DisplayHex;
use bitcoin::hex::{FromHex, DisplayHex};
use serde::de::Error;
use serde::{Deserializer, Serializer};

@@ -56,8 +55,7 @@ pub mod serde_hex {
}

pub mod opt {
use bitcoin::hashes::hex::FromHex;
use bitcoin_private::hex::exts::DisplayHex;
use bitcoin::hex::{FromHex, DisplayHex};
use serde::de::Error;
use serde::{Deserializer, Serializer};