Skip to content

Commit ee3646f

Browse files
committed
tests: avoid testing submitpackage when bitcoind version lower than 28
1 parent da7618b commit ee3646f

File tree

1 file changed

+117
-112
lines changed

1 file changed

+117
-112
lines changed

tests/rest.rs

Lines changed: 117 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -210,85 +210,89 @@ fn test_rest() -> Result<()> {
210210
// Elements-only tests
211211
#[cfg(not(feature = "liquid"))]
212212
{
213-
// Test with a real transaction package - create parent-child transactions
214-
// submitpackage requires between 2 and 25 transactions with proper dependencies
215-
let package_addr1 = tester.newaddress()?;
216-
let package_addr2 = tester.newaddress()?;
217-
218-
// Create parent transaction
219-
let tx1_result = tester.node_client().call::<Value>(
220-
"createrawtransaction",
221-
&[
222-
serde_json::json!([]),
223-
serde_json::json!({package_addr1.to_string(): 0.5}),
224-
],
225-
)?;
226-
let tx1_unsigned_hex = tx1_result.as_str().expect("raw tx hex").to_string();
227-
228-
let tx1_fund_result = tester
229-
.node_client()
230-
.call::<Value>("fundrawtransaction", &[serde_json::json!(tx1_unsigned_hex)])?;
231-
let tx1_funded_hex = tx1_fund_result["hex"]
232-
.as_str()
233-
.expect("funded tx hex")
234-
.to_string();
235-
236-
let tx1_sign_result = tester.node_client().call::<Value>(
237-
"signrawtransactionwithwallet",
238-
&[serde_json::json!(tx1_funded_hex)],
239-
)?;
240-
let tx1_signed_hex = tx1_sign_result["hex"]
241-
.as_str()
242-
.expect("signed tx hex")
243-
.to_string();
244-
245-
// Decode parent transaction to get its txid and find the output to spend
246-
let tx1_decoded = tester
247-
.node_client()
248-
.call::<Value>("decoderawtransaction", &[serde_json::json!(tx1_signed_hex)])?;
249-
let tx1_txid = tx1_decoded["txid"].as_str().expect("parent txid");
250-
251-
// Find the output going to package_addr1 (the one we want to spend)
252-
let tx1_vouts = tx1_decoded["vout"].as_array().expect("parent vouts");
253-
let mut spend_vout_index = None;
254-
let mut spend_vout_value = 0u64;
255-
256-
for (i, vout) in tx1_vouts.iter().enumerate() {
257-
if let Some(script_pub_key) = vout.get("scriptPubKey") {
258-
if let Some(address) = script_pub_key.get("address") {
259-
if address.as_str() == Some(&package_addr1.to_string()) {
260-
spend_vout_index = Some(i);
261-
// Convert from BTC to satoshis
262-
spend_vout_value =
263-
(vout["value"].as_f64().expect("vout value") * 100_000_000.0) as u64;
264-
break;
213+
let network_info = tester.node_client().call::<Value>("getnetworkinfo", &[])?;
214+
let version = network_info["version"].as_u64().expect("network version");
215+
if version >= 280000 {
216+
// Test with a real transaction package - create parent-child transactions
217+
// submitpackage requires between 2 and 25 transactions with proper dependencies
218+
let package_addr1 = tester.newaddress()?;
219+
let package_addr2 = tester.newaddress()?;
220+
221+
// Create parent transaction
222+
let tx1_result = tester.node_client().call::<Value>(
223+
"createrawtransaction",
224+
&[
225+
serde_json::json!([]),
226+
serde_json::json!({package_addr1.to_string(): 0.5}),
227+
],
228+
)?;
229+
let tx1_unsigned_hex = tx1_result.as_str().expect("raw tx hex").to_string();
230+
231+
let tx1_fund_result = tester
232+
.node_client()
233+
.call::<Value>("fundrawtransaction", &[serde_json::json!(tx1_unsigned_hex)])?;
234+
let tx1_funded_hex = tx1_fund_result["hex"]
235+
.as_str()
236+
.expect("funded tx hex")
237+
.to_string();
238+
239+
let tx1_sign_result = tester.node_client().call::<Value>(
240+
"signrawtransactionwithwallet",
241+
&[serde_json::json!(tx1_funded_hex)],
242+
)?;
243+
let tx1_signed_hex = tx1_sign_result["hex"]
244+
.as_str()
245+
.expect("signed tx hex")
246+
.to_string();
247+
248+
// Decode parent transaction to get its txid and find the output to spend
249+
let tx1_decoded = tester
250+
.node_client()
251+
.call::<Value>("decoderawtransaction", &[serde_json::json!(tx1_signed_hex)])?;
252+
let tx1_txid = tx1_decoded["txid"].as_str().expect("parent txid");
253+
254+
// Find the output going to package_addr1 (the one we want to spend)
255+
let tx1_vouts = tx1_decoded["vout"].as_array().expect("parent vouts");
256+
let mut spend_vout_index = None;
257+
let mut spend_vout_value = 0u64;
258+
259+
for (i, vout) in tx1_vouts.iter().enumerate() {
260+
if let Some(script_pub_key) = vout.get("scriptPubKey") {
261+
if let Some(address) = script_pub_key.get("address") {
262+
if address.as_str() == Some(&package_addr1.to_string()) {
263+
spend_vout_index = Some(i);
264+
// Convert from BTC to satoshis
265+
spend_vout_value = (vout["value"].as_f64().expect("vout value")
266+
* 100_000_000.0)
267+
as u64;
268+
break;
269+
}
265270
}
266271
}
267272
}
268-
}
269273

270-
let spend_vout_index = spend_vout_index.expect("Could not find output to spend");
271-
272-
// Create child transaction that spends from parent
273-
// Leave some satoshis for fee (e.g., 1000 sats)
274-
let child_output_value = spend_vout_value - 1000;
275-
let child_output_btc = child_output_value as f64 / 100_000_000.0;
276-
277-
let tx2_result = tester.node_client().call::<Value>(
278-
"createrawtransaction",
279-
&[
280-
serde_json::json!([{
281-
"txid": tx1_txid,
282-
"vout": spend_vout_index
283-
}]),
284-
serde_json::json!({package_addr2.to_string(): child_output_btc}),
285-
],
286-
)?;
287-
let tx2_unsigned_hex = tx2_result.as_str().expect("raw tx hex").to_string();
288-
289-
// Sign the child transaction
290-
// We need to provide the parent transaction's output details for signing
291-
let tx2_sign_result = tester.node_client().call::<Value>(
274+
let spend_vout_index = spend_vout_index.expect("Could not find output to spend");
275+
276+
// Create child transaction that spends from parent
277+
// Leave some satoshis for fee (e.g., 1000 sats)
278+
let child_output_value = spend_vout_value - 1000;
279+
let child_output_btc = child_output_value as f64 / 100_000_000.0;
280+
281+
let tx2_result = tester.node_client().call::<Value>(
282+
"createrawtransaction",
283+
&[
284+
serde_json::json!([{
285+
"txid": tx1_txid,
286+
"vout": spend_vout_index
287+
}]),
288+
serde_json::json!({package_addr2.to_string(): child_output_btc}),
289+
],
290+
)?;
291+
let tx2_unsigned_hex = tx2_result.as_str().expect("raw tx hex").to_string();
292+
293+
// Sign the child transaction
294+
// We need to provide the parent transaction's output details for signing
295+
let tx2_sign_result = tester.node_client().call::<Value>(
292296
"signrawtransactionwithwallet",
293297
&[
294298
serde_json::json!(tx2_unsigned_hex),
@@ -300,49 +304,50 @@ fn test_rest() -> Result<()> {
300304
}])
301305
],
302306
)?;
303-
let tx2_signed_hex = tx2_sign_result["hex"]
304-
.as_str()
305-
.expect("signed tx hex")
306-
.to_string();
307-
308-
// Debug: try calling submitpackage directly to see the result
309-
eprintln!("Trying submitpackage directly with parent-child transactions...");
310-
let direct_result = tester.node_client().call::<Value>(
311-
"submitpackage",
312-
&[serde_json::json!([
313-
tx1_signed_hex.clone(),
314-
tx2_signed_hex.clone()
315-
])],
316-
);
317-
match direct_result {
318-
Ok(result) => {
319-
eprintln!("Direct submitpackage succeeded: {:#?}", result);
320-
}
321-
Err(e) => {
322-
eprintln!("Direct submitpackage failed: {:?}", e);
307+
let tx2_signed_hex = tx2_sign_result["hex"]
308+
.as_str()
309+
.expect("signed tx hex")
310+
.to_string();
311+
312+
// Debug: try calling submitpackage directly to see the result
313+
eprintln!("Trying submitpackage directly with parent-child transactions...");
314+
let direct_result = tester.node_client().call::<Value>(
315+
"submitpackage",
316+
&[serde_json::json!([
317+
tx1_signed_hex.clone(),
318+
tx2_signed_hex.clone()
319+
])],
320+
);
321+
match direct_result {
322+
Ok(result) => {
323+
eprintln!("Direct submitpackage succeeded: {:#?}", result);
324+
}
325+
Err(e) => {
326+
eprintln!("Direct submitpackage failed: {:?}", e);
327+
}
323328
}
324-
}
325329

326-
// Now submit this transaction package via the package endpoint
327-
let package_json =
328-
serde_json::json!([tx1_signed_hex.clone(), tx2_signed_hex.clone()]).to_string();
329-
let package_result = ureq::post(&format!("http://{}/txs/package", rest_addr))
330-
.set("Content-Type", "application/json")
331-
.send_string(&package_json);
330+
// Now submit this transaction package via the package endpoint
331+
let package_json =
332+
serde_json::json!([tx1_signed_hex.clone(), tx2_signed_hex.clone()]).to_string();
333+
let package_result = ureq::post(&format!("http://{}/txs/package", rest_addr))
334+
.set("Content-Type", "application/json")
335+
.send_string(&package_json);
332336

333-
let package_resp = package_result.unwrap();
334-
assert_eq!(package_resp.status(), 200);
335-
let package_result = package_resp.into_json::<Value>()?;
337+
let package_resp = package_result.unwrap();
338+
assert_eq!(package_resp.status(), 200);
339+
let package_result = package_resp.into_json::<Value>()?;
336340

337-
// Verify the response structure
338-
assert!(package_result["tx-results"].is_object());
339-
assert!(package_result["package_msg"].is_string());
341+
// Verify the response structure
342+
assert!(package_result["tx-results"].is_object());
343+
assert!(package_result["package_msg"].is_string());
340344

341-
let tx_results = package_result["tx-results"].as_object().unwrap();
342-
assert_eq!(tx_results.len(), 2);
345+
let tx_results = package_result["tx-results"].as_object().unwrap();
346+
assert_eq!(tx_results.len(), 2);
343347

344-
// The transactions should be processed (whether accepted or rejected)
345-
assert!(!tx_results.is_empty());
348+
// The transactions should be processed (whether accepted or rejected)
349+
assert!(!tx_results.is_empty());
350+
}
346351
}
347352

348353
// Elements-only tests

0 commit comments

Comments
 (0)