Skip to content

Commit 9a95544

Browse files
committed
Use outpoint creation height when restoring locktimed packages
When we have an outpoint to claim which is lock-timed and the locktime is reached, we add it to `OnchainTxHandler::claimable_outpoints` to indicate the outpoint is now being claimed. However, `claimable_outpoints` is supposed to track when the outpoint first appeared on chain so that we can remove the claim if the outpoint is reorged out. Sadly, in the handling for lock-timed packages, we incorrectly stored the current height in `claimable_outpoints`, causing such claims to be removed in case of a reorg right after they were generated, even if the output we intend to claim isn't removed at all. Here we use the creation-height tracking added in the previous commit to actually address the issue, using the tracked height when adding a claim to `OnchainTxHandler::claimable_outpoints`. In cases where we have no information, we continue to use the current height, retaining the issue for locktimed packages on upgrades, but this simplifies cases where we actually don't have the information available anyway.
1 parent f916e13 commit 9a95544

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

lightning/src/chain/onchaintx.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -889,9 +889,10 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
889889
// Because fuzzing can cause hash collisions, we can end up with conflicting claim
890890
// ids here, so we only assert when not fuzzing.
891891
debug_assert!(cfg!(fuzzing) || self.pending_claim_requests.get(&claim_id).is_none());
892-
for k in req.outpoints() {
893-
log_info!(logger, "Registering claiming request for {}:{}", k.txid, k.vout);
894-
self.claimable_outpoints.insert(k.clone(), (claim_id, conf_height));
892+
for (k, outpoint_confirmation_height) in req.outpoints_and_creation_heights() {
893+
let creation_height = outpoint_confirmation_height.unwrap_or(conf_height);
894+
log_info!(logger, "Registering claiming request for {}:{}, which exists as of height {creation_height}", k.txid, k.vout);
895+
self.claimable_outpoints.insert(k.clone(), (claim_id, creation_height));
895896
}
896897
self.pending_claim_requests.insert(claim_id, req);
897898
}

lightning/src/chain/package.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,34 @@ impl PackageSolvingData {
810810
}
811811
}
812812

813+
fn input_confirmation_height(&self) -> Option<u32> {
814+
match self {
815+
PackageSolvingData::RevokedOutput(RevokedOutput {
816+
outpoint_confirmation_height,
817+
..
818+
})
819+
| PackageSolvingData::RevokedHTLCOutput(RevokedHTLCOutput {
820+
outpoint_confirmation_height,
821+
..
822+
})
823+
| PackageSolvingData::CounterpartyOfferedHTLCOutput(CounterpartyOfferedHTLCOutput {
824+
outpoint_confirmation_height,
825+
..
826+
})
827+
| PackageSolvingData::CounterpartyReceivedHTLCOutput(
828+
CounterpartyReceivedHTLCOutput { outpoint_confirmation_height, .. },
829+
)
830+
| PackageSolvingData::HolderHTLCOutput(HolderHTLCOutput {
831+
outpoint_confirmation_height,
832+
..
833+
}) => *outpoint_confirmation_height,
834+
// We don't bother to track `HolderFundingOutput`'s creation height as its the funding
835+
// transaction itself and we build `HolderFundingOutput`s before we actually get the
836+
// commitment transaction confirmed.
837+
PackageSolvingData::HolderFundingOutput(_) => None,
838+
}
839+
}
840+
813841
#[rustfmt::skip]
814842
fn as_tx_input(&self, previous_output: BitcoinOutPoint) -> TxIn {
815843
let sequence = match self {
@@ -1177,6 +1205,12 @@ impl PackageTemplate {
11771205
pub(crate) fn outpoints(&self) -> Vec<&BitcoinOutPoint> {
11781206
self.inputs.iter().map(|(o, _)| o).collect()
11791207
}
1208+
pub(crate) fn outpoints_and_creation_heights(
1209+
&self,
1210+
) -> impl Iterator<Item = (&BitcoinOutPoint, Option<u32>)> {
1211+
self.inputs.iter().map(|(o, p)| (o, p.input_confirmation_height()))
1212+
}
1213+
11801214
pub(crate) fn inputs(&self) -> impl ExactSizeIterator<Item = &PackageSolvingData> {
11811215
self.inputs.iter().map(|(_, i)| i)
11821216
}

0 commit comments

Comments
 (0)