Skip to content

Implement scantxoutset method and test #164

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 1 commit into
base: master
Choose a base branch
from
Open
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
24 changes: 24 additions & 0 deletions client/src/client_sync/v17/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,30 @@ macro_rules! impl_client_v17__savemempool {
};
}

/// Implements Bitcoin Core JSON-RPC API method `scantxoutset`
#[macro_export]
macro_rules! impl_client_v17__scantxoutset {
() => {
impl Client {
pub fn scan_tx_out_set(
&self,
action: ScanAction,
scan_objects: &[ScanObject],
) -> Result<ScanTxOutSet> {
let params = match action {
ScanAction::Start => {
vec![into_json(action)?, into_json(scan_objects)?]
}
ScanAction::Abort | ScanAction::Status => {
vec![into_json(action)?]
}
};
self.call("scantxoutset", &params)
}
}
};
}

/// Implements Bitcoin Core JSON-RPC API method `verifychain`
#[macro_export]
macro_rules! impl_client_v17__verifychain {
Expand Down
22 changes: 22 additions & 0 deletions client/src/client_sync/v17/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ crate::impl_client_v17__gettxoutsetinfo!();
crate::impl_client_v17__preciousblock!();
crate::impl_client_v17__pruneblockchain!();
crate::impl_client_v17__savemempool!();
crate::impl_client_v17__scantxoutset!();
crate::impl_client_v17__verifychain!();
crate::impl_client_v17__verifytxoutproof!();

Expand Down Expand Up @@ -214,3 +215,24 @@ pub struct WalletCreateFundedPsbtInput {
txid: Txid,
vout: u32,
}

/// Args for the `scantxoutset`
///
/// Represents the action for the `scantxoutset` RPC call.
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum ScanAction {
Start,
Abort,
Status,
}

/// Represents a scan object for scantxoutset (descriptor string or object).
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
#[serde(untagged)]
pub enum ScanObject {
/// Plain descriptor string
Descriptor(String),
/// Object containing descriptor and optional range
WithDesc { desc: String },
}
6 changes: 5 additions & 1 deletion client/src/client_sync/v18/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ use crate::types::v18::*;

#[rustfmt::skip] // Keep public re-exports separate.
pub use crate::client_sync::{
v17::{AddressType, Input, Output, TemplateRequest, TemplateRules, WalletCreateFundedPsbtInput},
v17::{
AddressType, Input, Output, ScanAction, ScanObject, TemplateRequest,
TemplateRules, WalletCreateFundedPsbtInput
},
};

// This publicly re-exports `Client`.
Expand Down Expand Up @@ -48,6 +51,7 @@ crate::impl_client_v17__gettxoutsetinfo!();
crate::impl_client_v17__preciousblock!();
crate::impl_client_v17__pruneblockchain!();
crate::impl_client_v17__savemempool!();
crate::impl_client_v17__scantxoutset!();
crate::impl_client_v17__verifychain!();
crate::impl_client_v17__verifytxoutproof!();

Expand Down
6 changes: 5 additions & 1 deletion client/src/client_sync/v19/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ use crate::types::v19::*;

#[rustfmt::skip] // Keep public re-exports separate.
pub use crate::client_sync::{
v17::{AddressType, Input, Output, TemplateRequest, TemplateRules, WalletCreateFundedPsbtInput},
v17::{
AddressType, Input, Output, ScanAction, ScanObject, TemplateRequest,
TemplateRules, WalletCreateFundedPsbtInput
},
};

crate::define_jsonrpc_minreq_client!("v19");
Expand Down Expand Up @@ -47,6 +50,7 @@ crate::impl_client_v17__gettxoutsetinfo!();
crate::impl_client_v17__preciousblock!();
crate::impl_client_v17__pruneblockchain!();
crate::impl_client_v17__savemempool!();
crate::impl_client_v17__scantxoutset!();
crate::impl_client_v17__verifychain!();
crate::impl_client_v17__verifytxoutproof!();

Expand Down
6 changes: 5 additions & 1 deletion client/src/client_sync/v20.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ use crate::types::v20::*;

#[rustfmt::skip] // Keep public re-exports separate.
pub use crate::client_sync::{
v17::{AddressType, Input, Output, TemplateRequest, TemplateRules, WalletCreateFundedPsbtInput},
v17::{
AddressType, Input, Output, ScanAction, ScanObject, TemplateRequest,
TemplateRules, WalletCreateFundedPsbtInput
},
};

crate::define_jsonrpc_minreq_client!("v20");
Expand Down Expand Up @@ -44,6 +47,7 @@ crate::impl_client_v17__gettxoutsetinfo!();
crate::impl_client_v17__preciousblock!();
crate::impl_client_v17__pruneblockchain!();
crate::impl_client_v17__savemempool!();
crate::impl_client_v17__scantxoutset!();
crate::impl_client_v17__verifychain!();
crate::impl_client_v17__verifytxoutproof!();

Expand Down
6 changes: 5 additions & 1 deletion client/src/client_sync/v21/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ use crate::types::v21::*;

#[rustfmt::skip] // Keep public re-exports separate.
pub use crate::client_sync::{
v17::{AddressType, Input, Output, TemplateRequest, TemplateRules, WalletCreateFundedPsbtInput},
v17::{
AddressType, Input, Output, ScanAction, ScanObject, TemplateRequest,
TemplateRules, WalletCreateFundedPsbtInput
},
};

crate::define_jsonrpc_minreq_client!("v21");
Expand Down Expand Up @@ -46,6 +49,7 @@ crate::impl_client_v17__gettxoutsetinfo!();
crate::impl_client_v17__preciousblock!();
crate::impl_client_v17__pruneblockchain!();
crate::impl_client_v17__savemempool!();
crate::impl_client_v17__scantxoutset!();
crate::impl_client_v17__verifychain!();
crate::impl_client_v17__verifytxoutproof!();

Expand Down
6 changes: 5 additions & 1 deletion client/src/client_sync/v22/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ use crate::types::v22::*;

#[rustfmt::skip] // Keep public re-exports separate.
pub use crate::client_sync::{
v17::{AddressType, Input, Output, TemplateRequest, TemplateRules, WalletCreateFundedPsbtInput},
v17::{
AddressType, Input, Output, ScanAction, ScanObject, TemplateRequest,
TemplateRules, WalletCreateFundedPsbtInput
},
};

crate::define_jsonrpc_minreq_client!("v22");
Expand Down Expand Up @@ -46,6 +49,7 @@ crate::impl_client_v17__gettxoutsetinfo!();
crate::impl_client_v17__preciousblock!();
crate::impl_client_v17__pruneblockchain!();
crate::impl_client_v17__savemempool!();
crate::impl_client_v17__scantxoutset!();
crate::impl_client_v17__verifychain!();
crate::impl_client_v17__verifytxoutproof!();

Expand Down
6 changes: 5 additions & 1 deletion client/src/client_sync/v23/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ use crate::types::v23::*;

#[rustfmt::skip] // Keep public re-exports separate.
pub use crate::client_sync::{
v17::{Input, Output, TemplateRequest, TemplateRules, WalletCreateFundedPsbtInput},
v17::{
Input, Output, ScanAction, ScanObject, TemplateRequest,
TemplateRules, WalletCreateFundedPsbtInput
},
};

crate::define_jsonrpc_minreq_client!("v23");
Expand Down Expand Up @@ -48,6 +51,7 @@ crate::impl_client_v17__gettxoutsetinfo!();
crate::impl_client_v17__preciousblock!();
crate::impl_client_v17__pruneblockchain!();
crate::impl_client_v23__savemempool!();
crate::impl_client_v17__scantxoutset!();
crate::impl_client_v17__verifychain!();
crate::impl_client_v17__verifytxoutproof!();

Expand Down
6 changes: 5 additions & 1 deletion client/src/client_sync/v24.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ use crate::types::v24::*;

#[rustfmt::skip] // Keep public re-exports separate.
pub use crate::client_sync::{
v17::{Input, Output, TemplateRequest, TemplateRules, WalletCreateFundedPsbtInput},
v17::{
Input, Output, ScanAction, ScanObject, TemplateRequest, TemplateRules,
WalletCreateFundedPsbtInput
},
v23::AddressType,
};

Expand Down Expand Up @@ -45,6 +48,7 @@ crate::impl_client_v17__gettxoutsetinfo!();
crate::impl_client_v17__preciousblock!();
crate::impl_client_v17__pruneblockchain!();
crate::impl_client_v23__savemempool!();
crate::impl_client_v17__scantxoutset!();
crate::impl_client_v17__verifychain!();
crate::impl_client_v17__verifytxoutproof!();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ use crate::types::v25::*;

#[rustfmt::skip] // Keep public re-exports separate.
pub use crate::client_sync::{
v17::{Input, Output, TemplateRequest, TemplateRules, WalletCreateFundedPsbtInput},
v17::{
Input, Output, ScanAction, ScanObject, TemplateRequest, TemplateRules,
WalletCreateFundedPsbtInput
},
v23::AddressType,
};

Expand Down Expand Up @@ -45,6 +48,7 @@ crate::impl_client_v17__gettxoutsetinfo!();
crate::impl_client_v17__preciousblock!();
crate::impl_client_v17__pruneblockchain!();
crate::impl_client_v23__savemempool!();
crate::impl_client_v17__scantxoutset!();
crate::impl_client_v17__verifychain!();
crate::impl_client_v17__verifytxoutproof!();

Expand Down
6 changes: 5 additions & 1 deletion client/src/client_sync/v26/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ use crate::types::v26::*;

#[rustfmt::skip] // Keep public re-exports separate.
pub use crate::client_sync::{
v17::{Input, Output, TemplateRequest, TemplateRules, WalletCreateFundedPsbtInput},
v17::{
Input, Output, ScanAction, ScanObject, TemplateRequest,
TemplateRules, WalletCreateFundedPsbtInput
},
v23::AddressType,
};

Expand Down Expand Up @@ -49,6 +52,7 @@ crate::impl_client_v26__gettxoutsetinfo!();
crate::impl_client_v17__preciousblock!();
crate::impl_client_v17__pruneblockchain!();
crate::impl_client_v23__savemempool!();
crate::impl_client_v17__scantxoutset!();
crate::impl_client_v17__verifychain!();
crate::impl_client_v17__verifytxoutproof!();

Expand Down
6 changes: 5 additions & 1 deletion client/src/client_sync/v27.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ use crate::types::v27::*;

#[rustfmt::skip] // Keep public re-exports separate.
pub use crate::client_sync::{
v17::{Input, Output, TemplateRequest, TemplateRules, WalletCreateFundedPsbtInput},
v17::{
Input, Output, ScanAction, ScanObject, TemplateRequest, TemplateRules,
WalletCreateFundedPsbtInput
},
v23::AddressType,
};

Expand Down Expand Up @@ -45,6 +48,7 @@ crate::impl_client_v26__gettxoutsetinfo!();
crate::impl_client_v17__preciousblock!();
crate::impl_client_v17__pruneblockchain!();
crate::impl_client_v23__savemempool!();
crate::impl_client_v17__scantxoutset!();
crate::impl_client_v17__verifychain!();
crate::impl_client_v17__verifytxoutproof!();

Expand Down
6 changes: 5 additions & 1 deletion client/src/client_sync/v28/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ use crate::types::v28::*;

#[rustfmt::skip] // Keep public re-exports separate.
pub use crate::client_sync::{
v17::{Input, Output, TemplateRequest, TemplateRules, WalletCreateFundedPsbtInput},
v17::{
Input, Output, ScanAction, ScanObject, TemplateRequest,
TemplateRules, WalletCreateFundedPsbtInput
},
v23::AddressType,
};

Expand Down Expand Up @@ -47,6 +50,7 @@ crate::impl_client_v26__gettxoutsetinfo!();
crate::impl_client_v17__preciousblock!();
crate::impl_client_v17__pruneblockchain!();
crate::impl_client_v23__savemempool!();
crate::impl_client_v17__scantxoutset!();
crate::impl_client_v17__verifychain!();
crate::impl_client_v17__verifytxoutproof!();

Expand Down
29 changes: 29 additions & 0 deletions integration_test/tests/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,35 @@ fn blockchain__savemempool() {
}
}

