Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 75 additions & 45 deletions lightning/src/ln/channel.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -1682,6 +1682,10 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider

fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor>;

fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession>;

fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>);

fn dual_funding_context(&self) -> &DualFundingChannelContext;

fn tx_add_input(&mut self, msg: &msgs::TxAddInput) -> InteractiveTxMessageSendResult {
Expand DownExpand Up@@ -1755,13 +1759,20 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider
}

fn funding_tx_constructed<L: Deref>(
&mut self, signing_session: &mut InteractiveTxSigningSession, logger: &L
) -> Result<(msgs::CommitmentSigned, Option<Event>), ChannelError>
&mut self, logger: &L
) -> Result<(Option<msgs::CommitmentSigned>, Option<Event>), ChannelError>
where
L::Target: Logger
{
let our_funding_satoshis = self.dual_funding_context().our_funding_satoshis;
let context = self.context_mut();
let (signing_session, context) = match self.interactive_tx_signing_session_with_context_mut() {
(Some(signing_session), context) => (signing_session, context),
(None, _) => return Err(ChannelError::Close(
(
"No signing session available for commitment signing".to_owned(),
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
))),
};

let mut output_index = None;
let expected_spk = context.get_funding_redeemscript().to_p2wsh();
Expand DownExpand Up@@ -1791,13 +1802,13 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider

let commitment_signed = context.get_initial_commitment_signed(logger);
let commitment_signed = match commitment_signed {
Ok(commitment_signed) => {
Some(commitment_signed) => {
context.funding_transaction = Some(signing_session.unsigned_tx.build_unsigned_tx());
commitment_signed
},
Err(err) => {
None => {
context.channel_transaction_parameters.funding_outpoint = None;
return Err(ChannelError::Close((err.to_string(), ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) })))
return Ok((None, None));
},
};

Expand DownExpand Up@@ -1832,7 +1843,7 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider
// Clear the interactive transaction constructor
self.interactive_tx_constructor_mut().take();

Ok((commitment_signed, funding_ready_for_sig_event))
Ok((Some(commitment_signed), funding_ready_for_sig_event))
}
}

Expand All@@ -1849,6 +1860,12 @@ impl<SP: Deref> InteractivelyFunded<SP> for OutboundV2Channel<SP> where SP::Targ
fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor> {
&mut self.interactive_tx_constructor
}
fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession> {
&mut self.signing_session
}
fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>) {
(&mut self.signing_session, &mut self.context)
}
}

impl<SP: Deref> InteractivelyFunded<SP> for InboundV2Channel<SP> where SP::Target: SignerProvider {
Expand All@@ -1864,6 +1881,12 @@ impl<SP: Deref> InteractivelyFunded<SP> for InboundV2Channel<SP> where SP::Targe
fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor> {
&mut self.interactive_tx_constructor
}
fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession> {
&mut self.signing_session
}
fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>) {
(&mut self.signing_session, &mut self.context)
}
}

impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -4013,7 +4036,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {

fn get_initial_counterparty_commitment_signature<L: Deref>(
&self, logger: &L
) -> Result<Signature, ChannelError>
) -> Option<Signature>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand All@@ -4026,21 +4049,15 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
ChannelSignerType::Ecdsa(ref ecdsa) => {
ecdsa.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), Vec::new(), &self.secp_ctx)
.map(|(signature, _)| signature)
.map_err(|_| ChannelError::Close(
(
"Failed to get signatures for new commitment_signed".to_owned(),
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
)))
.ok()
},
// TODO (taproot|arik)
#[cfg(taproot)]
_ => todo!(),
}
}

fn get_initial_commitment_signed<L: Deref>(
&mut self, logger: &L
) -> Result<msgs::CommitmentSigned, ChannelError>
fn get_initial_commitment_signed<L: Deref>(&mut self, logger: &L) -> Option<msgs::CommitmentSigned>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand All@@ -4052,31 +4069,42 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
}
self.assert_no_commitment_advancement("initial commitment_signed");

let signature = match self.get_initial_counterparty_commitment_signature(logger) {
Ok(res) => res,
Err(e) => {
log_error!(logger, "Got bad signatures: {:?}!", e);
return Err(e);
}
};
match self.get_initial_counterparty_commitment_signature(logger) {
Some(signature) => {
if self.signer_pending_funding {
log_trace!(logger, "Counterparty commitment signature ready for initial commitment_signed message: clearing signer_pending_funding");
self.signer_pending_funding = false;
}

log_info!(logger, "Generated commitment_signed for peer for channel {}", &self.channel_id());
log_info!(logger, "Generated commitment_signed for peer for channel {}", &self.channel_id);

Ok(msgs::CommitmentSigned {
channel_id: self.channel_id,
htlc_signatures: vec![],
signature,
batch: None,
#[cfg(taproot)]
partial_signature_with_nonce: None,
})
Some(msgs::CommitmentSigned {
channel_id: self.channel_id,
htlc_signatures: vec![],
signature,
batch: None,
#[cfg(taproot)]
partial_signature_with_nonce: None,
})
},
None => {
#[cfg(not(async_signing))] {
panic!("Failed to get signature for initial commitment_signed");
}
#[cfg(async_signing)] {
log_trace!(logger, "Counterparty commitment signature not available for initial commitment_signed message; setting signer_pending_funding");
self.signer_pending_funding = true;
None
}
},
}
}

#[cfg(test)]
pub fn get_initial_counterparty_commitment_signature_for_test<L: Deref>(
&mut self, logger: &L, channel_transaction_parameters: ChannelTransactionParameters,
counterparty_cur_commitment_point_override: PublicKey,
) -> Result<Signature, ChannelError>
) -> Option<Signature>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand DownExpand Up@@ -8723,6 +8751,7 @@ pub(super) struct OutboundV2Channel<SP: Deref> where SP::Target: SignerProvider
pub dual_funding_context: DualFundingChannelContext,
/// The current interactive transaction construction session under negotiation.
interactive_tx_constructor: Option<InteractiveTxConstructor>,
signing_session: Option<InteractiveTxSigningSession>,
}

impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -8782,6 +8811,7 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
our_funding_inputs: funding_inputs,
},
interactive_tx_constructor: None,
signing_session: None,
};
Ok(chan)
}
Expand DownExpand Up@@ -8849,13 +8879,12 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
}
}

pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
let channel = Channel {
pub fn into_channel(self) -> Channel<SP> {
debug_assert!(self.signing_session.is_some());
Channel {
context: self.context,
interactive_tx_signing_session: Some(signing_session),
};

Ok(channel)
interactive_tx_signing_session: self.signing_session,
}
}
}

Expand All@@ -8866,6 +8895,7 @@ pub(super) struct InboundV2Channel<SP: Deref> where SP::Target: SignerProvider {
pub dual_funding_context: DualFundingChannelContext,
/// The current interactive transaction construction session under negotiation.
interactive_tx_constructor: Option<InteractiveTxConstructor>,
signing_session: Option<InteractiveTxSigningSession>,
}

impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -8968,6 +8998,7 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
dual_funding_context,
interactive_tx_constructor,
unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 },
signing_session: None,
})
}

Expand DownExpand Up@@ -9043,13 +9074,12 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
self.generate_accept_channel_v2_message()
}

pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
let channel = Channel {
pub fn into_channel(self) -> Channel<SP> {
debug_assert!(self.signing_session.is_some());
Channel {
context: self.context,
interactive_tx_signing_session: Some(signing_session),
};

Ok(channel)
interactive_tx_signing_session: self.signing_session,
}
}
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 75 additions & 45 deletions lightning/src/ln/channel.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -1682,6 +1682,10 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider

fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor>;

fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession>;

fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>);

fn dual_funding_context(&self) -> &DualFundingChannelContext;

fn tx_add_input(&mut self, msg: &msgs::TxAddInput) -> InteractiveTxMessageSendResult {
Expand DownExpand Up@@ -1755,13 +1759,20 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider
}

fn funding_tx_constructed<L: Deref>(
&mut self, signing_session: &mut InteractiveTxSigningSession, logger: &L
) -> Result<(msgs::CommitmentSigned, Option<Event>), ChannelError>
&mut self, logger: &L
) -> Result<(Option<msgs::CommitmentSigned>, Option<Event>), ChannelError>
where
L::Target: Logger
{
let our_funding_satoshis = self.dual_funding_context().our_funding_satoshis;
let context = self.context_mut();
let (signing_session, context) = match self.interactive_tx_signing_session_with_context_mut() {
(Some(signing_session), context) => (signing_session, context),
(None, _) => return Err(ChannelError::Close(
(
"No signing session available for commitment signing".to_owned(),
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
))),
};

let mut output_index = None;
let expected_spk = context.get_funding_redeemscript().to_p2wsh();
Expand DownExpand Up@@ -1791,13 +1802,13 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider

let commitment_signed = context.get_initial_commitment_signed(logger);
let commitment_signed = match commitment_signed {
Ok(commitment_signed) => {
Some(commitment_signed) => {
context.funding_transaction = Some(signing_session.unsigned_tx.build_unsigned_tx());
commitment_signed
},
Err(err) => {
None => {
context.channel_transaction_parameters.funding_outpoint = None;
return Err(ChannelError::Close((err.to_string(), ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) })))
return Ok((None, None));
},
};

Expand DownExpand Up@@ -1832,7 +1843,7 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider
// Clear the interactive transaction constructor
self.interactive_tx_constructor_mut().take();

Ok((commitment_signed, funding_ready_for_sig_event))
Ok((Some(commitment_signed), funding_ready_for_sig_event))
}
}

Expand All@@ -1849,6 +1860,12 @@ impl<SP: Deref> InteractivelyFunded<SP> for OutboundV2Channel<SP> where SP::Targ
fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor> {
&mut self.interactive_tx_constructor
}
fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession> {
&mut self.signing_session
}
fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>) {
(&mut self.signing_session, &mut self.context)
}
}

impl<SP: Deref> InteractivelyFunded<SP> for InboundV2Channel<SP> where SP::Target: SignerProvider {
Expand All@@ -1864,6 +1881,12 @@ impl<SP: Deref> InteractivelyFunded<SP> for InboundV2Channel<SP> where SP::Targe
fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor> {
&mut self.interactive_tx_constructor
}
fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession> {
&mut self.signing_session
}
fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>) {
(&mut self.signing_session, &mut self.context)
}
}

impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -4013,7 +4036,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {

fn get_initial_counterparty_commitment_signature<L: Deref>(
&self, logger: &L
) -> Result<Signature, ChannelError>
) -> Option<Signature>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand All@@ -4026,21 +4049,15 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
ChannelSignerType::Ecdsa(ref ecdsa) => {
ecdsa.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), Vec::new(), &self.secp_ctx)
.map(|(signature, _)| signature)
.map_err(|_| ChannelError::Close(
(
"Failed to get signatures for new commitment_signed".to_owned(),
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
)))
.ok()
},
// TODO (taproot|arik)
#[cfg(taproot)]
_ => todo!(),
}
}

fn get_initial_commitment_signed<L: Deref>(
&mut self, logger: &L
) -> Result<msgs::CommitmentSigned, ChannelError>
fn get_initial_commitment_signed<L: Deref>(&mut self, logger: &L) -> Option<msgs::CommitmentSigned>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand All@@ -4052,31 +4069,42 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
}
self.assert_no_commitment_advancement("initial commitment_signed");

let signature = match self.get_initial_counterparty_commitment_signature(logger) {
Ok(res) => res,
Err(e) => {
log_error!(logger, "Got bad signatures: {:?}!", e);
return Err(e);
}
};
match self.get_initial_counterparty_commitment_signature(logger) {
Some(signature) => {
if self.signer_pending_funding {
log_trace!(logger, "Counterparty commitment signature ready for initial commitment_signed message: clearing signer_pending_funding");
self.signer_pending_funding = false;
}

log_info!(logger, "Generated commitment_signed for peer for channel {}", &self.channel_id());
log_info!(logger, "Generated commitment_signed for peer for channel {}", &self.channel_id);

Ok(msgs::CommitmentSigned {
channel_id: self.channel_id,
htlc_signatures: vec![],
signature,
batch: None,
#[cfg(taproot)]
partial_signature_with_nonce: None,
})
Some(msgs::CommitmentSigned {
channel_id: self.channel_id,
htlc_signatures: vec![],
signature,
batch: None,
#[cfg(taproot)]
partial_signature_with_nonce: None,
})
},
None => {
#[cfg(not(async_signing))] {
panic!("Failed to get signature for initial commitment_signed");
}
#[cfg(async_signing)] {
log_trace!(logger, "Counterparty commitment signature not available for initial commitment_signed message; setting signer_pending_funding");
self.signer_pending_funding = true;
None
}
},
}
}

#[cfg(test)]
pub fn get_initial_counterparty_commitment_signature_for_test<L: Deref>(
&mut self, logger: &L, channel_transaction_parameters: ChannelTransactionParameters,
counterparty_cur_commitment_point_override: PublicKey,
) -> Result<Signature, ChannelError>
) -> Option<Signature>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand DownExpand Up@@ -8723,6 +8751,7 @@ pub(super) struct OutboundV2Channel<SP: Deref> where SP::Target: SignerProvider
pub dual_funding_context: DualFundingChannelContext,
/// The current interactive transaction construction session under negotiation.
interactive_tx_constructor: Option<InteractiveTxConstructor>,
signing_session: Option<InteractiveTxSigningSession>,
}

impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -8782,6 +8811,7 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
our_funding_inputs: funding_inputs,
},
interactive_tx_constructor: None,
signing_session: None,
};
Ok(chan)
}
Expand DownExpand Up@@ -8849,13 +8879,12 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
}
}

pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
let channel = Channel {
pub fn into_channel(self) -> Channel<SP> {
debug_assert!(self.signing_session.is_some());
Channel {
context: self.context,
interactive_tx_signing_session: Some(signing_session),
};

Ok(channel)
interactive_tx_signing_session: self.signing_session,
}
}
}

Expand All@@ -8866,6 +8895,7 @@ pub(super) struct InboundV2Channel<SP: Deref> where SP::Target: SignerProvider {
pub dual_funding_context: DualFundingChannelContext,
/// The current interactive transaction construction session under negotiation.
interactive_tx_constructor: Option<InteractiveTxConstructor>,
signing_session: Option<InteractiveTxSigningSession>,
}

impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -8968,6 +8998,7 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
dual_funding_context,
interactive_tx_constructor,
unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 },
signing_session: None,
})
}

Expand DownExpand Up@@ -9043,13 +9074,12 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
self.generate_accept_channel_v2_message()
}

pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
let channel = Channel {
pub fn into_channel(self) -> Channel<SP> {
debug_assert!(self.signing_session.is_some());
Channel {
context: self.context,
interactive_tx_signing_session: Some(signing_session),
};

Ok(channel)
interactive_tx_signing_session: self.signing_session,
}
}
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 75 additions & 45 deletions lightning/src/ln/channel.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -1682,6 +1682,10 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider

fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor>;

fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession>;

fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>);

fn dual_funding_context(&self) -> &DualFundingChannelContext;

fn tx_add_input(&mut self, msg: &msgs::TxAddInput) -> InteractiveTxMessageSendResult {
Expand DownExpand Up@@ -1755,13 +1759,20 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider
}

fn funding_tx_constructed<L: Deref>(
&mut self, signing_session: &mut InteractiveTxSigningSession, logger: &L
) -> Result<(msgs::CommitmentSigned, Option<Event>), ChannelError>
&mut self, logger: &L
) -> Result<(Option<msgs::CommitmentSigned>, Option<Event>), ChannelError>
where
L::Target: Logger
{
let our_funding_satoshis = self.dual_funding_context().our_funding_satoshis;
let context = self.context_mut();
let (signing_session, context) = match self.interactive_tx_signing_session_with_context_mut() {
(Some(signing_session), context) => (signing_session, context),
(None, _) => return Err(ChannelError::Close(
(
"No signing session available for commitment signing".to_owned(),
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
))),
};

let mut output_index = None;
let expected_spk = context.get_funding_redeemscript().to_p2wsh();
Expand DownExpand Up@@ -1791,13 +1802,13 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider

let commitment_signed = context.get_initial_commitment_signed(logger);
let commitment_signed = match commitment_signed {
Ok(commitment_signed) => {
Some(commitment_signed) => {
context.funding_transaction = Some(signing_session.unsigned_tx.build_unsigned_tx());
commitment_signed
},
Err(err) => {
None => {
context.channel_transaction_parameters.funding_outpoint = None;
return Err(ChannelError::Close((err.to_string(), ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) })))
return Ok((None, None));
},
};

Expand DownExpand Up@@ -1832,7 +1843,7 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider
// Clear the interactive transaction constructor
self.interactive_tx_constructor_mut().take();

Ok((commitment_signed, funding_ready_for_sig_event))
Ok((Some(commitment_signed), funding_ready_for_sig_event))
}
}

Expand All@@ -1849,6 +1860,12 @@ impl<SP: Deref> InteractivelyFunded<SP> for OutboundV2Channel<SP> where SP::Targ
fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor> {
&mut self.interactive_tx_constructor
}
fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession> {
&mut self.signing_session
}
fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>) {
(&mut self.signing_session, &mut self.context)
}
}

impl<SP: Deref> InteractivelyFunded<SP> for InboundV2Channel<SP> where SP::Target: SignerProvider {
Expand All@@ -1864,6 +1881,12 @@ impl<SP: Deref> InteractivelyFunded<SP> for InboundV2Channel<SP> where SP::Targe
fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor> {
&mut self.interactive_tx_constructor
}
fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession> {
&mut self.signing_session
}
fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>) {
(&mut self.signing_session, &mut self.context)
}
}

impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -4013,7 +4036,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {

fn get_initial_counterparty_commitment_signature<L: Deref>(
&self, logger: &L
) -> Result<Signature, ChannelError>
) -> Option<Signature>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand All@@ -4026,21 +4049,15 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
ChannelSignerType::Ecdsa(ref ecdsa) => {
ecdsa.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), Vec::new(), &self.secp_ctx)
.map(|(signature, _)| signature)
.map_err(|_| ChannelError::Close(
(
"Failed to get signatures for new commitment_signed".to_owned(),
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
)))
.ok()
},
// TODO (taproot|arik)
#[cfg(taproot)]
_ => todo!(),
}
}

fn get_initial_commitment_signed<L: Deref>(
&mut self, logger: &L
) -> Result<msgs::CommitmentSigned, ChannelError>
fn get_initial_commitment_signed<L: Deref>(&mut self, logger: &L) -> Option<msgs::CommitmentSigned>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand All@@ -4052,31 +4069,42 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
}
self.assert_no_commitment_advancement("initial commitment_signed");

let signature = match self.get_initial_counterparty_commitment_signature(logger) {
Ok(res) => res,
Err(e) => {
log_error!(logger, "Got bad signatures: {:?}!", e);
return Err(e);
}
};
match self.get_initial_counterparty_commitment_signature(logger) {
Some(signature) => {
if self.signer_pending_funding {
log_trace!(logger, "Counterparty commitment signature ready for initial commitment_signed message: clearing signer_pending_funding");
self.signer_pending_funding = false;
}

log_info!(logger, "Generated commitment_signed for peer for channel {}", &self.channel_id());
log_info!(logger, "Generated commitment_signed for peer for channel {}", &self.channel_id);

Ok(msgs::CommitmentSigned {
channel_id: self.channel_id,
htlc_signatures: vec![],
signature,
batch: None,
#[cfg(taproot)]
partial_signature_with_nonce: None,
})
Some(msgs::CommitmentSigned {
channel_id: self.channel_id,
htlc_signatures: vec![],
signature,
batch: None,
#[cfg(taproot)]
partial_signature_with_nonce: None,
})
},
None => {
#[cfg(not(async_signing))] {
panic!("Failed to get signature for initial commitment_signed");
}
#[cfg(async_signing)] {
log_trace!(logger, "Counterparty commitment signature not available for initial commitment_signed message; setting signer_pending_funding");
self.signer_pending_funding = true;
None
}
},
}
}

#[cfg(test)]
pub fn get_initial_counterparty_commitment_signature_for_test<L: Deref>(
&mut self, logger: &L, channel_transaction_parameters: ChannelTransactionParameters,
counterparty_cur_commitment_point_override: PublicKey,
) -> Result<Signature, ChannelError>
) -> Option<Signature>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand DownExpand Up@@ -8723,6 +8751,7 @@ pub(super) struct OutboundV2Channel<SP: Deref> where SP::Target: SignerProvider
pub dual_funding_context: DualFundingChannelContext,
/// The current interactive transaction construction session under negotiation.
interactive_tx_constructor: Option<InteractiveTxConstructor>,
signing_session: Option<InteractiveTxSigningSession>,
}

impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -8782,6 +8811,7 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
our_funding_inputs: funding_inputs,
},
interactive_tx_constructor: None,
signing_session: None,
};
Ok(chan)
}
Expand DownExpand Up@@ -8849,13 +8879,12 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
}
}

pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
let channel = Channel {
pub fn into_channel(self) -> Channel<SP> {
debug_assert!(self.signing_session.is_some());
Channel {
context: self.context,
interactive_tx_signing_session: Some(signing_session),
};

Ok(channel)
interactive_tx_signing_session: self.signing_session,
}
}
}

Expand All@@ -8866,6 +8895,7 @@ pub(super) struct InboundV2Channel<SP: Deref> where SP::Target: SignerProvider {
pub dual_funding_context: DualFundingChannelContext,
/// The current interactive transaction construction session under negotiation.
interactive_tx_constructor: Option<InteractiveTxConstructor>,
signing_session: Option<InteractiveTxSigningSession>,
}

impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -8968,6 +8998,7 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
dual_funding_context,
interactive_tx_constructor,
unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 },
signing_session: None,
})
}

Expand DownExpand Up@@ -9043,13 +9074,12 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
self.generate_accept_channel_v2_message()
}

pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
let channel = Channel {
pub fn into_channel(self) -> Channel<SP> {
debug_assert!(self.signing_session.is_some());
Channel {
context: self.context,
interactive_tx_signing_session: Some(signing_session),
};

Ok(channel)
interactive_tx_signing_session: self.signing_session,
}
}
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 75 additions & 45 deletions lightning/src/ln/channel.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -1682,6 +1682,10 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider

fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor>;

fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession>;

fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>);

fn dual_funding_context(&self) -> &DualFundingChannelContext;

fn tx_add_input(&mut self, msg: &msgs::TxAddInput) -> InteractiveTxMessageSendResult {
Expand DownExpand Up@@ -1755,13 +1759,20 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider
}

fn funding_tx_constructed<L: Deref>(
&mut self, signing_session: &mut InteractiveTxSigningSession, logger: &L
) -> Result<(msgs::CommitmentSigned, Option<Event>), ChannelError>
&mut self, logger: &L
) -> Result<(Option<msgs::CommitmentSigned>, Option<Event>), ChannelError>
where
L::Target: Logger
{
let our_funding_satoshis = self.dual_funding_context().our_funding_satoshis;
let context = self.context_mut();
let (signing_session, context) = match self.interactive_tx_signing_session_with_context_mut() {
(Some(signing_session), context) => (signing_session, context),
(None, _) => return Err(ChannelError::Close(
(
"No signing session available for commitment signing".to_owned(),
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
))),
};

let mut output_index = None;
let expected_spk = context.get_funding_redeemscript().to_p2wsh();
Expand DownExpand Up@@ -1791,13 +1802,13 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider

let commitment_signed = context.get_initial_commitment_signed(logger);
let commitment_signed = match commitment_signed {
Ok(commitment_signed) => {
Some(commitment_signed) => {
context.funding_transaction = Some(signing_session.unsigned_tx.build_unsigned_tx());
commitment_signed
},
Err(err) => {
None => {
context.channel_transaction_parameters.funding_outpoint = None;
return Err(ChannelError::Close((err.to_string(), ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) })))
return Ok((None, None));
},
};

Expand DownExpand Up@@ -1832,7 +1843,7 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider
// Clear the interactive transaction constructor
self.interactive_tx_constructor_mut().take();

Ok((commitment_signed, funding_ready_for_sig_event))
Ok((Some(commitment_signed), funding_ready_for_sig_event))
}
}

Expand All@@ -1849,6 +1860,12 @@ impl<SP: Deref> InteractivelyFunded<SP> for OutboundV2Channel<SP> where SP::Targ
fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor> {
&mut self.interactive_tx_constructor
}
fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession> {
&mut self.signing_session
}
fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>) {
(&mut self.signing_session, &mut self.context)
}
}

impl<SP: Deref> InteractivelyFunded<SP> for InboundV2Channel<SP> where SP::Target: SignerProvider {
Expand All@@ -1864,6 +1881,12 @@ impl<SP: Deref> InteractivelyFunded<SP> for InboundV2Channel<SP> where SP::Targe
fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor> {
&mut self.interactive_tx_constructor
}
fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession> {
&mut self.signing_session
}
fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>) {
(&mut self.signing_session, &mut self.context)
}
}

impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -4013,7 +4036,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {

fn get_initial_counterparty_commitment_signature<L: Deref>(
&self, logger: &L
) -> Result<Signature, ChannelError>
) -> Option<Signature>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand All@@ -4026,21 +4049,15 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
ChannelSignerType::Ecdsa(ref ecdsa) => {
ecdsa.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), Vec::new(), &self.secp_ctx)
.map(|(signature, _)| signature)
.map_err(|_| ChannelError::Close(
(
"Failed to get signatures for new commitment_signed".to_owned(),
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
)))
.ok()
},
// TODO (taproot|arik)
#[cfg(taproot)]
_ => todo!(),
}
}

fn get_initial_commitment_signed<L: Deref>(
&mut self, logger: &L
) -> Result<msgs::CommitmentSigned, ChannelError>
fn get_initial_commitment_signed<L: Deref>(&mut self, logger: &L) -> Option<msgs::CommitmentSigned>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand All@@ -4052,31 +4069,42 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
}
self.assert_no_commitment_advancement("initial commitment_signed");

let signature = match self.get_initial_counterparty_commitment_signature(logger) {
Ok(res) => res,
Err(e) => {
log_error!(logger, "Got bad signatures: {:?}!", e);
return Err(e);
}
};
match self.get_initial_counterparty_commitment_signature(logger) {
Some(signature) => {
if self.signer_pending_funding {
log_trace!(logger, "Counterparty commitment signature ready for initial commitment_signed message: clearing signer_pending_funding");
self.signer_pending_funding = false;
}

log_info!(logger, "Generated commitment_signed for peer for channel {}", &self.channel_id());
log_info!(logger, "Generated commitment_signed for peer for channel {}", &self.channel_id);

Ok(msgs::CommitmentSigned {
channel_id: self.channel_id,
htlc_signatures: vec![],
signature,
batch: None,
#[cfg(taproot)]
partial_signature_with_nonce: None,
})
Some(msgs::CommitmentSigned {
channel_id: self.channel_id,
htlc_signatures: vec![],
signature,
batch: None,
#[cfg(taproot)]
partial_signature_with_nonce: None,
})
},
None => {
#[cfg(not(async_signing))] {
panic!("Failed to get signature for initial commitment_signed");
}
#[cfg(async_signing)] {
log_trace!(logger, "Counterparty commitment signature not available for initial commitment_signed message; setting signer_pending_funding");
self.signer_pending_funding = true;
None
}
},
}
}

#[cfg(test)]
pub fn get_initial_counterparty_commitment_signature_for_test<L: Deref>(
&mut self, logger: &L, channel_transaction_parameters: ChannelTransactionParameters,
counterparty_cur_commitment_point_override: PublicKey,
) -> Result<Signature, ChannelError>
) -> Option<Signature>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand DownExpand Up@@ -8723,6 +8751,7 @@ pub(super) struct OutboundV2Channel<SP: Deref> where SP::Target: SignerProvider
pub dual_funding_context: DualFundingChannelContext,
/// The current interactive transaction construction session under negotiation.
interactive_tx_constructor: Option<InteractiveTxConstructor>,
signing_session: Option<InteractiveTxSigningSession>,
}

impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -8782,6 +8811,7 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
our_funding_inputs: funding_inputs,
},
interactive_tx_constructor: None,
signing_session: None,
};
Ok(chan)
}
Expand DownExpand Up@@ -8849,13 +8879,12 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
}
}

pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
let channel = Channel {
pub fn into_channel(self) -> Channel<SP> {
debug_assert!(self.signing_session.is_some());
Channel {
context: self.context,
interactive_tx_signing_session: Some(signing_session),
};

Ok(channel)
interactive_tx_signing_session: self.signing_session,
}
}
}

Expand All@@ -8866,6 +8895,7 @@ pub(super) struct InboundV2Channel<SP: Deref> where SP::Target: SignerProvider {
pub dual_funding_context: DualFundingChannelContext,
/// The current interactive transaction construction session under negotiation.
interactive_tx_constructor: Option<InteractiveTxConstructor>,
signing_session: Option<InteractiveTxSigningSession>,
}

impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -8968,6 +8998,7 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
dual_funding_context,
interactive_tx_constructor,
unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 },
signing_session: None,
})
}

Expand DownExpand Up@@ -9043,13 +9074,12 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
self.generate_accept_channel_v2_message()
}

pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
let channel = Channel {
pub fn into_channel(self) -> Channel<SP> {
debug_assert!(self.signing_session.is_some());
Channel {
context: self.context,
interactive_tx_signing_session: Some(signing_session),
};

Ok(channel)
interactive_tx_signing_session: self.signing_session,
}
}
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 75 additions & 45 deletions lightning/src/ln/channel.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -1682,6 +1682,10 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider

fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor>;

fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession>;

fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>);

fn dual_funding_context(&self) -> &DualFundingChannelContext;

fn tx_add_input(&mut self, msg: &msgs::TxAddInput) -> InteractiveTxMessageSendResult {
Expand DownExpand Up@@ -1755,13 +1759,20 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider
}

fn funding_tx_constructed<L: Deref>(
&mut self, signing_session: &mut InteractiveTxSigningSession, logger: &L
) -> Result<(msgs::CommitmentSigned, Option<Event>), ChannelError>
&mut self, logger: &L
) -> Result<(Option<msgs::CommitmentSigned>, Option<Event>), ChannelError>
where
L::Target: Logger
{
let our_funding_satoshis = self.dual_funding_context().our_funding_satoshis;
let context = self.context_mut();
let (signing_session, context) = match self.interactive_tx_signing_session_with_context_mut() {
(Some(signing_session), context) => (signing_session, context),
(None, _) => return Err(ChannelError::Close(
(
"No signing session available for commitment signing".to_owned(),
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
))),
};

let mut output_index = None;
let expected_spk = context.get_funding_redeemscript().to_p2wsh();
Expand DownExpand Up@@ -1791,13 +1802,13 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider

let commitment_signed = context.get_initial_commitment_signed(logger);
let commitment_signed = match commitment_signed {
Ok(commitment_signed) => {
Some(commitment_signed) => {
context.funding_transaction = Some(signing_session.unsigned_tx.build_unsigned_tx());
commitment_signed
},
Err(err) => {
None => {
context.channel_transaction_parameters.funding_outpoint = None;
return Err(ChannelError::Close((err.to_string(), ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) })))
return Ok((None, None));
},
};

Expand DownExpand Up@@ -1832,7 +1843,7 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider
// Clear the interactive transaction constructor
self.interactive_tx_constructor_mut().take();

Ok((commitment_signed, funding_ready_for_sig_event))
Ok((Some(commitment_signed), funding_ready_for_sig_event))
}
}

Expand All@@ -1849,6 +1860,12 @@ impl<SP: Deref> InteractivelyFunded<SP> for OutboundV2Channel<SP> where SP::Targ
fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor> {
&mut self.interactive_tx_constructor
}
fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession> {
&mut self.signing_session
}
fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>) {
(&mut self.signing_session, &mut self.context)
}
}

impl<SP: Deref> InteractivelyFunded<SP> for InboundV2Channel<SP> where SP::Target: SignerProvider {
Expand All@@ -1864,6 +1881,12 @@ impl<SP: Deref> InteractivelyFunded<SP> for InboundV2Channel<SP> where SP::Targe
fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor> {
&mut self.interactive_tx_constructor
}
fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession> {
&mut self.signing_session
}
fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>) {
(&mut self.signing_session, &mut self.context)
}
}

impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -4013,7 +4036,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {

fn get_initial_counterparty_commitment_signature<L: Deref>(
&self, logger: &L
) -> Result<Signature, ChannelError>
) -> Option<Signature>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand All@@ -4026,21 +4049,15 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
ChannelSignerType::Ecdsa(ref ecdsa) => {
ecdsa.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), Vec::new(), &self.secp_ctx)
.map(|(signature, _)| signature)
.map_err(|_| ChannelError::Close(
(
"Failed to get signatures for new commitment_signed".to_owned(),
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
)))
.ok()
},
// TODO (taproot|arik)
#[cfg(taproot)]
_ => todo!(),
}
}

fn get_initial_commitment_signed<L: Deref>(
&mut self, logger: &L
) -> Result<msgs::CommitmentSigned, ChannelError>
fn get_initial_commitment_signed<L: Deref>(&mut self, logger: &L) -> Option<msgs::CommitmentSigned>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand All@@ -4052,31 +4069,42 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
}
self.assert_no_commitment_advancement("initial commitment_signed");

let signature = match self.get_initial_counterparty_commitment_signature(logger) {
Ok(res) => res,
Err(e) => {
log_error!(logger, "Got bad signatures: {:?}!", e);
return Err(e);
}
};
match self.get_initial_counterparty_commitment_signature(logger) {
Some(signature) => {
if self.signer_pending_funding {
log_trace!(logger, "Counterparty commitment signature ready for initial commitment_signed message: clearing signer_pending_funding");
self.signer_pending_funding = false;
}

log_info!(logger, "Generated commitment_signed for peer for channel {}", &self.channel_id());
log_info!(logger, "Generated commitment_signed for peer for channel {}", &self.channel_id);

Ok(msgs::CommitmentSigned {
channel_id: self.channel_id,
htlc_signatures: vec![],
signature,
batch: None,
#[cfg(taproot)]
partial_signature_with_nonce: None,
})
Some(msgs::CommitmentSigned {
channel_id: self.channel_id,
htlc_signatures: vec![],
signature,
batch: None,
#[cfg(taproot)]
partial_signature_with_nonce: None,
})
},
None => {
#[cfg(not(async_signing))] {
panic!("Failed to get signature for initial commitment_signed");
}
#[cfg(async_signing)] {
log_trace!(logger, "Counterparty commitment signature not available for initial commitment_signed message; setting signer_pending_funding");
self.signer_pending_funding = true;
None
}
},
}
}

#[cfg(test)]
pub fn get_initial_counterparty_commitment_signature_for_test<L: Deref>(
&mut self, logger: &L, channel_transaction_parameters: ChannelTransactionParameters,
counterparty_cur_commitment_point_override: PublicKey,
) -> Result<Signature, ChannelError>
) -> Option<Signature>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand DownExpand Up@@ -8723,6 +8751,7 @@ pub(super) struct OutboundV2Channel<SP: Deref> where SP::Target: SignerProvider
pub dual_funding_context: DualFundingChannelContext,
/// The current interactive transaction construction session under negotiation.
interactive_tx_constructor: Option<InteractiveTxConstructor>,
signing_session: Option<InteractiveTxSigningSession>,
}

impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -8782,6 +8811,7 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
our_funding_inputs: funding_inputs,
},
interactive_tx_constructor: None,
signing_session: None,
};
Ok(chan)
}
Expand DownExpand Up@@ -8849,13 +8879,12 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
}
}

pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
let channel = Channel {
pub fn into_channel(self) -> Channel<SP> {
debug_assert!(self.signing_session.is_some());
Channel {
context: self.context,
interactive_tx_signing_session: Some(signing_session),
};

Ok(channel)
interactive_tx_signing_session: self.signing_session,
}
}
}

Expand All@@ -8866,6 +8895,7 @@ pub(super) struct InboundV2Channel<SP: Deref> where SP::Target: SignerProvider {
pub dual_funding_context: DualFundingChannelContext,
/// The current interactive transaction construction session under negotiation.
interactive_tx_constructor: Option<InteractiveTxConstructor>,
signing_session: Option<InteractiveTxSigningSession>,
}

impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -8968,6 +8998,7 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
dual_funding_context,
interactive_tx_constructor,
unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 },
signing_session: None,
})
}

Expand DownExpand Up@@ -9043,13 +9074,12 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
self.generate_accept_channel_v2_message()
}

pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
let channel = Channel {
pub fn into_channel(self) -> Channel<SP> {
debug_assert!(self.signing_session.is_some());
Channel {
context: self.context,
interactive_tx_signing_session: Some(signing_session),
};

Ok(channel)
interactive_tx_signing_session: self.signing_session,
}
}
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 75 additions & 45 deletions lightning/src/ln/channel.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -1682,6 +1682,10 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider

fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor>;

fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession>;

fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>);

