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

Merge upstream #9

Open
wants to merge 62 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
1f5c57a
fix: version_bits_available maps String to u32
0xB10C May 4, 2021
f8f2cef
add: getrawmempool RPC verbose = true
0xB10C May 11, 2021
541e99f
Resolve unneeded semi-colon warning on rust 1.51
PastaPastaPasta Apr 27, 2021
86278c0
Add 'submitblock' RPC call.
Mar 18, 2021
8daa636
Fix redundant semicolon warning during build.
Mar 12, 2022
7a665aa
Make pub_keypool_oldest optional
mplsgrant Apr 3, 2022
b898243
Run cargo fmt
tcharding May 18, 2022
6030b61
Update `get_tx_out_set_info` to Core 22.0+
clarkmoody Jun 12, 2022
011599a
Remove String conversion in README example.
joegesualdo Aug 2, 2022
4e888de
Remove 1.29 restriction from CI and README
tcharding May 18, 2022
49db004
Fix in preparation for next edition
tcharding May 18, 2022
18d14b6
Enable edition 2018
tcharding May 18, 2022
c861370
Merge pull request #222 from tcharding/05-18-edition-2018
stevenroose Aug 17, 2022
5c59c1c
Merge pull request #232 from joegesualdo/joegesualdo-patch-1
stevenroose Aug 17, 2022
2e87541
Merge pull request #216 from mplsgrant/getwalletinfo-descriptor
stevenroose Aug 17, 2022
f0754ef
Merge pull request #228 from clarkmoody/gettxoutsetinfo
stevenroose Aug 17, 2022
1d6cc0f
Upgrade bitcoin dependency
tcharding Jul 12, 2022
e6f334f
Bump crate version to 0.16.0
tcharding Aug 8, 2022
661b58d
Merge pull request #234 from tcharding/08-09-upgrade-bitcoin
dpc Aug 18, 2022
33361ce
Merge rust-bitcoin/rust-bitcoincore-rpc#151: Add 'submitblock' rpc call
RCasatta Aug 23, 2022
5128bb2
changelog: Add remaining 0.16.0 items
stevenroose Aug 25, 2022
400a3c0
Merge rust-bitcoin/rust-bitcoincore-rpc#240: changelog: Add remaining…
RCasatta Aug 25, 2022
46d9970
Deserialize hexes without allocating intermediate Vec<u8>
RCasatta Aug 30, 2022
d2959ec
Bump jsonrpc dependency
tcharding Sep 11, 2022
bc072ae
feat: added listwalletdir rpc
sander2 Sep 14, 2022
64c4e19
Merge pull request #245 from sander2/feat/getwalletdir
stevenroose Sep 20, 2022
fef1b64
Merge pull request #241 from RCasatta/hex_reader
stevenroose Sep 20, 2022
1aff087
Merge pull request #244 from tcharding/09-12-bump-jsonrpc
stevenroose Sep 20, 2022
bde02d7
Merge pull request #213 from tnull/2022-03-fix-build-warning
stevenroose Sep 20, 2022
b1e329c
add joinpsbt
thesimplekid Nov 21, 2022
cc1814b
Merge rust-bitcoin/rust-bitcoincore-rpc#257: Add joinpsbt command
apoelstra Nov 24, 2022
13bd5d3
cargo fmt
thesimplekid Nov 24, 2022
d274dce
Merge rust-bitcoin/rust-bitcoincore-rpc#258: cargo +nightly fmt --che…
apoelstra Nov 24, 2022
a5844c7
Merge rust-bitcoin/rust-bitcoincore-rpc#172: Resolve unneeded semi-co…
apoelstra Nov 29, 2022
72783dd
Merge rust-bitcoin/rust-bitcoincore-rpc#176: fix: vbavailable map in …
apoelstra Nov 29, 2022
9186b66
Merge rust-bitcoin/rust-bitcoincore-rpc#177: add: getrawmempool RPC v…
apoelstra Nov 29, 2022
078ae14
get raw change address
thesimplekid Dec 2, 2022
9023cce
Add `address` field
thesimplekid Dec 5, 2022
bdc9f9b
Merge rust-bitcoin/rust-bitcoincore-rpc#263: Add `address` field for …
apoelstra Dec 5, 2022
6bfbda2
createpsbt
thesimplekid Dec 3, 2022
fc3a12d
Merge rust-bitcoin/rust-bitcoincore-rpc#265: Add `create_psbt`
apoelstra Dec 9, 2022
3f04a34
json: add Other variant to SoftforkType
benma Dec 20, 2022
6c4cd8a
Merge rust-bitcoin/rust-bitcoincore-rpc#268: json: add Other variant …
apoelstra Dec 21, 2022
7a8bec6
add combine raw transaction
thesimplekid Dec 22, 2022
794d040
add `decode_raw_transaction`
thesimplekid Dec 22, 2022
718ba56
Adds importdescriptors
sr-gi Sep 24, 2022
4ff70e8
Merge rust-bitcoin/rust-bitcoincore-rpc#270: add combine raw transaction
apoelstra Dec 30, 2022
6cd787a
Merge rust-bitcoin/rust-bitcoincore-rpc#248: Adds importdescriptors
apoelstra Dec 30, 2022
c7f3370
Merge rust-bitcoin/rust-bitcoincore-rpc#271: add `decode_raw_transact…
apoelstra Dec 30, 2022
158e7a0
Expose JsonOutPoint
casey Jan 1, 2023
13256b0
Merge rust-bitcoin/rust-bitcoincore-rpc#272: Expose JsonOutPoint
apoelstra Jan 1, 2023
edfd3eb
Derive Deserialize on ImportDescriptors
casey Jan 3, 2023
df2ab99
Remove lifetime
casey Jan 3, 2023
8cccc5f
Merge rust-bitcoin/rust-bitcoincore-rpc#273: Derive Deserialize on Im…
apoelstra Jan 4, 2023
d005ce9
Add AddressType::Bech32m
casey Jan 9, 2023
9e6dff7
Merge rust-bitcoin/rust-bitcoincore-rpc#274: Add AddressType::Bech32m
apoelstra Jan 13, 2023
0f1c9f8
Add getmempoolinfo
dev7ba Jan 26, 2023
7e141b6
Merge rust-bitcoin/rust-bitcoincore-rpc#261: add get raw change address
apoelstra Jan 30, 2023
b469e3f
Merge rust-bitcoin/rust-bitcoincore-rpc#275: Add getmempoolinfo
apoelstra Jan 30, 2023
0fe0814
merging with upstream
lorenzolfm Feb 7, 2023
5033d1b
using send_to_address correctly
lorenzolfm Feb 7, 2023
5d670f6
avoiding conflicts with locally installed bitcoind
lorenzolfm Feb 7, 2023
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: 1 addition & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
RUSTFMTCHK: false
- rust: 1.41.1
env:
PIN_VERSIONS: true
RUSTFMTCHK: false
steps:
- name: Checkout Crate
uses: actions/checkout@v2
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# 0.16.0