#[test]
fn blockchain__scan_tx_out_set_modelled() {
#[cfg(any(
feature = "v17",
feature = "v18",
feature = "v19",
feature = "v20",
feature = "v21"
))]
let node = Node::with_wallet(Wallet::None, &[]);

#[cfg(not(any(
feature = "v17",
feature = "v18",
feature = "v19",
feature = "v20",
feature = "v21"
)))]
let node = Node::with_wallet(Wallet::None, &["-coinstatsindex=1"]);

let dummy_pubkey_hex = "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798";
let scan_desc = format!("pkh({})", dummy_pubkey_hex);

let scan_objects: node::ScanObject = node::ScanObject::Descriptor(scan_desc);
let action: node::ScanAction = node::ScanAction::Start;

let _: Result<ScanTxOutSet, _> = node.client.scan_tx_out_set(action, &[scan_objects]);
}

#[test]
fn blockchain__verify_tx_out_proof__modelled() {
let node = Node::with_wallet(Wallet::Default, &[]);
Expand Down
47 changes: 47 additions & 0 deletions types/src/v17/blockchain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,53 @@ pub struct PruneBlockchain(
pub i64,
);

/// Result of JSON-RPC method `scantxoutset`.
///
/// > scantxoutset "action" ( [scanobjects,...] )
/// >
/// > Arguments:
/// > 1. "action" (string, required) The action to execute
/// > 2. "scanobjects" (array, required) Array of scan objects
#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(untagged)]
pub enum ScanTxOutSet {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh this is interesting. This is a new idea for the crate, it could be done for all the methods that have verbose results. I'm not sure it adds any value though. I'd just remove this and leave the three individual return types. Plus I'd document 'returned when the foo action as taken'.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

after looking at v28 I'm not sure - leave it with me for a bit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright... Noted. That would be great using it for the methods having verbose results.

/// Returns after scan completes
Start(ScanTxOutSetStart),
/// True (scan will be aborted), False (no scan to abort)
Abort(bool),
/// Scan in progress or Completed
Status(Option<ScanTxOutSetStatus>),
}

#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub struct ScanTxOutSetStart {
/// The unspents
pub unspents: Vec<ScanTxOutSetUnspent>,
/// The total amount of all found unspent outputs in BTC
pub total_amount: f64,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub struct ScanTxOutSetStatus {
/// Approximate percent complete
pub progress: f64,
}

#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub struct ScanTxOutSetUnspent {
/// The transaction id
pub txid: String,
/// The vout value
pub vout: u32,
/// The script key
#[serde(rename = "scriptPubKey")]
pub script_pubkey: String,
/// The total amount in BTC of unspent output
pub amount: f64,
/// Height of the unspent transaction output
pub height: u64,
}

