Skip to content

Commit 774dc9f

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 ebe2996 commit 774dc9f

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

capnp/mining.capnp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ interface Mining $Proxy.wrap("interfaces::Mining") {
2323
createNewBlock @4 (context :Proxy.Context, options: BlockCreateOptions, cooldown: Bool = true) -> (result: BlockTemplate);
2424
checkBlock @5 (context :Proxy.Context, block: Data, options: BlockCheckOptions) -> (reason: Text, debug: Text, result: Bool);
2525
interrupt @6 () -> ();
26+
getTransactionsByTxID @7 (context :Proxy.Context, txids: List(Data)) -> (result: List(Data));
27+
getTransactionsByWitnessID @8 (context :Proxy.Context, wtxids: List(Data)) -> (result: List(Data));
2628
}
2729

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

tests/test.rs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,102 @@ async fn mining_block_template_lifecycle() {
270270
.await;
271271
}
272272

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

0 commit comments

Comments
 (0)