fn dual_funding_context(&self) -> &DualFundingChannelContext;

fn tx_add_input(&mut self, msg: &msgs::TxAddInput) -> InteractiveTxMessageSendResult {
Expand DownExpand Up@@ -1755,13 +1759,20 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider
}

fn funding_tx_constructed<L: Deref>(
&mut self, signing_session: &mut InteractiveTxSigningSession, logger: &L
) -> Result<(msgs::CommitmentSigned, Option<Event>), ChannelError>
&mut self, logger: &L
) -> Result<(Option<msgs::CommitmentSigned>, Option<Event>), ChannelError>
where
L::Target: Logger
{
let our_funding_satoshis = self.dual_funding_context().our_funding_satoshis;
let context = self.context_mut();
let (signing_session, context) = match self.interactive_tx_signing_session_with_context_mut() {
(Some(signing_session), context) => (signing_session, context),
(None, _) => return Err(ChannelError::Close(
(
"No signing session available for commitment signing".to_owned(),
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
))),
};

let mut output_index = None;
let expected_spk = context.get_funding_redeemscript().to_p2wsh();
Expand DownExpand Up@@ -1791,13 +1802,13 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider

let commitment_signed = context.get_initial_commitment_signed(logger);
let commitment_signed = match commitment_signed {
Ok(commitment_signed) => {
Some(commitment_signed) => {
context.funding_transaction = Some(signing_session.unsigned_tx.build_unsigned_tx());
commitment_signed
},
Err(err) => {
None => {
context.channel_transaction_parameters.funding_outpoint = None;
return Err(ChannelError::Close((err.to_string(), ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) })))
return Ok((None, None));
},
};

Expand DownExpand Up@@ -1832,7 +1843,7 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider
// Clear the interactive transaction constructor
self.interactive_tx_constructor_mut().take();

Ok((commitment_signed, funding_ready_for_sig_event))
Ok((Some(commitment_signed), funding_ready_for_sig_event))
}
}

Expand All@@ -1849,6 +1860,12 @@ impl<SP: Deref> InteractivelyFunded<SP> for OutboundV2Channel<SP> where SP::Targ
fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor> {
&mut self.interactive_tx_constructor
}
fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession> {
&mut self.signing_session
}
fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>) {
(&mut self.signing_session, &mut self.context)
}
}

impl<SP: Deref> InteractivelyFunded<SP> for InboundV2Channel<SP> where SP::Target: SignerProvider {
Expand All@@ -1864,6 +1881,12 @@ impl<SP: Deref> InteractivelyFunded<SP> for InboundV2Channel<SP> where SP::Targe
fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor> {
&mut self.interactive_tx_constructor
}
fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession> {
&mut self.signing_session
}
fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>) {
(&mut self.signing_session, &mut self.context)
}
}

impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -4013,7 +4036,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {

fn get_initial_counterparty_commitment_signature<L: Deref>(
&self, logger: &L
) -> Result<Signature, ChannelError>
) -> Option<Signature>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand All@@ -4026,21 +4049,15 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
ChannelSignerType::Ecdsa(ref ecdsa) => {
ecdsa.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), Vec::new(), &self.secp_ctx)
.map(|(signature, _)| signature)
.map_err(|_| ChannelError::Close(
(
"Failed to get signatures for new commitment_signed".to_owned(),
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
)))
.ok()
},
// TODO (taproot|arik)
#[cfg(taproot)]
_ => todo!(),
}
}

fn get_initial_commitment_signed<L: Deref>(
&mut self, logger: &L
) -> Result<msgs::CommitmentSigned, ChannelError>
fn get_initial_commitment_signed<L: Deref>(&mut self, logger: &L) -> Option<msgs::CommitmentSigned>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand All@@ -4052,31 +4069,42 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
}
self.assert_no_commitment_advancement("initial commitment_signed");

let signature = match self.get_initial_counterparty_commitment_signature(logger) {
Ok(res) => res,
Err(e) => {
log_error!(logger, "Got bad signatures: {:?}!", e);
return Err(e);
}
};
match self.get_initial_counterparty_commitment_signature(logger) {
Some(signature) => {
if self.signer_pending_funding {
log_trace!(logger, "Counterparty commitment signature ready for initial commitment_signed message: clearing signer_pending_funding");
self.signer_pending_funding = false;
}

log_info!(logger, "Generated commitment_signed for peer for channel {}", &self.channel_id());
log_info!(logger, "Generated commitment_signed for peer for channel {}", &self.channel_id);

Ok(msgs::CommitmentSigned {
channel_id: self.channel_id,
htlc_signatures: vec![],
signature,
batch: None,
#[cfg(taproot)]
partial_signature_with_nonce: None,
})
Some(msgs::CommitmentSigned {
channel_id: self.channel_id,
htlc_signatures: vec![],
signature,
batch: None,
#[cfg(taproot)]
partial_signature_with_nonce: None,
})
},
None => {
#[cfg(not(async_signing))] {
panic!("Failed to get signature for initial commitment_signed");
}
#[cfg(async_signing)] {
log_trace!(logger, "Counterparty commitment signature not available for initial commitment_signed message; setting signer_pending_funding");
self.signer_pending_funding = true;
None
}
},
}
}

#[cfg(test)]
pub fn get_initial_counterparty_commitment_signature_for_test<L: Deref>(
&mut self, logger: &L, channel_transaction_parameters: ChannelTransactionParameters,
counterparty_cur_commitment_point_override: PublicKey,
) -> Result<Signature, ChannelError>
) -> Option<Signature>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand DownExpand Up@@ -8723,6 +8751,7 @@ pub(super) struct OutboundV2Channel<SP: Deref> where SP::Target: SignerProvider
pub dual_funding_context: DualFundingChannelContext,
/// The current interactive transaction construction session under negotiation.
interactive_tx_constructor: Option<InteractiveTxConstructor>,
signing_session: Option<InteractiveTxSigningSession>,
}

impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -8782,6 +8811,7 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
our_funding_inputs: funding_inputs,
},
interactive_tx_constructor: None,
signing_session: None,
};
Ok(chan)
}
Expand DownExpand Up@@ -8849,13 +8879,12 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
}
}

pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
let channel = Channel {
pub fn into_channel(self) -> Channel<SP> {
debug_assert!(self.signing_session.is_some());
Channel {
context: self.context,
interactive_tx_signing_session: Some(signing_session),
};

Ok(channel)
interactive_tx_signing_session: self.signing_session,
}
}
}

Expand All@@ -8866,6 +8895,7 @@ pub(super) struct InboundV2Channel<SP: Deref> where SP::Target: SignerProvider {
pub dual_funding_context: DualFundingChannelContext,
/// The current interactive transaction construction session under negotiation.
interactive_tx_constructor: Option<InteractiveTxConstructor>,
signing_session: Option<InteractiveTxSigningSession>,
}

impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -8968,6 +8998,7 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
dual_funding_context,
interactive_tx_constructor,
unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 },
signing_session: None,
})
}

Expand DownExpand Up@@ -9043,13 +9074,12 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
self.generate_accept_channel_v2_message()
}

pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
let channel = Channel {
pub fn into_channel(self) -> Channel<SP> {
debug_assert!(self.signing_session.is_some());
Channel {
context: self.context,
interactive_tx_signing_session: Some(signing_session),
};

Ok(channel)
interactive_tx_signing_session: self.signing_session,
}
}
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 75 additions & 45 deletions lightning/src/ln/channel.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -1682,6 +1682,10 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider

fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor>;

fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession>;

fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>);

fn dual_funding_context(&self) -> &DualFundingChannelContext;

