/// Outpoint under claim process by our own tx, once this one get enough confirmations, we remove it from
/// bump-txn candidate buffer.
Claim {
- claim_request: Txid,
+ package_id: PackageID,
},
/// Claim tx aggregate multiple claimable outpoints. One of the outpoint may be claimed by a counterparty party tx.
/// In this case, we need to drop the outpoint and regenerate a new claim tx. By safety, we keep tracking
impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
(0, Claim) => {
- (0, claim_request, required),
+ (0, package_id, required),
},
(1, ContentiousOutpoint) => {
(0, package, required),
// We check for outpoint spends within claims individually rather than as a set
// since requests can have outpoints split off.
if !self.onchain_events_awaiting_threshold_conf.iter()
- .any(|event_entry| if let OnchainEvent::Claim { claim_request } = event_entry.event {
- first_claim_txid_height.0 == claim_request.into_inner()
+ .any(|event_entry| if let OnchainEvent::Claim { package_id } = event_entry.event {
+ first_claim_txid_height.0 == package_id
} else {
// The onchain event is not a claim, keep seeking until we find one.
false
//... we need to verify equality between transaction outpoints and claim request
// outpoints to know if transaction is the original claim or a bumped one issued
// by us.
- let mut set_equality = true;
- if !request.requires_external_funding() || !request.is_malleable() {
- // If the claim does not require external funds to be allocated through
- // additional inputs we can simply check the inputs in order as they
- // cannot change under us.
- if request.outpoints().len() != tx.input.len() {
- set_equality = false;
- } else {
- for (claim_inp, tx_inp) in request.outpoints().iter().zip(tx.input.iter()) {
- if **claim_inp != tx_inp.previous_output {
- set_equality = false;
- }
- }
- }
- } else {
- // Otherwise, we'll do a linear search for each input (we don't expect
- // large input sets to exist) to ensure the request's input set is fully
- // spent to be resilient against the external claim reordering inputs.
- let mut spends_all_inputs = true;
- for request_input in request.outpoints() {
- if tx.input.iter().find(|input| input.previous_output == *request_input).is_none() {
- spends_all_inputs = false;
- break;
- }
+ let mut are_sets_equal = true;
+ let mut tx_inputs = tx.input.iter().map(|input| &input.previous_output).collect::<Vec<_>>();
+ tx_inputs.sort_unstable();
+ for request_input in request.outpoints() {
+ if tx_inputs.binary_search(&request_input).is_err() {
+ are_sets_equal = false;
+ break;
}
- set_equality = spends_all_inputs;
}
macro_rules! clean_claim_request_after_safety_delay {
txid: tx.txid(),
height: conf_height,
block_hash: Some(conf_hash),
- event: OnchainEvent::Claim { claim_request: Txid::from_inner(first_claim_txid_height.0) }
+ event: OnchainEvent::Claim { package_id: first_claim_txid_height.0 }
};
if !self.onchain_events_awaiting_threshold_conf.contains(&entry) {
self.onchain_events_awaiting_threshold_conf.push(entry);
// If this is our transaction (or our counterparty spent all the outputs
// before we could anyway with same inputs order than us), wait for
// ANTI_REORG_DELAY and clean the RBF tracking map.
- if set_equality {
+ if are_sets_equal {
clean_claim_request_after_safety_delay!();
} else { // If false, generate new claim request with update outpoint set
let mut at_least_one_drop = false;
for entry in onchain_events_awaiting_threshold_conf {
if entry.has_reached_confirmation_threshold(cur_height) {
match entry.event {
- OnchainEvent::Claim { claim_request } => {
- let package_id = claim_request.into_inner();
+ OnchainEvent::Claim { package_id } => {
// We may remove a whole set of claim outpoints here, as these one may have
// been aggregated in a single tx and claimed so atomically
if let Some(request) = self.pending_claim_requests.remove(&package_id) {
for outpoint in request.outpoints() {
- log_debug!(logger, "Removing claim tracking for {} due to maturation of claim tx {}.", outpoint, claim_request);
+ log_debug!(logger, "Removing claim tracking for {} due to maturation of claim package {}.",
+ outpoint, log_bytes!(package_id));
self.claimable_outpoints.remove(&outpoint);
#[cfg(anchors)]
self.pending_claim_events.remove(&package_id);
#[cfg(anchors)]
pub(crate) fn generate_external_htlc_claim(
- &mut self, outp: &::bitcoin::OutPoint, preimage: &Option<PaymentPreimage>
+ &self, outp: &::bitcoin::OutPoint, preimage: &Option<PaymentPreimage>
) -> Option<ExternalHTLCClaim> {
let find_htlc = |holder_commitment: &HolderCommitmentTransaction| -> Option<ExternalHTLCClaim> {
let trusted_tx = holder_commitment.trust();