/// Result of JSON-RPC method `verifychain`.
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub struct VerifyChain(pub bool);
Expand Down
7 changes: 4 additions & 3 deletions types/src/v17/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
//! | preciousblock | returns nothing | |
//! | pruneblockchain | returns numeric | |
//! | savemempool | returns nothing | |
//! | scantxoutset | omitted | API marked as experimental |
//! | scantxoutset | version + model | API marked as experimental |
//! | verifychain | returns boolean | |
//! | verifytxoutproof | version + model | |
//!
Expand Down Expand Up @@ -243,8 +243,9 @@ pub use self::{
GetMempoolDescendantsVerbose, GetMempoolEntry, GetMempoolInfo, GetMempoolInfoError,
GetRawMempool, GetRawMempoolVerbose, GetTxOut, GetTxOutError, GetTxOutSetInfo,
GetTxOutSetInfoError, MapMempoolEntryError, MempoolEntry, MempoolEntryError,
MempoolEntryFees, MempoolEntryFeesError, PruneBlockchain, Softfork, SoftforkReject,
VerifyChain, VerifyTxOutProof,
MempoolEntryFees, MempoolEntryFeesError, PruneBlockchain, ScanTxOutSet, ScanTxOutSetStart,
ScanTxOutSetStatus, ScanTxOutSetUnspent, Softfork, SoftforkReject, VerifyChain,
VerifyTxOutProof,
},
control::{GetMemoryInfoStats, Locked, Logging},
generating::{Generate, GenerateToAddress},
Expand Down
Loading