Skip to content

Run the foramtter #314

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
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
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
13 changes: 10 additions & 3 deletions client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ 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::{
Expand Down Expand Up @@ -893,7 +893,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)?])
}

Expand Down Expand Up @@ -1184,7 +1187,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()]))
}
Expand Down
129 changes: 92 additions & 37 deletions integration_test/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ use crate::json::BlockStatsFields as BsFields;
use bitcoin::consensus::encode::{deserialize, serialize_hex};
use bitcoin::hashes::hex::FromHex;
use bitcoin::hashes::Hash;
use bitcoin::{secp256k1, ScriptBuf, sighash};
use bitcoin::{secp256k1, sighash, ScriptBuf};
use bitcoin::{
Address, Amount, Network, OutPoint, PrivateKey,
Sequence, SignedAmount, Transaction, TxIn, TxOut, Txid, Witness,
Address, Amount, Network, OutPoint, PrivateKey, Sequence, SignedAmount, Transaction, TxIn,
TxOut, Txid, Witness,
};
use bitcoincore_rpc::bitcoincore_rpc_json::{
GetBlockTemplateModes, GetBlockTemplateRules, ScanTxOutRequest,
Expand Down Expand Up @@ -249,7 +249,8 @@ fn test_get_new_address(cl: &Client) {
let addr = cl.get_new_address(None, Some(json::AddressType::Bech32)).unwrap().assume_checked();
assert_eq!(addr.address_type(), Some(bitcoin::AddressType::P2wpkh));

let addr = cl.get_new_address(None, Some(json::AddressType::P2shSegwit)).unwrap().assume_checked();
let addr =
cl.get_new_address(None, Some(json::AddressType::P2shSegwit)).unwrap().assume_checked();
assert_eq!(addr.address_type(), Some(bitcoin::AddressType::P2sh));
}

Expand All @@ -260,7 +261,8 @@ fn test_get_raw_change_address(cl: &Client) {
let addr = cl.get_raw_change_address(Some(json::AddressType::Bech32)).unwrap().assume_checked();
assert_eq!(addr.address_type(), Some(bitcoin::AddressType::P2wpkh));

let addr = cl.get_raw_change_address(Some(json::AddressType::P2shSegwit)).unwrap().assume_checked();
let addr =
cl.get_raw_change_address(Some(json::AddressType::P2shSegwit)).unwrap().assume_checked();
assert_eq!(addr.address_type(), Some(bitcoin::AddressType::P2sh));
}

Expand Down Expand Up @@ -290,7 +292,9 @@ fn test_generate(cl: &Client) {
fn test_get_balance_generate_to_address(cl: &Client) {
let initial = cl.get_balance(None, None).unwrap();

let blocks = cl.generate_to_address(500, &cl.get_new_address(None, None).unwrap().assume_checked()).unwrap();
let blocks = cl
.generate_to_address(500, &cl.get_new_address(None, None).unwrap().assume_checked())
.unwrap();
assert_eq!(blocks.len(), 500);
assert_ne!(cl.get_balance(None, None).unwrap(), initial);
}
Expand All @@ -299,7 +303,9 @@ fn test_get_balances_generate_to_address(cl: &Client) {
if version() >= 190000 {
let initial = cl.get_balances().unwrap();

let blocks = cl.generate_to_address(500, &cl.get_new_address(None, None).unwrap().assume_checked()).unwrap();
let blocks = cl
.generate_to_address(500, &cl.get_new_address(None, None).unwrap().assume_checked())
.unwrap();
assert_eq!(blocks.len(), 500);
assert_ne!(cl.get_balances().unwrap(), initial);
}
Expand Down Expand Up @@ -375,7 +381,8 @@ fn test_get_address_info(cl: &Client) {
let info = cl.get_address_info(&addr).unwrap();
assert!(!info.witness_program.unwrap().is_empty());

let addr = cl.get_new_address(None, Some(json::AddressType::P2shSegwit)).unwrap().assume_checked();
let addr =
cl.get_new_address(None, Some(json::AddressType::P2shSegwit)).unwrap().assume_checked();
let info = cl.get_address_info(&addr).unwrap();
assert!(!info.hex.unwrap().is_empty());
}
Expand Down Expand Up @@ -431,27 +438,33 @@ fn test_get_received_by_address(cl: &Client) {
let _ = cl.send_to_address(&addr, btc(1), None, None, None, None, None, None).unwrap();
assert_eq!(cl.get_received_by_address(&addr, Some(0)).unwrap(), btc(1));
assert_eq!(cl.get_received_by_address(&addr, Some(1)).unwrap(), btc(0));
let _ = cl.generate_to_address(7, &cl.get_new_address(None, None).unwrap().assume_checked()).unwrap();
let _ = cl
.generate_to_address(7, &cl.get_new_address(None, None).unwrap().assume_checked())
.unwrap();
assert_eq!(cl.get_received_by_address(&addr, Some(6)).unwrap(), btc(1));
assert_eq!(cl.get_received_by_address(&addr, None).unwrap(), btc(1));
}

fn test_list_unspent(cl: &Client) {
let addr = cl.get_new_address(None, None).unwrap();
let addr_checked = addr.clone().assume_checked();
let txid = cl.send_to_address(&addr.clone().assume_checked(), btc(1), None, None, None, None, None, None).unwrap();
let unspent = cl.list_unspent(Some(0), None, Some(&[ &addr_checked]), None, None).unwrap();
let txid = cl
.send_to_address(&addr.clone().assume_checked(), btc(1), None, None, None, None, None, None)
.unwrap();
let unspent = cl.list_unspent(Some(0), None, Some(&[&addr_checked]), None, None).unwrap();
assert_eq!(unspent[0].txid, txid);
assert_eq!(unspent[0].address.as_ref(), Some(&addr));
assert_eq!(unspent[0].amount, btc(1));

let txid = cl.send_to_address(&addr_checked, btc(7), None, None, None, None, None, None).unwrap();
let txid =
cl.send_to_address(&addr_checked, btc(7), None, None, None, None, None, None).unwrap();
let options = json::ListUnspentQueryOptions {
minimum_amount: Some(btc(7)),
maximum_amount: Some(btc(7)),
..Default::default()
};
let unspent = cl.list_unspent(Some(0), None, Some(&[&addr_checked]), None, Some(options)).unwrap();
let unspent =
cl.list_unspent(Some(0), None, Some(&[&addr_checked]), None, Some(options)).unwrap();
assert_eq!(unspent.len(), 1);
assert_eq!(unspent[0].txid, txid);
assert_eq!(unspent[0].address.as_ref(), Some(&addr));
Expand All @@ -477,7 +490,9 @@ fn test_get_raw_transaction(cl: &Client) {
let info = cl.get_raw_transaction_info(&txid, None).unwrap();
assert_eq!(info.txid, txid);

let blocks = cl.generate_to_address(7, &cl.get_new_address(None, None).unwrap().assume_checked()).unwrap();
let blocks = cl
.generate_to_address(7, &cl.get_new_address(None, None).unwrap().assume_checked())
.unwrap();
let _ = cl.get_raw_transaction_info(&txid, Some(&blocks[0])).unwrap();
}

Expand Down Expand Up @@ -533,7 +548,9 @@ fn test_get_tx_out_proof(cl: &Client) {
cl.send_to_address(&RANDOM_ADDRESS, btc(1), None, None, None, None, None, None).unwrap();
let txid2 =
cl.send_to_address(&RANDOM_ADDRESS, btc(1), None, None, None, None, None, None).unwrap();
let blocks = cl.generate_to_address(7, &cl.get_new_address(None, None).unwrap().assume_checked()).unwrap();
let blocks = cl
.generate_to_address(7, &cl.get_new_address(None, None).unwrap().assume_checked())
.unwrap();
let proof = cl.get_tx_out_proof(&[txid1, txid2], Some(&blocks[0])).unwrap();
assert!(!proof.is_empty());
}
Expand All @@ -560,7 +577,9 @@ fn test_lock_unspent_unlock_unspent(cl: &Client) {
}

fn test_get_block_filter(cl: &Client) {
let blocks = cl.generate_to_address(7, &cl.get_new_address(None, None).unwrap().assume_checked()).unwrap();
let blocks = cl
.generate_to_address(7, &cl.get_new_address(None, None).unwrap().assume_checked())
.unwrap();
if version() >= 190000 {
let _ = cl.get_block_filter(&blocks[0]).unwrap();
} else {
Expand Down Expand Up @@ -631,7 +650,12 @@ fn test_sign_raw_transaction_with_send_raw_transaction(cl: &Client) {
};

let res = cl
.sign_raw_transaction_with_key(&tx, &[sk], None, Some(sighash::EcdsaSighashType::All.into()))
.sign_raw_transaction_with_key(
&tx,
&[sk],
None,
Some(sighash::EcdsaSighashType::All.into()),
)
.unwrap();
assert!(res.complete);
let _ = cl.send_raw_transaction(&res.transaction().unwrap()).unwrap();
Expand Down Expand Up @@ -1280,9 +1304,7 @@ fn test_getblocktemplate(cl: &Client) {
fn test_unloadwallet(cl: &Client) {
cl.create_wallet("testunloadwallet", None, None, None, None).unwrap();

let res = new_wallet_client("testunloadwallet")
.unload_wallet(None)
.unwrap();
let res = new_wallet_client("testunloadwallet").unload_wallet(None).unwrap();

if version() >= 210000 {
assert!(res.is_some());
Expand Down Expand Up @@ -1321,20 +1343,37 @@ fn test_wait_for_new_block(cl: &Client) {
let hash = cl.get_block_hash(height).unwrap();

assert!(cl.wait_for_new_block(std::u64::MAX).is_err()); // JSON integer out of range
assert_eq!(cl.wait_for_new_block(100).unwrap(), json::BlockRef{hash, height});
assert_eq!(
cl.wait_for_new_block(100).unwrap(),
json::BlockRef {
hash,
height
}
);
}

fn test_wait_for_block(cl: &Client) {
let height = cl.get_block_count().unwrap();
let hash = cl.get_block_hash(height).unwrap();

assert!(cl.wait_for_block(&hash, std::u64::MAX).is_err()); // JSON integer out of range
assert_eq!(cl.wait_for_block(&hash, 0).unwrap(), json::BlockRef{hash, height});
assert_eq!(
cl.wait_for_block(&hash, 0).unwrap(),
json::BlockRef {
hash,
height
}
);
}

fn test_get_descriptor_info(cl: &Client) {
let res = cl.get_descriptor_info(r"pkh(cSQPHDBwXGjVzWRqAHm6zfvQhaTuj1f2bFH58h55ghbjtFwvmeXR)").unwrap();
assert_eq!(res.descriptor, r"pkh(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c)#62k9sn4x");
let res = cl
.get_descriptor_info(r"pkh(cSQPHDBwXGjVzWRqAHm6zfvQhaTuj1f2bFH58h55ghbjtFwvmeXR)")
.unwrap();
assert_eq!(
res.descriptor,
r"pkh(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c)#62k9sn4x"
);
assert_eq!(res.is_range, false);
assert_eq!(res.is_solvable, true);
assert_eq!(res.has_private_keys, true);
Expand All @@ -1352,34 +1391,50 @@ fn test_get_descriptor_info(cl: &Client) {
fn test_add_multisig_address(cl: &Client) {
let addr1 = cl.get_new_address(None, Some(json::AddressType::Bech32)).unwrap().assume_checked();
let addr2 = cl.get_new_address(None, Some(json::AddressType::Bech32)).unwrap().assume_checked();
let addresses = [
json::PubKeyOrAddress::Address(&addr1),
json::PubKeyOrAddress::Address(&addr2),
];
let addresses =
[json::PubKeyOrAddress::Address(&addr1), json::PubKeyOrAddress::Address(&addr2)];

assert!(cl.add_multisig_address(addresses.len(), &addresses, None, None).is_ok());
assert!(cl.add_multisig_address(addresses.len() - 1, &addresses, None, None).is_ok());
assert!(cl.add_multisig_address(addresses.len() + 1, &addresses, None, None).is_err());
assert!(cl.add_multisig_address(0, &addresses, None, None).is_err());
assert!(cl.add_multisig_address(addresses.len(), &addresses, Some("test_label"), None).is_ok());
assert!(cl.add_multisig_address(addresses.len(), &addresses, None, Some(json::AddressType::Legacy)).is_ok());
assert!(cl.add_multisig_address(addresses.len(), &addresses, None, Some(json::AddressType::P2shSegwit)).is_ok());
assert!(cl.add_multisig_address(addresses.len(), &addresses, None, Some(json::AddressType::Bech32)).is_ok());
assert!(cl
.add_multisig_address(addresses.len(), &addresses, None, Some(json::AddressType::Legacy))
.is_ok());
assert!(cl
.add_multisig_address(
addresses.len(),
&addresses,
None,
Some(json::AddressType::P2shSegwit)
)
.is_ok());
assert!(cl
.add_multisig_address(addresses.len(), &addresses, None, Some(json::AddressType::Bech32))
.is_ok());
}

fn test_derive_addresses(cl: &Client) {
let descriptor = r"pkh(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c)#62k9sn4x";
assert_eq!(cl.derive_addresses(descriptor, None).unwrap(), vec!["mrkwtj5xpYQjHeJe5wsweNjVeTKkvR5fCr".parse().unwrap()]);
let descriptor =
r"pkh(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c)#62k9sn4x";
assert_eq!(
cl.derive_addresses(descriptor, None).unwrap(),
vec!["mrkwtj5xpYQjHeJe5wsweNjVeTKkvR5fCr".parse().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(),
]);
assert_eq!(
cl.derive_addresses(descriptor, Some([0, 1])).unwrap(),
vec![
"bcrt1q5n5tjkpva8v5s0uadu2y5f0g7pn4h5eqaq2ux2".parse().unwrap(),
"bcrt1qcgl303ht03ja2e0hudpwk7ypcxk5t478wspzlt".parse().unwrap(),
]
);
assert!(cl.derive_addresses(descriptor, None).is_err()); // Range must be specified for a ranged descriptor
}

Expand Down
21 changes: 12 additions & 9 deletions json/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1879,10 +1881,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>>,
Expand Down Expand Up @@ -2174,7 +2173,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>,
{
Expand All @@ -2183,8 +2182,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 {
Expand Down