fn tx_add_input(&mut self, msg: &msgs::TxAddInput) -> InteractiveTxMessageSendResult {
Expand DownExpand Up@@ -1755,13 +1759,20 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider
}

fn funding_tx_constructed<L: Deref>(
&mut self, signing_session: &mut InteractiveTxSigningSession, logger: &L
) -> Result<(msgs::CommitmentSigned, Option<Event>), ChannelError>
&mut self, logger: &L
) -> Result<(Option<msgs::CommitmentSigned>, Option<Event>), ChannelError>
where
L::Target: Logger
{
let our_funding_satoshis = self.dual_funding_context().our_funding_satoshis;
let context = self.context_mut();
let (signing_session, context) = match self.interactive_tx_signing_session_with_context_mut() {
(Some(signing_session), context) => (signing_session, context),
(None, _) => return Err(ChannelError::Close(
(
"No signing session available for commitment signing".to_owned(),
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
))),
};

let mut output_index = None;
let expected_spk = context.get_funding_redeemscript().to_p2wsh();
Expand DownExpand Up@@ -1791,13 +1802,13 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider

let commitment_signed = context.get_initial_commitment_signed(logger);
let commitment_signed = match commitment_signed {
Ok(commitment_signed) => {
Some(commitment_signed) => {
context.funding_transaction = Some(signing_session.unsigned_tx.build_unsigned_tx());
commitment_signed
},
Err(err) => {
None => {
context.channel_transaction_parameters.funding_outpoint = None;
return Err(ChannelError::Close((err.to_string(), ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) })))
return Ok((None, None));
},
};

Expand DownExpand Up@@ -1832,7 +1843,7 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider
// Clear the interactive transaction constructor
self.interactive_tx_constructor_mut().take();

Ok((commitment_signed, funding_ready_for_sig_event))
Ok((Some(commitment_signed), funding_ready_for_sig_event))
}
}

Expand All@@ -1849,6 +1860,12 @@ impl<SP: Deref> InteractivelyFunded<SP> for OutboundV2Channel<SP> where SP::Targ
fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor> {
&mut self.interactive_tx_constructor
}
fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession> {
&mut self.signing_session
}
fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>) {
(&mut self.signing_session, &mut self.context)
}
}

impl<SP: Deref> InteractivelyFunded<SP> for InboundV2Channel<SP> where SP::Target: SignerProvider {
Expand All@@ -1864,6 +1881,12 @@ impl<SP: Deref> InteractivelyFunded<SP> for InboundV2Channel<SP> where SP::Targe
fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor> {
&mut self.interactive_tx_constructor
}
fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession> {
&mut self.signing_session
}
fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>) {
(&mut self.signing_session, &mut self.context)
}
}

impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -4013,7 +4036,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {

fn get_initial_counterparty_commitment_signature<L: Deref>(
&self, logger: &L
) -> Result<Signature, ChannelError>
) -> Option<Signature>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand All@@ -4026,21 +4049,15 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
ChannelSignerType::Ecdsa(ref ecdsa) => {
ecdsa.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), Vec::new(), &self.secp_ctx)
.map(|(signature, _)| signature)
.map_err(|_| ChannelError::Close(
(
"Failed to get signatures for new commitment_signed".to_owned(),
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
)))
.ok()
},
// TODO (taproot|arik)
#[cfg(taproot)]
_ => todo!(),
}
}

fn get_initial_commitment_signed<L: Deref>(
&mut self, logger: &L
) -> Result<msgs::CommitmentSigned, ChannelError>
fn get_initial_commitment_signed<L: Deref>(&mut self, logger: &L) -> Option<msgs::CommitmentSigned>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand All@@ -4052,31 +4069,42 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
}
self.assert_no_commitment_advancement("initial commitment_signed");

let signature = match self.get_initial_counterparty_commitment_signature(logger) {
Ok(res) => res,
Err(e) => {
log_error!(logger, "Got bad signatures: {:?}!", e);
return Err(e);
}
};
match self.get_initial_counterparty_commitment_signature(logger) {
Some(signature) => {
if self.signer_pending_funding {
log_trace!(logger, "Counterparty commitment signature ready for initial commitment_signed message: clearing signer_pending_funding");
self.signer_pending_funding = false;
}

log_info!(logger, "Generated commitment_signed for peer for channel {}", &self.channel_id());
log_info!(logger, "Generated commitment_signed for peer for channel {}", &self.channel_id);

Ok(msgs::CommitmentSigned {
channel_id: self.channel_id,
htlc_signatures: vec![],
signature,
batch: None,
#[cfg(taproot)]
partial_signature_with_nonce: None,
})
Some(msgs::CommitmentSigned {
channel_id: self.channel_id,
htlc_signatures: vec![],
signature,
batch: None,
#[cfg(taproot)]
partial_signature_with_nonce: None,
})
},
None => {
#[cfg(not(async_signing))] {
panic!("Failed to get signature for initial commitment_signed");
}
#[cfg(async_signing)] {
log_trace!(logger, "Counterparty commitment signature not available for initial commitment_signed message; setting signer_pending_funding");
self.signer_pending_funding = true;
None
}
},
}
}

#[cfg(test)]
pub fn get_initial_counterparty_commitment_signature_for_test<L: Deref>(
&mut self, logger: &L, channel_transaction_parameters: ChannelTransactionParameters,
counterparty_cur_commitment_point_override: PublicKey,
) -> Result<Signature, ChannelError>
) -> Option<Signature>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand DownExpand Up@@ -8723,6 +8751,7 @@ pub(super) struct OutboundV2Channel<SP: Deref> where SP::Target: SignerProvider
pub dual_funding_context: DualFundingChannelContext,
/// The current interactive transaction construction session under negotiation.
interactive_tx_constructor: Option<InteractiveTxConstructor>,
signing_session: Option<InteractiveTxSigningSession>,
}

impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -8782,6 +8811,7 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
our_funding_inputs: funding_inputs,
},
interactive_tx_constructor: None,
signing_session: None,
};
Ok(chan)
}
Expand DownExpand Up@@ -8849,13 +8879,12 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
}
}

pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
let channel = Channel {
pub fn into_channel(self) -> Channel<SP> {
debug_assert!(self.signing_session.is_some());
Channel {
context: self.context,
interactive_tx_signing_session: Some(signing_session),
};

Ok(channel)
interactive_tx_signing_session: self.signing_session,
}
}
}

Expand All@@ -8866,6 +8895,7 @@ pub(super) struct InboundV2Channel<SP: Deref> where SP::Target: SignerProvider {
pub dual_funding_context: DualFundingChannelContext,
/// The current interactive transaction construction session under negotiation.
interactive_tx_constructor: Option<InteractiveTxConstructor>,
signing_session: Option<InteractiveTxSigningSession>,
}

impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -8968,6 +8998,7 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
dual_funding_context,
interactive_tx_constructor,
unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 },
signing_session: None,
})
}

Expand DownExpand Up@@ -9043,13 +9074,12 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
self.generate_accept_channel_v2_message()
}

pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
let channel = Channel {
pub fn into_channel(self) -> Channel<SP> {
debug_assert!(self.signing_session.is_some());
Channel {
context: self.context,
interactive_tx_signing_session: Some(signing_session),
};

Ok(channel)
interactive_tx_signing_session: self.signing_session,
}
}
}

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 75 additions & 45 deletions lightning/src/ln/channel.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -1682,6 +1682,10 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider

fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor>;

fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession>;

fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>);

fn dual_funding_context(&self) -> &DualFundingChannelContext;

