pub(crate) payment_hash: PaymentHash,
pub(crate) payment_preimage: Option<PaymentPreimage>,
pub(crate) source: HTLCSource,
- pub(crate) onchain_value_satoshis: Option<u64>,
+ pub(crate) htlc_value_satoshis: Option<u64>,
}
impl_writeable_tlv_based!(HTLCUpdate, {
(0, payment_hash, required),
- (1, onchain_value_satoshis, option),
+ (1, htlc_value_satoshis, option),
(2, source, required),
(4, payment_preimage, option),
});
HTLCUpdate {
source: HTLCSource,
payment_hash: PaymentHash,
- onchain_value_satoshis: Option<u64>,
+ htlc_value_satoshis: Option<u64>,
/// None in the second case, above, ie when there is no relevant output in the commitment
/// transaction which appeared on chain.
commitment_tx_output_idx: Option<u32>,
impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
(0, HTLCUpdate) => {
(0, source, required),
- (1, onchain_value_satoshis, option),
+ (1, htlc_value_satoshis, option),
(2, payment_hash, required),
(3, commitment_tx_output_idx, option),
},
commitment_txid: Txid,
htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
commitment_number: u64,
- their_revocation_point: PublicKey,
+ their_per_commitment_point: PublicKey,
},
PaymentPreimage {
payment_preimage: PaymentPreimage,
(1, LatestCounterpartyCommitmentTXInfo) => {
(0, commitment_txid, required),
(2, commitment_number, required),
- (4, their_revocation_point, required),
+ (4, their_per_commitment_point, required),
(6, htlc_outputs, vec_type),
},
(2, PaymentPreimage) => {
counterparty_commitment_params: CounterpartyCommitmentParameters,
funding_redeemscript: Script,
channel_value_satoshis: u64,
- // first is the idx of the first of the two revocation points
- their_cur_revocation_points: Option<(u64, PublicKey, Option<PublicKey>)>,
+ // first is the idx of the first of the two per-commitment points
+ their_cur_per_commitment_points: Option<(u64, PublicKey, Option<PublicKey>)>,
on_holder_tx_csv: u16,
// deserialization
current_holder_commitment_number: u64,
+ /// The set of payment hashes from inbound payments for which we know the preimage. Payment
+ /// preimages that are not included in any unrevoked local commitment transaction or unrevoked
+ /// remote commitment transactions are automatically removed when commitment transactions are
+ /// revoked.
payment_preimages: HashMap<PaymentHash, PaymentPreimage>,
// Note that `MonitorEvent`s MUST NOT be generated during update processing, only generated
self.counterparty_commitment_params != other.counterparty_commitment_params ||
self.funding_redeemscript != other.funding_redeemscript ||
self.channel_value_satoshis != other.channel_value_satoshis ||
- self.their_cur_revocation_points != other.their_cur_revocation_points ||
+ self.their_cur_per_commitment_points != other.their_cur_per_commitment_points ||
self.on_holder_tx_csv != other.on_holder_tx_csv ||
self.commitment_secrets != other.commitment_secrets ||
self.counterparty_claimable_outpoints != other.counterparty_claimable_outpoints ||
self.funding_redeemscript.write(writer)?;
self.channel_value_satoshis.write(writer)?;
- match self.their_cur_revocation_points {
+ match self.their_cur_per_commitment_points {
Some((idx, pubkey, second_option)) => {
writer.write_all(&byte_utils::be48_to_array(idx))?;
writer.write_all(&pubkey.serialize())?;
counterparty_commitment_params,
funding_redeemscript,
channel_value_satoshis,
- their_cur_revocation_points: None,
+ their_cur_per_commitment_points: None,
on_holder_tx_csv: counterparty_channel_parameters.selected_contest_delay,
txid: Txid,
htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
commitment_number: u64,
- their_revocation_point: PublicKey,
+ their_per_commitment_point: PublicKey,
logger: &L,
) where L::Target: Logger {
self.inner.lock().unwrap().provide_latest_counterparty_commitment_tx(
- txid, htlc_outputs, commitment_number, their_revocation_point, logger)
+ txid, htlc_outputs, commitment_number, their_per_commitment_point, logger)
}
#[cfg(test)]
self.inner.lock().unwrap().provide_latest_holder_commitment_tx(holder_commitment_tx, htlc_outputs).map_err(|_| ())
}
- #[cfg(test)]
+ /// This is used to provide payment preimage(s) out-of-band during startup without updating the
+ /// off-chain state with a new commitment transaction.
pub(crate) fn provide_payment_preimage<B: Deref, F: Deref, L: Deref>(
&self,
payment_hash: &PaymentHash,
res
}
+
+ pub(crate) fn get_stored_preimages(&self) -> HashMap<PaymentHash, PaymentPreimage> {
+ self.inner.lock().unwrap().payment_preimages.clone()
+ }
}
/// Compares a broadcasted commitment transaction's HTLCs with those in the latest state,
event: OnchainEvent::HTLCUpdate {
source: (**source).clone(),
payment_hash: htlc.payment_hash.clone(),
- onchain_value_satoshis: Some(htlc.amount_msat / 1000),
+ htlc_value_satoshis: Some(htlc.amount_msat / 1000),
commitment_tx_output_idx: None,
},
};
Ok(())
}
- pub(crate) fn provide_latest_counterparty_commitment_tx<L: Deref>(&mut self, txid: Txid, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>, commitment_number: u64, their_revocation_point: PublicKey, logger: &L) where L::Target: Logger {
+ pub(crate) fn provide_latest_counterparty_commitment_tx<L: Deref>(&mut self, txid: Txid, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>, commitment_number: u64, their_per_commitment_point: PublicKey, logger: &L) where L::Target: Logger {
// TODO: Encrypt the htlc_outputs data with the single-hash of the commitment transaction
// so that a remote monitor doesn't learn anything unless there is a malicious close.
// (only maybe, sadly we cant do the same for local info, as we need to be aware of
self.counterparty_claimable_outpoints.insert(txid, htlc_outputs.clone());
self.current_counterparty_commitment_number = commitment_number;
//TODO: Merge this into the other per-counterparty-transaction output storage stuff
- match self.their_cur_revocation_points {
+ match self.their_cur_per_commitment_points {
Some(old_points) => {
if old_points.0 == commitment_number + 1 {
- self.their_cur_revocation_points = Some((old_points.0, old_points.1, Some(their_revocation_point)));
+ self.their_cur_per_commitment_points = Some((old_points.0, old_points.1, Some(their_per_commitment_point)));
} else if old_points.0 == commitment_number + 2 {
if let Some(old_second_point) = old_points.2 {
- self.their_cur_revocation_points = Some((old_points.0 - 1, old_second_point, Some(their_revocation_point)));
+ self.their_cur_per_commitment_points = Some((old_points.0 - 1, old_second_point, Some(their_per_commitment_point)));
} else {
- self.their_cur_revocation_points = Some((commitment_number, their_revocation_point, None));
+ self.their_cur_per_commitment_points = Some((commitment_number, their_per_commitment_point, None));
}
} else {
- self.their_cur_revocation_points = Some((commitment_number, their_revocation_point, None));
+ self.their_cur_per_commitment_points = Some((commitment_number, their_per_commitment_point, None));
}
},
None => {
- self.their_cur_revocation_points = Some((commitment_number, their_revocation_point, None));
+ self.their_cur_per_commitment_points = Some((commitment_number, their_per_commitment_point, None));
}
}
let mut htlcs = Vec::with_capacity(htlc_outputs.len());
ret = Err(());
}
}
- ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid, htlc_outputs, commitment_number, their_revocation_point } => {
+ ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid, htlc_outputs, commitment_number, their_per_commitment_point } => {
log_trace!(logger, "Updating ChannelMonitor with latest counterparty commitment transaction info");
- self.provide_latest_counterparty_commitment_tx(*commitment_txid, htlc_outputs.clone(), *commitment_number, *their_revocation_point, logger)
+ self.provide_latest_counterparty_commitment_tx(*commitment_txid, htlc_outputs.clone(), *commitment_number, *their_per_commitment_point, logger)
},
ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage } => {
log_trace!(logger, "Updating ChannelMonitor with payment preimage");
fn get_counterparty_htlc_output_claim_reqs(&self, commitment_number: u64, commitment_txid: Txid, tx: Option<&Transaction>) -> Vec<PackageTemplate> {
let mut claimable_outpoints = Vec::new();
if let Some(htlc_outputs) = self.counterparty_claimable_outpoints.get(&commitment_txid) {
- if let Some(revocation_points) = self.their_cur_revocation_points {
- let revocation_point_option =
+ if let Some(per_commitment_points) = self.their_cur_per_commitment_points {
+ let per_commitment_point_option =
// If the counterparty commitment tx is the latest valid state, use their latest
// per-commitment point
- if revocation_points.0 == commitment_number { Some(&revocation_points.1) }
- else if let Some(point) = revocation_points.2.as_ref() {
+ if per_commitment_points.0 == commitment_number { Some(&per_commitment_points.1) }
+ else if let Some(point) = per_commitment_points.2.as_ref() {
// If counterparty commitment tx is the state previous to the latest valid state, use
// their previous per-commitment point (non-atomicity of revocation means it's valid for
// them to temporarily have two valid commitment txns from our viewpoint)
- if revocation_points.0 == commitment_number + 1 { Some(point) } else { None }
+ if per_commitment_points.0 == commitment_number + 1 { Some(point) } else { None }
} else { None };
- if let Some(revocation_point) = revocation_point_option {
+ if let Some(per_commitment_point) = per_commitment_point_option {
for (_, &(ref htlc, _)) in htlc_outputs.iter().enumerate() {
if let Some(transaction_output_index) = htlc.transaction_output_index {
if let Some(transaction) = tx {
}
let preimage = if htlc.offered { if let Some(p) = self.payment_preimages.get(&htlc.payment_hash) { Some(*p) } else { None } } else { None };
if preimage.is_some() || !htlc.offered {
- let counterparty_htlc_outp = if htlc.offered { PackageSolvingData::CounterpartyOfferedHTLCOutput(CounterpartyOfferedHTLCOutput::build(*revocation_point, self.counterparty_commitment_params.counterparty_delayed_payment_base_key, self.counterparty_commitment_params.counterparty_htlc_base_key, preimage.unwrap(), htlc.clone())) } else { PackageSolvingData::CounterpartyReceivedHTLCOutput(CounterpartyReceivedHTLCOutput::build(*revocation_point, self.counterparty_commitment_params.counterparty_delayed_payment_base_key, self.counterparty_commitment_params.counterparty_htlc_base_key, htlc.clone())) };
+ let counterparty_htlc_outp = if htlc.offered {
+ PackageSolvingData::CounterpartyOfferedHTLCOutput(
+ CounterpartyOfferedHTLCOutput::build(*per_commitment_point,
+ self.counterparty_commitment_params.counterparty_delayed_payment_base_key,
+ self.counterparty_commitment_params.counterparty_htlc_base_key,
+ preimage.unwrap(), htlc.clone()))
+ } else {
+ PackageSolvingData::CounterpartyReceivedHTLCOutput(
+ CounterpartyReceivedHTLCOutput::build(*per_commitment_point,
+ self.counterparty_commitment_params.counterparty_delayed_payment_base_key,
+ self.counterparty_commitment_params.counterparty_htlc_base_key,
+ htlc.clone()))
+ };
let aggregation = if !htlc.offered { false } else { true };
let counterparty_package = PackageTemplate::build_package(commitment_txid, transaction_output_index, counterparty_htlc_outp, htlc.cltv_expiry,aggregation, 0);
claimable_outpoints.push(counterparty_package);
// Produce actionable events from on-chain events having reached their threshold.
for entry in onchain_events_reaching_threshold_conf.drain(..) {
match entry.event {
- OnchainEvent::HTLCUpdate { ref source, payment_hash, onchain_value_satoshis, commitment_tx_output_idx } => {
+ OnchainEvent::HTLCUpdate { ref source, payment_hash, htlc_value_satoshis, commitment_tx_output_idx } => {
// Check for duplicate HTLC resolutions.
#[cfg(debug_assertions)]
{
payment_hash,
payment_preimage: None,
source: source.clone(),
- onchain_value_satoshis,
+ htlc_value_satoshis,
}));
if let Some(idx) = commitment_tx_output_idx {
self.htlcs_resolved_on_chain.push(IrrevocablyResolvedHTLC { commitment_tx_output_idx: idx, payment_preimage: None });
source,
payment_preimage: Some(payment_preimage),
payment_hash,
- onchain_value_satoshis: Some(amount_msat / 1000),
+ htlc_value_satoshis: Some(amount_msat / 1000),
}));
}
} else if offered_preimage_claim {
source,
payment_preimage: Some(payment_preimage),
payment_hash,
- onchain_value_satoshis: Some(amount_msat / 1000),
+ htlc_value_satoshis: Some(amount_msat / 1000),
}));
}
} else {
height,
event: OnchainEvent::HTLCUpdate {
source, payment_hash,
- onchain_value_satoshis: Some(amount_msat / 1000),
+ htlc_value_satoshis: Some(amount_msat / 1000),
commitment_tx_output_idx: Some(input.previous_output.vout),
},
};
let funding_redeemscript = Readable::read(reader)?;
let channel_value_satoshis = Readable::read(reader)?;
- let their_cur_revocation_points = {
+ let their_cur_per_commitment_points = {
let first_idx = <U48 as Readable>::read(reader)?.0;
if first_idx == 0 {
None
counterparty_commitment_params,
funding_redeemscript,
channel_value_satoshis,
- their_cur_revocation_points,
+ their_cur_per_commitment_points,
on_holder_tx_csv,