Skip to content
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

Update create_wallet to support Core v0.23.0 #230

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
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
2 changes: 2 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ jobs:
"0.20.0",
"0.20.1",
"0.21.0",
"22.0",
"23.0",
]
steps:
- name: Checkout Crate
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ The following versions are officially supported and automatically tested:
* 0.20.0
* 0.20.1
* 0.21.0
* 22.0
* 23.0

# Minimum Supported Rust Version (MSRV)
This library should always compile with any combination of features on **Rust 1.29**.
Expand Down
25 changes: 19 additions & 6 deletions client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,22 +271,28 @@ pub trait RpcApi: Sized {

fn create_wallet(
&self,
wallet: &str,
wallet_name: &str,
disable_private_keys: Option<bool>,
blank: Option<bool>,
passphrase: Option<&str>,
avoid_reuse: Option<bool>,
descriptors: Option<bool>,
load_on_startup: Option<bool>,
external_signer: Option<bool>,
) -> Result<json::LoadWalletResult> {
let mut args = [
wallet.into(),
wallet_name.into(),
opt_into_json(disable_private_keys)?,
opt_into_json(blank)?,
opt_into_json(passphrase)?,
opt_into_json(avoid_reuse)?,
opt_into_json(descriptors)?,
opt_into_json(load_on_startup)?,
opt_into_json(external_signer)?,
];
self.call(
"createwallet",
handle_defaults(&mut args, &[false.into(), false.into(), into_json("")?, false.into()]),
handle_defaults(&mut args, &[false.into(), false.into(), into_json("")?, false.into(), true.into(), false.into(), false.into()]),
)
}

Expand Down Expand Up @@ -1133,9 +1139,16 @@ pub trait RpcApi: Sized {
}

/// Returns statistics about the unspent transaction output set.
/// This call may take some time.
fn get_tx_out_set_info(&self) -> Result<json::GetTxOutSetInfoResult> {
self.call("gettxoutsetinfo", &[])
/// Note this call may take some time if you are not using coinstatsindex.
fn get_tx_out_set_info(
&self,
hash_type: Option<json::TxOutSetHashType>,
hash_or_height: Option<json::HashOrHeight>,
use_index: Option<bool>,
) -> Result<json::GetTxOutSetInfoResult> {
let mut args =
[opt_into_json(hash_type)?, opt_into_json(hash_or_height)?, opt_into_json(use_index)?];
self.call("gettxoutsetinfo", handle_defaults(&mut args, &[null(), null(), null()]))
}

/// Returns information about network traffic, including bytes in, bytes out,
Expand Down
11 changes: 10 additions & 1 deletion integration_test/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,23 @@ sleep 3
BLOCKFILTERARG=""
if bitcoind -version | grep -q "v0\.\(19\|2\)"; then
BLOCKFILTERARG="-blockfilterindex=1"
elif bitcoind -version | grep -q "v\(22\|23\)"; then
BLOCKFILTERARG="-blockfilterindex=1"
fi

FALLBACKFEEARG=""
if bitcoind -version | grep -q "v0\.2"; then
FALLBACKFEEARG="-fallbackfee=0.00001000"
elif bitcoind -version | grep -q "v\(22\|23\)"; then
FALLBACKFEEARG="-fallbackfee=0.00001000"
fi

COINSTATSINDEXARG=""
if bitcoind -version | grep -q "v[2-9]"; then
COINSTATSINDEXARG="-coinstatsindex=1"
fi

bitcoind -regtest $BLOCKFILTERARG $FALLBACKFEEARG \
bitcoind -regtest $BLOCKFILTERARG $FALLBACKFEEARG $COINSTATSINDEXARG \
-datadir=${TESTDIR}/2 \
-connect=127.0.0.1:12348 \
-rpcport=12349 \
Expand Down
44 changes: 33 additions & 11 deletions integration_test/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ use bitcoin::hashes::hex::{FromHex, ToHex};
use bitcoin::hashes::Hash;
use bitcoin::secp256k1;
use bitcoin::{
Address, Amount, Network, OutPoint, PrivateKey, Script, EcdsaSighashType, SignedAmount, Transaction,
TxIn, TxOut, Txid, Witness,
Address, Amount, EcdsaSighashType, Network, OutPoint, PrivateKey, Script, SignedAmount,
Transaction, TxIn, TxOut, Txid, Witness,
};
use bitcoincore_rpc::bitcoincore_rpc_json::{
GetBlockTemplateModes, GetBlockTemplateRules, ScanTxOutRequest,
Expand Down Expand Up @@ -134,7 +134,7 @@ fn main() {
unsafe { VERSION = cl.version().unwrap() };
println!("Version: {}", version());

cl.create_wallet("testwallet", None, None, None, None).unwrap();
cl.create_wallet("testwallet", None, None, None, None, Some(false), None, None).unwrap();

test_get_mining_info(&cl);
test_get_blockchain_info(&cl);
Expand Down Expand Up @@ -596,8 +596,9 @@ fn test_sign_raw_transaction_with_send_raw_transaction(cl: &Client) {
}],
};

let res =
cl.sign_raw_transaction_with_key(&tx, &[sk], None, Some(EcdsaSighashType::All.into())).unwrap();
let res = cl
.sign_raw_transaction_with_key(&tx, &[sk], None, Some(EcdsaSighashType::All.into()))
.unwrap();
assert!(res.complete);
let _ = cl.send_raw_transaction(&res.transaction().unwrap()).unwrap();
}
Expand Down Expand Up @@ -936,6 +937,9 @@ fn test_create_wallet(cl: &Client) {
blank: Option<bool>,
passphrase: Option<&'a str>,
avoid_reuse: Option<bool>,
descriptors: Option<bool>,
load_on_startup: Option<bool>,
external_signer: Option<bool>,
}

let mut wallet_params = vec![
Expand All @@ -945,20 +949,29 @@ fn test_create_wallet(cl: &Client) {
blank: None,
passphrase: None,
avoid_reuse: None,
descriptors: None,
load_on_startup: None,
external_signer: None,
},
WalletParams {
name: wallet_names[1],
disable_private_keys: Some(true),
blank: None,
passphrase: None,
avoid_reuse: None,
descriptors: None,
load_on_startup: None,
external_signer: None,
},
WalletParams {
name: wallet_names[2],
disable_private_keys: None,
blank: Some(true),
passphrase: None,
avoid_reuse: None,
descriptors: None,
load_on_startup: None,
external_signer: None,
},
];

Expand All @@ -969,13 +982,19 @@ fn test_create_wallet(cl: &Client) {
blank: None,
passphrase: Some("pass"),
avoid_reuse: None,
descriptors: None,
load_on_startup: None,
external_signer: None,
});
wallet_params.push(WalletParams {
name: wallet_names[4],
disable_private_keys: None,
blank: None,
passphrase: None,
avoid_reuse: Some(true),
descriptors: None,
load_on_startup: None,
external_signer: None,
});
}

Expand All @@ -987,6 +1006,9 @@ fn test_create_wallet(cl: &Client) {
wallet_param.blank,
wallet_param.passphrase,
wallet_param.avoid_reuse,
wallet_param.descriptors,
wallet_param.load_on_startup,
wallet_param.external_signer,
)
.unwrap();

Expand Down Expand Up @@ -1030,7 +1052,11 @@ fn test_create_wallet(cl: &Client) {
}

fn test_get_tx_out_set_info(cl: &Client) {
cl.get_tx_out_set_info().unwrap();
if version() >= 220000 {
cl.get_tx_out_set_info(Some(json::TxOutSetHashType::Muhash), None, Some(true)).unwrap();
} else {
cl.get_tx_out_set_info(None, None, None).unwrap();
}
}

fn test_get_chain_tips(cl: &Client) {
Expand Down Expand Up @@ -1081,11 +1107,7 @@ fn test_add_ban(cl: &Client) {
let res = cl.list_banned().unwrap();
assert_eq!(res.len(), 0);

assert_error_message!(
cl.add_ban("INVALID_STRING", 0, false),
-30,
"Error: Invalid IP/Subnet"
);
assert_error_message!(cl.add_ban("INVALID_STRING", 0, false), -30, "Error: Invalid IP/Subnet");
}

fn test_set_network_active(cl: &Client) {
Expand Down
85 changes: 77 additions & 8 deletions json/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1852,27 +1852,96 @@ pub struct SignRawTransactionInput {
pub amount: Option<Amount>,
}

/// Used to represent UTXO set hash type
#[derive(Clone, Serialize, PartialEq, Eq, Debug)]
#[serde(rename_all = "snake_case")]
pub enum TxOutSetHashType {
HashSerialized2,
Muhash,
None,
}

/// Used to specify a block hash or a height
#[derive(Clone, Serialize, PartialEq, Eq, Debug)]
#[serde(untagged)]
pub enum HashOrHeight {
BlockHash(bitcoin::BlockHash),
Height(u64),
}

#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetTxOutSetInfoResult {
/// The current block height (index)
/// The block height (index) of the returned statistics
pub height: u64,
/// The hash of the block at the tip of the chain
/// The hash of the block at which these statistics are calculated
#[serde(rename = "bestblock")]
pub best_block: bitcoin::BlockHash,
/// The number of transactions with unspent outputs
pub transactions: u64,
/// The number of transactions with unspent outputs (not available when coinstatsindex is used)
#[serde(default, skip_serializing_if = "Option::is_none")]
pub transactions: Option<u64>,
/// The number of unspent transaction outputs
#[serde(rename = "txouts")]
pub tx_outs: u64,
/// A meaningless metric for UTXO set size
pub bogosize: u64,
/// The serialized hash
pub hash_serialized_2: sha256::Hash,
/// The estimated size of the chainstate on disk
pub disk_size: u64,
/// The serialized hash (only present if 'hash_serialized_2' hash_type is chosen)
#[serde(default, skip_serializing_if = "Option::is_none")]
pub hash_serialized_2: Option<sha256::Hash>,
/// The serialized hash (only present if 'muhash' hash_type is chosen)
#[serde(default, skip_serializing_if = "Option::is_none")]
pub muhash: Option<sha256::Hash>,
/// The estimated size of the chainstate on disk (not available when coinstatsindex is used)
#[serde(default, skip_serializing_if = "Option::is_none")]
pub disk_size: Option<u64>,
/// The total amount
#[serde(with = "bitcoin::util::amount::serde::as_btc")]
pub total_amount: Amount,
/// The total amount of coins permanently excluded from the UTXO set (only available if coinstatsindex is used)
#[serde(
default,
skip_serializing_if = "Option::is_none",
with = "bitcoin::util::amount::serde::as_btc::opt"
)]
pub total_unspendable_amount: Option<Amount>,
/// Info on amounts in the block at this block height (only available if coinstatsindex is used)
#[serde(default, skip_serializing_if = "Option::is_none")]
pub block_info: Option<BlockInfo>,
}

/// Info on amounts in the block at the block height of the `gettxoutsetinfo` call (only available if coinstatsindex is used)
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct BlockInfo {
/// Amount of previous outputs spent
#[serde(with = "bitcoin::util::amount::serde::as_btc")]
pub prevout_spent: Amount,
/// Output size of the coinbase transaction
#[serde(with = "bitcoin::util::amount::serde::as_btc")]
pub coinbase: Amount,
/// Newly-created outputs
#[serde(with = "bitcoin::util::amount::serde::as_btc")]
pub new_outputs_ex_coinbase: Amount,
/// Amount of unspendable outputs
#[serde(with = "bitcoin::util::amount::serde::as_btc")]
pub unspendable: Amount,
/// Detailed view of the unspendable categories
pub unspendables: Unspendables,
}

/// Detailed view of the unspendable categories
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct Unspendables {
/// Unspendable coins from the Genesis block
#[serde(with = "bitcoin::util::amount::serde::as_btc")]
pub genesis_block: Amount,
/// Transactions overridden by duplicates (no longer possible with BIP30)
#[serde(with = "bitcoin::util::amount::serde::as_btc")]
pub bip30: Amount,
/// Amounts sent to scripts that are unspendable (for example OP_RETURN outputs)
#[serde(with = "bitcoin::util::amount::serde::as_btc")]
pub scripts: Amount,
/// Fee rewards that miners did not claim in their coinbase transaction
#[serde(with = "bitcoin::util::amount::serde::as_btc")]
pub unclaimed_rewards: Amount,
}

#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
Expand Down