mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-03-10 13:35:38 +01:00
Merge pull request #2753 from TheBlueMatt/2023-11-inbound-preimages
Provide inbound HTLC preimages to the `EcdsaChannelSigner`
This commit is contained in:
commit
12c2086d58
6 changed files with 44 additions and 30 deletions
|
@ -512,7 +512,8 @@ struct CommitmentStats<'a> {
|
||||||
htlcs_included: Vec<(HTLCOutputInCommitment, Option<&'a HTLCSource>)>, // the list of HTLCs (dust HTLCs *included*) which were not ignored when building the transaction
|
htlcs_included: Vec<(HTLCOutputInCommitment, Option<&'a HTLCSource>)>, // the list of HTLCs (dust HTLCs *included*) which were not ignored when building the transaction
|
||||||
local_balance_msat: u64, // local balance before fees but considering dust limits
|
local_balance_msat: u64, // local balance before fees but considering dust limits
|
||||||
remote_balance_msat: u64, // remote balance before fees but considering dust limits
|
remote_balance_msat: u64, // remote balance before fees but considering dust limits
|
||||||
preimages: Vec<PaymentPreimage>, // preimages for successful offered HTLCs since last commitment
|
outbound_htlc_preimages: Vec<PaymentPreimage>, // preimages for successful offered HTLCs since last commitment
|
||||||
|
inbound_htlc_preimages: Vec<PaymentPreimage>, // preimages for successful received HTLCs since last commitment
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Used when calculating whether we or the remote can afford an additional HTLC.
|
/// Used when calculating whether we or the remote can afford an additional HTLC.
|
||||||
|
@ -1428,6 +1429,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut inbound_htlc_preimages: Vec<PaymentPreimage> = Vec::new();
|
||||||
|
|
||||||
for ref htlc in self.pending_inbound_htlcs.iter() {
|
for ref htlc in self.pending_inbound_htlcs.iter() {
|
||||||
let (include, state_name) = match htlc.state {
|
let (include, state_name) = match htlc.state {
|
||||||
InboundHTLCState::RemoteAnnounced(_) => (!generated_by_local, "RemoteAnnounced"),
|
InboundHTLCState::RemoteAnnounced(_) => (!generated_by_local, "RemoteAnnounced"),
|
||||||
|
@ -1445,7 +1448,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
|
||||||
match &htlc.state {
|
match &htlc.state {
|
||||||
&InboundHTLCState::LocalRemoved(ref reason) => {
|
&InboundHTLCState::LocalRemoved(ref reason) => {
|
||||||
if generated_by_local {
|
if generated_by_local {
|
||||||
if let &InboundHTLCRemovalReason::Fulfill(_) = reason {
|
if let &InboundHTLCRemovalReason::Fulfill(preimage) = reason {
|
||||||
|
inbound_htlc_preimages.push(preimage);
|
||||||
value_to_self_msat_offset += htlc.amount_msat as i64;
|
value_to_self_msat_offset += htlc.amount_msat as i64;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1455,7 +1459,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut preimages: Vec<PaymentPreimage> = Vec::new();
|
|
||||||
|
let mut outbound_htlc_preimages: Vec<PaymentPreimage> = Vec::new();
|
||||||
|
|
||||||
for ref htlc in self.pending_outbound_htlcs.iter() {
|
for ref htlc in self.pending_outbound_htlcs.iter() {
|
||||||
let (include, state_name) = match htlc.state {
|
let (include, state_name) = match htlc.state {
|
||||||
|
@ -1474,7 +1479,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(preimage) = preimage_opt {
|
if let Some(preimage) = preimage_opt {
|
||||||
preimages.push(preimage);
|
outbound_htlc_preimages.push(preimage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if include {
|
if include {
|
||||||
|
@ -1580,7 +1585,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
|
||||||
htlcs_included,
|
htlcs_included,
|
||||||
local_balance_msat: value_to_self_msat as u64,
|
local_balance_msat: value_to_self_msat as u64,
|
||||||
remote_balance_msat: value_to_remote_msat as u64,
|
remote_balance_msat: value_to_remote_msat as u64,
|
||||||
preimages
|
inbound_htlc_preimages,
|
||||||
|
outbound_htlc_preimages,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2178,7 +2184,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
|
||||||
let signature = match &self.holder_signer {
|
let signature = match &self.holder_signer {
|
||||||
// TODO (taproot|arik): move match into calling method for Taproot
|
// TODO (taproot|arik): move match into calling method for Taproot
|
||||||
ChannelSignerType::Ecdsa(ecdsa) => {
|
ChannelSignerType::Ecdsa(ecdsa) => {
|
||||||
ecdsa.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), &self.secp_ctx)
|
ecdsa.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), Vec::new(), &self.secp_ctx)
|
||||||
.map(|(sig, _)| sig).ok()?
|
.map(|(sig, _)| sig).ok()?
|
||||||
},
|
},
|
||||||
// TODO (taproot|arik)
|
// TODO (taproot|arik)
|
||||||
|
@ -2216,7 +2222,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
|
||||||
match &self.holder_signer {
|
match &self.holder_signer {
|
||||||
// TODO (arik): move match into calling method for Taproot
|
// TODO (arik): move match into calling method for Taproot
|
||||||
ChannelSignerType::Ecdsa(ecdsa) => {
|
ChannelSignerType::Ecdsa(ecdsa) => {
|
||||||
let funding_signed = ecdsa.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), &self.secp_ctx)
|
let funding_signed = ecdsa.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), Vec::new(), &self.secp_ctx)
|
||||||
.map(|(signature, _)| msgs::FundingSigned {
|
.map(|(signature, _)| msgs::FundingSigned {
|
||||||
channel_id: self.channel_id(),
|
channel_id: self.channel_id(),
|
||||||
signature,
|
signature,
|
||||||
|
@ -3247,7 +3253,7 @@ impl<SP: Deref> Channel<SP> where
|
||||||
self.context.counterparty_funding_pubkey()
|
self.context.counterparty_funding_pubkey()
|
||||||
);
|
);
|
||||||
|
|
||||||
self.context.holder_signer.as_ref().validate_holder_commitment(&holder_commitment_tx, commitment_stats.preimages)
|
self.context.holder_signer.as_ref().validate_holder_commitment(&holder_commitment_tx, commitment_stats.outbound_htlc_preimages)
|
||||||
.map_err(|_| ChannelError::Close("Failed to validate our commitment".to_owned()))?;
|
.map_err(|_| ChannelError::Close("Failed to validate our commitment".to_owned()))?;
|
||||||
|
|
||||||
// Update state now that we've passed all the can-fail calls...
|
// Update state now that we've passed all the can-fail calls...
|
||||||
|
@ -5780,8 +5786,12 @@ impl<SP: Deref> Channel<SP> where
|
||||||
htlcs.push(htlc);
|
htlcs.push(htlc);
|
||||||
}
|
}
|
||||||
|
|
||||||
let res = ecdsa.sign_counterparty_commitment(&commitment_stats.tx, commitment_stats.preimages, &self.context.secp_ctx)
|
let res = ecdsa.sign_counterparty_commitment(
|
||||||
.map_err(|_| ChannelError::Ignore("Failed to get signatures for new commitment_signed".to_owned()))?;
|
&commitment_stats.tx,
|
||||||
|
commitment_stats.inbound_htlc_preimages,
|
||||||
|
commitment_stats.outbound_htlc_preimages,
|
||||||
|
&self.context.secp_ctx,
|
||||||
|
).map_err(|_| ChannelError::Ignore("Failed to get signatures for new commitment_signed".to_owned()))?;
|
||||||
signature = res.0;
|
signature = res.0;
|
||||||
htlc_signatures = res.1;
|
htlc_signatures = res.1;
|
||||||
|
|
||||||
|
|
|
@ -746,7 +746,7 @@ fn test_update_fee_that_funder_cannot_afford() {
|
||||||
&mut htlcs,
|
&mut htlcs,
|
||||||
&local_chan.context.channel_transaction_parameters.as_counterparty_broadcastable()
|
&local_chan.context.channel_transaction_parameters.as_counterparty_broadcastable()
|
||||||
);
|
);
|
||||||
local_chan_signer.as_ecdsa().unwrap().sign_counterparty_commitment(&commitment_tx, Vec::new(), &secp_ctx).unwrap()
|
local_chan_signer.as_ecdsa().unwrap().sign_counterparty_commitment(&commitment_tx, Vec::new(), Vec::new(), &secp_ctx).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
let commit_signed_msg = msgs::CommitmentSigned {
|
let commit_signed_msg = msgs::CommitmentSigned {
|
||||||
|
@ -1494,7 +1494,7 @@ fn test_fee_spike_violation_fails_htlc() {
|
||||||
&mut vec![(accepted_htlc_info, ())],
|
&mut vec![(accepted_htlc_info, ())],
|
||||||
&local_chan.context.channel_transaction_parameters.as_counterparty_broadcastable()
|
&local_chan.context.channel_transaction_parameters.as_counterparty_broadcastable()
|
||||||
);
|
);
|
||||||
local_chan_signer.as_ecdsa().unwrap().sign_counterparty_commitment(&commitment_tx, Vec::new(), &secp_ctx).unwrap()
|
local_chan_signer.as_ecdsa().unwrap().sign_counterparty_commitment(&commitment_tx, Vec::new(), Vec::new(), &secp_ctx).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
let commit_signed_msg = msgs::CommitmentSigned {
|
let commit_signed_msg = msgs::CommitmentSigned {
|
||||||
|
|
|
@ -29,16 +29,18 @@ pub trait EcdsaChannelSigner: ChannelSigner {
|
||||||
/// Policy checks should be implemented in this function, including checking the amount
|
/// Policy checks should be implemented in this function, including checking the amount
|
||||||
/// sent to us and checking the HTLCs.
|
/// sent to us and checking the HTLCs.
|
||||||
///
|
///
|
||||||
/// The preimages of outgoing HTLCs that were fulfilled since the last commitment are provided.
|
/// The preimages of outbound and inbound HTLCs that were fulfilled since the last commitment
|
||||||
/// A validating signer should ensure that an HTLC output is removed only when the matching
|
/// are provided. A validating signer should ensure that an outbound HTLC output is removed
|
||||||
/// preimage is provided, or when the value to holder is restored.
|
/// only when the matching preimage is provided and after the corresponding inbound HTLC has
|
||||||
|
/// been removed for forwarded payments.
|
||||||
///
|
///
|
||||||
/// Note that all the relevant preimages will be provided, but there may also be additional
|
/// Note that all the relevant preimages will be provided, but there may also be additional
|
||||||
/// irrelevant or duplicate preimages.
|
/// irrelevant or duplicate preimages.
|
||||||
//
|
//
|
||||||
// TODO: Document the things someone using this interface should enforce before signing.
|
// TODO: Document the things someone using this interface should enforce before signing.
|
||||||
fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction,
|
fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction,
|
||||||
preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<secp256k1::All>
|
inbound_htlc_preimages: Vec<PaymentPreimage>,
|
||||||
|
outbound_htlc_preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<secp256k1::All>,
|
||||||
) -> Result<(Signature, Vec<Signature>), ()>;
|
) -> Result<(Signature, Vec<Signature>), ()>;
|
||||||
/// Creates a signature for a holder's commitment transaction.
|
/// Creates a signature for a holder's commitment transaction.
|
||||||
///
|
///
|
||||||
|
|
|
@ -594,14 +594,14 @@ pub trait ChannelSigner {
|
||||||
/// Policy checks should be implemented in this function, including checking the amount
|
/// Policy checks should be implemented in this function, including checking the amount
|
||||||
/// sent to us and checking the HTLCs.
|
/// sent to us and checking the HTLCs.
|
||||||
///
|
///
|
||||||
/// The preimages of outgoing HTLCs that were fulfilled since the last commitment are provided.
|
/// The preimages of outbound HTLCs that were fulfilled since the last commitment are provided.
|
||||||
/// A validating signer should ensure that an HTLC output is removed only when the matching
|
/// A validating signer should ensure that an HTLC output is removed only when the matching
|
||||||
/// preimage is provided, or when the value to holder is restored.
|
/// preimage is provided, or when the value to holder is restored.
|
||||||
///
|
///
|
||||||
/// Note that all the relevant preimages will be provided, but there may also be additional
|
/// Note that all the relevant preimages will be provided, but there may also be additional
|
||||||
/// irrelevant or duplicate preimages.
|
/// irrelevant or duplicate preimages.
|
||||||
fn validate_holder_commitment(&self, holder_tx: &HolderCommitmentTransaction,
|
fn validate_holder_commitment(&self, holder_tx: &HolderCommitmentTransaction,
|
||||||
preimages: Vec<PaymentPreimage>) -> Result<(), ()>;
|
outbound_htlc_preimages: Vec<PaymentPreimage>) -> Result<(), ()>;
|
||||||
|
|
||||||
/// Validate the counterparty's revocation.
|
/// Validate the counterparty's revocation.
|
||||||
///
|
///
|
||||||
|
@ -1086,7 +1086,7 @@ impl ChannelSigner for InMemorySigner {
|
||||||
chan_utils::build_commitment_secret(&self.commitment_seed, idx)
|
chan_utils::build_commitment_secret(&self.commitment_seed, idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_holder_commitment(&self, _holder_tx: &HolderCommitmentTransaction, _preimages: Vec<PaymentPreimage>) -> Result<(), ()> {
|
fn validate_holder_commitment(&self, _holder_tx: &HolderCommitmentTransaction, _outbound_htlc_preimages: Vec<PaymentPreimage>) -> Result<(), ()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1112,7 +1112,7 @@ impl ChannelSigner for InMemorySigner {
|
||||||
const MISSING_PARAMS_ERR: &'static str = "ChannelSigner::provide_channel_parameters must be called before signing operations";
|
const MISSING_PARAMS_ERR: &'static str = "ChannelSigner::provide_channel_parameters must be called before signing operations";
|
||||||
|
|
||||||
impl EcdsaChannelSigner for InMemorySigner {
|
impl EcdsaChannelSigner for InMemorySigner {
|
||||||
fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction, _preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<(Signature, Vec<Signature>), ()> {
|
fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction, _inbound_htlc_preimages: Vec<PaymentPreimage>, _outbound_htlc_preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<(Signature, Vec<Signature>), ()> {
|
||||||
let trusted_tx = commitment_tx.trust();
|
let trusted_tx = commitment_tx.trust();
|
||||||
let keys = trusted_tx.keys();
|
let keys = trusted_tx.keys();
|
||||||
|
|
||||||
|
@ -1260,7 +1260,7 @@ impl TaprootChannelSigner for InMemorySigner {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn partially_sign_counterparty_commitment(&self, counterparty_nonce: PublicNonce, commitment_tx: &CommitmentTransaction, preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<All>) -> Result<(PartialSignatureWithNonce, Vec<schnorr::Signature>), ()> {
|
fn partially_sign_counterparty_commitment(&self, counterparty_nonce: PublicNonce, commitment_tx: &CommitmentTransaction, inbound_htlc_preimages: Vec<PaymentPreimage>, outbound_htlc_preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<All>) -> Result<(PartialSignatureWithNonce, Vec<schnorr::Signature>), ()> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,17 +27,19 @@ pub trait TaprootChannelSigner: ChannelSigner {
|
||||||
/// Policy checks should be implemented in this function, including checking the amount
|
/// Policy checks should be implemented in this function, including checking the amount
|
||||||
/// sent to us and checking the HTLCs.
|
/// sent to us and checking the HTLCs.
|
||||||
///
|
///
|
||||||
/// The preimages of outgoing HTLCs that were fulfilled since the last commitment are provided.
|
/// The preimages of outbound and inbound HTLCs that were fulfilled since the last commitment
|
||||||
/// A validating signer should ensure that an HTLC output is removed only when the matching
|
/// are provided. A validating signer should ensure that an outbound HTLC output is removed
|
||||||
/// preimage is provided, or when the value to holder is restored.
|
/// only when the matching preimage is provided and after the corresponding inbound HTLC has
|
||||||
|
/// been removed for forwarded payments.
|
||||||
///
|
///
|
||||||
/// Note that all the relevant preimages will be provided, but there may also be additional
|
/// Note that all the relevant preimages will be provided, but there may also be additional
|
||||||
/// irrelevant or duplicate preimages.
|
/// irrelevant or duplicate preimages.
|
||||||
//
|
//
|
||||||
// TODO: Document the things someone using this interface should enforce before signing.
|
// TODO: Document the things someone using this interface should enforce before signing.
|
||||||
fn partially_sign_counterparty_commitment(&self, counterparty_nonce: PublicNonce,
|
fn partially_sign_counterparty_commitment(&self, counterparty_nonce: PublicNonce,
|
||||||
commitment_tx: &CommitmentTransaction, preimages: Vec<PaymentPreimage>,
|
commitment_tx: &CommitmentTransaction,
|
||||||
secp_ctx: &Secp256k1<secp256k1::All>,
|
inbound_htlc_preimages: Vec<PaymentPreimage>,
|
||||||
|
outbound_htlc_preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<secp256k1::All>,
|
||||||
) -> Result<(PartialSignatureWithNonce, Vec<Signature>), ()>;
|
) -> Result<(PartialSignatureWithNonce, Vec<Signature>), ()>;
|
||||||
|
|
||||||
/// Creates a signature for a holder's commitment transaction.
|
/// Creates a signature for a holder's commitment transaction.
|
||||||
|
|
|
@ -138,7 +138,7 @@ impl ChannelSigner for TestChannelSigner {
|
||||||
self.inner.release_commitment_secret(idx)
|
self.inner.release_commitment_secret(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_holder_commitment(&self, holder_tx: &HolderCommitmentTransaction, _preimages: Vec<PaymentPreimage>) -> Result<(), ()> {
|
fn validate_holder_commitment(&self, holder_tx: &HolderCommitmentTransaction, _outbound_htlc_preimages: Vec<PaymentPreimage>) -> Result<(), ()> {
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
let idx = holder_tx.commitment_number();
|
let idx = holder_tx.commitment_number();
|
||||||
assert!(idx == state.last_holder_commitment || idx == state.last_holder_commitment - 1, "expecting to validate the current or next holder commitment - trying {}, current {}", idx, state.last_holder_commitment);
|
assert!(idx == state.last_holder_commitment || idx == state.last_holder_commitment - 1, "expecting to validate the current or next holder commitment - trying {}, current {}", idx, state.last_holder_commitment);
|
||||||
|
@ -166,7 +166,7 @@ impl ChannelSigner for TestChannelSigner {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EcdsaChannelSigner for TestChannelSigner {
|
impl EcdsaChannelSigner for TestChannelSigner {
|
||||||
fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction, preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<(Signature, Vec<Signature>), ()> {
|
fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction, inbound_htlc_preimages: Vec<PaymentPreimage>, outbound_htlc_preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<(Signature, Vec<Signature>), ()> {
|
||||||
self.verify_counterparty_commitment_tx(commitment_tx, secp_ctx);
|
self.verify_counterparty_commitment_tx(commitment_tx, secp_ctx);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -185,7 +185,7 @@ impl EcdsaChannelSigner for TestChannelSigner {
|
||||||
state.last_counterparty_commitment = cmp::min(last_commitment_number, actual_commitment_number)
|
state.last_counterparty_commitment = cmp::min(last_commitment_number, actual_commitment_number)
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(self.inner.sign_counterparty_commitment(commitment_tx, preimages, secp_ctx).unwrap())
|
Ok(self.inner.sign_counterparty_commitment(commitment_tx, inbound_htlc_preimages, outbound_htlc_preimages, secp_ctx).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign_holder_commitment(&self, commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()> {
|
fn sign_holder_commitment(&self, commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()> {
|
||||||
|
@ -288,7 +288,7 @@ impl TaprootChannelSigner for TestChannelSigner {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn partially_sign_counterparty_commitment(&self, counterparty_nonce: PublicNonce, commitment_tx: &CommitmentTransaction, preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<All>) -> Result<(PartialSignatureWithNonce, Vec<secp256k1::schnorr::Signature>), ()> {
|
fn partially_sign_counterparty_commitment(&self, counterparty_nonce: PublicNonce, commitment_tx: &CommitmentTransaction, inbound_htlc_preimages: Vec<PaymentPreimage>, outbound_htlc_preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<All>) -> Result<(PartialSignatureWithNonce, Vec<secp256k1::schnorr::Signature>), ()> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue