Skip to content

Commit 30bce38

Browse files
authored
Merge pull request #38 from tcharding/12-19-test
Test everything in the `blockchain` section for v17 and v18
2 parents 1484d9a + 3625782 commit 30bce38

File tree

11 files changed

+164
-90
lines changed

11 files changed

+164
-90
lines changed

client/src/client_sync/v17/blockchain.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ macro_rules! impl_client_v17__gettxout {
254254
macro_rules! impl_client_v17__gettxoutproof {
255255
() => {
256256
impl Client {
257-
pub fn get_tx_out_proof(&self, txids: Vec<Txid>) -> Result<GetTxOut> {
257+
pub fn get_tx_out_proof(&self, txids: &[Txid]) -> Result<String> {
258258
self.call("gettxoutproof", &[into_json(txids)?])
259259
}
260260
}
@@ -266,7 +266,7 @@ macro_rules! impl_client_v17__gettxoutproof {
266266
macro_rules! impl_client_v17__gettxoutsetinfo {
267267
() => {
268268
impl Client {
269-
pub fn get_tx_out_set_info(&self) -> Result<GetTxOut> {
269+
pub fn get_tx_out_set_info(&self) -> Result<GetTxOutSetInfo> {
270270
self.call("gettxoutsetinfo", &[])
271271
}
272272
}
@@ -279,7 +279,7 @@ macro_rules! impl_client_v17__verifytxoutproof {
279279
() => {
280280
impl Client {
281281
// `proof` is the hex-encoded proof generated by `gettxoutproof`.
282-
pub fn verify_tx_out_proof(&self, proof: &str) -> Result<GetTxOut> {
282+
pub fn verify_tx_out_proof(&self, proof: &str) -> Result<VerifyTxOutProof> {
283283
self.call("verifytxoutproof", &[into_json(proof)?])
284284
}
285285
}

client/src/client_sync/v18.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ crate::impl_client_v17__getmempooldescendants!();
3434
crate::impl_client_v17__getmempoolentry!();
3535
crate::impl_client_v17__getmempoolinfo!();
3636
crate::impl_client_v17__getrawmempool!();
37+
crate::impl_client_v17__gettxout!();
38+
crate::impl_client_v17__gettxoutproof!();
39+
crate::impl_client_v17__gettxoutsetinfo!();
40+
crate::impl_client_v17__verifytxoutproof!();
3741

3842
// == Control ==
3943
crate::impl_client_v17__getmemoryinfo!();

integration_test/src/lib.rs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,19 @@ pub trait NodeExt {
4848
/// Generates [`NBLOCKS`] to an address controlled by the loaded wallet.
4949
fn fund_wallet(&self);
5050

51-
/// Mine a block.
51+
/// Mines a block.
5252
///
5353
/// Should send mining reward to a new address for the loaded wallet.
5454
fn mine_a_block(&self);
5555

56-
/// Create a transaction and mine it.
56+
/// Creates a transaction in the mempool.
57+
///
58+
/// # Returns
59+
///
60+
/// The receive address and the transaction.
61+
fn create_mempool_transaction(&self) -> (bitcoin::Address, bitcoin::Txid);
62+
63+
/// Creates a transaction and mines a block that includes it in the chain.
5764
///
5865
/// # Returns
5966
///
@@ -77,12 +84,22 @@ impl NodeExt for Node {
7784
self.client.generate_to_address(NBLOCKS, &address).expect("failed to generate to address");
7885
}
7986

80-
fn create_mined_transaction(&self) -> (bitcoin::Address, bitcoin::Transaction) {
87+
fn mine_a_block(&self) {
88+
let address = self.client.new_address().expect("failed to get new address");
89+
self.client.generate_to_address(1, &address).expect("failed to generate to address");
90+
}
91+
92+
fn create_mempool_transaction(&self) -> (bitcoin::Address, bitcoin::Txid) {
8193
const MILLION_SATS: bitcoin::Amount = bitcoin::Amount::from_sat(1000000);
8294

8395
let address = self.client.new_address().expect("failed to get new address");
8496

85-
let _ = self.client.send_to_address(&address, MILLION_SATS);
97+
let txid = self.client.send_to_address(&address, MILLION_SATS).expect("failed to send to address").txid().expect("failed to convert hex to txid");
98+
(address, txid)
99+
}
100+
101+
fn create_mined_transaction(&self) -> (bitcoin::Address, bitcoin::Transaction) {
102+
let (address, _) = self.create_mempool_transaction();
86103
self.mine_a_block();
87104

88105
let best_block_hash = self.client.best_block_hash().expect("best_block_hash");
@@ -91,12 +108,6 @@ impl NodeExt for Node {
91108

92109
(address, tx)
93110
}
94-
95-
fn mine_a_block(&self) {
96-
// TODO: Consider returning the error.
97-
let address = self.client.new_address().expect("failed to get new address");
98-
self.client.generate_to_address(1, &address).expect("failed to generate to address");
99-
}
100111
}
101112

102113
/// Return a temporary file path.

integration_test/tests/blockchain.rs

Lines changed: 81 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -134,37 +134,103 @@ fn get_difficulty() {
134134

135135
#[test]
136136
#[cfg(feature = "TODO")]
137-
fn get_mempool_ancestors() { todo!() }
137+
fn get_mempool_ancestors() {
138+
// We can probably get away with not testing this because it returns the
139+
// same type as `getmempoolentry` which is tested below.
140+
}
138141

139142
#[test]
140143
#[cfg(feature = "TODO")]
141-
fn get_mempool_descendants() { todo!() }
144+
fn get_mempool_descendants() {
145+
// We can probably get away with not testing this because it returns the
146+
// same type as `getmempoolentry` which is tested below.
147+
}
142148

143149
#[test]
144-
#[cfg(feature = "TODO")]
145-
fn get_mempool_entry() { todo!() }
150+
fn get_mempool_entry() {
151+
let node = Node::new_with_default_wallet();
152+
node.fund_wallet();
153+
let (_address, txid) = node.create_mempool_transaction();
154+
155+
let json = node.client.get_mempool_entry(txid).expect("getmempoolentry");
156+
assert!(json.into_model().is_ok());
157+
}
146158

147159
#[test]
148-
#[cfg(feature = "TODO")]
149-
fn get_mempool_info() { todo!() }
160+
fn get_mempool_info() {
161+
let node = Node::new_with_default_wallet();
162+
node.fund_wallet();
163+
let (_address, _txid) = node.create_mempool_transaction();
164+
165+
// Test the type and into model conversion code.
166+
let json = node.client.get_mempool_info().expect("getmempoolinfo");
167+
let info = json.into_model().expect("into_model");
168+
// Sanity check.
169+
assert_eq!(info.size, 1);
170+
}
150171

151172
#[test]
152-
#[cfg(feature = "TODO")]
153-
fn get_raw_mempool() { todo!() }
173+
fn get_raw_mempool() {
174+
let node = Node::new_with_default_wallet();
175+
node.fund_wallet();
176+
let (_address, _txid) = node.create_mempool_transaction();
177+
178+
// Test the type and into model conversion code.
179+
let json = node.client.get_raw_mempool().expect("getrawmempool");
180+
let mempool = json.into_model().expect("into_model");
181+
// Sanity check.
182+
assert_eq!(mempool.0.len(), 1);
183+
}
154184

155185
#[test]
186+
// FIXME: Fails with getrawmempool verbose: JsonRpc(Json(Error("invalid type: map, expected a sequence", line: 1, column: 0)))
156187
#[cfg(feature = "TODO")]
157-
fn get_tx_out() { todo!() }
188+
fn get_raw_mempool_verbose() {
189+
let node = Node::new_with_default_wallet();
190+
node.fund_wallet();
191+
let (_address, _txid) = node.create_mempool_transaction();
192+
193+
// Test the type and into model conversion code.
194+
let json = node.client.get_raw_mempool_verbose().expect("getrawmempool verbose");
195+
let mempool = json.into_model().expect("into_model");
196+
// Sanity check.
197+
assert_eq!(mempool.0.len(), 1);
198+
}
158199

159200
#[test]
160-
#[cfg(feature = "TODO")]
161-
fn get_tx_out_proof() { todo!() }
201+
fn get_tx_out() {
202+
let node = Node::new_with_default_wallet();
203+
node.fund_wallet();
204+
let (_address, tx) = node.create_mined_transaction();
205+
let txid = tx.compute_txid();
206+
207+
// Test the type and into model conversion code.
208+
let json = node.client.get_tx_out(txid, 1).expect("gettxout");
209+
let _ = json.into_model().expect("into_model");
210+
}
162211

163212
#[test]
164-
#[cfg(feature = "TODO")]
165-
fn get_tx_out_set_info() { todo!() }
213+
fn get_tx_out_set_info() {
214+
let node = Node::new_with_default_wallet();
215+
node.fund_wallet();
216+
let (_address, _tx) = node.create_mined_transaction();
166217

218+
// Test the type and into model conversion code.
219+
let json = node.client.get_tx_out_set_info().expect("gettxoutsetinfo");
220+
let _ = json.into_model().expect("into_model");
221+
222+
}
223+
224+
// Implicitly tests the omitted method `gettxoutproof` as well.
167225
#[test]
168-
#[cfg(feature = "TODO")]
169-
fn verify_tx_out_proof() { todo!() }
226+
fn verify_tx_out_proof() {
227+
let node = Node::new_with_default_wallet();
228+
node.fund_wallet();
229+
let (_address, tx) = node.create_mined_transaction();
230+
let txid = tx.compute_txid();
231+
232+
let proof = node.client.get_tx_out_proof(&[txid]).expect("gettxoutproof");
170233

234+
let txids = node.client.verify_tx_out_proof(&proof).expect("verifytxoutproof");
235+
assert_eq!(txids.0.len(), 1);
236+
}

justfile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
set export
2+
3+
REPO_DIR := `git rev-parse --show-toplevel`
4+
15
default:
26
@just --list
37

@@ -12,10 +16,12 @@ check:
1216
# Lint everything.
1317
lint:
1418
cargo +$(cat ./nightly-version) clippy --workspace --all-targets --all-features -- --deny warnings
19+
cd $REPO_DIR/node > /dev/null; cargo +$(cat ../nightly-version) clippy --all-targets --all-features -- --deny warnings
1520

1621
# Run cargo fmt
1722
fmt:
1823
cargo +$(cat ./nightly-version) fmt --all
24+
cd $REPO_DIR/node > /dev/null; cargo +$(cat ../nightly-version) fmt
1925

2026
# Check the formatting
2127
format:

node/src/lib.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -401,9 +401,9 @@ impl Node {
401401
match client_base.create_wallet(wallet) {
402402
Ok(json) => {
403403
debug!("created wallet: {}", json.name());
404-
},
404+
}
405405
Err(e) => {
406-
debug!("initial create_wallet unsuccessful, try loading instead: {:?}", e);
406+
debug!("initial create_wallet failed, try load instead: {:?}", e);
407407
let wallet = client_base.load_wallet(wallet)?.name();
408408
debug!("loaded wallet: {}", wallet);
409409
}
@@ -577,9 +577,9 @@ mod test {
577577
use tempfile::TempDir;
578578

579579
use super::*;
580-
use crate::{exe_path, get_available_port, Node, Conf, LOCAL_IP};
581580
#[cfg(not(feature = "28_0"))]
582581
use crate::P2P;
582+
use crate::{exe_path, get_available_port, Conf, Node, LOCAL_IP};
583583

584584
#[test]
585585
fn test_local_ip() {
@@ -706,7 +706,8 @@ mod test {
706706
let node2 = Node::with_conf(&exe, &conf_node2).unwrap();
707707

708708
// Create Node 3 Connected To Node
709-
let conf_node3 = Conf::<'_> { p2p: node2.p2p_connect(false).unwrap(), ..Default::default() };
709+
let conf_node3 =
710+
Conf::<'_> { p2p: node2.p2p_connect(false).unwrap(), ..Default::default() };
710711
let node3 = Node::with_conf(exe_path().unwrap(), &conf_node3).unwrap();
711712

712713
// Get each nodes Peers

node/src/versions.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,22 @@ pub const VERSION: &str = "0.18.1";
4747
pub const VERSION: &str = "0.17.1";
4848

4949
// To make --no-default-features work we have to enable some feature, use most recent version same as for default.
50-
#[cfg(all(not(feature = "28_0"), not(feature = "27_1"), not(feature = "27_0"), not(feature = "26_2"), not(feature = "26_1"), not(feature = "26_0"), not(feature = "25_2"), not(feature = "24_2"), not(feature = "23_2"), not(feature = "22_1"), not(feature = "0_21_2"), not(feature = "0_20_2"), not(feature = "0_19_1"), not(feature = "0_18_1"), not(feature = "0_17_1")))]
51-
#[allow(dead_code)] // for --no-default-features
50+
#[cfg(all(
51+
not(feature = "28_0"),
52+
not(feature = "27_1"),
53+
not(feature = "27_0"),
54+
not(feature = "26_2"),
55+
not(feature = "26_1"),
56+
not(feature = "26_0"),
57+
not(feature = "25_2"),
58+
not(feature = "24_2"),
59+
not(feature = "23_2"),
60+
not(feature = "22_1"),
61+
not(feature = "0_21_2"),
62+
not(feature = "0_20_2"),
63+
not(feature = "0_19_1"),
64+
not(feature = "0_18_1"),
65+
not(feature = "0_17_1")
66+
))]
67+
#[allow(dead_code)] // for --no-default-features
5268
pub const VERSION: &str = "28.0";

types/src/v17/blockchain/into.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -502,14 +502,6 @@ impl GetTxOut {
502502
}
503503
}
504504

505-
impl GetTxOutProof {
506-
/// Converts version specific type to a version nonspecific, more strongly typed type.
507-
pub fn into_model(self) -> Result<model::GetTxOutProof, hex::HexToBytesError> {
508-
let data = Vec::from_hex(&self.0)?;
509-
Ok(model::GetTxOutProof(data))
510-
}
511-
}
512-
513505
impl GetTxOutSetInfo {
514506
/// Converts version specific type to a version nonspecific, more strongly typed type.
515507
pub fn into_model(self) -> Result<model::GetTxOutSetInfo, GetTxOutSetInfoError> {

types/src/v17/blockchain/mod.rs

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ pub struct GetTxOut {
599599
/// The transaction value in BTC.
600600
pub value: f64,
601601
/// The script pubkey.
602-
#[serde(rename = "scriptPubkey")]
602+
#[serde(rename = "scriptPubKey")]
603603
pub script_pubkey: ScriptPubkey,
604604
/// Coinbase or not.
605605
pub coinbase: bool,
@@ -621,28 +621,6 @@ pub struct ScriptPubkey {
621621
pub addresses: Vec<String>,
622622
}
623623

624-
/// Result of JSON-RPC method `gettxoutproof`.
625-
///
626-
/// > gettxoutproof ["txid",...] ( blockhash )
627-
/// >
628-
/// > Returns a hex-encoded proof that "txid" was included in a block.
629-
/// >
630-
/// > NOTE: By default this function only works sometimes. This is when there is an
631-
/// > unspent output in the utxo for this transaction. To make it always work,
632-
/// > you need to maintain a transaction index, using the -txindex command line option or
633-
/// > specify the block in which the transaction is included manually (by blockhash).
634-
/// >
635-
/// > Arguments:
636-
/// > 1. "txids" (string) A json array of txids to filter
637-
/// > [
638-
/// > "txid" (string) A transaction hash
639-
/// > ,...
640-
/// > ]
641-
///
642-
/// Inner field is a string that is a serialized, hex-encoded data for the proof.
643-
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
644-
pub struct GetTxOutProof(pub String);
645-
646624
/// Result of JSON-RPC method `gettxoutsetinfo`.
647625
///
648626
/// > gettxoutsetinfo

types/src/v17/mod.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,18 @@
2929
//! | getdifficulty | done |
3030
//! | getmempoolancestors | done (untested) |
3131
//! | getmempooldescendants | done (untested) |
32-
//! | getmempoolentry | done (untested) |
33-
//! | getmempoolinfo | done (untested) |
34-
//! | getrawmempool | done (untested) |
35-
//! | gettxout | done (untested) |
36-
//! | gettxoutproof | done (untested) |
37-
//! | gettxoutsetinfo | done (untested) |
32+
//! | getmempoolentry | done |
33+
//! | getmempoolinfo | done |
34+
//! | getrawmempool | done |
35+
//! | gettxout | done |
36+
//! | gettxoutproof | omitted |
37+
//! | gettxoutsetinfo | done |
3838
//! | preciousblock | omitted |
3939
//! | pruneblockchain | omitted |
4040
//! | savemempool | omitted |
4141
//! | scantxoutset | omitted |
4242
//! | verifychain | omitted |
43-
//! | verifytxoutproof | done (untested) |
43+
//! | verifytxoutproof | done |
4444
//!
4545
//! </details>
4646
//!
@@ -237,8 +237,8 @@ pub use self::{
237237
GetBlockVerbosityOne, GetBlockVerbosityZero, GetBlockchainInfo, GetChainTips,
238238
GetChainTxStats, GetDifficulty, GetMempoolAncestors, GetMempoolAncestorsVerbose,
239239
GetMempoolDescendants, GetMempoolDescendantsVerbose, GetMempoolEntry, GetMempoolInfo,
240-
GetRawMempool, GetRawMempoolVerbose, GetTxOut, GetTxOutProof, GetTxOutSetInfo,
241-
MempoolEntry, MempoolEntryFees, ScriptPubkey, Softfork, SoftforkReject, VerifyTxOutProof,
240+
GetRawMempool, GetRawMempoolVerbose, GetTxOut, GetTxOutSetInfo, MempoolEntry,
241+
MempoolEntryFees, ScriptPubkey, Softfork, SoftforkReject, VerifyTxOutProof,
242242
},
243243
control::{GetMemoryInfoStats, Locked, Logging, Uptime},
244244
generating::{Generate, GenerateToAddress},

0 commit comments

Comments
 (0)