- MSRV changed from 1.29 to 1.41.1
- bump bitcoin crate version to 0.29.0
- moved to Rust edition 2018
- make get_tx_out_set_info compatible with v22+
- add `submit_block`, `submit_block_bytes`, `submit_block_hex`

# 0.15.0

Expand Down
14 changes: 1 addition & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use bitcoincore_rpc::{Auth, Client, RpcApi};

fn main() {

let rpc = Client::new("http://localhost:8332".to_string(),
let rpc = Client::new("http://localhost:8332",
Auth::UserPass("<FILL RPC USERNAME>".to_string(),
"<FILL RPC PASSWORD>".to_string())).unwrap();
let best_block_hash = rpc.get_best_block_hash().unwrap();
Expand All @@ -48,15 +48,3 @@ The following versions are officially supported and automatically tested:

# Minimum Supported Rust Version (MSRV)
This library should always compile with any combination of features on **Rust 1.41.1**.

Because some dependencies have broken the build in minor/patch releases, to
compile with 1.41.1 you will need to run the following version-pinning command:
```
cargo update --package "cc" --precise "1.0.41"
cargo update --package "log:0.4.x" --precise "0.4.13" # x being the highest patch version, currently 14
cargo update --package "cfg-if" --precise "0.1.9"
cargo update --package "serde_json" --precise "1.0.39"
cargo update --package "serde" --precise "1.0.98"
cargo update --package "serde_derive" --precise "1.0.98"
cargo update --package "byteorder" --precise "1.3.4"
```
7 changes: 4 additions & 3 deletions client/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bitcoincore-rpc"
version = "0.15.0"
version = "0.16.0"
authors = [
"Steven Roose <steven@stevenroose.org>",
"Jean Pierre Dudey <jeandudey@hotmail.com>",
Expand All @@ -12,16 +12,17 @@ repository = "https://github.com/rust-bitcoin/rust-bitcoincore-rpc/"
description = "RPC client library for the Bitcoin Core JSON-RPC API."
keywords = ["crypto", "bitcoin", "bitcoin-core", "rpc"]
readme = "README.md"
edition = "2018"

[lib]
name = "bitcoincore_rpc"
path = "src/lib.rs"

[dependencies]
bitcoincore-rpc-json = { version = "0.15.0", path = "../json" }
bitcoincore-rpc-json = { version = "0.16.0", path = "../json" }

log = "0.4.5"
jsonrpc = "0.12.0"
jsonrpc = "0.13.0"

# Used for deserialization of JSON.
serde = "1"
Expand Down
140 changes: 118 additions & 22 deletions client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,30 @@ use std::iter::FromIterator;
use std::path::PathBuf;
use std::{fmt, result};

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

use bitcoin::hashes::hex::{FromHex, ToHex};
use bitcoin::secp256k1::ecdsa::Signature;
use bitcoin::{
use crate::bitcoin::hashes::hex::{FromHex, ToHex};
use crate::bitcoin::secp256k1::ecdsa::Signature;
use crate::bitcoin::{
Address, Amount, Block, BlockHeader, OutPoint, PrivateKey, PublicKey, Script, Transaction,
};
use log::Level::{Debug, Trace, Warn};

use error::*;
use json;
use queryable;
use crate::error::*;
use crate::json;
use crate::queryable;

/// Crate-specific Result type, shorthand for `std::result::Result` with our
/// crate-specific Error type;
pub type Result<T> = result::Result<T, Error>;

/// Outpoint that serializes and deserializes as a map, instead of a string,
/// for use as RPC arguments
#[derive(Clone, Debug, Serialize, Deserialize)]
struct JsonOutPoint {
pub struct JsonOutPoint {
pub txid: bitcoin::Txid,
pub vout: u32,
}
Expand Down Expand Up @@ -291,6 +293,12 @@ pub trait RpcApi: Sized {
self.call("listwallets", &[])
}

fn list_wallet_dir(&self) -> Result<Vec<String>> {
let result: json::ListWalletDirResult = self.call("listwalletdir", &[])?;
let names = result.wallets.into_iter().map(|x| x.name).collect();
Ok(names)
}

fn get_wallet_info(&self) -> Result<json::GetWalletInfoResult> {
self.call("getwalletinfo", &[])
}
Expand Down Expand Up @@ -318,8 +326,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()])?;
let bytes: Vec<u8> = FromHex::from_hex(&hex)?;
Ok(bitcoin::consensus::encode::deserialize(&bytes)?)
deserialize_hex(&hex)
}

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

fn get_block_header(&self, hash: &bitcoin::BlockHash) -> Result<BlockHeader> {
let hex: String = self.call("getblockheader", &[into_json(hash)?, false.into()])?;
let bytes: Vec<u8> = FromHex::from_hex(&hex)?;
Ok(bitcoin::consensus::encode::deserialize(&bytes)?)
deserialize_hex(&hex)
}

fn get_block_header_info(
Expand Down Expand Up @@ -379,7 +385,7 @@ pub trait RpcApi: Sized {
// - 0.18.x returns a "softforks" array and a "bip9_softforks" map.
// - 0.19.x returns a "softforks" map.
Ok(if self.version()? < 190000 {
use Error::UnexpectedStructure as err;
use crate::Error::UnexpectedStructure as err;

// First, remove both incompatible softfork fields.
// We need to scope the mutable ref here for v1.29 borrowck.
Expand Down Expand Up @@ -478,8 +484,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()]))?;
let bytes: Vec<u8> = FromHex::from_hex(&hex)?;
Ok(bitcoin::consensus::encode::deserialize(&bytes)?)
deserialize_hex(&hex)
}

fn get_raw_transaction_hex(
Expand Down Expand Up @@ -652,6 +657,14 @@ pub trait RpcApi: Sized {
self.call("importmulti", handle_defaults(&mut args, &[null()]))
}

fn import_descriptors(
&self,
req: json::ImportDescriptors,
) -> Result<Vec<json::ImportMultiResult>> {
let json_request = vec![serde_json::to_value(req)?];
self.call("importdescriptors", handle_defaults(&mut [json_request.into()], &[null()]))
}

fn set_label(&self, address: &Address, label: &str) -> Result<()> {
self.call("setlabel", &[address.to_string().into(), label.into()])
}
Expand Down Expand Up @@ -719,6 +732,27 @@ pub trait RpcApi: Sized {
self.call("listreceivedbyaddress", handle_defaults(&mut args, &defaults))
}

fn create_psbt(
&self,
inputs: &[json::CreateRawTransactionInput],
outputs: &HashMap<String, Amount>,
locktime: Option<i64>,
replaceable: Option<bool>,
) -> Result<String> {
let outs_converted = serde_json::Map::from_iter(
outputs.iter().map(|(k, v)| (k.clone(), serde_json::Value::from(v.to_btc()))),
);
self.call(
"createpsbt",
&[
into_json(inputs)?,
into_json(outs_converted)?,
into_json(locktime)?,
into_json(replaceable)?,
],
)
}

fn create_raw_transaction_hex(
&self,
utxos: &[json::CreateRawTransactionInput],
Expand Down Expand Up @@ -747,8 +781,17 @@ pub trait RpcApi: Sized {
replaceable: Option<bool>,
) -> Result<Transaction> {
let hex: String = self.create_raw_transaction_hex(utxos, outs, locktime, replaceable)?;
let bytes: Vec<u8> = FromHex::from_hex(&hex)?;
Ok(bitcoin::consensus::encode::deserialize(&bytes)?)
deserialize_hex(&hex)
}

fn decode_raw_transaction<R: RawTx>(
&self,
tx: R,
is_witness: Option<bool>,
) -> Result<json::DecodeRawTransactionResult> {
let mut args = [tx.raw_hex().into(), opt_into_json(is_witness)?];
let defaults = [null()];
self.call("decoderawtransaction", handle_defaults(&mut args, &defaults))
}

fn fund_raw_transaction<R: RawTx>(
Expand Down Expand Up @@ -840,6 +883,11 @@ pub trait RpcApi: Sized {
self.call("getnewaddress", &[opt_into_json(label)?, opt_into_json(address_type)?])
}

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

fn get_address_info(&self, address: &Address) -> Result<json::GetAddressInfoResult> {
self.call("getaddressinfo", &[address.to_string().into()])
}
Expand Down Expand Up @@ -871,11 +919,23 @@ pub trait RpcApi: Sized {
self.call("reconsiderblock", &[into_json(block_hash)?])
}

/// Returns details on the active state of the TX memory pool
fn get_mempool_info(&self) -> Result<json::GetMempoolInfoResult> {
self.call("getmempoolinfo", &[])
}

/// Get txids of all transactions in a memory pool
fn get_raw_mempool(&self) -> Result<Vec<bitcoin::Txid>> {
self.call("getrawmempool", &[])
}

/// Get details for the transactions in a memory pool
fn get_raw_mempool_verbose(
&self,
) -> Result<HashMap<bitcoin::Txid, json::GetMempoolEntryResult>> {
self.call("getrawmempool", &[into_json(true)?])
}

/// Get mempool data for given transaction
fn get_mempool_entry(&self, txid: &bitcoin::Txid) -> Result<json::GetMempoolEntryResult> {
self.call("getmempoolentry", &[into_json(txid)?])
Expand Down Expand Up @@ -1137,10 +1197,18 @@ pub trait RpcApi: Sized {
self.call("getdescriptorinfo", &[desc.to_string().into()])
}

fn join_psbt(&self, psbts: &[String]) -> Result<String> {
self.call("joinpsbts", &[into_json(psbts)?])
}

fn combine_psbt(&self, psbts: &[String]) -> Result<String> {
self.call("combinepsbt", &[into_json(psbts)?])
}

fn combine_raw_transaction(&self, hex_strings: &[String]) -> Result<String> {
self.call("combinerawtransaction", &[into_json(hex_strings)?])
}

fn finalize_psbt(&self, psbt: &str, extract: Option<bool>) -> Result<json::FinalizePsbtResult> {
let mut args = [into_json(psbt)?, opt_into_json(extract)?];
self.call("finalizepsbt", handle_defaults(&mut args, &[true.into()]))
Expand Down Expand Up @@ -1169,9 +1237,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 All @@ -1191,6 +1266,27 @@ pub trait RpcApi: Sized {
self.call("uptime", &[])
}

/// Submit a block
fn submit_block(&self, block: &bitcoin::Block) -> Result<()> {
let block_hex: String = bitcoin::consensus::encode::serialize_hex(block);
self.submit_block_hex(&block_hex)
}

/// Submit a raw block
fn submit_block_bytes(&self, block_bytes: &[u8]) -> Result<()> {
let block_hex: String = block_bytes.to_hex();
self.submit_block_hex(&block_hex)
}

/// Submit a block as a hex string
fn submit_block_hex(&self, block_hex: &str) -> Result<()> {
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()),
}
}

fn scan_tx_out_set_blocking(
&self,
descriptors: &[json::ScanTxOutRequest],
Expand Down Expand Up @@ -1292,12 +1388,12 @@ fn log_response(cmd: &str, resp: &Result<jsonrpc::Response>) {
#[cfg(test)]
mod tests {
use super::*;
use bitcoin;
use crate::bitcoin;
use serde_json;

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

Expand Down
9 changes: 6 additions & 3 deletions client/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@

use std::{error, fmt, io};

use bitcoin;
use bitcoin::hashes::hex;
use bitcoin::secp256k1;
use crate::bitcoin;
use crate::bitcoin::hashes::hex;
use crate::bitcoin::secp256k1;
use jsonrpc;
use serde_json;

Expand All @@ -29,6 +29,8 @@ pub enum Error {
InvalidCookieFile,
/// The JSON result had an unexpected structure.
UnexpectedStructure,
/// The daemon returned an error string.
ReturnedError(String),
}

impl From<jsonrpc::error::Error> for Error {
Expand Down Expand Up @@ -85,6 +87,7 @@ impl fmt::Display for Error {
Error::InvalidAmount(ref e) => write!(f, "invalid amount: {}", e),
Error::InvalidCookieFile => write!(f, "invalid cookie file"),
Error::UnexpectedStructure => write!(f, "the JSON result had an unexpected structure"),
Error::ReturnedError(ref s) => write!(f, "the daemon returned an error string: {}", s),
}
}
}
Expand Down
Loading