Skip to content

Commit 16776be

Browse files
committed
mining: add tx lookup IPC methods and integration coverage
Add Mining interface methods getTransactionsByTxID and getTransactionsByWitnessID to the capnp schema. Expand integration tests to call both methods with empty inputs, a real mempool transaction id and witness id, and unknown ids, verifying serialized transaction bytes for hits and empty results for misses.
1 parent 3343732 commit 16776be

2 files changed

Lines changed: 97 additions & 0 deletions

File tree

capnp/mining.capnp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ interface Mining $Proxy.wrap("interfaces::Mining") {
2424
checkBlock @5 (context :Proxy.Context, block: Data, options: BlockCheckOptions) -> (reason: Text, debug: Text, result: Bool);
2525
interrupt @6 () -> ();
2626
submitBlock @7 (context :Proxy.Context, block: Data) -> (reason: Text, debug: Text, result: Bool);
27+
getTransactionsByTxID @8 (context :Proxy.Context, txids: List(Data)) -> (result: List(Data));
28+
getTransactionsByWitnessID @9 (context :Proxy.Context, wtxids: List(Data)) -> (result: List(Data));
2729
}
2830

2931
interface BlockTemplate $Proxy.wrap("interfaces::BlockTemplate") {

tests/test.rs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use bitcoin_capnp_types::mining_capnp;
2+
use encoding::encode_to_vec;
23

34
#[path = "util/bitcoin_core.rs"]
45
mod bitcoin_core_util;
@@ -268,6 +269,100 @@ async fn mining_submit_block() {
268269
.await;
269270
}
270271

272+
/// getTransactionsByTxID and getTransactionsByWitnessID with empty lists and
273+
/// with a non-existent txid/wtxid.
274+
#[tokio::test]
275+
// Serialized because this test may mine blocks to recover wallet funding.
276+
#[serial_test::serial]
277+
async fn mining_get_transactions() {
278+
with_mining_client(|_client, thread, mining| async move {
279+
let wallet = bitcoin_test_wallet();
280+
ensure_wallet_loaded_and_funded(&wallet);
281+
282+
let real_tx = create_mempool_self_transfer(&wallet);
283+
let real_txid = real_tx.compute_txid().to_byte_array();
284+
let real_wtxid = real_tx.compute_wtxid().to_byte_array();
285+
let real_raw_tx = encode_to_vec(&real_tx);
286+
287+
// getTransactionsByTxID — empty list should return empty list.
288+
let mut req = mining.get_transactions_by_tx_i_d_request();
289+
req.get().get_context().unwrap().set_thread(thread.clone());
290+
req.get().init_txids(0);
291+
let resp = req.send().promise.await.unwrap();
292+
let results = resp.get().unwrap().get_result().unwrap();
293+
assert_eq!(
294+
results.len(),
295+
0,
296+
"empty txid list should return empty results"
297+
);
298+
299+
// getTransactionsByTxID — return real mempool tx and empty for unknown id.
300+
let fake_txid = [0x42u8; 32];
301+
let mut req = mining.get_transactions_by_tx_i_d_request();
302+
req.get().get_context().unwrap().set_thread(thread.clone());
303+
{
304+
let mut txids = req.get().init_txids(2);
305+
txids.set(0, &real_txid);
306+
txids.set(1, &fake_txid);
307+
}
308+
let resp = req.send().promise.await.unwrap();
309+
let results = resp.get().unwrap().get_result().unwrap();
310+
assert_eq!(
311+
results.len(),
312+
2,
313+
"should return one entry per requested txid, including misses"
314+
);
315+
assert_eq!(
316+
results.get(0).unwrap(),
317+
real_raw_tx.as_slice(),
318+
"known txid should return serialized transaction"
319+
);
320+
assert!(
321+
results.get(1).unwrap().is_empty(),
322+
"non-existent txid should return empty data"
323+
);
324+
325+
// getTransactionsByWitnessID — empty list should return empty list.
326+
let mut req = mining.get_transactions_by_witness_i_d_request();
327+
req.get().get_context().unwrap().set_thread(thread.clone());
328+
req.get().init_wtxids(0);
329+
let resp = req.send().promise.await.unwrap();
330+
let results = resp.get().unwrap().get_result().unwrap();
331+
assert_eq!(
332+
results.len(),
333+
0,
334+
"empty wtxid list should return empty results"
335+
);
336+
337+
// getTransactionsByWitnessID — return real mempool tx and empty for unknown id.
338+
let fake_wtxid = [0x43u8; 32];
339+
let mut req = mining.get_transactions_by_witness_i_d_request();
340+
req.get().get_context().unwrap().set_thread(thread.clone());
341+
{
342+
let mut wtxids = req.get().init_wtxids(2);
343+
wtxids.set(0, &real_wtxid);
344+
wtxids.set(1, &fake_wtxid);
345+
}
346+
let resp = req.send().promise.await.unwrap();
347+
let results = resp.get().unwrap().get_result().unwrap();
348+
assert_eq!(
349+
results.len(),
350+
2,
351+
"should return one entry per requested wtxid, including misses"
352+
);
353+
assert_eq!(
354+
results.get(0).unwrap(),
355+
real_raw_tx.as_slice(),
356+
"known wtxid should return serialized transaction"
357+
);
358+
assert!(
359+
results.get(1).unwrap().is_empty(),
360+
"non-existent wtxid should return empty data"
361+
);
362+
})
363+
.await;
364+
}
365+
271366
/// checkBlock with a template block payload, and interrupt.
272367
#[tokio::test]
273368
// Serialized because interrupt() can affect other in-flight mining waits.

0 commit comments

Comments
 (0)