fn tx_add_input(&mut self, msg: &msgs::TxAddInput) -> InteractiveTxMessageSendResult {
Expand DownExpand Up@@ -1755,13 +1759,20 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider
}

fn funding_tx_constructed<L: Deref>(
&mut self, signing_session: &mut InteractiveTxSigningSession, logger: &L
) -> Result<(msgs::CommitmentSigned, Option<Event>), ChannelError>
&mut self, logger: &L
) -> Result<(Option<msgs::CommitmentSigned>, Option<Event>), ChannelError>
where
L::Target: Logger
{
let our_funding_satoshis = self.dual_funding_context().our_funding_satoshis;
let context = self.context_mut();
let (signing_session, context) = match self.interactive_tx_signing_session_with_context_mut() {
(Some(signing_session), context) => (signing_session, context),
(None, _) => return Err(ChannelError::Close(
(
"No signing session available for commitment signing".to_owned(),
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
))),
};

let mut output_index = None;
let expected_spk = context.get_funding_redeemscript().to_p2wsh();
Expand DownExpand Up@@ -1791,13 +1802,13 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider

let commitment_signed = context.get_initial_commitment_signed(logger);
let commitment_signed = match commitment_signed {
Ok(commitment_signed) => {
Some(commitment_signed) => {
context.funding_transaction = Some(signing_session.unsigned_tx.build_unsigned_tx());
commitment_signed
},
Err(err) => {
None => {
context.channel_transaction_parameters.funding_outpoint = None;
return Err(ChannelError::Close((err.to_string(), ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) })))
return Ok((None, None));
},
};

Expand DownExpand Up@@ -1832,7 +1843,7 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider
// Clear the interactive transaction constructor
self.interactive_tx_constructor_mut().take();

Ok((commitment_signed, funding_ready_for_sig_event))
Ok((Some(commitment_signed), funding_ready_for_sig_event))
}
}

Expand All@@ -1849,6 +1860,12 @@ impl<SP: Deref> InteractivelyFunded<SP> for OutboundV2Channel<SP> where SP::Targ
fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor> {
&mut self.interactive_tx_constructor
}
fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession> {
&mut self.signing_session
}
fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>) {
(&mut self.signing_session, &mut self.context)
}
}

impl<SP: Deref> InteractivelyFunded<SP> for InboundV2Channel<SP> where SP::Target: SignerProvider {
Expand All@@ -1864,6 +1881,12 @@ impl<SP: Deref> InteractivelyFunded<SP> for InboundV2Channel<SP> where SP::Targe
fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor> {
&mut self.interactive_tx_constructor
}
fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession> {
&mut self.signing_session
}
fn interactive_tx_signing_session_with_context_mut(&mut self) -> (&mut Option<InteractiveTxSigningSession>, &mut ChannelContext<SP>) {
(&mut self.signing_session, &mut self.context)
}
}

impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -4013,7 +4036,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {

fn get_initial_counterparty_commitment_signature<L: Deref>(
&self, logger: &L
) -> Result<Signature, ChannelError>
) -> Option<Signature>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand All@@ -4026,21 +4049,15 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
ChannelSignerType::Ecdsa(ref ecdsa) => {
ecdsa.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), Vec::new(), &self.secp_ctx)
.map(|(signature, _)| signature)
.map_err(|_| ChannelError::Close(
(
"Failed to get signatures for new commitment_signed".to_owned(),
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
)))
.ok()
},
// TODO (taproot|arik)
#[cfg(taproot)]
_ => todo!(),
}
}

fn get_initial_commitment_signed<L: Deref>(
&mut self, logger: &L
) -> Result<msgs::CommitmentSigned, ChannelError>
fn get_initial_commitment_signed<L: Deref>(&mut self, logger: &L) -> Option<msgs::CommitmentSigned>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand All@@ -4052,31 +4069,42 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
}
self.assert_no_commitment_advancement("initial commitment_signed");

let signature = match self.get_initial_counterparty_commitment_signature(logger) {
Ok(res) => res,
Err(e) => {
log_error!(logger, "Got bad signatures: {:?}!", e);
return Err(e);
}
};
match self.get_initial_counterparty_commitment_signature(logger) {
Some(signature) => {
if self.signer_pending_funding {
log_trace!(logger, "Counterparty commitment signature ready for initial commitment_signed message: clearing signer_pending_funding");
self.signer_pending_funding = false;
}

log_info!(logger, "Generated commitment_signed for peer for channel {}", &self.channel_id());
log_info!(logger, "Generated commitment_signed for peer for channel {}", &self.channel_id);

Ok(msgs::CommitmentSigned {
channel_id: self.channel_id,
htlc_signatures: vec![],
signature,
batch: None,
#[cfg(taproot)]
partial_signature_with_nonce: None,
})
Some(msgs::CommitmentSigned {
channel_id: self.channel_id,
htlc_signatures: vec![],
signature,
batch: None,
#[cfg(taproot)]
partial_signature_with_nonce: None,
})
},
None => {
#[cfg(not(async_signing))] {
panic!("Failed to get signature for initial commitment_signed");
}
#[cfg(async_signing)] {
log_trace!(logger, "Counterparty commitment signature not available for initial commitment_signed message; setting signer_pending_funding");
self.signer_pending_funding = true;
None
}
},
}
}

#[cfg(test)]
pub fn get_initial_counterparty_commitment_signature_for_test<L: Deref>(
&mut self, logger: &L, channel_transaction_parameters: ChannelTransactionParameters,
counterparty_cur_commitment_point_override: PublicKey,
) -> Result<Signature, ChannelError>
) -> Option<Signature>
where
SP::Target: SignerProvider,
L::Target: Logger
Expand DownExpand Up@@ -8723,6 +8751,7 @@ pub(super) struct OutboundV2Channel<SP: Deref> where SP::Target: SignerProvider
pub dual_funding_context: DualFundingChannelContext,
/// The current interactive transaction construction session under negotiation.
interactive_tx_constructor: Option<InteractiveTxConstructor>,
signing_session: Option<InteractiveTxSigningSession>,
}

impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -8782,6 +8811,7 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
our_funding_inputs: funding_inputs,
},
interactive_tx_constructor: None,
signing_session: None,
};
Ok(chan)
}
Expand DownExpand Up@@ -8849,13 +8879,12 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
}
}

pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
let channel = Channel {
pub fn into_channel(self) -> Channel<SP> {
debug_assert!(self.signing_session.is_some());
Channel {
context: self.context,
interactive_tx_signing_session: Some(signing_session),
};

Ok(channel)
interactive_tx_signing_session: self.signing_session,
}
}
}

Expand All@@ -8866,6 +8895,7 @@ pub(super) struct InboundV2Channel<SP: Deref> where SP::Target: SignerProvider {
pub dual_funding_context: DualFundingChannelContext,
/// The current interactive transaction construction session under negotiation.
interactive_tx_constructor: Option<InteractiveTxConstructor>,
signing_session: Option<InteractiveTxSigningSession>,
}

impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
Expand DownExpand Up@@ -8968,6 +8998,7 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
dual_funding_context,
interactive_tx_constructor,
unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 },
signing_session: None,
})
}

Expand DownExpand Up@@ -9043,13 +9074,12 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
self.generate_accept_channel_v2_message()
}

pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
let channel = Channel {
pub fn into_channel(self) -> Channel<SP> {
debug_assert!(self.signing_session.is_some());
Channel {
context: self.context,
interactive_tx_signing_session: Some(signing_session),
};

Ok(channel)
interactive_tx_signing_session: self.signing_session,
}
}
}

Expand Down
Loading