Skip to content

Commit a177511

Browse files
committed
Make PackageTemplate::merge_package fallible
This moves panics to a higher level, allows failures to be handled gracefully in some cases, and supports more explicit testing without using `#[should_panic]`.
1 parent 8307ce0 commit a177511

File tree

2 files changed

+20
-22
lines changed

2 files changed

+20
-22
lines changed

lightning/src/chain/onchaintx.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -772,8 +772,11 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
772772
for j in 0..i {
773773
if requests[i].can_merge_with(&requests[j], cur_height) {
774774
let merge = requests.remove(i);
775-
requests[j].merge_package(merge);
776-
break;
775+
if let Err(rejected) = requests[j].merge_package(merge) {
776+
requests.insert(i, rejected);
777+
} else {
778+
break;
779+
}
777780
}
778781
}
779782
}
@@ -1101,7 +1104,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
11011104
OnchainEvent::ContentiousOutpoint { package } => {
11021105
if let Some(pending_claim) = self.claimable_outpoints.get(package.outpoints()[0]) {
11031106
if let Some(request) = self.pending_claim_requests.get_mut(&pending_claim.0) {
1104-
request.merge_package(package);
1107+
assert!(request.merge_package(package).is_ok());
11051108
// Using a HashMap guarantee us than if we have multiple outpoints getting
11061109
// resurrected only one bump claim tx is going to be broadcast
11071110
bump_candidates.insert(pending_claim.clone(), request.clone());

lightning/src/chain/package.rs

+14-19
Original file line numberDiff line numberDiff line change
@@ -828,18 +828,18 @@ impl PackageTemplate {
828828
}
829829
}
830830
}
831-
pub(crate) fn merge_package(&mut self, mut merge_from: PackageTemplate) {
831+
pub(crate) fn merge_package(&mut self, mut merge_from: PackageTemplate) -> Result<(), PackageTemplate> {
832832
if self.malleability == PackageMalleability::Untractable || merge_from.malleability == PackageMalleability::Untractable {
833-
panic!("Merging template on untractable packages");
833+
return Err(merge_from);
834834
}
835835
if !self.aggregable || !merge_from.aggregable {
836-
panic!("Merging non aggregatable packages");
836+
return Err(merge_from);
837837
}
838838
if let Some((_, lead_input)) = self.inputs.first() {
839839
for (_, v) in merge_from.inputs.iter() {
840-
if !lead_input.is_compatible(v) { panic!("Merging outputs from differing types !"); }
840+
if !lead_input.is_compatible(v) { return Err(merge_from); }
841841
}
842-
} else { panic!("Merging template on an empty package"); }
842+
} else { return Err(merge_from); }
843843
for (k, v) in merge_from.inputs.drain(..) {
844844
self.inputs.push((k, v));
845845
}
@@ -851,6 +851,7 @@ impl PackageTemplate {
851851
self.feerate_previous = merge_from.feerate_previous;
852852
}
853853
self.height_timer = cmp::min(self.height_timer, merge_from.height_timer);
854+
Ok(())
854855
}
855856
/// Gets the amount of all outptus being spent by this package, only valid for malleable
856857
/// packages.
@@ -1320,7 +1321,6 @@ mod tests {
13201321
}
13211322

13221323
#[test]
1323-
#[should_panic]
13241324
fn test_package_untractable_merge_to() {
13251325
let txid = Txid::from_str("c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e").unwrap();
13261326
let secp_ctx = Secp256k1::new();
@@ -1329,11 +1329,10 @@ mod tests {
13291329

13301330
let mut untractable_package = PackageTemplate::build_package(txid, 0, revk_outp.clone(), 1000);
13311331
let malleable_package = PackageTemplate::build_package(txid, 1, htlc_outp.clone(), 1000);
1332-
untractable_package.merge_package(malleable_package);
1332+
assert!(untractable_package.merge_package(malleable_package).is_err());
13331333
}
13341334

13351335
#[test]
1336-
#[should_panic]
13371336
fn test_package_untractable_merge_from() {
13381337
let txid = Txid::from_str("c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e").unwrap();
13391338
let secp_ctx = Secp256k1::new();
@@ -1342,11 +1341,10 @@ mod tests {
13421341

13431342
let mut malleable_package = PackageTemplate::build_package(txid, 0, htlc_outp.clone(), 1000);
13441343
let untractable_package = PackageTemplate::build_package(txid, 1, revk_outp.clone(), 1000);
1345-
malleable_package.merge_package(untractable_package);
1344+
assert!(malleable_package.merge_package(untractable_package).is_err());
13461345
}
13471346

13481347
#[test]
1349-
#[should_panic]
13501348
fn test_package_noaggregation_to() {
13511349
let txid = Txid::from_str("c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e").unwrap();
13521350
let secp_ctx = Secp256k1::new();
@@ -1355,11 +1353,10 @@ mod tests {
13551353

13561354
let mut noaggregation_package = PackageTemplate::build_package(txid, 0, revk_outp_counterparty_balance.clone(), 1000);
13571355
let aggregation_package = PackageTemplate::build_package(txid, 1, revk_outp.clone(), 1000);
1358-
noaggregation_package.merge_package(aggregation_package);
1356+
assert!(noaggregation_package.merge_package(aggregation_package).is_err());
13591357
}
13601358

13611359
#[test]
1362-
#[should_panic]
13631360
fn test_package_noaggregation_from() {
13641361
let txid = Txid::from_str("c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e").unwrap();
13651362
let secp_ctx = Secp256k1::new();
@@ -1368,11 +1365,10 @@ mod tests {
13681365

13691366
let mut aggregation_package = PackageTemplate::build_package(txid, 0, revk_outp.clone(), 1000);
13701367
let noaggregation_package = PackageTemplate::build_package(txid, 1, revk_outp_counterparty_balance.clone(), 1000);
1371-
aggregation_package.merge_package(noaggregation_package);
1368+
assert!(aggregation_package.merge_package(noaggregation_package).is_err());
13721369
}
13731370

13741371
#[test]
1375-
#[should_panic]
13761372
fn test_package_empty() {
13771373
let txid = Txid::from_str("c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e").unwrap();
13781374
let secp_ctx = Secp256k1::new();
@@ -1381,11 +1377,10 @@ mod tests {
13811377
let mut empty_package = PackageTemplate::build_package(txid, 0, revk_outp.clone(), 1000);
13821378
empty_package.inputs = vec![];
13831379
let package = PackageTemplate::build_package(txid, 1, revk_outp.clone(), 1000);
1384-
empty_package.merge_package(package);
1380+
assert!(empty_package.merge_package(package).is_err());
13851381
}
13861382

13871383
#[test]
1388-
#[should_panic]
13891384
fn test_package_differing_categories() {
13901385
let txid = Txid::from_str("c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e").unwrap();
13911386
let secp_ctx = Secp256k1::new();
@@ -1394,7 +1389,7 @@ mod tests {
13941389

13951390
let mut revoked_package = PackageTemplate::build_package(txid, 0, revk_outp, 1000);
13961391
let counterparty_package = PackageTemplate::build_package(txid, 1, counterparty_outp, 1000);
1397-
revoked_package.merge_package(counterparty_package);
1392+
assert!(revoked_package.merge_package(counterparty_package).is_err());
13981393
}
13991394

14001395
#[test]
@@ -1409,8 +1404,8 @@ mod tests {
14091404
let package_two = PackageTemplate::build_package(txid, 1, revk_outp_two, 1000);
14101405
let package_three = PackageTemplate::build_package(txid, 2, revk_outp_three, 1000);
14111406

1412-
package_one.merge_package(package_two);
1413-
package_one.merge_package(package_three);
1407+
assert!(package_one.merge_package(package_two).is_ok());
1408+
assert!(package_one.merge_package(package_three).is_ok());
14141409
assert_eq!(package_one.outpoints().len(), 3);
14151410

14161411
if let Some(split_package) = package_one.split_package(&BitcoinOutPoint { txid, vout: 1 }) {

0 commit comments

Comments
 (0)